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