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

From: Laurent (laurent.orseau at gmail.com)
Date: Fri Jan 8 11:26:17 EST 2010

Now I've been trying a few times to generalize such a macro, because I
occasionnaly need something like that, but with not much success.

At best, I'd like something that I could use like this :
(define-syntax-rule (define-identifier name-piece ... val)
  (with-new-identifier (new-id name-piece ...)
                       (define new-id val)))

The with-new-identifier macro would construct a name from name-pieces
(strings, symbols, numbers, whatever simple values), so that the previous
macro could assign it a value.


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

 ;; 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?

Thanks,
Laurent
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.

2010/1/8 Carl Eastlund <cce at ccs.neu.edu>

> On Fri, Jan 8, 2010 at 8:55 AM,  <mike at goblin.punk.net> wrote:
> >
> > Thank you for the explanation.  At the time, I was just
> > exploring what I could do with Scheme.  I am still trying to
> > think Scheme-ishly.  I haven't learned macros yet, but maybe
> > that should move up on my agenda.
> >
> > Scheme seems to have more levels of indirection than what I'm
> > used to.  Returning to my (contrived) problem, how might I force
> > the evaluation of a symbol?  For example, the apply expression
> > below will evaluate date-year and then apply the procedure to
> > a-date, but the subsequent map expression will get the symbol
> > 'date-year and try to apply that to a-date.
> >
> > Or is this approach a dead end in Scheme?
> >
> > (define selectors
> >  (map (λ (a-symbol) (string->symbol (string-append "date-"
> (symbol->string a-symbol))))
> >       '(year
> >         month
> >         day
> >         week-day
> >         hour
> >         minute
> >         second)))
> >
> > (apply date-year (list a-date))
> >
> > (map (λ (x) (apply x (list a-date)))
> >     selectors)
> >
> > Thanks again,
> > MJG
> >
> > P.S.  I've changed my subscription details to try to avoid
> > triggering the spam filter.
>
> Definitely time to move macros up on your agenda.  Evaluating a
> run-time symbol to a run-time function is tricky... it's really no
> easier than evaluating a run-time number to a run-time function.
> Run-time symbols are just symbols, they don't have another meaning.
>
> Compile-time symbols, on the other hand, are used as variable names in
> compiled code.  They can easily correspond to run-time functions:
>
> (define (f x) (+ x 1))
> f ;; <-- compile-time symbol, run-time function
>
> Macros let you compute with compile-time symbols and construct
> variables, so they let you play games like the renaming you want to
> do.
>
> Here's some freebie code:
>
> --------------------------------------------------
>
> #lang scheme
>
> ;; define a macro for binding one shorthand:
> (define-syntax (define-shorthand stx)
>
>  ;; helper function for tedious conversion of compile-time datatypes...
>  (define (combine-variable-names prefix suffix)
>    (datum->syntax ;; from symbol to variable name
>     stx
>     (string->symbol ;; from string to symbol
>      (string-append ;; combine strings
>       (symbol->string (syntax-e prefix)) ;; from variable name to
> symbol to string
>       "-"
>       (symbol->string (syntax-e suffix))))))
>
>  ;; here's the meat of the macro:
>  (syntax-case stx ()
>    [(define-shorthand prefix suffix) ;; pull apart the macro's inputs
>     (with-syntax ([long (combine-variable-names #'prefix #'suffix)])
> ;; combine the names
>       #'(define suffix long))])) ;; construct the resulting definition
>
> ;; define another macro for several shorthands at once:
> (define-syntax-rule (define-shorthands prefix [suffix ...])
>  (begin (define-shorthand prefix suffix) ...))
>
> ;; now try it out:
> (define-shorthands date [year month day week-day hour minute second])
>
> (define now (seconds->date (current-seconds)))
>
> (year now)
> (month now)
> (day now)
> (week-day now)
> (hour now)
> (minute now)
> (second now)
>
> --------------------------------------------------
>
> This is not a particularly easy macro to write.  It turns out
> combining multiple variable names (such as date + year = date-year) is
> a bit tedious, and not supported in the simplest form of macros.  The
> simple ones just shuffle around existing names, without creating new
> ones.  Still, it's an alternative to using eval, and maybe a starting
> point for finding out more about macros.
>
> Good luck and happy Scheming!
>
> --Carl
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100108/0b0fd33d/attachment.html>

Posted on the users mailing list.