SCaml: It's not a scam.

Since 2019-09, DaiLambda has worked on a small secret project called SCaml, a compiler for smart contracts for Tezos blockchain. Now reaching its pre-release status, we have revealed its existence in Tezos Smart Contracts: Programming Languages and Formal Verification on 2019-11-22.

SCaml is a statically typed purely functional programming language. It is a strict subset of OCaml, which is wildly used in computer science and finance including Tezos protocol implementation. It compiles a subset of OCaml to Michelson, stack based VM language for Tezos smart contracts.

Benefits and Possibilities of being a Subset

SCaml’s goal is simplicity. For this goal it sticks to be a strict subset of OCaml, unlike the existing OCaml compilers (Liquidity and LIGO) to Michelson which have extra features. Being a strict subset of an existing language has the following benefits:

Low development cost
It is built over OCaml’s compiler infrastructure library compiler-libs to use its parser and type-checker as they are. Concentrating only on its Michelson backend, we could write the first full version of SCaml just in 5 days.
High quality
OCaml is battle tested for more than 20 years. We can free-ride on its quality assured parser and type-checker.
Low learning cost
OCaml programmers can start writing smart contracts in SCaml immediately without any surprises. Newcomers can learn SCaml via existing tutorial materials of OCaml. Us developers need not write a long document to explain the difference in the language and the language it based upon.
Free tooling
Many existing eco-system tools for OCaml are usable for SCaml for free: code highlighter, reformatter, indenter, IDE, preprocessor, etc. etc.
Simulation in native code
Valid SCaml programs are also valid OCaml programs. With an OCaml library (which does not exist yet) to emulate the Michelson primitives, one can simulate smart contract executions much faster than the Michelson interpreter by compiling them with OCaml to native code. It will make it possible to perform efficient Monte Carlo simulations of Tezos smart contracts.
Code sharing between dApp layers
SCaml will enable dApp development in one language. Smart contract on chain, server code off chain, and UI for the clients can be all written in one language, OCaml, sharing some code. SCaml, OCaml, and JSOO will compile code to Michelson for the smart contract, native code for the server side, and JavaScript for the clients respectively.
Easy to extend
SCaml is compatible with OCaml and uses OCaml’s compiler infrastructure. It permits compiler researchers (of course they know OCaml internals!) to implement their ideas of smart contract compilations and verifications easily.

Stay cheap, simple, but solid

SCaml will not promise cool features:

  • It does not check all the typing details of Michelson. Let Michelson’s type-checker do it.
  • Keep to the standard OCaml typing. No additional cool but complex typing to secure smart contracts.
  • No sexy tools specialized for it. Use existing tools for OCaml.
  • No O’Reilly book covered with a cute animal.

Instead, we work for a solid compiler with the least effort, optimistically hoping things emerge around it. DSL with better features which compiles down to SCaml. Proof of SCaml compilation correctness. Formal verification of contracts written in SCaml, etc.

Example: a voting app

Here is a small example of SCaml code which implements a simple voting:

open SCaml

A library module SCaml provides the access to Michelson primitives.

type config =
  { title          : string
  ; beginning_time : timestamp
  ; finish_time    : timestamp
  }
(* Records *)

type action =
  | Vote of string
  | Init of config
(* Variant *)

type storage =
  { config     : config
  ; candidates : (string, int) map  (* Map *)
  ; voters     : address set        (* Set *)
  }

let init config =
  { config
  ; candidates = Map [ ("Yes", Int 0); ("No", Int 0) ]  (* Map literal *)
  ; voters     = Set [] (* Set literal *)
  }

Michelson’s arbitrary length integers have to be wrapped with Int constructor. This is required for the compilation by OCaml to use the appropriate arithmetic library. This lousiness can be removed by introducing a simple PPX preprocessor.

let vote name storage =
  let now = Global.get_now () in

  assert (now >= storage.config.beginning_time && storage.config.finish_time > now);

  let addr = Global.get_source () in

  assert (not (Set.mem addr storage.voters));

  let x = match Map.get name storage.candidates with
    | Some i -> i
    | None -> Int 0
  in
  ([] : operation list),  (* type constraint required *)
  { storage with
    candidates = Map.update name (Some (x + Int 1)) storage.candidates
  ; voters     = Set.update addr true storage.voters
  }

SCaml is monomorphic and cannot handle polymorphic values of OCaml. When OCaml type-checker infers something too general, you have to constrain the types to monomorphic.

let main action storage = match action with
  | Vote name -> vote name storage
  | Init config -> ([], init config)

Unless specified explicitly, SCaml takes the last value definition as the entry point of the smart contract.

This code can be compiled just by

$ scamlc vote.ml

which produces vote.tz. If you make mistakes then you see familiar OCaml parse error and typing error messages. If you see something unusual, it is because your code uses features not supported by SCaml.

Features (not in SCaml)

SCaml does not support the following OCaml features. You should first check this list before trying it.

Recursion by let rec

Michelson has no opcode for recursion. Therefore no let rec construct.

Map/iter/folding over lists, sets, maps, and big maps are supported via SCaml library functions. Simple loops are also available via Loop.left using LOOP Michelson opcode.

Polymorphism

Michelson is monomorphic language. So is SCaml. You cannot define polymorphic values.

If you happen to define a polymorphic value, SCaml compiler asks you to add a type constraint to it.

Separate compilation

A contract must be written in one file.

Others

  • Modules.
  • Labeled functions.
  • Partial application of primitives defined in SCaml.
  • Side effects: reference, mutable record fields, arrays.
  • Exceptions.
  • Classes, and objects.

Road Map

“Road map” is another expression of “promises almost never fulfilled in time”.

SCaml 1.0 “Pyramid” on 2020-01-01

Pyramid will be the first stable release of SCaml. It should cover all the Michelson opcodes.

After Pyramid, we concentrate on maintenance for a while, to make it stable.

SCaml 1.1 “Salting” around 2020-03

Salting will be a release to support the next Tezos protocol upgrade, likely called Carthage. It will contain only support for the upgrade, bug fixes and trivial optimizations.

Name of the Game

‘S’ of SCaml is for Small, Simple, Stupidraightforward, Solid compiler for Smart contracts. It also means Smart Contract Abstract Machine Language. The naming follows a beautiful tradition from the OCaml community to call variants of OCaml compiler xCaml where x represents the idea behind the variations.

No, it’s not a scam. Because Scams never name themselves scam.