When to use ' (or quote) in Lisp? -
after making through major parts of introductory lisp book, still couldn't understand special operator (quote)
(or equivalent '
) function does, yet has been on lisp code i've seen.
what do?
short answer bypass default evaluation rules , not evaluate expression (symbol or s-exp), passing along function typed.
long answer: default evaluation rule
when regular (i'll come later) function invoked, arguments passed evaluated. means can write this:
(* (+ 2) 3)
which in turn evaluates (+ 2)
, evaluating a
, 2. value of symbol a
looked in current variable binding set, , replaced. a
bound value 3:
(let ((a 3)) (* (+ 2) 3))
we'd (+ 3 2)
, + invoked on 3 , 2 yielding 5. our original form (* 5 3)
yielding 15.
explain quote
already!
alright. seen above, arguments function evaluated, if pass symbol a
, not value, don't want evaluate it. lisp symbols can double both values, , markers in other languages have used strings, such keys hash tables.
this quote
comes in. want plot resource allocations python application, rather plotting in lisp. have python app this:
print "'(" while allocating: if random.random() > 0.5: print "(allocate %d)" random.randint(0, 20) else: print "(free %d)" % random.randint(0, 20) ... print ")"
giving output looking (slightly prettyfied):
'((allocate 3) (allocate 7) (free 14) (allocate 19) ...)
remember said quote
("tick") causing default rule not apply? good. otherwise happen values of allocate
, free
looked up, , don't want that. in our lisp, wish do:
(dolist (entry allocation-log) (case (first entry) (allocate (plot-allocation (second entry))) (free (plot-free (second entry)))))
for data given above, following sequence of function calls have been made:
(plot-allocation 3) (plot-allocation 7) (plot-free 14) (plot-allocation 19)
but list
?
well, do want evaluate arguments. have nifty function manipulating number , string , returning list of resulting ... things. let's make false start:
(defun mess-with (number string) '(value-of-number (1+ number) something-with-string (length string))) lisp> (mess-with 20 "foo") (value-of-number (1+ number) something-with-string (length string))
hey! that's not wanted. want selectively evaluate arguments, , leave others symbols. try #2!
(defun mess-with (number string) (list 'value-of-number (1+ number) 'something-with-string (length string))) lisp> (mess-with 20 "foo") (value-of-number 21 something-with-string 3)
not quote
, backquote
much better! incidently, pattern common in (mostly) macros, there special syntax doing that. backquote:
(defun mess-with (number string) `(value-of-number ,(1+ number) something-with-string ,(length string)))
it's using quote
, option explicitly evaluate arguments prefixing them comma. result equivalent using list
, if you're generating code macro want evaluate small parts of code returned, backquote more suited. shorter lists, list
can more readable.
hey, forgot quote
!
so, leave us? oh right, quote
do? returns argument(s) unevaluated! remember said in beginning regular functions? turns out operators/functions need not evaluate arguments. such if -- wouldn't want else branch evaluated if wasn't taken, right? so-called special operators, macros, work that. special operators "axiom" of language -- minimal set of rules -- upon can implement rest of lisp combining them in different ways.
back quote
, though:
lisp> (quote spiffy-symbol) spiffy-symbol lisp> 'spiffy-symbol ; ' shorthand ("reader macro"), shown above spiffy-symbol
compare (on steel-bank common lisp):
lisp> spiffy-symbol debugger invoked on unbound-variable in thread #<thread "initial thread" running {a69f6a9}>: variable spiffy-symbol unbound. type debugger help, or (sb-ext:quit) exit sbcl. restarts (invokable number or possibly-abbreviated name): 0: [abort] exit debugger, returning top level. (sb-int:simple-eval-in-lexenv spiffy-symbol #<null-lexenv>) 0]
because there no spiffy-symbol
in current scope!
summing up
quote
, backquote
(with comma), , list
of tools use create lists, not lists of values, seen can used lightweight (no need define struct
) data structures!
if wish learn more, recommend peter seibel's book practical common lisp practical approach learning lisp, if you're programming @ large. on lisp journey, you'll start using packages too. ron garret's the idiot's guide common lisp packages give explanation of those.
happy hacking!
Comments
Post a Comment