Getting Started with Synoema
From installation to your first project in 5 minutes
1. Installation
Pre-built binary (recommended)
Download from GitHub Releases for macOS, Linux, or Windows:
./synoema install # copies to ~/.synoema/bin, adds to PATH
From source (requires Rust)
git clone https://github.com/Delimitter/synoema
cd synoema
cargo install --path lang/crates/synoema-repl
MCP server only (no Rust needed)
npx synoema-mcp
Verify installation
synoema eval "6 * 7"
# 42
2. Your First Program
Create a project
synoema init myapp
cd myapp
This creates:
myapp/
src/
main.sno # entry point
synoema.toml # project config
Edit src/main.sno
-- My first Synoema program
greet name = "Hello, ${name}!"
main = print (greet "World")
Run it
synoema run src/main.sno
# Hello, World!
3. Core Concepts
Functions are equations
No def, no return. Just name args = body. The last expression is the result:
double x = x * 2
add x y = x + y
greet name = "Hello, ${name}!"
Pattern matching with multiple equations
Define the same function multiple times with different patterns. First match wins:
fac 0 = 1
fac n = n * fac (n - 1)
describe 0 = "zero"
describe 1 = "one"
describe _ = "many"
Lists use spaces, not commas
nums = [1 2 3 4 5] -- NOT [1, 2, 3]
empty = []
range = [1..10] -- [1 2 3 ... 10]
combined = [1 2] ++ [3 4] -- [1 2 3 4]
Ternary instead of if/else
abs x = ? x < 0 -> -x : x
classify n =
? n > 0 -> "positive"
: ? n < 0 -> "negative"
: "zero"
Pipes for data flow
result = [1..20]
|> filter even
|> map (\x -> x * x)
|> sum
-- 1140
4. Running Programs
Interpreter (full features)
synoema run program.sno
Supports all features: file I/O, TCP networking, HTTP, channels, subprocess execution.
JIT compiler (fast execution)
synoema jit program.sno
Cranelift JIT compilation — ~3x faster than interpreter, ~3x faster than Python. Does not support I/O or concurrency.
Evaluate expressions
synoema eval "map (\x -> x * x) [1 2 3 4 5]"
# [1 4 9 16 25]
synoema eval "foldl (\a b -> a + b) 0 [1..100]"
# 5050
Watch mode
synoema watch run program.sno
Automatically re-runs on file changes. Great for iterative development.
Build to bytecode
synoema build program.sno # outputs program.sno.bc
synoema run program.sno.bc # run from bytecode
5. Working with Data
Records (like structs/objects)
-- Create
user = {name = "Alice", age = 30}
-- Access fields
user.name -- "Alice"
-- Update (spread syntax)
older = {...user, age = user.age + 1}
-- Pattern match
greet {name, age} = "${name} is ${show age}"
Algebraic data types (like enums)
-- Define
Shape = Circle Float | Rect Float Float | Point
-- Construct
s = Circle 5.0
-- Pattern match
area (Circle r) = 3.14159 * r * r
area (Rect w h) = w * h
area Point = 0.0
Error handling with Result
-- Functions that can fail return Result
safe_div x 0 = Err "division by zero"
safe_div x y = Ok (x / y)
-- Chain with and_then
compute x =
a <- safe_div x 2
b <- safe_div a 3
Ok (a + b)
-- Extract value
main =
result = safe_div 10 3
print (unwrap_or 0 result) -- 3
6. Input / Output
Console
main =
print "What is your name?"
name <- readline
print "Hello, ${name}!"
File I/O
-- Read entire file
content = file_read "data.txt"
-- Line by line
main =
fd = fd_open "data.txt"
line1 = fd_readline fd
line2 = fd_readline fd
fd_close fd
print "${line1}, ${line2}"
-- Write
main =
fd = fd_open_write "output.txt"
fd_write fd "Hello, file!"
fd_close fd
HTTP requests
main =
result = http_get "http://httpbin.org/get"
? result
-> Ok body -> print body
-> Err msg -> print "Error: ${msg}"
Run external commands
main =
fd = fd_popen "ls -la"
line = fd_readline fd
print line
fd_close fd
TCP server
handle client =
req = fd_readline client
fd_write client "HTTP/1.0 200 OK\r\n\r\nHello!"
fd_close client
main =
listener = tcp_listen 8080
print "Listening on :8080"
loop l = handle (tcp_accept l) ; loop l
loop listener
7. Testing
Doctests (in doc comments)
--- Compute factorial.
--- example: fac 5 == 120
--- example: fac 0 == 1
fac 0 = 1
fac n = n * fac (n - 1)
Unit tests
test "base case" = fac 0 == 1
test "fac 5" = fac 5 == 120
test "fac 10" = fac 10 == 3628800
Property tests
test "reverse is involution" =
prop xs -> reverse (reverse xs) == xs
test "sort is sorted" =
prop xs -> is_sorted (sort xs)
Run tests
synoema test src/main.sno # single file
synoema test src/ # entire directory
8. Using with LLMs
MCP Server (Claude, Cursor, Zed)
-- Add to your MCP config:
{
"mcpServers": {
"synoema": {
"command": "npx",
"args": ["synoema-mcp"]
}
}
}
-- Available tools:
-- eval: evaluate Synoema expressions
-- typecheck: check types without running
-- run: execute a Synoema program
Constrained decoding (llama.cpp)
./main -m model.gguf \
--grammar-file synoema.gbnf \
-p "-- Quicksort in Synoema" \
-n 128
GBNF grammar guarantees 100% syntactically valid output. No post-processing needed.
Prompt template for code generation
System: You write Synoema code. Key rules:
- Functions: name args = body (no def/return)
- Lists: [1 2 3] (spaces, no commas)
- Ternary: ? cond -> then : else
- Pipes: x |> f |> g
- Lambda: \x -> expr
- Concat: ++ (strings/lists)
- Pattern match via multiple equations
User: Write a function that removes duplicates from a list
9. IDE Support
VS Code extension
cd vscode-extension && ./install.sh
Cmd+Shift+R— run current fileCmd+Shift+J— JIT compile- Syntax highlighting for
.snofiles
LSP server
Built-in Language Server Protocol support:
- Diagnostics — parse and type errors inline
- Go-to-definition — jump to function/type declarations
- Hover — see inferred types
- Completion — builtins, prelude, in-scope names
cargo install --path lang/crates/synoema-lsp
10. CLI Cheatsheet
| Command | What it does |
|---|---|
synoema run file.sno | Run with interpreter (full I/O) |
synoema jit file.sno | Run with JIT (~3x faster) |
synoema eval "expr" | Evaluate expression |
synoema build file.sno | Compile to bytecode |
synoema test dir/ | Run doctests + unit + property tests |
synoema doc file.sno | Generate documentation |
synoema doc --contracts file.sno | Contract summary table |
synoema watch run file.sno | Watch + re-run on change |
synoema init myapp | Scaffold new project |
synoema install | Install to ~/.synoema/bin |
synoema changelog old.sno new.sno | API diff (type + contract changes) |
synoema --errors json run file.sno | Machine-readable errors for LLMs |
11. Deployment & Daemon Mode
Synoema programs (including HTTP servers) run as regular processes. To run as a background daemon, use OS-level process management.
Quick: nohup (any Unix)
# Start in background, log to file
nohup synoema run server.sno > server.log 2>&1 &
echo $! > server.pid
# Stop
kill $(cat server.pid)
macOS: launchd (auto-restart, boot start)
Create ~/Library/LaunchAgents/com.synoema.website.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.synoema.website</string>
<key>ProgramArguments</key>
<array>
<string>/Users/YOU/.synoema/bin/synoema</string>
<string>run</string>
<string>/path/to/website.sno</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>SNO_PORT</key>
<string>3000</string>
<key>SNO_STATIC_DIR</key>
<string>/path/to/static</string>
<key>SNO_BASE_DIR</key>
<string>/path/to/pages</string>
</dict>
<key>WorkingDirectory</key>
<string>/path/to/project</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/synoema-website.log</string>
<key>StandardErrorPath</key>
<string>/tmp/synoema-website.err</string>
</dict>
</plist>
# Load (starts immediately + on boot)
launchctl load ~/Library/LaunchAgents/com.synoema.website.plist
# Unload (stop)
launchctl unload ~/Library/LaunchAgents/com.synoema.website.plist
# Check status
launchctl list | grep synoema
Linux: systemd (auto-restart, boot start)
Create /etc/systemd/system/synoema-website.service:
[Unit]
Description=Synoema Website Server
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/synoema
Environment=SNO_PORT=3000
Environment=SNO_STATIC_DIR=/opt/synoema/static
Environment=SNO_BASE_DIR=/opt/synoema/pages
ExecStart=/usr/local/bin/synoema run /opt/synoema/website.sno
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
# Enable and start
sudo systemctl enable synoema-website
sudo systemctl start synoema-website
# Check status / logs
systemctl status synoema-website
journalctl -u synoema-website -f
Docker
FROM rust:1.75-slim AS build
WORKDIR /app
COPY . .
RUN cargo install --path lang/crates/synoema-repl
FROM debian:bookworm-slim
COPY --from=build /usr/local/cargo/bin/synoema /usr/local/bin/
COPY examples/website/ /app/website/
WORKDIR /app
ENV SNO_PORT=3000
ENV SNO_STATIC_DIR=/app/website/static
ENV SNO_BASE_DIR=/app/website
EXPOSE 3000
CMD ["synoema", "run", "/app/website/website.sno"]
docker build -t synoema-website .
docker run -d -p 3000:3000 --name sno-web synoema-website
Environment variables
| Variable | Default | Description |
|---|---|---|
SNO_PORT | 3000 | TCP port |
SNO_STATIC_DIR | examples/website/static | Static files directory |
SNO_BASE_DIR | examples/website | HTML pages directory |
SNO_CACHE_TTL | 3600 | Static asset cache max-age (seconds) |
SNO_VERSION | 0.1.0-alpha.3 | Version shown in headers/footer |
Next Steps
Read the Docs
Full language reference with types, operators, standard library, and I/O.
Study Examples
38 example programs covering algorithms, data structures, servers, and tools.
Try Online
Experiment in the playground — no installation needed.