| Short version: Here (http://www.rntz.net/files/escape.patch) is a patch against arc3.tar that adds a special form, '$, that combines the best features of CatDancer's 'mz and anarki's old '$ macro: namely, pass-through-compiler semantics from the former and unquotation of arbitrary arc expressions from the latter. CatDancer's variously-named special form (which I will henceforth call 'mz) for bypassing the arc compiler has caused quite a bit of discussion. On the surface, it is similar to anarki's '$ macro; however, the latter allows the use of unquoting to substitute arc expressions into the evaluated scheme code. 'mz does not have this feature per se, but thanks to the way the arc compiler works, it is easy to access local arc variables from inside 'mz, since they are compiled down to correspondingly-named mzscheme local variables. Accessing arc global variables, however, requires adding a prefix to their symbols ('__ for anarki, '_ for arc3). Finally, even in 'mz, one still cannot substitute arbitrary arc code into the scheme code. With a bit of hacking, it turns out there is a way to create a special form which, while still retaining the fundamental aspect of 'mz (that it passes code through the compiler rather than adding an extra layer of indirection with 'eval), allows us to substitute arbitrary arc into scheme. Because it operates more like the corresponding anarki macro, and to avoid confusion with whatever CatDancer eventually decides to name his hack, I've chosen '$ as the name for this special form. For simple cases, it behaves the same as 'mz and '$. arc> $.dynamic-wind
#<procedure:dynamic-wind>
arc> ($ (symbol->string 'foo))
"foo"
If we take a look behind the scenes, it operates similarly to 'mz in that it substitutes the provided code directly into the compilation, rather than using 'eval, to get at mzscheme. This means you can access arc local variables directly: arc> (let x 2 ($ (+ x 3)))
5
arc> user break
; I'm now at the mzscheme prompt, and am invoking the arc compiler
; directly to see what arc code using '$ compiles down to.
> (ac '(let x 2 ($ (+ x 3))) ())
((lambda (x) (+ x 3)) 2)
However, as with '$, unquotation provides us with a more robust way to substitute arc expressions into scheme code: arc> (= y 4)
4
arc> (let x "foo" ($ (+ 2 ,(len x) ,y)))
9
arc> user break
; Let's take a look at what's going on here.
> (ac '(let x "foo" ($ (+ 2 ,(len x) ,y))) ())
((lambda (x) (+ 2 (ar-funcall1 _len x) _y)) "foo")
At this point you know all you need to know to use '$, save how to get at it. I'll probably be pushing some preliminary work on updating anarki to arc3 in the next few days, and this will be among it, but for now, here's a git-diff against arc3: http://www.rntz.net/files/escape.patch. Note that this patch, being against arc3.tar, won't work if applied to eg. anarki's master branch (for one thing, the name of '$ will by design conflict with anarki's '$ macro). It should work against the official branch, though.How the hack works is a bit complicated. It involves a small refactoring of the quasiquote-handling code in ac.scm. Your best bet is probably just to look at the diff; and if you don't already understand how scheme (and hence arc) deal with nested quasiquoting, that's more or less a prerequisite. But from a user's standpoint, it should "just work". |