(Re)Introducing Rook
March 5th, 2007
For the past few weeks, I’ve been documenting my progress on the development of a new programming language. It is mostly an experiment to see whether or not I could do it, rather than an attempt to actually gain widespread use. Also, it’s giving me an opportunity to learn more about how functional languages work. In fact, I’m not even releasing the source code yet. I think it’ll be worth releasing after a few more key features are implemented. Still, I’ve made a lot of progress in the past week, and it’s worth presenting the first draft of the language’s documentation as well as some examples.
It’s called Rook. If Guido van Rossum can name a language after his favorite comedy troupe, I can name mine after my favorite member of the passerine order of birds.
In this post I’ll just dive right in with some examples. If something seems fishy, I’d recommend skimming the documentation linked to above. The bottom line is that it behaves a lot like a subset of Scheme, but its syntax is supposed to be more familiar to people who use C-derived languages. I’ve even got a little editor with an interactive REPL based loosely on DrScheme.
In the example screenshot, I start by defining a recursive function (factorial) as well as two mutually-recursive functions (even and odd). The ‘def’ expressions define functions. Rook is dynamically typed, so if we tried to pass a boolean value to the factorial function, it wouldn’t let you know something was wrong until it actually tried to evaluate the function body. Also, the identifiers inside method bodies aren’t checked until they are actually used, so we can define even(n) before odd(n) actually exists, and all is well. By being lazy about these checks, recursion works with no need for special-case code in the interpreter.
Next, the screenshot shows a function named apply, which takes in a function and two additional arguments, and calls that function with those arguments. first(a,b) and second(a,b) return the respective argument, ignoring the other one. In the REPL, you can see that apply(first, 1, 2) evaluates to 1 and apply(second, 1, 2) evaluates to 2. Also, note that we can treat operators as identifiers, passing in the plus operator so that apply((+), 1, 2) evaluates to 3.
The more exhaustive documentation linked to above goes into more about scope, nested scope, local variables, closures, and the like, but more examples won’t be very interesting until I have support for some collection data types like linked lists.