1
votes

I am recently learning scheme and curious at a design that a macro can't be evaluated without an identifier, while a lambda(procedure) can be done so.

For example, I can use an anonymous lambda as this:

((lambda x x) 1 2 3)

Where it seems I have to define a macro using the following syntax:

(define-macro my-macro (lambda x x))

I am curious why there's so a such method do create a macro directly like this:

(define my-macro (macro-lambda x x))

I suppose if regard a macro and a lambda as different types, the second one might be more elegant.

My questions are:

  1. what does define-macro do?
  2. what's the fundamental difference between a macro and a lambda?
  3. are there anonymous macros in scheme, if not, why?
2

2 Answers

5
votes

First an example of how to emulate an "anonymous macro". Then I'll comment on the usefulness.

Consider this anonymous macro transformer, that takes a syntax object representing a number and returns a new syntax object representing the double of the input number.

(λ (stx) 
  (datum->syntax stx
    (* 2 (syntax->datum stx))))

We can test it like this:

> ((λ (stx) 
    (datum->syntax stx
      (* 2 (syntax->datum stx))))
  #'3)

The result is a syntax object with a 6.

If we want the actual number 6, we can use eval.

> (eval ((λ (stx) 
          (datum->syntax stx
            (* 2 (syntax->datum stx))))
        #'3))
6

Now we have used the anonymous syntax transformer to rewrite the 3 into a 6.

Is an anonymous macro useful?

Anonymous functions are used in places where you a function, but you only need it once. If the same anonymous functions is used twice in a program, it would be better to give it a name, and then just refer to it twice.

The same is the case for syntax transformations. If you need the same transformation at least twice, you should give it a name. The only time an anonymous syntax transformation would make sense is, if it were used once only. In most cases it will be simpler just to write the result of the transformation. I can't think of an example, where an anonymous transformation would make things simpler.

Note: All examples were tested in Racket.

0
votes

Macros are transforming the tree at compile time whereas the rest of the code is executed at run time.

In general, both operations (macro expansion and lisp code execution) are procedures working on lists. I.e. there is no fundamental difference in lambda for macros and for procedures, it is just the time at which they are executed. This means that a few other problems arise, such as naming, etc.

(define ..) is executed at run time, so your suggestion would not really work I think.

So the defmacro syntax is making clear that a macro is a normal function but evaluated at compile time. macro-lambda would rather shadow this.