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.<br><br>At best, I'd like something that I could use like this :<br><span style="font-family: courier new,monospace;">(define-syntax-rule (define-identifier name-piece ... val)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (with-new-identifier (new-id name-piece ...)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (define new-id val)))</span><br style="font-family: courier new,monospace;">
<br>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.<br><br><br>For example on trying to generalize the macro given by Carl, I often run into problems like that:<br>
<br><span style="font-family: courier new,monospace;">(define-syntax (define-shorthand2 stx)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (define (->string x) ;; turn anything into a string</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (format "~a" x))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (define-syntax-rule (combine-variable-names x ...)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (datum->syntax ;; from symbol to variable name</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> stx</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (string->symbol ;; from string to symbol</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (string-append ;; combine strings</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (->string (syntax-e x)) ...))))</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ;; here's the meat of the macro:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (syntax-case stx ()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> [(define-shorthand2 (new-id x ...) body ...)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (with-syntax ([long (combine-variable-names #'x ...)]) ; PROBLEM</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;"> body ...)]))</span><br style="font-family: courier new,monospace;"><br>The problem is with the ellipses that won't be included properly.<br>
I also tried (and failed) using <span style="font-family: courier new,monospace;">#'...</span> or <span style="font-family: courier new,monospace;">#`#,@(x ...)</span> just to see, without being too sure about what that meant.<br>
<br>Could I have a hint on how I could do that?<br><br>Thanks,<br>Laurent<br>P.S. : And that is very frustrating because it is so easy with defmacro... <br>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.<br>
<br><div class="gmail_quote">2010/1/8 Carl Eastlund <span dir="ltr"><<a href="mailto:cce@ccs.neu.edu">cce@ccs.neu.edu</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im">On Fri, Jan 8, 2010 at 8:55 AM, <<a href="mailto:mike@goblin.punk.net">mike@goblin.punk.net</a>> wrote:<br>
><br>
</div><div><div></div><div class="h5">> Thank you for the explanation. At the time, I was just<br>
> exploring what I could do with Scheme. I am still trying to<br>
> think Scheme-ishly. I haven't learned macros yet, but maybe<br>
> that should move up on my agenda.<br>
><br>
> Scheme seems to have more levels of indirection than what I'm<br>
> used to. Returning to my (contrived) problem, how might I force<br>
> the evaluation of a symbol? For example, the apply expression<br>
> below will evaluate date-year and then apply the procedure to<br>
> a-date, but the subsequent map expression will get the symbol<br>
> 'date-year and try to apply that to a-date.<br>
><br>
> Or is this approach a dead end in Scheme?<br>
><br>
> (define selectors<br>
> (map (ė (a-symbol) (string->symbol (string-append "date-" (symbol->string a-symbol))))<br>
> '(year<br>
> month<br>
> day<br>
> week-day<br>
> hour<br>
> minute<br>
> second)))<br>
><br>
> (apply date-year (list a-date))<br>
><br>
> (map (ė (x) (apply x (list a-date)))<br>
> selectors)<br>
><br>
> Thanks again,<br>
> MJG<br>
><br>
> P.S. I've changed my subscription details to try to avoid<br>
> triggering the spam filter.<br>
<br>
</div></div>Definitely time to move macros up on your agenda. Evaluating a<br>
run-time symbol to a run-time function is tricky... it's really no<br>
easier than evaluating a run-time number to a run-time function.<br>
Run-time symbols are just symbols, they don't have another meaning.<br>
<br>
Compile-time symbols, on the other hand, are used as variable names in<br>
compiled code. They can easily correspond to run-time functions:<br>
<br>
(define (f x) (+ x 1))<br>
f ;; <-- compile-time symbol, run-time function<br>
<br>
Macros let you compute with compile-time symbols and construct<br>
variables, so they let you play games like the renaming you want to<br>
do.<br>
<br>
Here's some freebie code:<br>
<br>
--------------------------------------------------<br>
<br>
#lang scheme<br>
<br>
;; define a macro for binding one shorthand:<br>
(define-syntax (define-shorthand stx)<br>
<br>
;; helper function for tedious conversion of compile-time datatypes...<br>
(define (combine-variable-names prefix suffix)<br>
(datum->syntax ;; from symbol to variable name<br>
stx<br>
(string->symbol ;; from string to symbol<br>
(string-append ;; combine strings<br>
(symbol->string (syntax-e prefix)) ;; from variable name to<br>
symbol to string<br>
"-"<br>
(symbol->string (syntax-e suffix))))))<br>
<br>
;; here's the meat of the macro:<br>
(syntax-case stx ()<br>
[(define-shorthand prefix suffix) ;; pull apart the macro's inputs<br>
(with-syntax ([long (combine-variable-names #'prefix #'suffix)])<br>
;; combine the names<br>
#'(define suffix long))])) ;; construct the resulting definition<br>
<br>
;; define another macro for several shorthands at once:<br>
(define-syntax-rule (define-shorthands prefix [suffix ...])<br>
(begin (define-shorthand prefix suffix) ...))<br>
<br>
;; now try it out:<br>
(define-shorthands date [year month day week-day hour minute second])<br>
<br>
(define now (seconds->date (current-seconds)))<br>
<br>
(year now)<br>
(month now)<br>
(day now)<br>
(week-day now)<br>
(hour now)<br>
(minute now)<br>
(second now)<br>
<br>
--------------------------------------------------<br>
<br>
This is not a particularly easy macro to write. It turns out<br>
combining multiple variable names (such as date + year = date-year) is<br>
a bit tedious, and not supported in the simplest form of macros. The<br>
simple ones just shuffle around existing names, without creating new<br>
ones. Still, it's an alternative to using eval, and maybe a starting<br>
point for finding out more about macros.<br>
<br>
Good luck and happy Scheming!<br>
<font color="#888888"><br>
--Carl<br>
</font><div><div></div><div class="h5">_________________________________________________<br>
For list-related administrative tasks:<br>
<a href="http://list.cs.brown.edu/mailman/listinfo/plt-scheme" target="_blank">http://list.cs.brown.edu/mailman/listinfo/plt-scheme</a><br>
</div></div></blockquote></div><br>