Letlang specification finalized!

David Delassus
6 min readFeb 4, 2024

A long time has passed since the last update on Letlang… This is mainly because I hadn’t had the free time in the past months. But the last few weeks, I took the time to finalize the specification for the v0.1.0 🙂

For this specification, the syntax of the language has changed to better reflect its semantics. The architecture of the compiler has also been redesigned quite a bit.

All those changes were for the sake of simplicity and clarity. With this specification, the language is now more coherent and less like an aggregate of random features.

A new command line interface

One thing I like about C and C++ (and Rust without Cargo) is the simplicity of the CLI, you take one source file and make a build artifact:

$ gcc -c foo.c -o foo.o

Up until now, Letlang needed a letproject.toml file and expected a specific folder tree. It was inspired by the design of Cargo. But Cargo is not a compiler, it is a package manager/build system. It relies on rustc, the actual Rust compiler.

One thing that remains the same is that every Letlang module is translated to a Rust crate. There are 2 kinds of crates that Letlang will produce: library crates, and executable crates. The way to build them has changed though:

$ letlangc --type=lib --rpath /path/to/runtime-crate foo.let
$ letlangc --type=exe --rpath /path/to/runtime-crate bar.let

Library artifacts will produce a libfoo.lla archive containing the following:

|-- libfoo.lli
|-+ lldep_foo/
|-- Cargo.toml
|-+ src/
|-- lib.rs

The libfoo.lli file contains what is called the “Binary Module Interface”. It is a description of the exported Letlang symbols that will be used during the name resolution phase of compilation. This allows the developer to not need the actual Letlang code for a module in order to depend on it.