A Lisp implementation for Lua
Urn is a new language developed by me, SquidDev, and demhydraz. Urn is a Lisp dialect with a focus on minimism which compiles to Lua.
So what is a Lisp?
Lisp is a whole family of programming languages, including Common Lisp, Scheme and Clojure. Unlike your standard imperative language with if statements, loops and expressions, Lisp just has one thing: the list. All expressions are function calls, but with the function on the right of the leading parenthesis.
For example, in Lua you might write something like:
if x % 2 == 0 then
print(x / 2)
else
print(3 * x + 1)
end
in Lisp you'd write:
(if (= (% x 2) 0)
(print! (/ x 2))
(print! (+ (* 3 x) 1)))
So some of you just closed this window in disgust and, to be fair, that is an acceptable first time reaction, but bare with. In return, you get some powerful meta-programming tools which allows you to augment the language in any way you desire.Macros, the heart of Urn
One of the key features of Lisps is the ability to manipulate code at compile time, transforming it and allowing new syntax. This is achieved through macros. Macros are defined and used just like normal functions, but instead are given a representation of your program and manipulate it, producing new code. One such example is the if macro, as used above:
(defmacro if (c t B)
`(cond (,c ,t) (true ,B)))
I won't go too much into what is going on here, but in short: you define a macro if which takes three arguments c: the condition, t: the code to execute when true and b, the code to execute when false. It then returns a new expression with these variables spliced in.Whilst this is a simple example, macros allow you to extend the language in a whole host of ways: all major constructs (variable assignment, loops, assertions) are implemented via macros. In fact, the "core" language of Urn is composed of just a few simple builtins:
- define, define-macro and define-native allow you to create top level definitions.
- quote, syntax-quote, unquote and unquote-splice allow you to easily switch between code and data.
- lambda creates a new function with the specified arguments and body.
- cond is an if-elseif chain, executing the first body whose corresponding expression is truthy.
- set! assigns an already existing variable (such as a function argument) a new value.
- import will load code from another file.
Features
Powerful assertion and testing framework, ensuring your code is (generally) correct.
Detailed parser messages, helping you find that problem as soon as possible.
Getting started
Urn is currently hosted on GitLab and mirrored on GitHub. You can clone the repo from either location, or download a zipped version.
You should just be able to execute run.lua to launch the REPL, or specify a series of .lisp files in order to compile a set of files.
Currently the Urn compiler will not run on ComputerCraft, though the compiled files should work without problem. You might be able to get it to run under BSRocks - I'll get back to you on that one.
You can find some auto-generated documentation online. Hopefully this will be expanded in the future to include tutorials and what not.