Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>Short answer</strong> Bypass the default evaluation rules and do <em>not</em> evaluate the expression (symbol or s-exp), passing it along to the function exactly as typed.</p> <p><strong>Long Answer: The Default Evaluation Rule</strong></p> <p>When a regular (I'll come to that later) function is invoked, all arguments passed to it are evaluated. This means you can write this:</p> <pre><code>(* (+ a 2) 3) </code></pre> <p>Which in turn evaluates <code>(+ a 2)</code>, by evaluating <code>a</code> and 2. The value of the symbol <code>a</code> is looked up in the current variable binding set, and then replaced. Say <code>a</code> is currently bound to the value 3:</p> <pre><code>(let ((a 3)) (* (+ a 2) 3)) </code></pre> <p>We'd get <code>(+ 3 2)</code>, + is then invoked on 3 and 2 yielding 5. Our original form is now <code>(* 5 3)</code> yielding 15.</p> <p><strong>Explain <code>quote</code> Already!</strong></p> <p>Alright. As seen above, all arguments to a function are evaluated, so if you would like to pass the <em>symbol</em> <code>a</code> and not its value, you don't want to evaluate it. Lisp symbols can double both as their values, and markers where you in other languages would have used strings, such as keys to hash tables.</p> <p>This is where <code>quote</code> comes in. Say you want to plot resource allocations from a Python application, but rather do the plotting in Lisp. Have your Python app do something like this:</p> <pre><code>print "'(" while allocating: if random.random() &gt; 0.5: print "(allocate %d)" random.randint(0, 20) else: print "(free %d)" % random.randint(0, 20) ... print ")" </code></pre> <p>Giving you output looking like this (slightly prettyfied):</p> <pre><code>'((allocate 3) (allocate 7) (free 14) (allocate 19) ...) </code></pre> <p>Remember what I said about <code>quote</code> ("tick") causing the default rule not to apply? Good. What would otherwise happen is that the values of <code>allocate</code> and <code>free</code> are looked up, and we don't want that. In our Lisp, we wish to do:</p> <pre><code>(dolist (entry allocation-log) (case (first entry) (allocate (plot-allocation (second entry))) (free (plot-free (second entry))))) </code></pre> <p>For the data given above, the following sequence of function calls would have been made:</p> <pre><code>(plot-allocation 3) (plot-allocation 7) (plot-free 14) (plot-allocation 19) </code></pre> <p><strong>But What About <code>list</code>?</strong></p> <p>Well, sometimes you <em>do</em> want to evaluate the arguments. Say you have a nifty function manipulating a number and a string and returning a list of the resulting ... things. Let's make a false start:</p> <pre><code>(defun mess-with (number string) '(value-of-number (1+ number) something-with-string (length string))) Lisp&gt; (mess-with 20 "foo") (VALUE-OF-NUMBER (1+ NUMBER) SOMETHING-WITH-STRING (LENGTH STRING)) </code></pre> <p>Hey! That's not what we wanted. We want to <em>selectively</em> evaluate some arguments, and leave the others as symbols. Try #2!</p> <pre><code>(defun mess-with (number string) (list 'value-of-number (1+ number) 'something-with-string (length string))) Lisp&gt; (mess-with 20 "foo") (VALUE-OF-NUMBER 21 SOMETHING-WITH-STRING 3) </code></pre> <p><strong>Not Just <code>quote</code>, But <code>backquote</code></strong></p> <p>Much better! Incidently, this pattern is so common in (mostly) macros, that there is special syntax for doing just that. The backquote:</p> <pre><code>(defun mess-with (number string) `(value-of-number ,(1+ number) something-with-string ,(length string))) </code></pre> <p>It's like using <code>quote</code>, but with the option to explicitly evaluate some arguments by prefixing them with comma. The result is equivalent to using <code>list</code>, but if you're generating code from a macro you often only want to evaluate small parts of the code returned, so the backquote is more suited. For shorter lists, <code>list</code> can be more readable.</p> <p><strong>Hey, You Forgot About <code>quote</code>!</strong></p> <p>So, where does this leave us? Oh right, what does <code>quote</code> actually do? It simply returns its argument(s) unevaluated! Remember what I said in the beginning about regular functions? Turns out that some operators/functions need to <em>not</em> evaluate their arguments. Such as IF -- you wouldn't want the else branch to be evaluated if it wasn't taken, right? So-called <em>special operators</em>, together with macros, work like that. Special operators are also the "axiom" of the language -- minimal set of rules -- upon which you can implement the rest of Lisp by combining them together in different ways. </p> <p>Back to <code>quote</code>, though:</p> <pre><code>Lisp&gt; (quote spiffy-symbol) SPIFFY-SYMBOL Lisp&gt; 'spiffy-symbol ; ' is just a shorthand ("reader macro"), as shown above SPIFFY-SYMBOL </code></pre> <p>Compare to (on Steel-Bank Common Lisp):</p> <pre><code>Lisp&gt; spiffy-symbol debugger invoked on a UNBOUND-VARIABLE in thread #&lt;THREAD "initial thread" RUNNING {A69F6A9}&gt;: The variable SPIFFY-SYMBOL is unbound. Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level. (SB-INT:SIMPLE-EVAL-IN-LEXENV SPIFFY-SYMBOL #&lt;NULL-LEXENV&gt;) 0] </code></pre> <p>Because there is no <code>spiffy-symbol</code> in the current scope!</p> <p><strong>Summing Up</strong></p> <p><code>quote</code>, <code>backquote</code> (with comma), and <code>list</code> are some of the tools you use to create lists, that are not only lists of values, but as you seen can be used as lightweight (no need to define a <code>struct</code>) data structures!</p> <p>If you wish to learn more, I recommend Peter Seibel's book <a href="http://gigamonkeys.com/book" rel="noreferrer">Practical Common Lisp</a> for a practical approach to learning Lisp, if you're already into programming at large. Eventually on your Lisp journey, you'll start using packages too. Ron Garret's <a href="http://www.flownet.com/ron/packages.pdf" rel="noreferrer">The Idiot's Guide to Common Lisp Packages</a> will give you good explanation of those.</p> <p>Happy hacking!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload