The Resurrection of LLL: Part I

According to Merriam-Webster's secondary definition, resurrection is

the act of causing something that had ended or been forgotten or lost to exist again, to be used again, etc.

That's an apt description of the current state of LLL. In this series of articles and the associated GitHub repository, I intend to show that Ethereum's Low-level Lisp-like Language is a viable language in which to write smart contracts. I will demonstrate how LLL can fit into a contract development workflow and how it can provide a unique environment in which to challenge one's approach to writing Ethereum contracts.

I know that many people will disagree with my thoughts here. For most, Solidity will remain their main contract development language—and that's perfectly fine. But I think it's important to have alternatives. Developers used to choose between LLL, Serpent, Mutan and Solidity. But now, aside from a few hangers-on, the vast majority of contract development is done in Solidity. I'm simply offering an alternative approach.

In upcoming articles I will be making some assumptions. First, I assume a familiarity with Ethereum itself. Second, this is definitely for developers, especially developers already familiar with smart contract development. I only assume a passing familiarity with Lisp, however. LLL is similar to Lisp but is definitely not Lisp.

The problem

I have come here not to bury Solidity, but to praise it (to inversely paraphrase Mark Antony). Solidity is an excellent solution to a difficult problem: How can we attract regular developers to an entirely new platform? The answer is, give them a system that is familiar to them. This results in a reduced on-boarding time; a developer can start writing smart contracts much sooner.

But there's a problem with that.

Contract development is hard. On the surface it seems so familiar, and indeed it's easy to get a toy contract up and running in a relatively short time. But we've recently seen how easy it is to cause chaos with one misplaced line of code. Add to that the myriad of security concerns and the difficulty in addressing them and you have a system not suitable for casual developers, especially with real money at stake. You have to be invested, so to speak, to develop secure contracts.

Keep in mind, however, that Ethereum is still a very young platform. Many—if not all—of these issues will be addressed in the future. But right now, as Ethereum's major release names, Frontier and Homestead, suggest, it's a bit of a wild west out there.

An aura of familiarity

One of the issues I've seen discussed is the fact that Solidity is almost JavaScript. A result of this is that people who know JavaScript think they know Solidity. This is a valid assumption; it's exactly what is intended. But contract development is very different from regular development so this familiarity is a false comfort and can, in fact, lead to disaster.

I believe we need to separate the mindset of front-end development from that of contract development. I've heard it said that contracts are to the blockchain as stored procedures are to a relational database. It's not a perfect fit but it illustrates that in no way is contract development similar to front-end development, or even to most back-end development, for that matter. In addition, stored procedures are not something that the average developer writes on a regular basis.

Don't get me wrong: front-end development is also hard. But the technologies and processes involved are light-years away from what are effectively stored procedures. And the consequences of a bug don't have the same potential for monetary loss.

One way to drive home the difference is to remove the familiarity. Doing so will force one to re-evaluate how to go about writing a contract instead of relying on what seems to be relevant experience in another language.

A bit of history

Back when Vitalik, Jeff, Gavin and the rest were developing the beginnings of Ethereum, they knew they didn't want to write code directly in assembler. The EVM, or Ethereum Virtual Machine, is a very simple VM with only basic jumps and stack manipulation for program control. But they also knew they couldn't come up with an all-encompassing high-level language in an acceptable time frame. As a result, LLL was born.

A lovely little language

LLL is a thin layer on top of the EVM that resembles Lisp. All EVM opcodes are available in LLL. On top of that it provides control structures (for, when, if, etc.) that are difficult and confusing to do in assembler. It also provides other convenient abstractions such a macros, and has the ability to include other source files as well.

LLL does use Lisp's parentheses, but as with Lisp they're mainly for the parser. Lisp developers use indentation to indicate code blocks, much like Python. That's why you see stacks of right-parentheses near the end of code blocks; it's really just cleanup from preceding left-parentheses.


In this series of articles I will present and examine a contract function dispatcher written in LLL and an example contract that uses this dispatcher, allowing the contract to replace itself with a newer and/or less buggy version. The contracts will use logging to support events, and will be callable from web3, as they support the same calling format as Solidity. Function modifiers are also presented and discussed.

In the next article we install the LLL compiler, lllc. We also start the examination of the dispatcher by discussing its supporting files, beginning with constants.lll, which leads us to LLL macros.

See you there!