Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Common Lisp why does the macro OR use a gensym, but not AND?

In Common Lisp (SBCL 1.0.58) why does the macro OR use a gensym, but not AND?

For example,

    CL-USER> (macroexpand '(and 1 2 3 4 5))
    (IF 1
        (AND 2 3 4 5)
        NIL)
    T
    CL-USER> (macroexpand '(or 1 2 3 4 5))
    (LET ((#:G967 1))
      (IF #:G967
          #:G967
          (OR 2 3 4 5)))
    T
    CL-USER> 

I looked at defboot.lisp where the macros are defined but found nothing relevant in the comments.

like image 822
kes Avatar asked Aug 27 '12 18:08

kes


People also ask

Do macros commonly Lisp?

Common Lisp doesn't support macros so every Lisp programmer can create their own variants of standard control constructs any more than C supports functions so every C programmer can write trivial variants of the functions in the C standard library.

How are macros implemented in Lisp?

Macros will be used in Lisp code. During a macroexpansion phase, the Lisp expression will be passed to the macro function. This macro function can do arbitrary computation at macroexpansion time. The result of this call has to be again Lisp code.

What are Lisp macros good for?

The special power that Lisp macros have is that they can control evaluation (as seen by evaluating the input expression via ~expr and do arbitrary source-to-source transformations with the full power of the language available.

How can you define macros in Lisp give an example?

that takes arguments and returns a LISP form to be evaluated. It is useful when the same code has to be executed with a few variable changes. For example, rather than writing the same code for squaring a number, we can define a macro that holds the code for squaring.


1 Answers

That's because the implemented logic operators are intended to be short-circuiting and to return the value produced by the last form they evaluated.

To achieve this, and does not need a gensym because the last form it evaluates will either produce NIL or be the result of the final tail call to itself.

On the other hand, or has to return the first non-NIL value it evaluates, so it cannot rely on the tail call. It needs a gensym to do that, because without one:

(IF 1
    1
    (OR 2 3 4 5))

1 appears twice in the expansion, and in our case that means the expression that produces 1 is evaluated twice. And you never want that in your macros.

like image 100
Frédéric Hamidi Avatar answered Sep 28 '22 05:09

Frédéric Hamidi