I recently started working on making the language accepted by CTCO fall more in line with how the Clojure grammar is defined. My first foray in this effort was changing the way
fn was represented to handle all the forms it's supposed to in full Clojure (e.g. the optional name, condition map, multiple formals vectors/bodies, etc.). In making this change, I realized that the current representation of
fn, a record aptly named
Fn, actually represented something more akin to a single formals vector/function body in a full
fn expression. This was an especially enlightening realization because it made the use of the
Fn record for
defn bodies seem more in line with reality and less like I was lazy in implementing variadic
defn expressions. Note that the original implementational reason was laziness; I just got really lucky that it turned out to be a logical representation.
With that ephiphany, I decided that the best way to add full
fn to the language was by first changing the existing
Fn record to be
FnBody, since that seemed to be what it actually represented. Really this was a cosmetic change; the representation stayed the same, and no algorithms were affected by it. Having made the change, it seemed like the next step was to create a new
Fn that had the appropriate additional fields.
For whatever reason, this brought me to yet another conclusion about the internal design of CTCO. Maybe it was some extra months of experience since I wrote the original code. Maybe it was reading the Clojure docs more closely. Maybe it was a subconcious, self-destructive nature that just wants to make recreational coding as difficult as possible.
In any case, my next steps for CTCO include stripping back the forms represented after the parser. As with any good Lisp dialect, Clojure has a simple core of fewer than a couple dozen forms, and the rest of the language is built from it. CTCO suffers from representing things that are common, but not basic language forms. Thus I want to take those things out, like
defn and instead replace them with the most basic internal representation.
So what does this change look like? To the outside observer, not much; the interface should stay the same. To the guy hacking on internal algorithms, it's also pretty minimal. In fact, it might even make the internals easier. The point of this change is to take the vast array of Clojure expressions that can be handed to CTCO and boil them down to those few basic forms that define the core of the language. It'll mean ripping out some of the internal records which, again, will probably make little difference to most of the algorithms (thanks to the beauty of protocols). Most of the burden will be put onto the parser, as it will need to be beefed up to do the translation to core forms.
This proposed update should roll out pretty soon. I don't actually think it will take long, and hopefully it will make it easier to expand the language (as I've been promising to do for months.