[racket] for/hash: bad syntax in: for/hash
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 04-01-12 10:57, Marijn wrote:
> On 03-01-12 20:15, 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: [...]
>
> Thanks for taking the time to look into this.
>
>> 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*'.
>
> It took me a while to understand what you're saying here, but if I
> am not mistaken you're saying that the result of the
> macro-expansion is a function-application with `let*' (or
> `for/hash') in the function position. Then when #%app looks that
> name up in the environment it doesn't find anything and thus
> complains about it. What I would then expect is that it complains
> about an undefined variable `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.
>
> It's not so obvious to me why this should degenerate into a
> function call; I'd say it depends on the result of (with-variables
> let*).
Okay, so I thought about this some more... and while I still think
this is weird behaviour, for my current code it is rather academic, as
it would just fail with unexpanded macro-calls in the arguments of
let*. Which means that I've again fallen into the trap of not thinking
hard enough about how macros are different than functions. Basically,
my idea was to transform:
(dependent-boxes
((a)
(b (* 2 a))
(c (+ 2 a b))))
into something which would automatically propagate changes in any
cell/box to any other box which was dependent on it. Pretty much
exactly like a spreadsheet does. As target for that transformation I
had chosen something like:
(letrec
((value-store (mlist (mcons 'a #f) (mcons 'b #f) (mcons 'c #f)))
(rule-store (make-hash
`((a . ,(lambda () ""))
(b . ,(lambda () (* 2 (value-store-ref 'a))))
(c . ,(lambda () (+ 2 (value-store-ref 'a) (value-store-ref
'b)))) ))))
...)
together with surrounding structure such that values could be entered
and read and such that for each value-change, dependent boxes would be
updated automatically. Before today I though this was a pretty sweet
setup. But even if my macro had worked as I had intended, it wouldn't
have respected lexical scope within rules. So I guess it's back to the
drawing board for me. (I don't recall there being any logic to using
an alist for the value-store and a hash-table for the rule-store.
Probably that's just how things grew...)
Marijn
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.18 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAk8EcwcACgkQp/VmCx0OL2xEyQCggrb6Fq2hc5EB2ujJGsS/SNpH
RBQAoJf0wk6t6P/zESx8xBwAZnTCsit6
=3zAm
-----END PGP SIGNATURE-----