<h4>Quoting and Unquoting in Common Lisp</h4> <p>Thursday, Nov 23, 2023</p> <p> Reading <u>Let Over Lambda</u> (LOL), and in Chapter 3 he demonstrates how to create macros that will only evaluate a form once. The macro is <code>defmacro!</code> and on page 60 he gives an example of it's use and the results. </p> <pre> (defmacro! square (o!x) `(progn (format t "[~a gives ~a]~%") ',o!x ,g!x) (* ,g!x ,g!x)) </pre> <p> Note the <code>quote-unquote (',)</code> preceding <code>o!x</code> </p> <p> The thing I have to remember is that macros do not evaluate the forms they are given, but return forms to be evaluated later. </p> <p>To show how this works, set a variable to a form that is quoted.</p> <pre> CL-USER> (defvar b '(+ 1 3)) (+ 1 3) </pre> <p>The REPL returns the form unevaluated.</p> <p>If we use it in an expression, backquote the expression and unquote symbol B, we will see how it expands. </p> <pre> CL-USER> `(+ 1 ,b) (+ 1 (+ 1 3)) </pre> <p>And if we evaluate the above it will return 5.</p> <pre> CL-USER> (eval `(+ 1 ,b)) 5 </pre> <p>BUT, if we quote-unquote it, the top-level returns:</p> <pre> CL-USER> `(+ 1 ',b) (+ 1 '(+ 1 3)) </pre> <p>If we were to evaluate the above it would throw us into the debugger because of <code>'(+ 1 3)</code> </p> <p> To evaluate it without throwing an error we need to perform two evaluations: </p> <pre> CL-USER> (eval `(+ 1 (eval ',b))) 5 </pre> <p> This also demonstrates how functions evaluate their arguments first BEFORE they perform the calculations in defined in the function. </p> <p> With macros, they do not evaluate their arguments. Macros return forms to be evaluated later. Thus, when a macro is given an expression <code>(+ 1 3)</code> it needs to be unquoted in order to be evaluated at a later time (remember when defining macros everything is wrapped in a backquote). </p>