Friday, February 8th, 2008

ArcLite: Arc for JavaScript

Category: JavaScript

Jonathan Tang has fallen into the Arc fun and took some time to fully implement it in JavaScript.

It differs from Paul’s implementation:

  • Supports Unicode, at least as well as JavaScript supports it.
  • There are very few I/O primitives – the ones that do exist write to the string “Eval.stdout”, which can be tested and reset as necessary.
  • I started work on a FFI but abandoned it so I could get back to my real projects. :-) The plan was to add ‘jscall’ and ‘jsref’ special forms that act as the function-call and object/array indexing operations, respectively. You can use Types.to_js() and Types.to_arc() to convert Arc values back and forth to JavaScript, along with the Types.* constructors themselves.
  • String objects are immutable, because JavaScript does not offer mutable strings. (= (a-string 0) new-char) returns the new string, but does not modify the old one. A few functions in arclib have been redefined to account for this; see the #arclitelib element in this page’s source.
  • (set foo 1) operates in the lexical environment instead of always setting a global. It still sets a global if it can’t find the symbol in the lexical environment. This is necessary for the Arc library to function.
  • Tagged data items (eg. macros) can be called and set like their underlying data type.
  • Continuations are not implemented. I had started on a CPS-based interpreter, but then realized that JavaScript lacks tail-call optimization and has a recursion limit of 1000 calls, which’ll make any CPS-transformation blow the stack.
  • Macros are looked up in the lexical environment, and are expanded right before the form is evaluated rather than when it is defined. This opens up a couple possibilities:
    1. You can theoretically have first-class macros; if you pass a macro value to a function, then the body of that function is expanded using the definition of the passed-in macro.
    2. You can have lexical macros. If you already have a binding defined in a function, then (mac …) will set that binding rather than adding a new one to the global environment. This only applies if a binding already exists; if not, (mac …) will create one in the global environment, just like the reference implementation.
  • Other than this, the interpreter seems to execute arc.arc fine. Since arc.arc is considered the specification for Arc, I guess this means that ArcLite is a fully-conforming implementation. There may be a few bugs though; most functions are not well-tested, and I had to write my own reader implementation and primitive data types instead of piggybacking off Scheme.
  • Don’t expect a speed-demon. This is an AST-interpreter running on top of an interpreted language that’s roughly 1000x slower than C. I’m surprised it works at all.

Paul also put out an Arc Challenge:

Write a web program such that:

  • The first page of the program displays nothing but a text box and a submit button. You enter some arbitrary text and press the submit button, which takes you to …
  • The second page is nothing but a single link labeled “click here”. The URL linked to must not contain the text entered in the first step (i.e. you are not supposed to pass the text as a parameter on the link). Clicking the link takes you to …
  • The third page which contains “You said: XXX” (where XXX is the text you entered in the first step).

Paul implemented this via:

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

Many others have thrown their hat in the ring too, including Jim Weirich:

  1. Conversation.interact do |io|
  2.   text = io.ask
  3.   io.pause("click here")
  4.   io.tell("You said: #{text}")
  5. end

Posted by Dion Almaer at 9:12 am

2.5 rating from 15 votes


Comments feed TrackBack URI

I don’t quite understand this competition. It is far too simple. How is the HTML/CSS person on the team supposed to style these pages with a layout, header, footer, error messages etc? Does the arc solution stay so amazingly compact when all the normal requirements are added or does it balloon up to the same size as a solution in any one of the web frameworks with HTML templates?

Comment by Peter Michaux — February 8, 2008

I like arclite and tried Paul’s test in it. Got an error: (stdin):1: Error: Symbol ‘said’ has no value

0: said

Any ideas how to fix this?

Thanks, Steve

Comment by jsgrahamus — May 18, 2011

Leave a comment

You must be logged in to post a comment.