[racket] macro vs function differing results

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Feb 7 11:40:05 EST 2014

The `=defun` macro introduces the `*cont*` binding as the argument of
`=foo`. Hygienic macro expansion ensures that this macro-introduced
bindings does not capture uses of `*cont*` that appear in the macro
use. Specifically, the `*cont*` in

   (=defun (foo x) *cont*)

refers to the module-level definition, and not to the macro-introduced
argument.

To implement a macro along the lines of `=defun`, probably you want to
use `define-syntax-parameter` and `syntax-parameterize`.

At Fri, 7 Feb 2014 08:37:04 -0700, Kevin Forchione wrote:
> I’m trying to resolve why I get differing results in a let form when using a 
> macro versus using the expanded function version. Here’s an example using 
> racket 5.93:
> 
> #lang racket
> 
> (require (for-syntax racket/syntax))
> 
> (define *cont* identity)
> 
> (define-syntax (=defun stx)
>   (syntax-case stx ()
>     [(_ (name parm ...) body ...)
>      (with-syntax ([f (format-id stx "=~a" #'name)]
>                    [*cont* (format-id stx "~a" '*cont*)])
>        #'(begin
>            (define-syntax-rule (name parm ...)
>              (f *cont* parm ...))
>            (define (f *cont* parm ...) body ...)))]))
> 
> (=defun (foo x) *cont*)
> 
> (let ([*cont* cdr])
>     (foo 10))
> => #<procedure:identity>
> 
> (let ([*cont* cdr])
>     (=foo *cont* 10))
> => #<procedure:cdr>
> 
> Why does the macro return identity, while the function returns cdd?
> 
> Thanks!
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users


Posted on the users mailing list.