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

From: Eli Barzilay (eli at barzilay.org)
Date: Sat Jan 9 01:42:51 EST 2010

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.

>  ;; here's the meat of the macro:
>  (syntax-case stx ()
>    [(define-shorthand2 (new-id x ...) body ...)
>     (with-syntax ([long (combine-variable-names #'x ...)]) ; PROBLEM
>       body ...)]))
> 
> The problem is with the ellipses that won't be included properly.  I
> also tried (and failed) using #'... or #`#,@(x ...) just to see,
> without being too sure about what that meant.
> 
> Could I have a hint on how I could do that?

The problem there (among several others, like the unquoted `body', the
fact that `new-id' and `long' are never used, etc.) 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

If you insist on using a macro, then you can do this:

  (define-syntax (define-shorthand stx)
    (define (->string x) (format "~a" x))
    (define-syntax-rule (combine-variable-names xs)
      (datum->syntax
       stx
       (string->symbol
        (apply string-append
               (map ->string (syntax->datum xs))))))
    (syntax-case stx ()
      [(define-shorthand x ... expr)
       (with-syntax ([long (combine-variable-names #'(x ...))])
         #'(define long expr))]))
  (define-shorthand x y z 123)
  xyz

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.)


> 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.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!


Posted on the users mailing list.