Introduction to Scheme
Introduction to Scheme
MemCP embeds a small Scheme dialect used by the SQL parsers, query planner, modules, and application endpoints. Start the interactive console with ./memcp lib/main.scm; background services use --no-repl.
Scheme represents calls and code with the same list syntax. That makes the dialect well suited to MemCP's query compiler: the SQL planner constructs Scheme programs as data, optimizes them, and evaluates or compiles them.
The console prints each expression result, which makes the evaluation model easy to explore:
> 12 = 12 > (+ 1 2 3) = 6 > (+ 2 (* 2 4)) = 10 > (concat "Hello " "World") = "Hello World"
Startup also loads the configured data directory and Scheme modules before opening the SQL/HTTP listeners. The exact banner and number of startup tests change between releases, so scripts should not parse that text.
Values and calls
<syntaxhighlight lang="scheme"> (+ 1 2) (concat "hello " "world") (map '(1 2 3) (lambda (x) (* x x))) </syntaxhighlight>
Numbers, booleans, strings, symbols, lists, functions, sessions, and storage objects are ordinary values. A list in expression position is a call: its first item is the procedure and the rest are arguments. Whitespace separates forms; parentheses define nesting.
| Form | Meaning |
|---|---|
42, 3.5, true, "text" |
Literal values |
(+ 1 2) |
Call + with two arguments
|
'name |
The symbol name, not the value bound to it
|
'(1 2 3) |
Construct a list value instead of calling 1
|
'("name" "Ada" "active" true) |
Flat key/value list used as an associative object |
Quoting and generated code
Use quoting to build code or data: '(+ 4 5) constructs delayed code, while (eval '(+ 4 5)) evaluates it. Values that should be computed now can be embedded into a quoted outer form; procedure symbols whose execution is delayed remain quoted. This distinction matters throughout the query planner.
<syntaxhighlight lang="scheme"> (set delayed '(+ 4 5)) (eval delayed) /* 9 */ (map '(1 2 3) (lambda (x) (* x x))) </syntaxhighlight>
Do not add or remove parentheses by visual guesswork in large generated expressions. Repository Scheme files are formatted and checked with python3 tools/lint_scm.py.
Functions and scope
Lambdas have exactly a parameter list and one body. Use begin when that body needs several forms:
<syntaxhighlight lang="scheme"> (define greet (lambda (name) (begin (print "greeting " name) (concat "Hello, " name))))
(greet "Ada") </syntaxhighlight>
Functions are closures and may be passed to map, reducers, scanners, parsers, and handlers. define and set create a binding in the current scope in this dialect; set is not an imperative mutation of an outer lexical variable.
Pattern matching and modules
match is the usual way to express alternatives and destructure lists, strings, or regular-expression results. Modules are loaded with import; application entrypoints typically import the required library files and then install handlers or start a server.
<syntaxhighlight lang="scheme"> (match value '(x y) (+ x y) (regex "^/users/([0-9]+)$" path id) id false) </syntaxhighlight>
See Parsers, Lists and Objects, and the matching examples in the repository for the exact pattern forms.
State and concurrency
The dialect is functional by default. set defines a binding in the current scope; it does not imperatively mutate an outer binding. Use (newsession) when code intentionally needs a thread-safe mutable key/value context shared across parallel work.
<syntaxhighlight lang="scheme"> (set request_state (newsession)) (request_state "user_id" 42) (request_state "user_id") /* 42 */ </syntaxhighlight>
Independent functional work may run in parallel. Supported hot procedures can be compiled by the native x86-64 JIT; unsupported shapes remain interpreted without changing language semantics. See Full SCM API documentation, Parallel Computing, and In-Database WebApps and REST Services.
Where to continue
- Full SCM API documentation lists generated chapters and signatures.
- Lists and Objects explains lists, associative objects, mapping, and reduction.
- IO covers files, HTTP request/response objects, and servers.
- Storage documents the low-level table and scan interface; application code normally starts with SQL.
- JIT Compilation and Parallel Computing explain runtime optimization boundaries.