Skip to content

REPL Guide

Launch the interactive REPL with no arguments:

kaappi
Kaappi Scheme v0.22.3
Type ,help for commands, ,quit to exit.

kaappi> (+ 1 2)
3
kaappi> _
3

Line Editing

The REPL uses linenoise for line editing with full terminal support.

Key Action
Left / Right Move cursor
Up / Down Navigate history
Ctrl+A Move to start of line
Ctrl+E Move to end of line
Ctrl+K Delete from cursor to end
Ctrl+U Delete entire line
Ctrl+W Delete previous word
Ctrl+L Clear screen
Ctrl+D Delete char at cursor (or exit if line empty)
Ctrl+T Transpose characters
Tab Auto-complete symbol names
Ctrl+R Reverse history search
Ctrl+C Cancel current line

Syntax Highlighting

The REPL provides real-time syntax coloring as you type, covering all R7RS token types:

Element Dark theme Light theme
Keywords (define, lambda, if, let, ...) Bright magenta Magenta
Strings ("hello") Bright green Green
Numbers (42, #xff, +inf.0) Bright yellow Red
Comments (;, #| |#, #;) Gray Gray
Booleans (#t, #f, #true, #false) Bright cyan Cyan
Character literals (#\space, #\λ) Bright yellow Red
Parentheses and brackets Gray Gray
Vector / bytevector (#(, #u8() Gray Gray
Quote / quasiquote / unquote (', `, ,, ,@) Bright magenta Magenta
Directives (#!fold-case) Gray Gray
Matched parenthesis Bold bright yellow Bold red
Primary prompt Bright green Blue
Continuation prompt Gray Gray

Highlighting is applied per-keystroke and does not affect cursor positioning or copy-paste behavior.

Theme Presets

The REPL ships with two color presets optimized for terminal background contrast:

  • dark (default) — bright ANSI colors for dark terminal backgrounds
  • light — standard ANSI colors for light terminal backgrounds

Select a preset in ~/.kaappi/config:

repl.theme: light

Customizing Colors

Override individual token colors in ~/.kaappi/config:

repl.theme: dark
repl.color.keyword: bright-cyan
repl.color.number: bright-red
repl.color.prompt: blue

Available color names: black, red, green, yellow, blue, magenta, cyan, white, and bright variants (bright-black, bright-red, ..., bright-white). Prefix with bold for bold (bold bright-yellow). Use none to disable color for a token type.

Configurable keys: repl.color.keyword, repl.color.string, repl.color.number, repl.color.comment, repl.color.boolean, repl.color.paren, repl.color.match-paren, repl.color.prompt, repl.color.continuation.

Disabling Colors

Set the NO_COLOR environment variable to disable all REPL coloring:

NO_COLOR=1 kaappi

Or disable highlighting while keeping other config:

repl.highlight: false

Parenthesis Matching

When the cursor is adjacent to a parenthesis, the REPL highlights the matching opening or closing parenthesis. This makes it easy to see the structure of nested expressions while editing, and is independent of syntax coloring.

Tab Completion

Press Tab to complete symbol names from the global environment:

kaappi> string-<TAB>
string-append  string-copy  string-length  string-ref  ...

Completion matches all bound symbols — built-in procedures, your own definitions, and imported library exports.

Comma commands are also completed:

kaappi> ,ti<TAB>
,time

History

History is saved automatically to ~/.kaappi/history. Up to 1000 entries are preserved across sessions (configurable via repl.history-length in ~/.kaappi/config).

  • Up / Down arrows — navigate through previous entries
  • Ctrl+P / Ctrl+N — same as Up / Down

Reverse History Search (Ctrl+R)

Press Ctrl+R to incrementally search through history, just like bash:

kaappi> <Ctrl+R>
(reverse-i-search)'': 

Type a search query — matching history entries appear as you type:

(reverse-i-search)'def': (define (fib n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
Key Action
Type characters Refine search
Ctrl+R Jump to next (older) match
Enter Accept the match for editing
Escape Cancel and restore original line
Backspace Remove last search character

Multi-line Input

Expressions with unmatched parentheses automatically continue on the next line:

kaappi> (define (square x)
  ...    (* x x))
kaappi> (square 7)
49

The prompt changes to ... while input is incomplete. The primary prompt can be customized via repl.prompt in ~/.kaappi/config. Press Ctrl+C to cancel a multi-line entry.

The _ Variable

The special variable _ always holds the result of the last evaluation:

kaappi> (* 6 7)
42
kaappi> (+ _ 8)
50
kaappi> (string-append "answer: " (number->string _))
"answer: 50"

This is useful for exploratory programming — evaluate something, then use the result without re-typing or binding it.

Pretty Printing

Large results are formatted with indentation and line wrapping rather than printed on a single long line. The REPL detects the terminal width and formats output accordingly:

kaappi> '((name "Alice" age 30) (name "Bob" age 25) (name "Carol" age 28))
;=> ((name "Alice" age 30)
     (name "Bob" age 25)
     (name "Carol" age 28))

Multiple Values

When an expression returns multiple values at the top level, all values are displayed:

kaappi> (values 1 2 3)
1
2
3

REPL Commands

All commands start with a comma (,). They are not Scheme expressions.

Evaluation

,time <expr> — Measure execution time

kaappi> ,time (fib 30)
832040
; 0.173 seconds

,type <expr> — Show result type

kaappi> ,type (+ 1 2)
; integer
kaappi> ,type "hello"
; string
kaappi> ,type (list 1 2 3)
; pair
kaappi> ,type car
; procedure
kaappi> ,type #t
; boolean

,expand <expr> — Show macro expansion

Works on user-defined macros. Built-in forms like when are compiled directly rather than defined as macros, so ,expand (when ...) reports not a macro: when. Identifiers that a macro template introduces are shown with their hygiene-renaming prefix (__hyg_...):

kaappi> (define-syntax my-when
  ...     (syntax-rules ()
  ...       ((_ test body ...) (if test (begin body ...)))))
kaappi> ,expand (my-when #t (display "yes"))
(__hyg_1_if #t (begin (display "yes")))

,profile <expr> — Detailed profiling

Shows per-function timing, call counts, and memory allocations:

kaappi> ,profile (fib 25)
75025

Profile (2549242 instructions, 364177 calls):
  Self ms  Total ms    Calls  Alloc KB  Function
      27.3     591.5   242785        -    fib (<repl>:1)
       2.6       2.6   121392        -    + (built-in)
  ...

,dis <expr> — Disassemble a procedure

Shows the register-based bytecode for a procedure:

kaappi> ,dis factorial
; Function: factorial
; Source: <repl>:1
; Arity: 1, Locals: 7, Upvalues: 0
; Constants: <=, 1, *, factorial, -
;
  0000  move            r2, r0
  0005  load_const      r3, 1
  ...

This is a shortcut for (disassemble <expr>). See Debugging for details.

Inspection

,describe <symbol> — Show binding details

Shows the type, arity, and source location of a procedure:

kaappi> ,describe car
  car
    type: procedure
    arity: 1
kaappi> ,describe map
  map
    type: procedure
    arity: 2, locals: 9
kaappi> ,describe +
  +
    type: procedure
    arity: 0+

For user-defined procedures, it also shows the source file and line:

kaappi> (define (greet name) (string-append "Hello, " name))
kaappi> ,describe greet
  greet
    type: procedure
    arity: 1, locals: 4
    source: <repl>:1

,apropos <string> — Search bindings

Searches all global bindings for names containing the given substring:

kaappi> ,apropos vector
  vector-every
  vector-length
  make-vector
  vector-ref
  vector-fill!
  vector-skip
  vector-reverse!
  vector-fold-right
  read-bytevector!
  vector->string
  ...
; 65 matches

,env [prefix] — List bindings

Lists all global bindings, optionally filtered by prefix:

kaappi> ,env string-
  string->number
  string-copy
  string-concatenate
  string-suffix?
  string->list
  ...
; 55 bindings

Debugging

,break <name> — Set breakpoint

kaappi> ,break fib
Breakpoint set on fib

,condition <id> <expr> — Conditional breakpoint

Only break when the Scheme expression evaluates to a truthy value:

kaappi> ,condition 0 (> n 10)
Condition set

,breakpoints — List breakpoints

kaappi> ,breakpoints
  [0] fib if (> n 10)

,step <expr> — Single-step evaluation

kaappi> ,step (+ 1 2)

,delete all — Clear all breakpoints

kaappi> ,delete all
All breakpoints deleted

System

,gc — Show GC statistics

kaappi> ,gc
GC Statistics:
  Collections:       42
  Live objects:      1523 (peak: 3201)
  Heap size:         48736 bytes (peak: 102400)
  ...

,version — Show Kaappi version

kaappi> ,version
Kaappi Scheme v0.22.3

,load <file> — Load and run a Scheme file

kaappi> ,load helpers.scm

Equivalent to (load "helpers.scm"). Definitions in the file become available in the current REPL session.

,import <lib> — Import a library

kaappi> ,import (srfi 1)
kaappi> (iota 5)
(0 1 2 3 4)

Import one or more libraries interactively, just like (import ...) at the top of a program. Supports all import modifiers (only, except, rename, prefix):

kaappi> ,import (only (srfi 1) iota fold)

,help — Show all commands

kaappi> ,help
Commands:
  ,help             Show this message
  ,quit             Exit the REPL

 -- Evaluation:
  ,time <expr>      Measure execution time
  ,type <expr>      Show result type
  ,expand <expr>    Show macro expansion
  ,profile <expr>   Profile timing, calls, and allocations
  ,dis <expr>       Disassemble a procedure

 -- Inspection:
  ,describe <sym>   Show procedure arity and type
  ,apropos <str>    Search bindings by substring
  ,env [prefix]     List bindings (optionally filtered by prefix)

 -- Debugging:
  ,break <name>     Set breakpoint on function
  ,condition <id> <expr>  Set conditional breakpoint
  ,breakpoints      List active breakpoints
  ,delete all       Clear all breakpoints
  ,step <expr>      Evaluate with single-stepping

 -- System:
  ,gc               Show GC statistics
  ,version          Show Kaappi version
  ,load <file>      Load and run a Scheme file
  ,import <lib>     Import a library (e.g. ,import (srfi 1))

The variable _ holds the last result.

Exiting

kaappi> ,quit

You can also type (exit) or press Ctrl+D on an empty line.


Next: CLI Reference