[plt-scheme] Macro changing behaviour

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Tue Apr 21 18:44:59 EDT 2009

On Apr 21, 2009, at 6:30 PM, Paulo J. Matos wrote:

> Hi all,
>
> I have a simple issue:
> (define-syntax-rule (test proc . args)
>  (apply proc args))
> (test (lambda () (+ 1 1)))
>
> doesn't work. Generates:
> #%app: missing procedure expression; probably originally (), which is
> an illegal empty application in: (#%app)
>
> But this works:
> (apply (lambda () (+ 1 1)) '())
>
> So, somewhere this goes wrong. Can someone explain me what's the  
> issue?

Your example expands into this expression (see using the macro stepper):

(apply (lambda () (+ 1 1)) ())

The second argument, (), is illegal in PLT Scheme v4. The error says '# 
%app' because it is interpreted as an empty application, which is not  
allowed.

--

Let's back up and look at the skeleton of your macro again:

(define-syntax-rule (test proc . args)
   (apply proc ???))

What is 'args'?
Well, it's probably supposed to be a (syntax) list of expressions.

What do you need for the final argument of 'apply'?
It must be an expression resulting in a list. (Not the same as a list  
of expressions!)

How do you form an expression resulting in a list from a list of  
expressions?
Use the list procedure.

Here's the macro, rewritten:

(define-syntax-rule (test proc . args)
   (apply proc (list . args))

or, more idiomatically:

(define-syntax-rule (test proc arg ...)
   (apply proc (list arg ...))

Ryan



Posted on the users mailing list.