Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the @ sign needed in this macro definition?

In the following when macro:

(defmacro when (condition &rest body)
  `(if ,condition (progn ,@body)))

Why is there an "at" @ sign?

like image 911
Luke Avatar asked Apr 14 '11 10:04

Luke


People also ask

What does ## mean in AC macro?

The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.

What is# define macro?

The #define creates a macro, which is the association of an identifier or parameterized identifier with a token string. After the macro is defined, the compiler can substitute the token string for each occurrence of the identifier in the source file.

What is a macro call definition?

SC26-4940-06. A macro definition is a named sequence of statements you can call with a macro instruction. When it is called, the assembler processes and normally generates assembler language statements from the definition into the source module.

What is mean by macro definition How do you write macro macro expansion?

Macro represents a group of commonly used statements in the source programming language. Macro Processor replaces each macro instruction with the corresponding group of source language statements. This is known as the expansion of macros.


2 Answers

The @ can also be thought of deconstructing the list and appending it to the list appears in as described in Practical Common Lisp.

`(a ,@(list 1 2) c) 

is the equivalent of:

(append (list 'a) (list 1 2) (list 'c)) 

which produces:

(a 1 2 c)
like image 22
Gewthen Avatar answered Sep 18 '22 08:09

Gewthen


When inserting computed values in quasiquoted section there are two operators:

  • The "comma" operator ,
  • The "comma-splice" operator ,@

Comma , inserts the value of following expression in the quasi-quoted sexpr, comma-splice instead requires the expression following is a list and can be used only inside a quasi-quoted list: the effect is inserting all elements of the expression in the quasi-quoted list in the position where the operator appears.

It's very easy to see the difference by making a little experiment

> (let ((x '(1 2 3 4))) `(this is an example ,x of expansion))
(THIS IS AN EXAMPLE (1 2 3 4) OF EXPANSION)

> (let ((x '(1 2 3 4))) `(this is an example ,@x of expansion))
(THIS IS AN EXAMPLE 1 2 3 4 OF EXPANSION)

As you can see the use of ,@ will place the elements of the list directly inside in the expansion. Without you get instead the list placed in the expansion.

Using ,@ with an expression that doesn't result in a list will be an error when the substitution is performed:

* (defun f (x) `(here ,@x we go))
F
* (f '(1 2 3))
(HERE 1 2 3 WE GO)
* (f '99)

debugger invoked on a TYPE-ERROR in thread
#<THREAD "main thread" RUNNING {10009F80D3}>:
  The value
    99
  is not of type
    LIST
  when binding SB-IMPL::X

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-IMPL::APPEND2 99 (WE GO)) [external]
0] 

Using ,@ not inside a list is instead an error when the quasi-quoted section is analyzed:

* (defun g (x) `,@x)

debugger invoked on a SB-INT:SIMPLE-READER-ERROR in thread
#<THREAD "main thread" RUNNING {10009F80D3}>:
  `,@X is not a well-formed backquote expression

    Stream: #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDIN* {10000279E3}>

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-IMPL::BACKQUOTE-CHARMACRO #<SYNONYM-STREAM :SYMBOL SB-SYS:*STDIN* {10000279E3}> #<unused argument>)
0] 
like image 99
6502 Avatar answered Sep 17 '22 08:09

6502