Why Low Level Lisp (LLL) is my preferred language for Ethereum development

Unfortunately there appears to be a large barrier of entry to begin writing EVM-based code. The documentation is essentially non-existent for many languages, and for Solidity, outdated. Before I started looking into how to program for the EVM, I partially read the Ethereum white and yellow paper. Essentially the entire system boils down (up?) to this equation:
Which can be interpreted as "A function Y, which takes the current global state and a transaction T, returns the next new state."

After that I went on the hunt for some languages I could use. At one time or another you've probably heard the term "Solidity", which is a JavaScript-like language that compiles down to EVM assembly. You've probably also heard it's pretty terrible, in more than one way. For this reason I've looked seriously at alternatives.

Currently everything is Alphaware. Missing documentation, outdated documentation, non-existent code, buggy compilers, and so on are common in the Ethereum development world. In order to get anything done, you need to look for posts by fellow developers and read the EVM source code, found in the solidity repository. During my research these were the languages I found:

Simplicity

A language that aims to be formally verified and rigorous. Currently has no implementation, but is specified in this paper. It looks fairly painful to use at first glance.

Viper

A Python-esque language striving to provide more explicit data moving and typing. The successor to Serpent. Because I'm not a Python fan, I didn't give it a chance, but it looks pretty good!

JULIA

"Joyful universal language (for) inline assembly" is provided in the Solidity repository. It's supposed to offer a functional-like language to work with EVM's assembly. It looks very nice when you go to use it. Lots of documentation, the grammar is there, and some other interesting bits. Then you actually go and use it - turns out the grammar is totally out of date, and when resorting to looking at the compiler source, you learn it's missing more than half of the functions it claims to have...!! Talk about frustrating.

Bamboo

Bamboo is very similar to Solidity, except it introduces the concept of states, which is popular in video games. Basically you define the contract and all the states it will be in. In each state you define the functions that are available, or the behavior of a particular function that may change between states. My biggest concern for Bamboo is they say it will compile your contracts with bugs sometimes.

LLL

Low Level Lisp ticks a bunch of boxes for me. Macros, functional paradigm, and it doesn't abstract away the EVM. This means I have full control and expressive power where all the other languages for the EVM don't. It even has zero cost abstractions, and only includes functions you actually call. Most importantly, LLL is considered "complete", so no language changes will break your contract code, and it actually compiles.

A quick comparison

LLL is included in the Solidity repository (just like JULIA). I think at one point in its history, Solidity compiled to LLL, but I'm not entirely sure. As a test, I re-implemented a #ethereum-dev user's contract that simply set and get a value. The contract can be viewed here:

https://ropsten.etherscan.io/address/0xe10027cd345efcf4745954141b2f5d9c4c762ad6#code

The Solidity code:

pragma solidity ^0.4.0;

contract SimpleStorage {
    uint storedData;

function set(uint x) public {
        storedData = x;
    }

function get() public constant returns (uint) {
        return storedData;
    }
}

The LLL code:

(seq
  (include "./constants.lll")
  (include "./utility.lll")

  (def 'stored-data 0x02)
  (def 'set 0x60fe47b1)
  (def 'get 0x6d4ce63c)

  ; Init
  (sstore stored-data 0x00)

  ; Code
  (returnlll (seq
    (when (= function-id set)
      (sstore stored-data (calldataload 0))
    )

    (when (= function-id get)
      (return @@stored-data 32)
    )
  ))
)

It's larger, but only for now. It's possible to write macros to make this code look much cleaner, such as this:

(seq
  (create-contract)
  (var stored-data)

  (code
    (fn set
      (sstore stored-data (calldataload 0))
    )
    (fn get
      (return @@stored-data 32)
    )
  )
)


To me this looks very elegant for the level we are programming at (right at the EVM!). The next step would be to use formal verification tools, or type hinting, or similar, to enforce certain behavior.

Programming close to the EVM is important because there will be so many contract developers who will have no idea what is actually happening under the hood, wasting gas and generating large bytecode.

Look at the bytecode size of the above Solidity code:

6060604052341561000f57600080fd5b60d38061001d6000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606e575b600080fd5b3415605857600080fd5b606c60048080359060200190919050506094565b005b3415607857600080fd5b607e609e565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a7230582080f030459ec8d49213acad5343ead1262366a06a043109c433b5676387897bdd0029

and the LLL code:

600060025560348060116000396000f3006360fe47b160e060020a6000350414156019576000356002555b636d4ce63c60e060020a6000350414156033576020600254f35b

I think that says enough.

Comments

  1. LLL in the browser with Blockly: https://kuip.github.io/loki/demos/evm/

    ReplyDelete
    Replies
    1. i'd love to know what your needs are and return to that project to make it better.

      Delete
  2. Another option. The Red programming language.
    http://www.red-lang.org/

    ReplyDelete
    Replies
    1. Where is it listed that it can target the EVM? I looked here but it's not listed: http://www.red-lang.org/p/getting-started.html

      Delete

Post a Comment

Popular Posts