[racket] for/hash: bad syntax in: for/hash
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