[racket] for/hash: bad syntax in: for/hash

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Tue Jan 3 15:06:26 EST 2012

Would syntax/parse have done better? 


On Jan 3, 2012, at 2:15 PM, Eli Barzilay wrote:

> Two hours ago, Marijn wrote:
>> Hi,
>> 
>> for/hash is giving me a syntax-error, but the error is in
>> macro-expanded code which is not shown by default and which is also
>> seemingly inaccessible via the macro-stepper. The for/hash
>> expression works outside my macro, so I guess it's my fault, but it
>> would help if the syntax-error could be a bit more informative. The
>> code: [...]
> 
> 1. The problem is not `for/hash' -- it's in your macro.  You can see
>   that by replacing it, for example, with `let*' and the error
>   changes accordingly.
> 
> 2. Minimizing the code in obvious ways got me down to this macro soup
>   which fails in the same way:
> 
>     (define-syntax dependent-boxes
>       (syntax-rules ()
>         ((_ ((_variable_ . _rule_) ...))
>          (let ()
>            (define-syntax with-variables
>              (syntax-rules (_variable_ ...)
>                [(_ (a (... ...))) ((with-variables a) (... ...))]
>                [(_ _variable_) (list '_variable_)]
>                ...
>                [(_ non-variable) non-variable]))
>            (define-syntax rule-with-variables
>              (syntax-rules ()
>                [(_ (rule)) (lambda () (with-variables rule))]))
>            (list (rule-with-variables _rule_) ...)))))
>     (dependent-boxes ((profit (let* ((y 1)) 2))))
> 
>   Looks like the macro stepper does not step through local macros (at
>   least not in this case), but it did the first step of expanding the
>   `dependent-boxes' macro.
> 
> 3. This leads to a smaller code that fails the same.
> 
>     (let ()
>       (define-syntax with-variables
>         (syntax-rules (profit)
>           ((_ (a ...)) ((with-variables a) ...))
>           ((_ profit) (list 'profit))
>           ((_ non-variable) non-variable)))
>       (define-syntax rule-with-variables
>         (syntax-rules () ((_ (rule)) (lambda () (with-variables rule)))))
>       (list (rule-with-variables ((let* ((y 1)) 2)))))
> 
> 4. It's now easy to continue reducing it to the core of the problem:
> 
>     (define-syntax with-variables
>       (syntax-rules ()
>         ((_ (a ...)) ((with-variables a) ...))
>         ((_ a) a)))
>     (with-variables (let* ((y 1)) 2))
> 
>   Looks like you're doing a code walk (which is what makes me think
>   that this is too complex for whatever it is you're trying to do),
>   and treat some names in a special way.  The problem is that
> 
>     ((with-variables a) ...)
> 
>   is creating a function application so the error is the same as just
>   entering `let*' to get its value -- and the only error that it can
>   throw at this point is a "bad syntax" with the whole expression,
>   which is just `let*'.
> 
> 5. And BTW, the reason it doesn't work is that the first expansion
>   gets to
> 
>     ((with-variables let*) (with-variables ((y 1))) (with-variables 2))
> 
>   and this form is not a macro -- so it's expanded as a function
>   call,
> 
>     (#%app ...same...)
> 
>   and the rest is obvious.
> 
> -- 
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                    http://barzilay.org/                   Maze is Life!
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users



Posted on the users mailing list.