Implement, explore & perhaps extend The Egg Language as described by Marijn Haverbeke in Eloquent Javascript.
See and experience how any computer language* is in fact implemented... in some other computer language!
Here, Egg is written in javascript (javascript is perhaps an uncommon choice for this kind of thing, but it doesn't matter).
Here's a quick introduction to Egg.
To set a variable:
define(word, 2)
Note assignment is not done with =
, it's define
that does that, which can be confusing.
It's worth pausing to let that sink in.
To get the variable back:
print(word)
> 2
Now something much harder. Here's a function definition for timesBy
, a higher order function, which returns a function.
Function defininitions take the form fun(args... body)
, with however many args you want. The thing we define below, timesBy
, is a function (fun
), that has one arg, howMuch
. Its body, which is the same as its return value, then follows, in the form of a function definition. So, timesBy
is function which makes functions which timesBy howMuch
you specify.
Define timesBy
:
define(timesBy,
fun(howMuch, define(anon,
fun(byWhat, *(howMuch, byWhat))
)
)
)
Call timesBy
to get a function back:
define(timesBy4, timesBy(4))
Call the function just made:
print(timesBy4(5))
> 20
Or do both steps at once, i.e. call the factory then immediately call the resulting function.
You might have seen this form in javascript.
print(timesBy(4)(5))
> 20
To reiterate, if you ended the line after the (4)
above, what you'd have is a function, so the (5)
after that is another invocation.
Higher order functions are by no means the meat and potatoes of the language implementation. They're pretty incidental, and I don't think Marijn even pointed out that Egg supported them. The interesting stuff is a lot simpler than that. I just wanted turn up the gas for the introduction.
In Marijn's own words:
Building your own programming language is surprisingly easy (as long as you do not aim too high) and very enlightening.
Eloquent Javascript is a wonderful book, by the way! The role of this repository is to consolidate the code which Marijn has provided in Chapter 12, then explore & extend it.
My own why do this right now is that writing a DSL/language like this helps build a strong foundation for Lisp/Clojure, which I'm currently learning.
Clone the repo & check out the commit history to see the language being constructed.
Be OK with regular expressions & recursion and/or willing to refresh.
Want to know how a programming language is created!
Everything. There's loads of scope to modify the code here.
- allow comments (easy)
- add arrays (easy)
- consider how to convert it to a compiler
- consider where macros would fit if this was a Lisp
- consider how to make a REPL
- write a little text adventure in egg based on a Lisp/Scheme example.
- since egg is already in PN, why not move the first opening parens to the left, to be closer to S-expr & more lispish. Am finding the half-way house syntax rather unreadable. Have never seen a language quite like this!
- shorten
define
todef
&function
tofn
current syntax:
do(
define(x, 10),
if(>(x, 5),
print("large"),
print("small")))
consider change to new syntax:
(do
(def x, 10),
(if (> x, 5),
(print "large"),
(print "small")))
- if above works, remove commas or make them optional, to get:
(do
(def x 10)
(if (> x 5)
(print "large")
(print "small")))
- consider
anon
functions. If name is "anon", make actually anonymous, unreferencable? So, how islambda
defined?
* except hardware.