Archive for December, 2007

Next Steps…?

So I’ve reached a fork in the road with my current project and am trying to figure out which path to take. I’m hoping that writing this will help me reach a conclusion.

For the past several months I’ve been building a Scheme interpreter (originally a Lisp one, but the I converted) in Flash. The differences between my this one and the previous ones are as follow.

  • Scheme instead of Lisp, this allowed me to focus on a smaller subset of commands to implement, not just my favorite ones at the time.
  • Ability to interact with the full underlying Flash Player, which allows me to mess with graphics and all those other things that you’d actually expect from an interpreter built on Flash.
  • Nifty things like continuations and optimized tail-calls, allows me to implement things in this interpreter quicker and with significantly less code that if I were implementing it in ActionScript.

So anyway, I’ve gotten to the point where I’m quite happy with what I have and I’m trying to figure out what to do next. So my options are.

  • Release it to the world as is. Probably with source code too. See who’s interested and what ideas they may have with how to make it better. The other possibility is to release it in some sort of interactive tutorial form which would let people with little or no Scheme/Lisp experience (or maybe no Flash experience) to play with it and see the power and possibilities.
  • Abstract all the ActionScript code (it is all AS2 right now since that gave me the greatest flexibility) to a level where I’m defining the interpreter in a smaller subset of Scheme and ActionScript bytecode. This would hopefully allow me to then to create a compilers specific to different VM’s such as AS3 or SilverLight or something.

    I haven’t fully thought this one out yet, but it’s currently the most attractive of the paths because it seems the most interesting and most challenging. This would then probably wind up leading into the option above.

  • The last of the options is to use the interpreter in a CMS/Web-Framework that I created a proof-of-concept for a few years back. The basic idea was if you had the same language available on the client-side as you did on the server-side, and if that language was good enough to allow you to abstract over the atrociousness of HTML and CSS, then you would be able to create higher-level web-app designs that could be altered in real-time without ever talking to the server.

    This seems like a really cool idea to me, especially if it was combined with a continuations, but in the end it would just be another web framework, and I don’t even really do any website building. I think this is only interesting to me because it allows you to show programmers and non-programmers some of the magic that Lisp lets you do (this is something that really excited me about my POC, because people that knew enough about the web would say things like “You can’t do that!!”)

Yeah, so this didn’t help me too much. They all seem to have their merits. I know this isn’t the flame-bait that my last post was, but any input would be greatly appreciated.

I chose Scheme over Common Lisp

I know this may seem like heresy, but it’s the truth. A few weeks ago I made the choice to move from Common Lisp (I had been using the Allegro implementation for about 2.5 years) to PLT Scheme.

I don’t want to go on and on like I know have reached some level of enlightenment that CL users haven’t, but I would like to briefly list some of my feelings about the switch.

What I like better about Scheme even though I once mentioned it as a reason why I wouldn’t

  • Functions and variables in the same namespace
    This always seemed like the move from a Lisp-1 to a Lisp-2 was a positive thing. You wouldn’t have to worry about having a variable that clashed with the name of a function, but it seems like was only an issue of having way too many functions with crazy names all over the place. The big problem that it creates is that you have to use FUNCALL to execute a function store in a variable, you have to use #’ to pass a function to an applicative, and you have to treat functions different than variables in general. (If you want to see something really scary try looking at the Y Combinator implemented in Common Lisp)

    I’ve found that in Scheme my code is more elegant, tends to be far more functional and the only real concession I’ve had to make is that i can’t call a variable LIST (like any one ever actually does that, even in CL people use LST or LIS).

    I should also mention that I’ve read that as of R6RS Scheme will be case-sensitive by default, which would allow you to use case conventions to separate variables from functions if you so desired.

  • The define syntax
    Whenever I used to try and read Scheme code I found myself overwhelmed by the define statement. Not only was it significantly different looking that the defun, defparameter, and let statements that I was used to, but that they were used differently, they were nested all over the place, functions created inside other functions and other odd things that made my brain hurt.

    As it turns out, for me, using (DEFINE (square x) is way more natural for lisp than (defun square (x), since in the end it’s the same syntax as that way that you call the function. Also by using Swindle (an add-on to PLT-Scheme) you have the syntactic-sugar available for currying.


    (define ((add a) b) (+ a b))

    winds up being compiled to

    (define (add a) (lambda (b) (+ a b)))

    Like I said above I find now that my Scheme code is way more functional than my CL code ever was and I think this is a big part of it, I wind up using recursion and folds all the time instead of the doTimes, doList, while and loop constructs that I used to use. As much as this was a bit hard to get used to, it wound up being way more readable and concise than the iteration constructs.

  • Continuations
    Ever since I heard of continuations I was intrigued, but they aren’t available in CL. All the reading that I did as to why mentioned that the reason for this is that it was essentially a GOTO statement, and that THROW and CATCH were available. Also, the feeling that I got was that unless you’re doing a continuation-based webserver that they are just an interesting toy that’s fun to play with.

    Turns out that I find it hard to believe that I lived without continuations before (the same feeling that I had when I discovered closures). The AMB and AMB-COLLECT macros wind up being particularly useful for permutations. The following code collects a list of all lists with lengths from 1-4, where each item in the list is 1-4.


    (define (make-list n)
      (if (positive? n) (cons (amb 1 2 3 4) (make-list (- n 1)))
          null))
     
    (amb-collect
    (make-list (amb 1 2 3 4)))

    this is pretty cool too.


    (define (between a b)
      (if (<= a b)
          (amb a (between (+ a 1) b))
          (amb)))
     
    (let ((a (between 2 9))
          (b (between 2 9))
          (c (between 2 9)))
      (amb-assert (= (+ (* a a) (* b b)) (* c c)))
      (list a b c))
     

    Continuations and the AMB macro are probably going to need their own post. I should also mention that the understanding of CPS-style coding has forever change the way I code javascript and actionscript.

The only other thing that I going to mention is that I really enjoy APPEND! being the destructive version of APPEND instead of the CL NCONC, there are tons of examples like this. These kinds of decisions made by the Scheme crowd actually make a ton of sense, where as when trying to learn CL was kind of like memorizing history.

The only thing that still bugs me about Scheme is the separation of #f from NIL. I know I shouldn’t have a problem with this since it makes tons of sense, but it still bothers me that when I’m using recursion, instead of (IF LST , I’m forced to write (IF (NOT (NULL? LST)).

That’s all I have for now. Let the angry comments begin.