Saturday, June 17, 2006

Scheme2Js - Mixing JavaScript and scheme

I just learned about the Scheme2Js project, which I find interesting. It's actually used in HOP, which is really unique in itself. HOP appears to be an approach to writing web applications where you write both the client and server side code together (in a Lisp'ish notation), yet they run in totally different environments. That description doesn't do it justice - so check out their homepage.

I'm especially interested in Scheme2Js because I think application frameworks like SISCWeb have demonstrated how you can cleanly mix back end source code with front end HTML, yet they haven't addressed the issue of dealing with front end JavaScript. Scheme2Js appears to be at least one answer to this - simply write your front end JavaScript in Scheme and compile it back into JavaScript.

I suppose for the Java and related technology crowd this whole point seems kind of strange. Who really cares about mixing markup with JavaScript? But one of the real values of programming a web application in Scheme is that you maintain the expressive power of a real programming language (like Java) yet have the markup structure of a language like XML. JSP solves this by allowing you to express Java concepts in various tags (like c:forEach) - but that gets clumsy for anything beyond the most basic expressions.

I actually ran into this problem of how to compose JavaScript in a Scheme webapp just the other day. Rather than using the sophisticated approach offered by Scheme2Js, I took a different (and easier!) route. Consider that I started with code like this:

  `(p (b "Hello") " world! At the beep it will be:"
      (script (@ (language "JavaScript"))
        "document.writeln(new Date());"))

That's basically Scheme code mixed in with a bit of JavaScript in the middle. It works, but that gets annoying. With this approach, I have to worry about which set of quotes I'm using, and all the other hassles of hosting one language within another.

I spent some time looking around at various solutions to make the above easier to read. While there were some options around, I decided to take advantage of Scheme's really easy to use list processing and quickly developed my own way of representing JavaScript in a Scheme friendly notation. In about 10 minutes I was able to write an interpreter that supported:

  `(p (b "Hello") " world! At the beep it will be:"
     ,(jsexpr (@ document (& writeln (new Date)))))

Which is much more Scheme friendly. Again, my goal wasn't to be able to write JavaScript in Scheme, but to simply represent JavaScript in a friendlier format.

By taking advantage of Scheme's macro system (and quasiquote), I'm able to support seeing Scheme variables inside of jsexpr blocks. So I can write:

 (jsexpr (@ document (& writeln (+ "Welcome " ,user-name 
                                   " - thanks for visiting!"))))

Where user-name is a variable from the server side program that will appear in the client side JavaScript.

Even though my solution worked, I'm eager to check out Scheme2Js and see if it can replace my quick and dirty DSL hack.

Via: Lambda The Ultimate

No comments:

Post a Comment