← Back to Blog

The Lateralus REPL

April 15, 2025 toolingrepl

The Lateralus REPL (Read-Eval-Print Loop) provides immediate feedback for exploration, debugging, and prototyping. Unlike batch compilation, the REPL lets you interact with the language in real-time.

◉ Starting the REPL

$ lateralus repl
Lateralus v1.5.0 REPL
Type :help for commands, :quit to exit

|> _

The |> prompt reflects the pipeline-first philosophy.

◉ Basic Usage

|> 1 + 2
3

|> "hello" |> upper
"HELLO"

|> [1, 2, 3] |> map(fn(x) { x * 2 }) |> sum
12

|> let x = 42
|> x * 2
84

Variables persist across lines. Pipelines work naturally.

◉ Multiline Input

The REPL detects incomplete expressions automatically:

|> fn greet(name: str) {
...     "Hello, " + name + "!"
... }
|> greet("World")
"Hello, World!"

|> match 42 {
...     0 => "zero",
...     n if n > 0 => "positive",
...     _ => "negative",
... }
"positive"

◉ REPL Commands

Special commands start with ::

:help           Show all commands
:quit           Exit REPL (or Ctrl+D)
:clear          Clear screen
:reset          Reset all state (variables, functions)
:type <expr>    Show inferred type
:ast <expr>     Show parsed AST
:ir <expr>      Show generated IR
:time <expr>    Measure evaluation time
:load <file>    Load and execute file
:save <file>    Save session to file
:history        Show command history
:env            Show all bindings

◉ Type Inspection

|> :type 42
int

|> :type [1, 2, 3]
list[int]

|> :type fn(x) { x + 1 }
fn(int) -> int

|> :type filter
fn[T](items: list[T], pred: fn(T) -> bool) -> list[T]

|> :type map
fn[T, U](items: list[T], f: fn(T) -> U) -> list[U]

◉ Loading Files

|> :load utils.ltl
Loaded 5 functions, 2 structs

|> :load data.ltl
Loaded 'data' binding

|> data |> filter(fn(x) { x > 0 }) |> len
42

Loaded definitions become available immediately.

◉ Debugging with AST/IR

|> :ast 1 + 2 * 3
BinOp(
  Add,
  Literal(1),
  BinOp(Mul, Literal(2), Literal(3))
)

|> :ir [1, 2, 3] |> sum
LOAD_CONST [1, 2, 3]
LOAD_GLOBAL sum
CALL_PIPELINE 1
RETURN

◉ Timing and Benchmarking

|> :time range(1, 1000000) |> sum
499999500000
Time: 45.3ms

|> :time fib(35)
9227465
Time: 892ms

◉ Tab Completion

Press Tab to complete:

|> ma<TAB>
map     match   max     math

|> math.<TAB>
math.sin    math.cos    math.sqrt    math.pow
math.abs    math.floor  math.ceil    math.round

|> stru<TAB>
struct   String

◉ History and Editing

Standard readline keybindings:

History persists to ~/.lateralus_history.

◉ Syntax Highlighting

The REPL highlights as you type:

◉ Configuring the REPL

Create ~/.lateralus/repl.toml:

# REPL configuration
prompt = "|> "
multiline_prompt = "... "
history_size = 10000
auto_print = true        # Print expression results
color = true             # Syntax highlighting
strict_mode = false      # Allow type inference

[keybindings]
ctrl_d = "quit"
ctrl_l = "clear"

◉ Session Example

$ lateralus repl
Lateralus v1.5.0 REPL

|> // Define a struct
|> struct Point { x: float, y: float }

|> // Constructor
|> let p = Point { x: 3.0, y: 4.0 }

|> // Pipeline to compute distance
|> fn distance(p: Point) -> float {
...     math.sqrt(p.x * p.x + p.y * p.y)
... }

|> distance(p)
5.0

|> // List of points
|> let points = [
...     Point { x: 0.0, y: 0.0 },
...     Point { x: 3.0, y: 4.0 },
...     Point { x: 1.0, y: 1.0 },
... ]

|> points |> map(distance) |> max
Some(5.0)

|> :save session.ltl
Saved 2 structs, 1 function, 2 bindings

|> :quit

The REPL is available in the online playground or via lateralus repl locally.