awwx.ws
The latest version of this hack is template5

template2

Cheating with Unicode: readably embed other languages in Arc

Many projects involve multiple computer languages... for example, I might be using Arc on the server and HTML and JavaScript in the browser; and then in the server I might also be calling out to Perl or Java for particular functionality.

One approach is to keep each language in its own separate source code file, which works until I want an easy way to insert values or other manipulate what I’m doing with the other language. The other option is to be able to completely express the other language in Arc’s syntax (from Take the Arc Challange):

(defop said req
  (aform [w/link (pr "you said: " (arg _ "foo"))
           (pr "click here")]
    (input "foo") 
    (submit)))

...which is terrific if someone has gone to the effort to make that possible! :-)

And then there’s the middle ground, where I’m embedding some other language in an Arc source code file, but still writing the other language’s code in the syntax of the other language. Which is usually rather ugly, since syntax characters meaningful to Arc have to be escaped in some way.

But wait! If the other language’s code that we want to embed is written purely in ASCII, and we can use Unicode characters for our Arc syntax, now we never have to escape anything in the other language!

(= gmailprog ‡
use strict;
use MIME::Lite;

my $msg = MIME::Lite->new(
        From    => «from»,
        To      => «to»,
        Subject => «subject»,
        Type    => 'TEXT',
        Data    => «message»
    )->as_string();
‡)

Of course this only works (never having to escape any characters in the other language) as long as we don’t need to use the Unicode characters in the other language that we’re using as the template and field delimiters: ‡, «, and ».

‡...‡ returns a template, which when called with a table (or a function that can be called with a key and returns a value like a table does), will fill in the template fields with the values from the table. For example,

arc> (‡Hi «name»!  How are you?‡ (obj name "Fred"))
"Hi Fred!  How are you?"

Why have the syntax return a template that is then called with the field values to construct the final string, instead of simply returning the final string immediately? For example, why not

(let name "Fred"
  ‡Hi «name»!  How are you?‡)

Well, I found that I often wanted to apply some common transformation to the field values before inserting them into the template. For example, for a Perl program, I want to convert the input strings into a Perl string.

And, why use two characters to delimit the field names? Why not use one character to introduce the field name, and then use the MzScheme reader to pull off the next symbol? For example, why not

‡Hi →name!  How are you?‡

It turns out the MzScheme reader is pretty greedy about what it will take as part of a symbol name, so it actually reads that as “name!” instead of as “name”. I could parse just alphanumeric characters for the field name, but then I wouldn’t be able to follow a field immediately with an alphanumeric character in a template. So I went with delimiting the field name on both sides, since that will always work.

Get this hack

Download template2.arc and the hacks it uses: ac and span.

Or, using the hackinator:

$ hack \
    ycombinator.com/arc/arc3.1.tar \
    awwx.ws/ac0.patch \
    awwx.ws/ac1.arc \
    awwx.ws/span0.arc \
    awwx.ws/template2.arc

unLicense

This code is in the public domain.

Contact me

Twitter: awwx
Email: andrew.wilcox [at] gmail.com