Lamber, a Simple Language
Lamber is a minimalist functional programming language with a focus on graspability, readability… and compilation to pure untyped Lambda Calculus, of course! It’s inspired by Lua, Haskell, and Wisp. And it smells of creamy cheese!
Lamber in a Postcard
def factorial function (n) if (= n 0) then 1 else * n : factorial : dec n .
Step by step:
- You can bind things to names/variables (like
factorial) withlet,def,local, andvar. All of these do the same thing, so pick the one you like the most. - Functions are all there is to Lamber. It compiles to raw lambdas, after all. It’s only consequential that things you bind to vars are
fn-s,lambda-s,a ndfunction-s. - There’s
if~/~whento do conditional checks. Withelsebranches andelse ifchaining. Boring stuff, right? - There’s no need for explicit
returnstatement, because the last form in the function/branch is the return value.- So factorial returns either
1or… wait, I need to explain some more.
- So factorial returns either
- Functions are prefix in Lamber, so
= n 0means “n is equal to zero” anddec nmeans decreasing n. - There’s no looping in Lamber, only recursion.
- Luckily, first-class functions and abundance of list processing utilities in the standard library make explicit looping unnecessary in most cases.
- There are several special syntax pieces, mostly stolen from Wisp:
:colon to chain function calls. Lamber emphasizes composable functions that are easy to chain, as in* n : factorial : dec n:- Decrease n.
- Call
factorialon it. - And multiply the result by
n.
.period is a shortcut forend(like in Lua and the kind.) You can do explicitendtoo, but it’s not as pretty:
else * n : factorial : dec n end
Values
There’s a number of guiding principles Lamber is built around:
- Minimalism
- If something is not absolutely necessary, it’s not going to be there.
- Cognitive
- All there is in the language should fit into one moderately overwhelmed programmer’s head.
- Footprint
- Implementation should be small enough.
- Build
- All the libraries and apps are provided as files on CLI or in
LAMBER_PATHand sorted lexicographically. Want to load your lib earlier? Just rename the file! - Syntactical
- There shouldn’t be more than ten pieces of syntax in the language.
- As of the moment of writing, there are eight:
let/defetc. variable definition.ifbranching.function-s.type-s.- Literal values, like booleans, numbers, and strings.
- Function calls.
- Colons.
- Periods.
- As of the moment of writing, there are eight:
- Readability
- Lambda Calculus is scary. Lua is not. Lamber tries to be somewhere in between the two, with the bias towards Lua.
- Functional design
- Functional programming won, and you have to live with it. Make your functions composable and higher-order. And no side-effects (well, there’s ./lib/8000-io.lmb, but hush!)
Installation & Getting Started
- Clone the repo:
git clone --recursive https://github.com/aartaka/lamber
- Install a Lisp implementation like SBCL.
- Compile the
lamberexecutable withmake all - Use the generated
lamberas in
./lamber example/hello.lmb # Hello, world! ./lamber example/factorial.lmb int # 120