Blog

Introducing Antril and Larva 0.8

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:

Terminal
irm https://www.antril.org/install.ps1 | iex

On Linux and macOS:

Terminal
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:

Terminal
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:

Terminal
larva --version
larva 0.8.0

A first program

larva new creates a project from a template:

Terminal
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:

Antril
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:

Terminal
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:

Antril
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" });
	}
}
Terminal
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 is Describe(Planet p) : str. A function type is func<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 all loop.
  • Free functions live in namespaces. into namespace Hello { … } holds functions, types and constants. Main is just a free function.
  • Primitives go further than usual. Integers range from i8 to i256 and u8 to u256, and floats from f16 to f256. str is text, and a type without ? can never hold null.

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:

.queen
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:

Terminal
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:

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:

Terminal
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: custom is 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.
  • Main cannot take text arguments from the command line yet.
  • Native executables need the MSVC tools. Linux and macOS native builds are not finished.
  • larva build compiles the whole program every time. An incremental cache per assembly is planned. larva run already skips the build when nothing changed.

Get started

We look forward to seeing what you make with it.

All posts · Atom feed · RSS

Esc