Today we are releasing Larva 0.8.0, with Antril 0.8.0. Antril is a statically typed language with classes, value types, records, generics, async code and reactive code. Each project chooses how its memory is managed: a tracing collector, reference counting, arenas or manual delete. Larva is the toolchain behind one command, larva. It creates projects, compiles them to native code or WebAssembly, manages packages, generates bindings to C libraries and runs the language server your editor talks to. This post is a short tour of both, and of how to start.
Install
On Windows, from PowerShell:
irm https://www.antril.org/install.ps1 | iex
On Linux and macOS:
curl -fsSL https://www.antril.org/install.sh | sh
The script takes the options of install.sh. For example, --no-path installs without adding ~/.local/bin to your PATH:
curl -fsSL https://www.antril.org/install.sh | sh -s -- --no-path
If you would rather download a file, the download page has the Windows setup wizard, a portable zip and the Linux and macOS archives. The setup wizard and install.sh install for the current user, without administrator rights. The Linux and macOS packages are new in this release and have been tested less than the Windows installer, so please tell us if something goes wrong. Install Larva lists every option.
Then check it from a new terminal:
larva --version
larva 0.8.0
A first program
larva new creates a project from a template:
larva new Console-App Hello
C:\work\Hello: Console App in Antril (Program.ant, Hello.queen)
larva build Hello\Hello.queen
The project is a folder with a .queen project file and a Program.ant:
import System;
into namespace Hello
{
/// The program's entry.
Main()
{
Console.WriteLine("Hello from Larva!");
}
}
larva run builds the program if something changed, then runs it:
cd Hello
larva run
C:\work\Hello\bin\Hello.exe (llvm back end, O3, entry Hello::Hello.$Module.Main)
Hello from Larva!
The first line is larva's build report. It goes to the error stream, so your program's own output stays separate. Your first program goes through the project step by step.
What Antril looks like
Here is a slightly larger Program.ant. It uses a record, a switch with property patterns, string interpolation, a lambda and a with copy:
import System;
into namespace Hello
{
public record class Planet
{
public:
str Name;
f64 Mass;
new(str Name, f64 Mass);
}
Describe(Planet p) : str => p switch
{
{ Mass: < 0.1 } => "tiny",
{ Mass: < 10.0 } => "rocky",
_ => "a giant",
};
Main()
{
List<Planet> planets = new List<Planet>();
planets.Add(new Planet("Mercury", 0.055));
planets.Add(new Planet("Earth", 1.0));
planets.Add(new Planet("Jupiter", 317.8));
loop (Planet p in planets)
Console.WriteLine($"{p.Name,-8} {Describe(p)}");
func<Planet> : bool heavy = p => p.Mass >= 1.0;
Console.WriteLine($"{planets.Where(heavy).Count} of {planets.Count} weigh at least one Earth");
Console.WriteLine(planets[1] with { Name = "Terra" });
}
}
larva run
Mercury tiny
Earth rocky
Jupiter a giant
2 of 3 weigh at least one Earth
Planet { Name = Terra, Mass = 1 }
Some things to notice:
- Types come first, results come last. A variable is
f64 Mass. A function isDescribe(Planet p) : str. A function type isfunc<Planet> : bool. - Members are grouped by access.
public:applies to every member under it until the next label, like a section. - One keyword for every loop.
loop (x in items),loop (condition),loop (i32 i = 0..10)and the three-part form are allloop. - Free functions live in namespaces.
into namespace Hello { … }holds functions, types and constants.Mainis just a free function. - Primitives go further than usual. Integers range from
i8toi256andu8tou256, and floats fromf16tof256.stris text, and a type without?can never holdnull.
The language tour covers the rest: classes and value types, interfaces with default bodies, enums over integers, strings or values, tuples, generics with constraints such as T : number or T : op +(T, T) : T, variadic generics, custom operators with new symbols, extension blocks, exceptions, iterators with yield, async/await, and reactive fields with computed values and effects.
Memory is a project setting
Antril code does not say how memory is given back. The project does, with one key in its .queen file:
chunk BUILD:
gc: refcount
gc: |
How objects are freed |
|---|---|
default |
A tracing collector finds unreachable objects. |
refcount |
Each object is freed when its last reference goes. |
arena |
Objects are freed together when their region { … } block closes. |
manual |
You free each object with delete, in unsafe code. |
The same source compiles in every mode. What changes is when objects are freed, and so when destructors (destroy()) run. A program can also use libraries compiled for a different mode. On top of this, Antril has &T and &mut T references checked by a borrow checker (off by default, or as warnings, or enforced), pointers in unsafe code, and fixed buffers kept inside an object. All of it is in Memory.
Larva, the toolchain
Everything goes through larva:
| Command | What it does |
|---|---|
larva new, run, build |
Create, run and build projects. |
larva lib |
Compile sources into a Larva library (a .dll that carries compiled Larva code). |
larva config |
Your machine's defaults: GC mode, back end, borrow checker and more. |
larva hive |
Packages. |
larva bind |
Bindings to native libraries, from a C header or a .bind description. |
larva types, show, search |
Browse the standard library and your own code. |
larva languages, lsp |
Installed languages, and the language server. |
larva build has several back ends. LLVM is the default, and it optimizes. Larva's own x86-64 back end (--backend x64) compiles faster. WebAssembly (--target wasm-llvm) writes an app.wasm, an app.js that loads it and an app.html that runs it in a page. The larva command describes every option.
On Windows, native executables are linked with the MSVC build tools. Native builds on Linux and macOS are not finished yet: there, today, larva checks code and builds libraries.
Languages are packs
Larva itself does not contain a programming language. Each language is a language pack: a frontend that turns source text into Larva's typed program model, a view that writes that model back as source, and the editor services. Antril is the pack in Languages/Antril. Its files are hashed in its manifest, and the manifest is signed:
larva languages
Antril 0.8.0 (antril: .ant)
…
status: ok (files verified)
Every tool works on that shared model: builds, packages, bindings, the type browser and the language server. So a library written in one language can be used from another as a compiled .dll. The internals book explains how packs are loaded and checked.
The standard library
System.Core is written in Antril and installed already compiled, as System.Core.dll next to larva. import System; is all a program needs. It has collections, text and StringBuilder, Math over every number type, files and streams, JSON and regular expressions, TCP and HTTP, processes, threads, tasks, reactive primitives and interop with C. Browse it in the library browser or from the terminal:
larva search Sqrt
System.Math.Sqrt<T : INumber<T>>(T x) : T
System.Math.ISqrt<T : INumber<T>>(T x) : T
Hive
Hive is the package manager, built into larva. A package is a signed library named Author/Name. It comes from the public registry on antril.org, from another server, or from a folder:
larva hive add Antril-Organization/SDL3@^3.5
A follow-up post on the blog explains how packages and languages are signed.
Editor support
There are two VS Code extensions. Install Antril and it brings Larva with it. The Larva extension runs larva lsp. It shows errors as you type (including the borrow checker's), completion, hover and go to definition, also into the standard library, which opens decompiled as Antril. It also understands .queen files and adds commands such as New Project from a Template, Run, Build WebAssembly and Bind a Native Library. The Antril extension adds syntax highlighting, snippets and file icons for .ant files. Other editors that speak the Language Server Protocol can run larva lsp the same way.
What is not there yet
We would rather say this plainly. The architecture page keeps the list:
gc: customis accepted, but there is no interface for writing your own collector yet. Such projects are built with the tracing collector.- Larva's own WebAssembly back end (
--target wasm) produces invalid modules for some programs. Use--target wasm-llvm. Maincannot take text arguments from the command line yet.- Native executables need the MSVC tools. Linux and macOS native builds are not finished.
larva buildcompiles the whole program every time. An incremental cache per assembly is planned.larva runalready skips the build when nothing changed.
Get started
- Install Larva, or go straight to the download page.
- Write your first program, then take the language tour.
- Read the release notes for 0.8.0.
- Find packages on Hive, and ask questions or show what you build on the forum.
We look forward to seeing what you make with it.