I've written in the past about compiling Arc to JavaScript and shared a compiler I'd been working on to do the job [1, 2, 3, 4]. Soon afterward I stopped working on the project, stumped by some issues I couldn't resolve. I've been thinking about this project again a lot recently and have some new ideas I'd like to share. The biggest issues stumping me when I last looked at this project had to do with the gap between idiomatic Arc and idiomatic JavaScript. For example, we love to nest function calls in Arc because they're tail-call optimized and the syntax makes it so pleasant. In JavaScript, on the other hand, we need to go a little easy on the nested function calls (since there is no TCO), but object method chaining is huge. fallintothis observed that my project "[wasn't] just an Arc-to-Javascript compiler, but also a DSL for Javascript in Arc." [5] I wrestled with that duality for some time, but recently realized that making a good JavaScript DSL was my top priority, with the compiler just serving as the means to that end. So, I'm now in the mindset of designing a little language that compiles to JavaScript and that, while inspired by pg's Arc, makes no attempt to be faithful to it. What I'd like to end up with is something not unlike CoffeeScript [6], only s-expression based and with macros. I've started by stripping Arc of all its ssyntax, with those characters in mind for a different ssyntax layer better suited to writing idiomatic JavaScript. I think that in the long run, a well-thought out new ssyntax will be the answer. For the moment though, it's kinda neat what you can do just with the superset of Arc's valid symbols that comes from eliminating the ssyntax (and doing a bit of reader hacking, hence my recent question about this [7]): ; Arc-like expressions ; Compiled JavaScript output
({ a 1 b 2 c 3) {a: 1, b: 2, c: 3}
([ 1 2 3) [1, 2, 3]
(. ($ "body") $("p.neat")
(addClass "ohmy") .addClass("ohmy")
(show "slow")) .show("slow");
; not sure about this one
(=> anArray 'someKey) anArray['someKey']
Here are the ssyntax possibilities I'm most attracted to. They corresponding to the four above examples, respectively: {a 1 b 2 c 3}
[1 2 3]
($ "body")
.(addClass "ohmy")
.(show "slow"))
anArray['someKey]
Of course, lots of the language can remain like Arc, because Arc has some really great operators that work fine in JavaScript: (fn () foo) function() { return foo; }
(def bar () var bar = function() {
(= pet "dog") var pet = "dog";
(alert return alert("my pet is a " + pet);
(+ "my pet is a " pet))) };
(if a b (function() {
c d if (a) {
e) return b;
else if (c) {
return d;
} else {
return e;
}
}).call(this);
(do x y z) (function() {
x;
y;
return z;
}).call(this);
(let x 5 (function() {
(alert var x = 5;
(+ "x is " x))) return alert("x is " + x);
}).call(this);
This one is pretty insignificant but for some reason I like it. The ternary operator macro could be a synonym for if, functionally speaking (since we probably want to break down JavaScript's statement/expression dichotomy), except that it has the different flavor of JS output: (?: a b (a ? b
c d : (c ? d
e) : e))
One big break from the previous compiler implementation is that we focus on JavaScript's data types, not Arc's. That means having arrays, objects, true, false and null (and undefined?) instead of conses, hashes, t and nil.Ah, I need to wrap this up. I know I've left out a lot of details here, but I'd love to get feedback on what there is so far. --- References [1] "Try Arc->Javascript": http://arclanguage.org/item?id=12156 [2] "JavaScript Compiler, js.arc (w/ arc.js)": http://arclanguage.org/item?id=11918 [3] "Poll: Best representation for JS dot notation": http://arclanguage.org/item?id=12079 [4] "Ask HN: Designing a Parenscript alternative": http://news.ycombinator.com/item?id=1949275 [5] Comment on [1]: http://arclanguage.org/item?id=12165 [6] CoffeeScript: http://jashkenas.github.com/coffee-script/ [7] "Extend Arc's ssyntax?": http://arclanguage.org/item?id=12866 --- Relevant but not mentioned: * "Ask: html and javascript in arc": http://arclanguage.org/item?id=12421 * Parenscript: http://common-lisp.net/project/parenscript/ * SibilantJS: http://sibilantjs.info/ * lisp.js: http://lisp-js.posterous.com/lispjs-a-lisp-for-nodejs-0 |