Install & run
Amber compiles from source on first run. Nothing is installed system-wide, there is no package to add and no prefix to choose — the checkout is the installation.
Clone
git clone https://github.com/BonucciAndrea/amber.git
cd amberLinux / WSL2
sudo apt-get update && sudo apt-get install -y build-essential # one-time
chmod +x a build.sh install.sh # restore exec bits if the copy dropped them
./a # builds, then opens the REPLmacOS (Intel or Apple Silicon)
xcode-select --install # installs the Command Line Tools (clang); one-time
chmod +x a build.sh install.sh
./a./a compiles the interpreter with portable -O3 and drops you at the
prompt. It recompiles automatically whenever the C sources change, so you never run a stale build.
If ./a prints Permission denied, the executable bit was
lost in transfer — the chmod +x line fixes it, or just run bash a.
Machine-tuned builds
The default build is portable C99 and always includes -pthread (needed by the
multithreaded vector engine) plus the scalar SIMD fallback. For a build that turns on
AVX2 (x86_64) or NEON (aarch64), set AMBER_NATIVE=1:
AMBER_NATIVE=1 ./build.sh # machine-tuned`simd 0 / prints which backend was selected: scalar / avx2 / neonNEON activates unconditionally on Apple Silicon regardless of the flag, since aarch64
implies it. The tuning flag itself is probed, not assumed: -march=native
is x86 syntax that Apple clang rejects outright, so build.sh falls back to
-mcpu=native and, failing both, to a portable build.
One command instead of all of the above
./install.sh # or: bash install.sh (if the +x bit was lost)
AMBER_NATIVE=1 ./install.sh # ... with a machine-tuned buildinstall.sh checks you have a C compiler (and prints the exact package command for
your distro if you do not), repairs the executable bit on every script, builds, runs the self-test,
and writes a managed shell block into the rc file your login shell actually reads —
~/.zshrc for zsh, ~/.bash_profile on macOS bash, ~/.bashrc on
Linux bash, ~/.profile otherwise. Re-running it replaces that block rather than
appending a second copy.
Shell configuration
# === Amber - native engine configuration ===================================
# AMBER_HOME is the Amber checkout ITSELF. Amber is one self-contained folder:
# there is no bin/ directory, nothing is copied anywhere, and deleting the
# folder uninstalls it completely.
export AMBER_HOME="$HOME/amber"
# amber -> the full REPL: repl.k, the q/kdb+ vocabulary and the stdlib.
alias amber='AMBER_NATIVE=1 "$AMBER_HOME/a"'
# amberx -> the bare interpreter for scripts and pipes: no REPL, no stdlib.
alias amberx='"$AMBER_HOME/amber"'
# Pin the vector engine to your physical cores; omit to use every core.
# alias amber='AMBER_NATIVE=1 AMBER_THREADS=8 "$AMBER_HOME/a"'
# Aliases do not exist in non-interactive shells. For scripts, cron and CI,
# symlink the launcher instead of putting the repo root on PATH:
# mkdir -p ~/.local/bin && ln -sf "$AMBER_HOME/a" ~/.local/bin/amberThree variants that look right and are not
| Looks like | Why it does not work |
|---|---|
PATH="$AMBER_HOME/bin:$PATH" |
Amber has no bin/, lib/ or share/ split and installs
nothing outside its folder. That path does not exist. $AMBER_HOME is the checkout,
not a prefix. |
alias amber='$AMBER_HOME/amber' |
The bare amber binary is the interpreter with no stdlib:
select, aj and sum are undefined there. Alias the
launcher a, which loads repl.k, which loads everything else. |
AMBER_NATIVE=1 ./amber |
AMBER_NATIVE is a build-time variable read by build.sh,
not by the interpreter. It belongs on the a alias — which may rebuild — and does
nothing on amberx. |
Environment variables the engine reads at run time
| Variable | Default | Effect |
|---|---|---|
AMBER_THREADS | online CPU count (cap 64) | Vector-engine lanes and peach worker count. =1 forces serial. |
AMBER_DIAG | off | Render the full Rust-style error[…] report alongside the terse caret line. |
AMBER_NO_EDIT | off | Disable the native line editor; Amber reads whole lines instead. |
AMBER_NO_RLWRAP | off | Suppress the rlwrap fallback that AMBER_NO_EDIT=1 would otherwise use. |
AMBER_HOME | — | Where satellites (python-amber, amberd) load the .k standard library from. |
There is no AMBER_MEM_MB: the heap is mmap'd with
MAP_NORESERVE and sized lazily by the OS, so there is nothing to tune.
Do not use rlwrap
rlwrap runs the wrapped program on a pty and speaks readline on its behalf, which only works for
a program that reads whole lines in canonical mode. Amber puts the terminal into raw mode
and reads single keypresses, so rlwrap is doing nothing useful — and says so, mid-session, while the
two editors fight over one cursor and garble the redraw. ./a execs the interpreter
directly.
The native editor (src/ln.c, ~700 lines of C99 + POSIX termios, no
readline, no curses, no dependency) gives you:
| Key | Action |
|---|---|
| ← →, Ctrl-B / Ctrl-F | move by character |
| Ctrl-A / Ctrl-E, Home / End | start / end of line |
| ↑ ↓, Ctrl-P / Ctrl-N | history, persisted in ~/.amber_history |
| Backspace, Del, Ctrl-W / Ctrl-U / Ctrl-K | delete char / word / to start / to end |
| Tab | complete globals, table columns, \ commands, the vocabulary, and whole lines you already ran |
| Ctrl-L · Ctrl-C · Ctrl-D | clear screen · abandon the line · exit on an empty line |
The editor degrades to a plain line read whenever stdin/stdout are not a terminal, so
echo '2+2' | ./a, here-docs and CI runs behave byte-for-byte as they always did. If you
genuinely need the fallback (a dumb terminal, an editor subshell, a screen reader):
AMBER_NO_EDIT=1 ./a # Amber reads whole lines; ./a wraps it in: rlwrap -n -a
AMBER_NO_RLWRAP=1 AMBER_NO_EDIT=1 ./a # ... or not even thatVerify the install
./amber --version # amber 1.9.6
./amber --help # options + the full \-command reference
./amber examples/tour.k # a worked example of EVERY function
./amber examples/basics.k # a 2-minute intro
./amber examples/tick.k # trades & quotes: as-of/window joins, VWAP, OHLC
./amber examples/hft.k # the finance module walkthrough
./amber test.k # core suite (163)
tests/run_tests.sh # build + all K suites + C unit tests + fuzz pass
tests/run_tests.sh --asan # ... and again under AddressSanitizer + UBSanThe showcase demo
One command builds Amber with maximum optimization and runs the Mega Demo: a 5,000,000-row HFT
tick session (VWAP, a tacit 50-period EMA, a native as-of join), a 10,000,000-element vector-op
benchmark, and a couple of \ast/\disasm samples straight from the real
parser and compiler.
./demo.sh # portable -O3 build
AMBER_NATIVE=1 ./demo.sh # -march=native build (fastest on this machine)== benchmark summary =======================================
stage ms
----------
gentq 2381.9
vwap 151.2
ema 0.1
asof 704.0
------------------------------------------------------------
total: ~3.2 s end-to-end for 500,000 tradesThe shared library
Every satellite — python-amber, amber-arrow, amberd —
links libamber.so rather than the executable. Build it explicitly:
./build.sh # ./amber (unchanged; identical binary, zero new cost)
./build.sh --shared # ./amber + libamber.so
./build.sh --shared-only # libamber.so only
AMBER_SHARED=1 ./build.sh # same as --shared, for callers that cannot pass a flagAmber is a single self-contained folder. The interpreter is named amber (never
k or q), built only inside the folder, never placed on your
PATH. It reads and writes no config, no QHOME, no dotfiles. Your kdb+,
kona and other k/q installs are untouched.