Hi again,<br><br><div class="gmail_quote">On Thu, Jul 14, 2011 at 6:23 PM, Eli Barzilay <span dir="ltr">&lt;<a href="mailto:eli@barzilay.org">eli@barzilay.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">Two hours ago, Markku Rontu wrote:<br>
&gt; &gt; this is not really true. The domain specific languages of<br>
&gt; &gt; syntax-rules and syntax-case macro transformers exist purely for<br>
&gt; &gt; your convenience. You can always manipulate syntax objects<br>
&gt; &gt; directly, all the necessary procedures are available and<br>
&gt; &gt; documented in section 11 of the Racket reference manual.<br>
&gt; &gt;<br>
&gt; I&#39;m sure the section 11 does go through the relevant issues, but<br>
&gt; doesn&#39;t feel like a good introduction to the matter.<br>
<br>
</div>It&#39;s a reference, it&#39;s not supposed to be an introduction. For a more<br>
in-depth introduction than my blog post, see the chapter in the racket<br>
guide:<br>
<br>
<a href="http://docs.racket-lang.org/guide/macros.html" target="_blank">http://docs.racket-lang.org/guide/macros.html</a><br>
<div class="im"><br></div></blockquote><div><br>I feel reference material tends to require some other material as support. Your blog posting was a good start. Maybe it&#39;s wishful thinking, but many other languages have a lot of screencasts and talks online that I can watch. And also articles where I can see how people build stuff from scratch using their favourite environment. That&#39;s really cool stuff and I wish there was more on Racket as well.<br>
<br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class="im">
<br>
&gt; I can theorise that I can manipulate these syntax objects with plain<br>
&gt; old functions but nowhere does it seem to show a complete useful<br>
&gt; case. What I&#39;m missing is an example that contains all the bits but<br>
&gt; that is not as complicated like the Racket sources themselves. Maybe<br>
&gt; I just didn&#39;t find it?<br>
<br>
</div>Note that usually you start with `syntax-rules&#39; because it&#39;s simple<br>
and covers many cases. But running straight to the macro system<br>
bowels can be confusing since it&#39;s not just &quot;lists and symbols&quot;. So<br>
the main tool that is used is `syntax-case&#39;, which can be used in a<br>
very similar way to `syntax-rules&#39;:<br>
<br>
(define def<br>
(syntax-rules (=)<br>
[(def x = y) (define x y)]))<br>
<br>
gets translated to<br>
<br>
(define (def stx)<br>
(syntax-case stx (=)<br>
[(def x = y) #&#39;(define x y)]))<br>
<br>
It looks similar, but there are important differences:<br>
<br>
* `syntax-rules&#39; is creating a macro function (=&gt; it is itself a<br>
macro) for you, abstracting all of the details out. The translation<br>
defines `def&#39; as a function directly -- se we have a name for the<br>
input syntax, `stx&#39; is often used by convention.<br>
<br>
* We then use `syntax-case&#39; which has the same kind of pattern<br>
language you know from `syntax-rules&#39;, but it needs to have its<br>
input specified directly. It&#39;s common to pass `stx&#39;, the input to<br>
the macro, but you can really give it anything you want.<br>
<br>
* And the most important change is that #&#39; in the result. With<br>
`syntax-rules&#39;, the results are actually templates for plugging<br>
pattern variables in. But since we&#39;re writing plain racket code<br>
here, the results can be any racket expression. In this case, I use<br>
#&#39;(define x y) which is actually short for (syntax (define x y)).<br>
This `syntax&#39; thing is very similar to `quote&#39;, or actually more<br>
like a kind of a quasiquote since pattern matched variables are<br>
plugged into it -- so it&#39;s not really `x&#39; and `y&#39; that will be in<br>
the result, it will instead be what the `x&#39; and `y&#39; variables<br>
matched over when `stx&#39; was fed into `syntax-case&#39;.<br>
<br>
Again, see that blog post for an introduction that explains more from<br>
this POV.<br>
<br>
(This kind of explanations were also made countless times; it&#39;s easy<br>
to fall into the syntax-rules-only trap though.)<br>
<div class="im"><br></div></blockquote><div><br>Fortunately, I didn&#39;t fall for that one. I&#39;ve been using syntax-case successfully for a long time because I quite soon needed to start breaking hygiene. I mostly write macros as sugar for various DSLs. There I need to often introduce new variables and avoid repetition.<br>
</div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class="im">
<br>
&gt; It&#39;s simple, it&#39;s been explained countless times, it works in many<br>
&gt; cases.<br>
<br>
</div>No, it&#39;s broken in pretty much all cases. Give me a single symbolic<br>
macro and I&#39;ll show you how it&#39;s broken. (And point out how CL<br>
bypasses the problem...)<br>
<div><div></div><div class="h5"><br></div></div></blockquote><div><br>I think it&#39;s a bit disingenuous to say they are broken. People made successful systems using their simple but broken tools, yes? People are making successful systems in crippled languages such as Java and CL. And some people even like it :-) Sure they can only build a limited thing with the broken tool, but if you stay within its limits it doesn&#39;t matter, does it? Nobody is trying to implement Typed Clojure on top of the macro system, I hope :-) But as syntactic sugar for a DSL, where&#39;s the big problem that makes it entirely broken?<br>
<br>From a theoretical point of view, I think you are absolutely correct that the symbolic macros are broken. From a practical point of view, you can prove Racket macro superiority only by implementing superior systems and showing in practice that the choices you made were superior.<br>
<br>-Markku<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div><div class="h5">
--<br>
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:<br>
<a href="http://barzilay.org/" target="_blank">http://barzilay.org/</a> Maze is Life!<br>
</div></div></blockquote></div><br>