Structured
Structs, enums, unions, interfaces, and datatypes for describing data. A type satisfies
an interface or datatype by having the right members, with no implements clause.
Programming Language
ADM is statically typed and compiles to native binaries. Contracts, transactions, background services, and UI components are part of the language - not libraries you bolt on.
module rocket {
use std.units::*
// Contracts: checked when the function starts and when it returns.
def burnTime(fuel Mass, rate MassFlow) !Time {
expects {
assert rate > 0 onerror fail "engine off"
}
let t = fuel / rate
return t
provides {
assert t < 10(min) onerror fail "burn too long: {t.str(min)}"
}
}
// Compiled for the GPU; runs on the CPU when there is none.
cuda def cool(temps float64[], by float64) !none {
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < temps_len) temps[i] -= by;
}
async def weather() string {
use std.net.http
let reply = http.get("https://wttr.in/Cape+Canaveral?format=3") onerror return "no go"
return reply.text() onerror recover "no go"
}
async def range() string {
return "go"
}
}
application Launch {
use (
std.units::*
rocket
)
let fuel Mass = 0
def load(m Mass) {
begin { fuel += m }
rollback { fuel -= m }
}
// When anything inside fails, every rollback runs.
def fuelUp(m Mass) !none {
transaction {
load(m)
let t = try rocket.burnTime(fuel, 2.5(t/s))
println("burn for {t.str(s)}")
} onerror (err error) {
println("scrubbed: {err.message}, fuel back to {fuel.str(t)}")
recover none
}
return none
}
def new(args string[]) int {
fuelUp(2000(t)) onerror return 1
fuelUp(400(t)) onerror return 1
// Both checks run at once; the first answer wins.
let status = await (rocket.weather() || rocket.range())
println("status: {status}")
// All four engines compared in one SIMD instruction.
let temps = float64[910.0, 870.0, 1020.0, 880.0]
let v vec4<float64>
let hot = v.load(temps, 0).gt(v.splat(1000.0))
if hot.any() {
rocket.cool(temps, 50.0) onerror recover none
}
// One task per engine, spread across cores, reporting on a channel.
let telemetry channel<string> = new(size = 4)
forall let (i, t) in temps {
telemetry <- "engine {i}: {int(t)} K"
}
telemetry.close()
for let line in telemetry {
println(line)
}
return 0
}
}
Structs, enums, unions, interfaces, and datatypes for describing data. A type satisfies
an interface or datatype by having the right members, with no implements clause.
Pattern matching, string interpolation, async/await, and channels. Errors are values:
!T to return one, try to pass it up, onerror to handle it.
Compiles ahead of time for Linux, macOS, Windows, Android, iOS, and WASM. SIMD vectors
are built into the language, and a cuda def function runs on the GPU.
Numbers can carry units: 100(km), 9.81(m/s²). Distance divided
by time gives a speed, which you can print in km/h, m/s or any other speed unit. Over 700
units are built in, counting prefixed forms like km and MiB.
The standard library is written in ADM: networking, cryptography, compression, and codecs for many file formats (images, audio, video, fonts, documents, archives, mail).
Control what each program and each library can access (files, the network, devices) through permissions and policies. You see what a library needs before you add it, and the user decides what the app gets when it runs.
ADM ships as a single self-contained package: the compiler, the standard library and a bundled C toolchain. The standard library still has gaps; read the docs or browse the examples to see where it's heading.
Not yet. The macOS package is coming; Linux is the only platform released today.
Install with one command (current user, no sudo):
curl -fsSL https://raw.githubusercontent.com/admlang/adm/main/install.sh | sh
Installs into ~/.adm and adds ~/.adm/bin to your PATH. Later,
adm update fetches new releases. Prefer to do it by hand? Grab the
adm-<version>-linux-amd64.tar.gz from the
latest release, unpack it
anywhere and put its bin/ on PATH. The IntelliJ plugin is on the same page.
Not yet. The Windows package is coming; Linux is the only platform released today.