Getting started#
This page takes you from nothing to a running Alpha program, then to a GPU training executable. If you only want to look around, the REPL runs the real compiler in your browser.
Requirements#
| For | You need |
|---|---|
| The compiler | Linux on x86-64 (AArch64 works for the direct native target), GHC 9.10.3 and cabal 3.12 |
| Running on a GPU | A supported NVIDIA card (see Hardware) with the Linux driver's 580 branch. Alpha talks to the driver directly, so the CUDA toolkit is not needed. |
Build the compiler#
The current compiler is a Haskell bootstrap that compiles Alpha source, including the compiler's own Alpha packages.
git clone https://github.com/thomasdavis/alpha.git
cd alpha
(cd bootstrap/haskell && cabal build -O2 exe:alpha)
export PATH="$(dirname "$(cd bootstrap/haskell && cabal list-bin -O2 exe:alpha)"):$PATH"
alpha version
alpha doctor # checks the workspace and lists every command
Your first program#
Save this as Hello.alpha:
module Hello
def double : (pi unrestricted n : Nat . Nat) =
(lambda unrestricted n : Nat . (nat-add n n))
def main : Nat =
(double 21)
Run it, then build it as a native executable:
$ alpha run --edition alpha-2027 --root Hello.alpha; echo $?
42
$ alpha build hello.elf --profile dev --edition alpha-2027 --root Hello.alpha
$ ./hello.elf; echo $?
42
main's natural number becomes the process exit status. The ELF is about 29 KB, static, and has no libc. Inside the Alpha repository the workspace manifest (alpha.project) already selects the alpha-2027 edition, so you can drop --edition there.
What you just wrote:
module Hellonames the module.(pi unrestricted n : Nat . Nat)is a function type.piis the dependent function type; here the result type does not depend onn, so it reads likeNat -> Nat.unrestrictedis the binder's quantity:nmay be used any number of times at run time. The others areerased(never at run time),affine(at most once) andlinear(exactly once).(double 21)appliesdoubleto21.
When something is wrong#
Errors carry stable codes. Change unrestricted to linear in double: n is now used twice, which a linear binder forbids.
$ alpha check --edition alpha-2027 --root Hello.alpha
./Hello.alpha:4:3: ALPHA-QUANTITY-VIOLATION: [module Hello] linear binder n is used 2 time(s)
Diagnostics lists the catalogued codes with their repairs, and alpha explain CODE prints the entry for one.
Build a learning system#
Bob is the smallest system in the repository: a next-byte predictor. This builds it as one self-contained RTX 3090 training and inference executable (about 800 KB, about 40 seconds):
alpha build bob-rtx3090.elf --profile release --artifact-value artifact \
--root systems/bob/src/Bob/Build/RTX3090Artifact.alpha
Each system's README explains its run protocol: train, continue from a checkpoint, predict. Learning systems lists every system and where it runs.
In the browser#
The REPL checks a module with the real compiler, then evaluates main and shows its type and value. It runs in a sandbox with no network and uses the reference evaluator, so nothing is compiled to native code there.
Where next#
- Language guide: syntax, types, quantities, effects and families.
- Families and branches: defining and consuming data.
- Language and compiler: how a program becomes an executable.
- Specification: the exact rules, when prose is not enough.