Lumen is a very small, self-hosted Lisp for Lua and JavaScript. It provides a flexible compilation environment with an extensible reader, macros, and extensible special forms, but otherwise attempts to match the target runtime environment as closely as possible. You can get started by running bin/lumen on a machine with Node.js, Lua, or LuaJIT installed.
Introduction
Every piece of code in Lumen is an expression, and expressions can be evaluated to give values. Lumen has a few kinds of expressions that evaluate to themselves:
> 17
17
> -5e4
-50000
> true
true
> false
false
Strings are enclosed in quotation marks, and may contain newlines. Special characters are escaped using a backslash:
nil represents nothingness, and it isn't printed back at the command line:
> nil
>
Comments start with ; and continue through the rest of the line:
> 7 ; everyone's favourite
7
Lists contain other values, and are written by enclosing expressions in parentheses. Operators are called by placing them at the beginning of a list expression, and list values can be constructed using the list operator:
A shortcut for a key whose value is true looks like this, called a flag:
> (list :yes)
(yes: true)
Variables
Variables are declared using define and define-global. Variables declared with define are available for use anywhere in subsequent expressions in the same scope, and define-global makes them globally available.
> (define-global zzz "ho")
> zzz
"ho"
> (do (define x 10) (+ x 9))
19
do evaluates multiple expressions, and itself evaluates to the value of the last expression.
Variables for a limited scope are introduced using let:
> (let (x 10 y 20)
(+ x y))
30
> (let x 41 (+ x 1))
42
> (let x 1
(let x 2
(print x))
(print x))
2
1
You can see that let accepts a list of names and values, called bindings, or it can work with a single binding. More than one expression can follow the bindings, which works like do:
> (let (x 10 y 20)
(print x)
(+ x y))
10
30
> (let x 9
(print "hi")
(let y (+ x 1) y))
hi
10
Assignment
Variables and list values can be updated using set, which evaluates to the value that it updated:
> (let x 10
(set x 15))
15
> (let x 10
(set x 20)
(+ x 5))
25
> (let a (list 1 2 3)
(set (at a 1) "b")
a)
(1 "b" 3)
> (let a (list foo: 17)
(set (get a "foo") 19)
a)
(foo: 19)
Conditionals
Conditional evaluation is done using an if expression. The value of an if expression is that of the branch whose condition evaluated to true:
Macros allow you to write functions that manipulate expressions before they have been evaluated. Macros take expressions as parameters and return an expression:
> (define-macro when (condition rest: body)
`(if ,condition (do ,@body)))
(macro: function)
> (when true
(print 'hi)
(+ 10 20))
hi
30
Acknowledgements
Lumen was conceived and designed with Daniel Gackle, and many fixes and improvements have been contributed by Shawn Presser.
请发表评论