I propose adding a primitive called "ac-tunnel" to Arc: (define (ac s env)
(cond ((string? s) (string-copy s)) ; to avoid immutable strings
...
+ ((eq? (xcar s) 'ac-tunnel) (cadr s))
ac-tunnel is a syntax that passes its arguments unchanged through the Arc compiler: (ac-tunnel (+ 1 2))
"(+ 1 2)" appears unchanged in Arc's compiled Scheme output and so is evaluated by Scheme as a Scheme expression. The syntax is not limited to literal Scheme code: an Arc macro can expand into ac-tunnel, and so can generate Scheme code.Name I suggest calling this feature "ac-tunnel" because it is part of the Arc compiler. Although people liked the "mz" name that I had been previously using, I think that "ac-tunnel" fits in better with the naming of other compiler functions such as ac-denil, ac-niltree, ac-global-name, etc. And, it's easy to define "mz" in terms of "ac-tunnel", for people who would like easy access to Scheme features for quick hacks. Motivation "ac-tunnel" can be used as a mechanism to call Scheme libraries from the MzScheme implementation of Arc, or to modify Arc's runtime. The advantage I see in adding "ac-tunnel" as a primitive to Arc is that it enables capabilities without them having to be made part of the official release of Arc. Most everyone who programs in Arc wants to see their favorite feature X as part of Arc. (Often expressed online as "how can anyone claim that Arc is any good when it doesn't even have X??!") However pg may not want to add X to Arc until he's had a chance to think about a good way to do it. Any code (aside from Arc itself) that uses "ac-tunnel" is by definition going outside the boundaries of official Arc, but "ac-tunnel" creates a safety valve for people who want an X that isn't in Arc by making it easy to get X. Comparison to Anarki's "$" "ac-tunnel" is a more general syntax than Anarki's "$" function which evals a Scheme expression: "$" can be defined using "ac-tunnel", but the reverse is not true. Comparison to xdef For calling libraries written in Scheme, this would have a different purpose than the implementation of Arc primitives done with xdef in ac.scm. We have to have primitives: we can't implement Arc without haven't something to implement Arc on top of. Calling libraries written in Scheme lets us use code that could be ported to Arc but hasn't been yet; or might be done for efficiency; but we can call a Scheme library without having to make that library part of the definition of Arc. Why not name after the backend To answer the question of why shouldn't the "pass-through-compiler" feature be named after the backend ("mz") since a particular "ac-tunnel" expression will be useless on some other backend, consider a scenario where an Arc program running on top of MzScheme and one running on top of some other backend such as Common Lisp might both want to call a Scheme library. To make calls to a Scheme library, we'd probably have some interface functions such as, for example, a toscheme to convert Arc values to Scheme values and fromscheme for the other direction; a function to call a Scheme function with the Arc arguments automatically converted into Scheme values and back again for the return value, and so on. The implementation of the interface functions would naturally be very different depending on the backend: in MzScheme, the interface functions would be calling parts of the Arc compiler such as ac-niltree to help with the conversion of Arc and Scheme values; while in Common Lisp version might be communicating with a separate Scheme process, or be calling an implementation of Scheme written in Common Lisp. Thus the interface functions need to know which backend they're running on, and so will know whether it can use "ac-tunnel" in its implementation or not. The Arc code which only wants to call a Scheme library will use the interface functions, and so doesn't need to know about or use "ac-tunnel" directly. |