Sigmal is a total, pure, statically typed, compiled programming language.
Core principles:
= is the only binding operator: is used exclusively for typing. is used exclusively for projectionSigmal compiles to LLVM and WASM with minimal runtime components.
All names are introduced using:
name = expression;
There are no implicit bindings. There is no def keyword. There are no
declaration forms separate from expressions.
A file evaluates to a record value.
Example file:
& {
x = 10;
y = 20;
}
This is a record literal.
There is no top-level namespace outside the file’s record value.
: is used exclusively for typing:
x : T = value;
There is no other meaning for :.
. performs record/module projection:
module.field
There is no :: operator.
Projection is left associative:
a.b.c
means:
(a.b).c
Application is whitespace-based:
f x y
means:
((f x) y)
Parentheses are for grouping only.
There are no struct or enum keywords.
Inductive types use ASCII symbolic syntax.
Example:
MyEnum = # {
True;
False;
};
The # form constructs an inductive type.
.$ refers to the type constructor:
t : MyEnum.$ = MyEnum.True;
Constructors are projected via .:
MyEnum.True
There is no implicit global constructor namespace.
Record values use & {}:
Point = & {
x = 0;
y = 0;
};
Records are first-class values. Modules are records. There is no distinction between modules and records.
Sigmal has no tracing garbage collector.
Rc, optional Weak)Reference counting is deterministic and semantically unobservable.
The allocator interface lives in std.alloc:
Allocator = & {
alloc = fn (size: USize, align: USize) -> Ptr<U8> { ... };
free = fn (ptr: Ptr<U8>, size: USize, align: USize) -> Unit { ... };
};
std.alloc.default exists on all targets.
For wasm32-unknown-unknown, it is implemented internally using linear
memory.
Effects are modeled using explicit capability values.
Interfaces are defined in std.core.
Example:
IO = & {
write = fn (Bytes) -> Unit;
read = fn () -> Bytes;
};
Implementations are provided in std.cap.
Example:
std.cap.io.default
Programs consume capability values explicitly:
greet = fn (io: std.core.IO) {
io.write (encodeUtf8 "Hello");
};
There is no ambient global effect.
Stable across all targets:
std.core — Pure logical foundationstd.low — Freestanding systems primitivesstd.alloc — Allocator interface and default allocatorstd.cap — Capability implementationsstd.abi — ABI definitionsstd.high — High-level functional utilitiesNames remain identical across targets.
export "entry" = functionValue;
Only functions may be exported in wasm32-unknown-unknown.
import "host.func" : (U32 -> Unit);
Imports bind external symbols to local names.
Supported comment forms:
// line comment/* ... */ nested block comment/// documentation comment/** ... */ documentation block= is the only binding operator.: is only used for typing.. is only projection.struct or enum keywords.#).