[plt-scheme] On macros and Scheme

From: Richard Cleis (rcleis at mac.com)
Date: Wed Dec 19 08:43:42 EST 2007

On Dec 19, 2007, at 3:14 AM, Majorinc, Kazimir wrote:

> Joshua Zucker wrote:
>> I enjoy the blog "Good Math, Bad Math", and the latest installment is
>> particularly relevant to us:
>>   http://scienceblogs.com/goodmath/2007/12/macros_why_theyre_evil.php
>>
>> Basically he says that macros are evil, and some are eviller than
>> others, but, well, maybe Scheme gets it right, and if only there were
>> a macro debugger ...
>>
>> I think these PLT guys have something figured out, maybe :)
>>
> Macro Stepper is really good one, but author is right, macros are  
> bad, they are hard to debug, macro expansion is very space and time  
> consuming - unsuitable for runtime generated code, not first-class  
> citizens ... Macro semantics and syntax of macro call is still more  
> handy/powerful than functions, but with few I'd say, feasible  
> improvements in Scheme semantics, functions could do everything  
> macros can. Look at this two functions:
>
> (define (display-expression-and-value expr env)
>  (parameterize ((current-namespace env))
>                (display "(evaluates-to ")
>                (display expr)
>                (display " ")
>                (display (eval expr))
>                (display ") \n")))
>
> (define (++ var env)
>  (parameterize ((current-namespace env))
>                (eval `(set! ,var (+ (eval ,var) 1)))))
>
> (define x 4)
> (display-expression-and-value '(+ x x) (current-namespace))
> (++ 'x (current-namespace))
> (display x)
>
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
> ;
> ;(evaluates-to (+ x x) 8)
> ;5
>
> This is typically done by macros, namespaces make it possible by  
> function. Unfortunately, syntax of the function call in this  
> example is quite a bit uglier and eval does not recognize all  
> variables - but really only few small steps are left from this  
> point to making macros obsolete.

In your example, the point of a macro would be to allow the  
expression and value to be displayed without requiring a change in  
syntax.  Your function requires quoting the expression; I wouldn't  
want to have to explain that to anyone who uses my software... it's  
hard enough to get them to use Scheme in the first place.  They ought  
to be able to type

(display (+ x x))

to get 4, and type

(display-expression-and-value (+ x x))

to get the result you specified.


Scheme macros are difficult to debug if they are used to do difficult  
things.  Doesn't that apply to any form of programming?  In your  
simple example, it might be tempting to write a macro like:

(define-syntax display-x&v
   (syntax-rules ()
     ((_ expr)
      (begin
        (display "evaluates-to ")
        (display 'expr)
        (display " ")
        (display expr)
        (newline)))))

and then claim that it is hard to debug all of those display  
functions.  But a macro that requires almost no debugging could call  
a function that contains the debugging 'requirement' :

(define-syntax display-expression-and-value
   (syntax-rules ()
     ((_ expr)
      (dx&v 'expr expr))))

(define  (dx&v expr val)
   (display "evaluates-to ")
   (display expr)
   (display " ")
   (display val)
   (newline))

In other words: you could debug the function using
'(+ x x) and (+ x x)
for arguments, then easily write the macro.

rac






>
>
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.