1
0
Fork 0
cl-sites/lisp-docs.github.io/docs/tutorial/macros.html

82 lines
No EOL
97 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-tutorial/macros" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.0.1">
<title data-rh="true">Macros | Common Lisp Docs</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://lisp-docs.github.io/img/1024px-Lisp_logo.svg.png"><meta data-rh="true" name="twitter:image" content="https://lisp-docs.github.io/img/1024px-Lisp_logo.svg.png"><meta data-rh="true" property="og:url" content="https://lisp-docs.github.io/docs/tutorial/macros"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="google-site-verification" content="Vzaw013_bfdKeUVG89Ch3W1zC9_vH9ID2dPB9Dz0vr0"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Macros | Common Lisp Docs"><meta data-rh="true" name="description" content="One of the most distinctive features of Common Lisp is its macros. Macros are special functions which operate on code before it is compiled. In most other languages, code is strutured according to a fairly complex syntax, which is parsed to generate an abstract syntax tree. This is designed to be used internally by the compiler or interpreter and writing functions which operate on code is generally very challenging."><meta data-rh="true" property="og:description" content="One of the most distinctive features of Common Lisp is its macros. Macros are special functions which operate on code before it is compiled. In most other languages, code is strutured according to a fairly complex syntax, which is parsed to generate an abstract syntax tree. This is designed to be used internally by the compiler or interpreter and writing functions which operate on code is generally very challenging."><link data-rh="true" rel="icon" href="../../img/favicon.ico"><link data-rh="true" rel="canonical" href="macros.html"><link data-rh="true" rel="alternate" href="macros.html" hreflang="en"><link data-rh="true" rel="alternate" href="macros.html" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://C1F2Q5VM6X-dsn.algolia.net" crossorigin="anonymous"><link rel="alternate" type="application/rss+xml" href="../../blog/rss.xml" title="Common Lisp Docs RSS Feed">
<link rel="alternate" type="application/atom+xml" href="../../blog/atom.xml" title="Common Lisp Docs Atom Feed">
<link rel="search" type="application/opensearchdescription+xml" title="Common Lisp Docs" href="../../opensearch.xml"><link rel="stylesheet" href="../../assets/css/styles.d316d1e5.css">
<script src="../../assets/js/runtime~main.eb788e4f.js" defer="defer"></script>
<script src="../../assets/js/main.8eecaa6d.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return localStorage.getItem("theme")}catch(t){}}();t(null!==e?e:"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="macros.html#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="../../index.html"><div class="navbar__logo"><img src="../../img/logo.svg" alt="Lisp Logo" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="../../img/logo.svg" alt="Lisp Logo" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate">Common Lisp Docs</b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="../tutorial.html">Tutorial</a><a href="../../cl-language-reference/index.html" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Technical Reference</a><a class="navbar__item navbar__link" href="../whylisp.html">Why Lisp?</a><a class="navbar__item navbar__link" href="../howto.html">Guides</a></div><div class="navbar__items navbar__items--right"><a class="navbar__item navbar__link" href="../contribute.html">Contribute!</a><a class="navbar__item navbar__link" href="../help.html">Getting Help</a><a class="navbar__item navbar__link" href="../about.html">About</a><a class="navbar__item navbar__link" href="../../blog.html">Blog</a><a href="https://github.com/lisp-docs" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="Switch between dark and light mode (currently light mode)" aria-label="Switch between dark and light mode (currently light mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg></button></div><div class="navbarSearchContainer_Bca1"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0"><div class="docsWrapper_hBAB"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docRoot_UBD9"><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class="sidebarViewport_aRkj"><div class="sidebar_njMd"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="../tutorial.html">Tutorial Introduction</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="for_beginners.html">Beginner Programmers</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="for_programmers.html">Experienced Programmers</a><button aria-label="Expand sidebar category &#x27;Experienced Programmers&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" href="macros.html">Macros</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="projects.html">Structuring projects</a><button aria-label="Expand sidebar category &#x27;Structuring projects&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="documentation.html">Documenting your Code</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="motivation.html">Motivation</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="using-cl-implementation.html">Using a Common Lisp Implementation</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="informal-introduction-to-lisp.html">An Informal Introduction to Common Lisp</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="control-flows.html">Control Flow</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="data-structures.html">Data Structures</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="processing-data.html">Processing Data</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="io.html">Input and Output</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="errors.html">Dealing with Errors</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="classes-methods.html">Classes and Methods</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist" aria-expanded="false" href="../category/advanced-topics.html">Advanced Topics</a><button aria-label="Expand sidebar category &#x27;Advanced Topics&#x27;" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="https://lisp-docs.github.io/docs/tutorial/index">Index</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="glossary.html">Glossary</a></li></ul></nav></div></div></aside><main class="docMainContainer_TBSr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="../../index.html"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">Macros</span><meta itemprop="position" content="1"></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><h1>Macros</h1>
<p>One of the most distinctive features of Common Lisp is its macros. Macros are special functions which operate on code before it is compiled. In most other languages, code is strutured according to a fairly complex syntax, which is parsed to generate an abstract syntax tree. This is designed to be used internally by the compiler or interpreter and writing functions which operate on code is generally very challenging.
Lisp code is already structed as a tree, written with s-expressions and read in as a familiar cons structure which can be manipulated in the same way as any other data. This equivalance between code and data is described by the Greek word &quot;homoiconicity&quot; meaning &quot;same representation&quot;, and it makes Lisp macros particularly powerful and easy to write.</p>
<p>Macros have multiple uses. They can introduce new syntax to the language, control when code is evaluated and how many times, or make programs more efficient by doing computation at compile time. This tutorial will explore some simple but useful examples.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="and">And<a href="macros.html#and" class="hash-link" aria-label="Direct link to And" title="Direct link to And"></a></h2>
<p>Suppose we have some lisp forms and we want to check they all evaluate to true. The obvious way to write this is (and a b c), where a b and c are some arbitrary lisp forms. We could implement this as a function, using rest parameters and recursion to operate on an arbitrary number of values before returning either the final value, or nil if any of the other values are nil.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token defun keyword" style="color:#00009f">defun</span><span class="token defun"> </span><span class="token defun function" style="color:#d73a49">and</span><span class="token defun"> </span><span class="token defun punctuation" style="color:#393A34">(</span><span class="token defun arguments rest-vars lisp-marker">&amp;rest</span><span class="token defun arguments rest-vars"> </span><span class="token defun arguments rest-vars argument variable" style="color:#36acaa">values</span><span class="token defun punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">when</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">car</span><span class="token plain"> values</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">cdr</span><span class="token plain"> values</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">and</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">cdr</span><span class="token plain"> values</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">car</span><span class="token plain"> values</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">and</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token number" style="color:#36acaa">3</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">and</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">nil</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This seems to work, but suppose we are writing a control system for a rocket silo. We want to perform a sequence of operations, checking each stage returns a true value to indicate it has been successfully completed.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">and</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">open-doors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">prime-fuel-tanks</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">launch-rocket</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="order-of-evaluation">Order of evaluation<a href="macros.html#order-of-evaluation" class="hash-link" aria-label="Direct link to Order of evaluation" title="Direct link to Order of evaluation"></a></h3>
<p>Why did our silo just blow up?</p>
<p>These are all functions with side effects. Calling open-doors sends a signal to open the doors and then returns t if sensors indicate the doors have opened correctly or nil otherwise. When a function is called all of its arguments are all evaluated first, followed by the body of the function. This means that our <code>and</code> expression will try to open the doors, prime the fuel tanks and launch the rocket, and only afterwards check the doors opened successfully.</p>
<p>With a macro we can control exactly when the evaluation happens</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token defun keyword" style="color:#00009f">defmacro</span><span class="token defun"> </span><span class="token defun function" style="color:#d73a49">%and</span><span class="token defun"> </span><span class="token defun punctuation" style="color:#393A34">(</span><span class="token defun arguments rest-vars lisp-marker">&amp;rest</span><span class="token defun arguments rest-vars"> </span><span class="token defun arguments rest-vars argument variable" style="color:#36acaa">forms</span><span class="token defun punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">list</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;when</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">car</span><span class="token plain"> forms</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">cddr</span><span class="token plain"> forms</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">cons</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;%and</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">cdr</span><span class="token plain"> forms</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">cadr</span><span class="token plain"> forms</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Our missile silo controller is expanded at compile time to</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">open-doors</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">prime-fuel-tanks</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">launch-rocket</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>If an argument evaluates to nil, the chain of <code>if</code> statements is broken and none of the remaining arguments are evaulated.</p>
<p>Notice that <code>(when a b)</code> is itself a macro invocation, which expands to <code>(if a b)</code>. Many expressions which require special syntax in other languages are implemented as macros in Lisp. The AND macro is part of the language specification which means it is provided by all Common Lisp implementations, usually with code similar to our example.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="backquote">Backquote<a href="macros.html#backquote" class="hash-link" aria-label="Direct link to Backquote" title="Direct link to Backquote"></a></h2>
<p>Common Lisp&#x27;s backquote syntax is very useful tool for constructing code in macros and complex data structures generally. Instead of constructing a data structure with functions like <code>cons</code> <code>list</code> and <code>append</code>, one can simple write a quoted template and insert values into it by unquoting with commas.
For instance, instead of</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">append</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">&#x27;(</span><span class="token car">there</span><span class="token plain"> will be</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">incf</span><span class="token plain"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">&#x27;(</span><span class="token car">green</span><span class="token plain"> bottles standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>With backquote we can write</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token defvar keyword" style="color:#00009f">defvar</span><span class="token defvar"> </span><span class="token defvar variable" style="color:#36acaa">n</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">N</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token punctuation" style="color:#393A34">,(</span><span class="token car">decf</span><span class="token plain"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> green bottles standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token number" style="color:#36acaa">9</span><span class="token plain"> green bottles standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token punctuation" style="color:#393A34">,(</span><span class="token car">decf</span><span class="token plain"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> green bottles standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token number" style="color:#36acaa">8</span><span class="token plain"> green bottles standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>The comma unquotes the expression following it so it is evaluated as if it were outside the quote. n is decremented and the result is inserted into the quoted structure.</p>
<p>Lists can also be unquoted with <code>,@</code> which splices the contents of the list into the surrounding structure. Compare</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token defvar keyword" style="color:#00009f">defvar</span><span class="token defvar"> </span><span class="token defvar variable" style="color:#36acaa">object</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">&#x27;(</span><span class="token car">green</span><span class="token plain"> bottle</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">OBJECT</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,object</span><span class="token plain"> standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">green</span><span class="token plain"> bottle</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,@object</span><span class="token plain"> standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">there</span><span class="token plain"> will be </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> green bottle standing on the wall</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>Backquote is extremely useful for generating code in macros. Subsequent examples will make heavy use of it.</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="comparing-numbers">Comparing numbers<a href="macros.html#comparing-numbers" class="hash-link" aria-label="Direct link to Comparing numbers" title="Direct link to Comparing numbers"></a></h2>
<p>Quite often a program needs to compare two numbers and do something different depending on which is larger. In Lisp we could use a <code>cond</code> form like this</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">cond</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&lt;</span><span class="token plain"> x y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">y-is-bigger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">=</span><span class="token plain"> x y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">both-equal</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">t</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x-is-bigger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This is quite long winded for such a common pattern. It would be clearer and more convenient if we could write something like <code>(compare (x y) (y-is-bigger) (x-is-bigger) (both-equal))</code>. Luckily with macros we can.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token defun keyword" style="color:#00009f">defmacro</span><span class="token defun"> </span><span class="token defun function" style="color:#d73a49">compare</span><span class="token defun"> </span><span class="token defun punctuation" style="color:#393A34">(</span><span class="token defun arguments punctuation" style="color:#393A34">(</span><span class="token defun arguments argument variable" style="color:#36acaa">a</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">b</span><span class="token defun arguments punctuation" style="color:#393A34">)</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&lt;</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">=</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&gt;</span><span class="token defun punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token keyword" style="color:#00009f">cond</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&lt;</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,a</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&lt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">=</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,a</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,=</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">t</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="destructuring-lambda-lists">Destructuring lambda lists<a href="macros.html#destructuring-lambda-lists" class="hash-link" aria-label="Direct link to Destructuring lambda lists" title="Direct link to Destructuring lambda lists"></a></h3>
<p>Unlike ordinary functions where arguments are interpreted and bound according to an ordinary lambda list, the arguments to a macro are destructured, and defined by a destructuring lambda list. This means we can define a macro which takes structured arguments and have the variables bound automatically. In <code>compare</code> we have put <code>a</code> and <code>b</code> into their own list for clarity.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">y</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">compare</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;y-is-bigger</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;both-equal</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;x-is-bigger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">X-IS-BIGGER</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>This appears to work but there is a problem.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">11</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">y</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">compare</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">decf</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;b-is-bigger</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;both-equal</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;a-is-bigger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">A-IS-BIGGER</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="unintentional-repeated-evaluation">Unintentional repeated evaluation<a href="macros.html#unintentional-repeated-evaluation" class="hash-link" aria-label="Direct link to Unintentional repeated evaluation" title="Direct link to Unintentional repeated evaluation"></a></h3>
<p>If x is 11, <code>(decf x)</code> will decrement <code>x</code> and return 10, so the result we would expect is BOTH-EQUAL.
What is happening is that when the first test, <code>(&lt; ,a ,b)</code>, fails, a and b are evaluated again in the second test where we have <code>(= ,a ,b)</code>. Arguments to a macro are not evaluated until after the macro is expanded, so if our macro returns a form which contains <code>a</code> twice, it will be evaluated twice. For functions which have side effects or require a lot of computation, this is not good.</p>
<p>We can solve this problem by generating code to evaluate a and b and bind them to variables before comparing them.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token defun keyword" style="color:#00009f">defmacro</span><span class="token defun"> </span><span class="token defun function" style="color:#d73a49">compare</span><span class="token defun"> </span><span class="token defun punctuation" style="color:#393A34">(</span><span class="token defun arguments punctuation" style="color:#393A34">(</span><span class="token defun arguments argument variable" style="color:#36acaa">a</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">b</span><span class="token defun arguments punctuation" style="color:#393A34">)</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&lt;</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">=</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&gt;</span><span class="token defun punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">a</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">b</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">cond</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&lt;</span><span class="token plain"> a b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&lt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">=</span><span class="token plain"> a b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,=</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">t</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">11</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">y</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">compare</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">decf</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;b-is-bigger</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;both-equal</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;a-is-bigger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">BOTH-EQUAL</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="unintentional-variable-capture">Unintentional variable capture<a href="macros.html#unintentional-variable-capture" class="hash-link" aria-label="Direct link to Unintentional variable capture" title="Direct link to Unintentional variable capture"></a></h3>
<p>Good, now <code>(decf x)</code> is only performed once and the result is equal to y. Have we finished? How about this?</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">y</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">a</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;y-is-bigger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">b</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;both-equal</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">c</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;x-is-bigger</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">compare</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> a b c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">10</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>What has happened here? We expected to get back the value of a: <code>&#x27;y-is-bigger</code>. Instead of which the value of x has leaked through, replacing the value we supplied. Let&#x27;s look at the expansion of this macro (we can get the result of expanding a macro at runtime with the <code>macroexpand</code> function)</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">* </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">macroexpand</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">&#x27;(</span><span class="token car">compare</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">x</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> a b c</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">LET</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">A</span><span class="token plain"> X</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">B</span><span class="token plain"> Y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">COND</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&lt;</span><span class="token plain"> A B</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> A</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">=</span><span class="token plain"> A B</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> B</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">T</span><span class="token plain"> C</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="gensym">Gensym<a href="macros.html#gensym" class="hash-link" aria-label="Direct link to Gensym" title="Direct link to Gensym"></a></h3>
<p>Looking at the expanded form it&#x27;s quite obvious what is going wrong. <code>x</code> is bound to <code>a</code> in the code produced by the macro which overrides the outer binding of a to &#x27;y-is-bigger. We could get around this by coming up with more obscure names for bindings in macros, but there is a better solution. The function <code>gensym</code> returns a new uninterned symbol. Gensyms are guarenteed to be unique because no uninterned symbol is eq to any other, so if we bind a value to a gensym, we can be certain no other variables will be accidentally captured.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token defun keyword" style="color:#00009f">defmacro</span><span class="token defun"> </span><span class="token defun function" style="color:#d73a49">compare</span><span class="token defun"> </span><span class="token defun punctuation" style="color:#393A34">(</span><span class="token defun arguments punctuation" style="color:#393A34">(</span><span class="token defun arguments argument variable" style="color:#36acaa">a</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">b</span><span class="token defun arguments punctuation" style="color:#393A34">)</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&lt;</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">=</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&gt;</span><span class="token defun punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">asym</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">gensym</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">bsym</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">gensym</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token splice symbol variable" style="color:#36acaa">,asym</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,a</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token splice symbol variable" style="color:#36acaa">,bsym</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">cond</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&lt;</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,asym</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,bsym</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&lt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">=</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,asym</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,bsym</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,=</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">t</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="once-only">Once-only<a href="macros.html#once-only" class="hash-link" aria-label="Direct link to Once-only" title="Direct link to Once-only"></a></h3>
<p>This can be expressed far more elegantly using the <code>once-only</code> macro, originally written by Peter Norvig and available in the Alexandria utility library. <code>once-only</code> automatically introduces gensym bindings for expressions in exactly the same way as the previous example.</p>
<div class="language-lisp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-lisp codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">require</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;alexandria</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">import</span><span class="token plain"> </span><span class="token quoted-symbol variable symbol" style="color:#36acaa">&#x27;alexandria</span><span class="token lisp-property property" style="color:#36acaa">:once-only</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">(</span><span class="token defun keyword" style="color:#00009f">defmacro</span><span class="token defun"> </span><span class="token defun function" style="color:#d73a49">compare</span><span class="token defun"> </span><span class="token defun punctuation" style="color:#393A34">(</span><span class="token defun arguments punctuation" style="color:#393A34">(</span><span class="token defun arguments argument variable" style="color:#36acaa">a</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">b</span><span class="token defun arguments punctuation" style="color:#393A34">)</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&lt;</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">=</span><span class="token defun arguments"> </span><span class="token defun arguments argument variable" style="color:#36acaa">&gt;</span><span class="token defun punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">once-only</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">a</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">`(</span><span class="token keyword" style="color:#00009f">cond</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">&lt;</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,a</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&lt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token car">=</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,a</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,=</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">t</span><span class="token plain"> </span><span class="token splice symbol variable" style="color:#36acaa">,&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="understanding-macros">Understanding Macros<a href="macros.html#understanding-macros" class="hash-link" aria-label="Direct link to Understanding Macros" title="Direct link to Understanding Macros"></a></h2>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="time-of-evaluation">Time of Evaluation<a href="macros.html#time-of-evaluation" class="hash-link" aria-label="Direct link to Time of Evaluation" title="Direct link to Time of Evaluation"></a></h3>
<p>\ </p>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="the--comma--back-quote-and--quote-operators">The <code>,</code> Comma, <code>`</code> Back Quote, and <code>&#x27;</code> Quote operators<a href="macros.html#the--comma--back-quote-and--quote-operators" class="hash-link" aria-label="Direct link to the--comma--back-quote-and--quote-operators" title="Direct link to the--comma--back-quote-and--quote-operators"></a></h3>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="the--splice-operator">The <code>@</code> Splice operator<a href="macros.html#the--splice-operator" class="hash-link" aria-label="Direct link to the--splice-operator" title="Direct link to the--splice-operator"></a></h3>
<h3 class="anchor anchorWithStickyNavbar_LWe7" id="declaring-variables-with-gensym">Declaring Variables with GENSYM<a href="macros.html#declaring-variables-with-gensym" class="hash-link" aria-label="Direct link to Declaring Variables with GENSYM" title="Direct link to Declaring Variables with GENSYM"></a></h3>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="variable-capture">Variable Capture<a href="macros.html#variable-capture" class="hash-link" aria-label="Direct link to Variable Capture" title="Direct link to Variable Capture"></a></h2>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="classic-macro-pitfalls">Classic Macro Pitfalls<a href="macros.html#classic-macro-pitfalls" class="hash-link" aria-label="Direct link to Classic Macro Pitfalls" title="Direct link to Classic Macro Pitfalls"></a></h2>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="reader-macros">Reader Macros<a href="macros.html#reader-macros" class="hash-link" aria-label="Direct link to Reader Macros" title="Direct link to Reader Macros"></a></h2></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class="col"><a href="https://github.com/lisp-docs/lisp-docs.github.io/tree/main/docs/tutorial/macros.md" target="_blank" rel="noopener noreferrer" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_Z9Sw" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_vwxv"><span class="theme-last-updated">Last updated<!-- --> by <b>Daniel Nussenbaum</b></span></div></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="for_programmers/scheme.html"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">CL from Scheme</div></a><a class="pagination-nav__link pagination-nav__link--next" href="projects.html"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Structuring Projects</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="macros.html#and" class="table-of-contents__link toc-highlight">And</a><ul><li><a href="macros.html#order-of-evaluation" class="table-of-contents__link toc-highlight">Order of evaluation</a></li></ul></li><li><a href="macros.html#backquote" class="table-of-contents__link toc-highlight">Backquote</a></li><li><a href="macros.html#comparing-numbers" class="table-of-contents__link toc-highlight">Comparing numbers</a><ul><li><a href="macros.html#destructuring-lambda-lists" class="table-of-contents__link toc-highlight">Destructuring lambda lists</a></li><li><a href="macros.html#unintentional-repeated-evaluation" class="table-of-contents__link toc-highlight">Unintentional repeated evaluation</a></li><li><a href="macros.html#unintentional-variable-capture" class="table-of-contents__link toc-highlight">Unintentional variable capture</a></li><li><a href="macros.html#gensym" class="table-of-contents__link toc-highlight">Gensym</a></li><li><a href="macros.html#once-only" class="table-of-contents__link toc-highlight">Once-only</a></li></ul></li><li><a href="macros.html#understanding-macros" class="table-of-contents__link toc-highlight">Understanding Macros</a><ul><li><a href="macros.html#time-of-evaluation" class="table-of-contents__link toc-highlight">Time of Evaluation</a></li><li><a href="macros.html#the--comma--back-quote-and--quote-operators" class="table-of-contents__link toc-highlight">The <code>,</code> Comma, <code>`</code> Back Quote, and <code>&#39;</code> Quote operators</a></li><li><a href="macros.html#the--splice-operator" class="table-of-contents__link toc-highlight">The <code>@</code> Splice operator</a></li><li><a href="macros.html#declaring-variables-with-gensym" class="table-of-contents__link toc-highlight">Declaring Variables with GENSYM</a></li></ul></li><li><a href="macros.html#variable-capture" class="table-of-contents__link toc-highlight">Variable Capture</a></li><li><a href="macros.html#classic-macro-pitfalls" class="table-of-contents__link toc-highlight">Classic Macro Pitfalls</a></li><li><a href="macros.html#reader-macros" class="table-of-contents__link toc-highlight">Reader Macros</a></li></ul></div></div></div></div></main></div></div></div><footer class="footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="../tutorial.html">Common Lisp Tutorial</a></li><li class="footer__item"><a href="../../cl-language-reference/index.html" target="_blank" rel="noopener noreferrer" class="footer__link-item">Common Lisp Technical Reference</a></li><li class="footer__item"><a class="footer__link-item" href="../help.html">Help</a></li></ul></div><div class="col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://stackoverflow.com/questions/tagged/common-lisp" target="_blank" rel="noopener noreferrer" class="footer__link-item">Stack Overflow<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/hhk46CE" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://www.reddit.com/r/common_lisp" target="_blank" rel="noopener noreferrer" class="footer__link-item">Reddit<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://irclog.tymoon.eu/libera/commonlisp" target="_blank" rel="noopener noreferrer" class="footer__link-item">IRC<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">More</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="../../blog.html">Blog</a></li><li class="footer__item"><a href="https://github.com/lisp-docs/lisp-docs.github.io" target="_blank" rel="noopener noreferrer" class="footer__link-item">Tutorial and General Content GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://github.com/lisp-docs/cl-language-reference/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Technical Reference GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="../contribute.html">Contribute to the Docs</a></li></ul></div><div class="col footer__col"><div class="footer__title">Common Lisp Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="../about.html">About</a></li><li class="footer__item"><a class="footer__link-item" href="../whylisp.html">Why Lisp</a></li><li class="footer__item"><a class="footer__link-item" href="../getting-started.html">Getting Started</a></li><li class="footer__item"><a class="footer__link-item" href="../faq.html">FAQ</a></li><li class="footer__item"><a class="footer__link-item" href="../help.html">Getting Help</a></li><li class="footer__item"><a class="footer__link-item" href="../howto.html">How To Guides</a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2024 Common Lisp Docs, MIT License (see GitHub Repo).</div></div></div></footer></div>
</body>
</html>