3

What is the effect and use of ', in backquoted expressions in lisp? Does it have a name and is it documented somewhere? And how common and useful is it?

For example:

(defmacro test-exp (exp)
  `(format t "~&~S => ~S~%" ',exp ,exp))

My guess is that here it will take whatever exp literally is, at macro expansion time, and replace ',exp with it. (As opposed to evaluating exp and replacing ,exp with it).

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
Michele Piccolini
  • 2,634
  • 16
  • 29

2 Answers2

7

You guessed right.

quote

The special operator quote defines an expression which evaluates to its subform, literally. For example:

(quote (looks like a function call))

The inner form looks like a function call, but for the Lisp reader, this is just a list of symbols. The expression (quote ...) evaluates to that list, without trying to evaluate the list as code.

There is special syntax for quoting expression, the quote character, so that 'exp is the same as (quote exp). That's usually how you write symbols when you don't want to evaluate them.

backquote / comma

Quasiquotation is a way to quote only part of an expression.

The backtick acts like a quote: the data inside it is not evaluated, except when they are prefixed by a comma, in which case evaluation is toggle back on. The following expression

`(format t "~s" ,exp)

... could be written:

(list 'format 't '"~s" exp)

I added quotes before literals that otherwise would be self-evaluating, for completeness, but in practice you would write the same list as follows:

(list 'format t "~s" exp)

Here exp is evaluated, and the whole form gives a list that ressembles a call to format, where env is replaced by whatever its value is.

quote comma

The quote/comma combo you see in the example is a common idiom where you want to put an argument given at macroexpansion time (i.e. code) literally in the code being expanded, without evaluating it. If you test your macro by macroexpanding it, you can see the resulting code:

(macroexpand '(test-exp (+ 5 8)))

=> (FORMAT T "~&~S => ~S~%" '(+ 5 8) (+ 5 8))

The literal (+ 5 8) form is placed within a (quote ...) form, making it unevaluated at runtime. Meanwhile, the same expression is put as-is next to it, thus evaluating it at runtime. If you evaluate the resulting expression, it prints:

 (+ 5 8) => 13
coredump
  • 37,664
  • 5
  • 43
  • 77
  • `',exp` is essentially `(quote (unquote exp))`. I understand `unquote` makes sense only inside a `quasiquote`. I suspect `',exp` is different from `exp` only if `quote` and `unquote` are run in compile time. Am I right? Can they differ in functions also? – pii_ke May 25 '21 at 20:43
3

', can only be used in backquoted expressions. They are two different reader macros ' for quoting and the , for evaluation in backquoted s-expressions. The comma can only appear in a backquoted expression.

`(a ',(+ 1 2))

Above is the same as

`(a (QUOTE ,(+ 1 2)))

Since ' is a reader macro for quote.

Thus it is having a similar effect as:

(list (quote a) (list (quote quote) (+ 1 2)))

which evaluates to

(A (QUOTE 3))

Compare

`(a ',(+ 1 2))

with the evaluated result

(A (QUOTE 3))

It basically quotes the evaluated result of (+ 1 2) and includes it in the list.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346