[plt-scheme] Re: Novice question: evaluating symbols

From: Laurent (laurent.orseau at gmail.com)
Date: Sat Jan 9 04:17:58 EST 2010

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>

Posted on the users mailing list.