[plt-scheme] Re: Novice question: evaluating symbols
Thanks a lot for the detailed answer (comments below, main matter at the
end).
On Sat, Jan 9, 2010 at 07:42, Eli Barzilay <eli at barzilay.org> wrote:
> On Jan 8, Laurent wrote:
> > For example on trying to generalize the macro given by Carl, I often
> > run into problems like that:
> >
> > (define-syntax (define-shorthand2 stx)
> >
> > (define (->string x) ;; turn anything into a string
> > (format "~a" x))
> >
> > (define-syntax-rule (combine-variable-names x ...)
> > (datum->syntax ;; from symbol to variable name
> > stx
> > (string->symbol ;; from string to symbol
> > (string-append ;; combine strings
> > (->string (syntax-e x)) ...))))
>
> Why is this a macro? Even with `defmacro', this makes more sense as
> just a function that appends a bunch of symbols.
>
In my past attempts (on a different macro for a similar purpose), I had
problems with `apply' (no #%app or #%top blablabla) so I thought the `...'
might help.
Now I guess I didn't use it with a `with-syntax', or the inner functions
were outside of the macro body (I've just learned about the utility of inner
functions in macros).
>
> The problem there (among several others, like the unquoted `body', the
> fact that `new-id' and `long' are never used, etc.)
Oh, yes, sorry about that, that was only a sketch to show the kind of
problem.
> is that
> `combine-variable-names' is just a macro (that is used inside a
> macro). If you don't use a macro, then you can make it with very
> simple code (I needed to guess what you're trying to do, because of
> those errors):
>
> (define-syntax (define-shorthand stx)
> (define (->string x) (format "~a" x))
> (define (combine-variable-names xs)
> (datum->syntax
> stx
> (string->symbol
> (apply string-append (map ->string xs)))))
> (syntax-case stx ()
> [(define-shorthand x ... expr)
> (with-syntax ([long (combine-variable-names (syntax->datum #'(x
> ...)))])
> #'(define long expr))]))
> (define-shorthand x y z 123)
> xyz
>
That's exactly what I was trying to do... (why didn't I re-try using
`apply'! grrrr....)
>
> If you insist on using a macro, then you can do this:
> [snip]
>
A function is all what is needed.
> But there is no way for this to work:
>
> (combine-variable-names #'x ...)
>
> because the `...' are only meaningful in `syntax' (or the #'
> shorthand). Another way to see the problem is that the `...' in the
> input pattern stands for a variable arity expression in the runtime
> code -- but in the syntax code, (combine-variable-names #'x ...) is
> just a function with two arguments. (Kind of.)
>
Yes, that's why I tried to use it in a syntax and unsplice it like #`#,@(x
...) but that obviously means nothing.
Now for the real problem:
> P.S. : And that is very frustrating because it is so easy with
> > defmacro... I'm pretty sure many people are working hard to extend
> > nicely the syntax macro system, but I have much difficulty to use it
> > correctly and I find it cumbersome when you deal with non-trivial
> > macros. That's my major grief about Scheme.
>
> Did you try to write it with `defmacro'? If you feel comfortable with
> it, it might be a good way to see the real problem.
>
For the sake of it, here it is (yes, with `apply'):
#lang scheme
(require mzlib/defmacro)
(define-macro (define-shorthand xs val)
(define (->string x)
(format "~a" x))
(define (combine-variable-names xs)
(string->symbol
(apply string-append (map ->string xs))))
(let ([new-id (combine-variable-names xs)])
`(define ,new-id ,val)))
(define-shorthand (x y z) 123)
xyz
(Btw, isn't this macro hygienic?)
My main problem is that `syntax-rules', `syntax-case', `with-syntax' and
others that I have not used yet use the syntax in quite different ways, and
sometimes you have to #' and sometimes you have to (syntax->datum ....) and
sometimes not. I have a hard time to know when to use the right one at the
right time (the docs are a bit obscure on these points).
Whereas in `defmacro', I know exactly when to use `quote' and `unquote'.
Wouldn't it be possible to define "safe" quotes and unquotes for syntax
macros, without having to go from syntax to datum and vice-versa at weird
places?
I mean, syntax objects are encapsulating other data that I really don't need
99% of the time.
So why should I bother about something I don't want?
Thanks again for your answers,
Laurent
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100109/4f003b84/attachment.html>