Thanks a lot for the detailed answer (comments below, main matter at the end).<br><br><div class="gmail_quote">On Sat, Jan 9, 2010 at 07:42, Eli Barzilay <span dir="ltr"><<a href="mailto:eli@barzilay.org">eli@barzilay.org</a>></span> wrote:<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 Jan 8, Laurent wrote:<br>
> For example on trying to generalize the macro given by Carl, I often<br>
> run into problems like that:<br>
><br>
> (define-syntax (define-shorthand2 stx)<br>
><br>
> (define (->string x) ;; turn anything into a string<br>
> (format "~a" x))<br>
><br>
> (define-syntax-rule (combine-variable-names x ...)<br>
> (datum->syntax ;; from symbol to variable name<br>
> stx<br>
> (string->symbol ;; from string to symbol<br>
> (string-append ;; combine strings<br>
> (->string (syntax-e x)) ...))))<br>
<br>
</div>Why is this a macro? Even with `defmacro', this makes more sense as<br>
just a function that appends a bunch of symbols.<br></blockquote><div><br>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.<br>
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).<br><br> </div><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"><br>
</div>The problem there (among several others, like the unquoted `body', the<br>
fact that `new-id' and `long' are never used, etc.)</blockquote><div><br>Oh, yes, sorry about that, that was only a sketch to show the kind of problem.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
is that<br>
`combine-variable-names' is just a macro (that is used inside a<br>
macro). If you don't use a macro, then you can make it with very<br>
simple code (I needed to guess what you're trying to do, because of<br>
those errors):<br>
<div class="im"><br>
(define-syntax (define-shorthand stx)<br>
</div> (define (->string x) (format "~a" x))<br>
(define (combine-variable-names xs)<br>
(datum->syntax<br>
stx<br>
(string->symbol<br>
(apply string-append (map ->string xs)))))<br>
(syntax-case stx ()<br>
[(define-shorthand x ... expr)<br>
(with-syntax ([long (combine-variable-names (syntax->datum #'(x ...)))])<br>
#'(define long expr))]))<br>
(define-shorthand x y z 123)<br>
xyz<br></blockquote><div><br>That's exactly what I was trying to do... (why didn't I re-try using `apply'! grrrr....)<br><br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
If you insist on using a macro, then you can do this:<br>[snip]<br></blockquote><div><br>A function is all what is needed.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
But there is no way for this to work:<br>
<br>
(combine-variable-names #'x ...)<br>
<br>
because the `...' are only meaningful in `syntax' (or the #'<br>
shorthand). Another way to see the problem is that the `...' in the<br>
input pattern stands for a variable arity expression in the runtime<br>
code -- but in the syntax code, (combine-variable-names #'x ...) is<br>
just a function with two arguments. (Kind of.)<br></blockquote><div><br>Yes, that's why I tried to use it in a syntax and unsplice it like #`#,@(x ...) but that obviously means nothing.<br><br><br>Now for the real problem:<br>
<br></div><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">
> P.S. : And that is very frustrating because it is so easy with<br>
> defmacro... I'm pretty sure many people are working hard to extend<br>
> nicely the syntax macro system, but I have much difficulty to use it<br>
> correctly and I find it cumbersome when you deal with non-trivial<br>
> macros. That's my major grief about Scheme.<br>
<br>
</div>Did you try to write it with `defmacro'? If you feel comfortable with<br>
it, it might be a good way to see the real problem.<br></blockquote><div><br>For the sake of it, here it is (yes, with `apply'):<br><span style="font-family: courier new,monospace;">#lang scheme</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(require mzlib/defmacro)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">(define-macro (define-shorthand xs val)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (define (->string x)</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;"><span style="font-family: courier new,monospace;"> (define (combine-variable-names xs)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (string->symbol</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> (apply string-append (map ->string xs))))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (let ([new-id (combine-variable-names xs)])</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 style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">(define-shorthand (x y z) 123)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">xyz</span><br style="font-family: courier new,monospace;">
<br>(Btw, isn't this macro hygienic?)<br><br>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).<br>
</div></div>Whereas in `defmacro', I know exactly when to use `quote' and `unquote'.<br><br>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?<br>
I mean, syntax objects are encapsulating other data that I really don't need 99% of the time.<br>So why should I bother about something I don't want?<br><br>Thanks again for your answers,<br>Laurent<br>