# Jitzu — Full Documentation
> A typed shell and scripting language on .NET. Pipe OS command output into typed functions; call any NuGet package directly.
Status: alpha — small stdlib, not production-ready. Open source.
Source: https://jitzu.dev — all documentation pages concatenated in canonical order.
---
# Getting Started
---
## Overview
> What Jitzu is and why it exists
# What is Jitzu?
Jitzu is two things in one: an **interactive shell** you use as your terminal, and a **typed scripting language** you write real programs in. Both share the same runtime, the same type system, and the same package ecosystem.
## The Shell
Jitzu ships with an interactive shell (just run `jz` with no arguments) that replaces bash, zsh, or PowerShell for daily use. It has the commands you expect — `ls`, `cd`, `cat`, `grep` — plus features built for modern workflows:
- **Tab completion** for files, commands, variables, and types
- **Typed pipes** that flow OS command output into Jitzu functions
- **Ctrl+R reverse search**, arrow-key history predictions, and a git-aware prompt
- **Directory labels** — name a directory once, use it as a path prefix everywhere
```shell
simon ~/projects/api (main) *
> find src -ext cs
src/Parser.cs
src/Lexer.cs
src/Interpreter.cs
> git log --oneline | first
a1b2c3d Add pattern matching support
> label git ~/git/
> cd git:jitzu/site
```
## The Language
At the prompt or in `.jz` files, you write in a language that borrows from Rust, C#, F#, and TypeScript. It's expression-based, statically typed with inference, and has pattern matching, union types, and string interpolation built in.
```jitzu
// Variables — immutable by default
let name = "Jitzu"
let mut counter = 0
// Functions return their last expression
fun greet(who: String): String {
\`Hello, {who}!\`
}
// Union types and pattern matching
union Shape {
Circle(Double),
Square(Double),
}
let area = match shape {
Shape.Circle(r) => 3.14159 * r ** 2,
Shape.Square(s) => s ** 2,
}
```
## NuGet Packages
Any .NET NuGet package works out of the box. Add a directive, import what you need, and use it — no project files, no restore step.
```jitzu
#:package Newtonsoft.Json@13.0.4
open "Newtonsoft.Json" as { JsonConvert }
let json = JsonConvert.SerializeObject(user)
print(json)
```
## Runtime
Jitzu compiles your code to bytecode and runs it on a stack-based VM built on .NET 10. It's fast enough for scripting and interactive use, and gives you access to the entire .NET ecosystem.
## Next Steps
- [Installation](/docs/getting-started/installation) — download and set up Jitzu
- [Shell Overview](/docs/shell/overview) — learn the shell commands and features
- [Language Basics](/docs/language/basic-syntax) — start writing Jitzu code
---
## Installation
> How to install Jitzu on your system
# Installation
Jitzu is distributed as a single standalone binary — `jz` — that serves as both the script interpreter and the interactive shell. Download the self-contained build for your platform — it bundles the .NET runtime, so it works on any machine with no prerequisites.
_See [Installation](/docs/getting-started/installation) for platform downloads._
## Package Managers
### Windows (Scoop)
```bash
scoop bucket add jitzu https://github.com/jitzulang/jitzu
scoop install jz
```
## Self-Contained Binary
The self-contained binary bundles the .NET runtime, so it works on any machine with no
prerequisites. This is the easiest way to get started without a package manager.
### Windows
Download `jitzu-win-x64.zip` from the [latest GitHub release](https://github.com/jitzulang/jitzu/releases/latest) and extract it. Add the extracted directory to your PATH, or move the binary to a directory already on your PATH.
```bash
# PowerShell
Expand-Archive jitzu-win-x64.zip -DestinationPath C:\\tools\\jitzu
$env:PATH += ";C:\\tools\\jitzu"
# Or move to a directory already on PATH
Move-Item jz.exe C:\\Windows\\
```
### macOS
Download `jitzu-osx-arm64.zip` (Apple Silicon) or `jitzu-osx-x64.zip` (Intel) from the [latest release](https://github.com/jitzulang/jitzu/releases/latest).
```bash
unzip jitzu-osx-arm64.zip
sudo mv jz /usr/local/bin/
chmod +x /usr/local/bin/jz
```
### Linux
Download `jitzu-linux-x64.zip` from the [latest release](https://github.com/jitzulang/jitzu/releases/latest).
```bash
unzip jitzu-linux-x64.zip
sudo mv jz /usr/local/bin/
chmod +x /usr/local/bin/jz
```
## Self-Update
Jitzu can update itself:
```bash
jz upgrade
```
## Build from Source
Jitzu requires the [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) to build from source.
```bash
git clone https://github.com/jitzulang/jitzu.git
cd jitzu
dotnet build
dotnet run --project Jitzu.Shell -- --help
dotnet run --project Jitzu.Shell
```
## Verify Installation
Check the interpreter is on your PATH:
```bash
jz --version
# jz v0.2.0
```
Then launch the shell:
```shell
jz v0.2.0
• runtime : 10.0.0
• config : ~/.jitzu/config.jz
• platform : Unix
Type \`help\` to get started.
> 1 + 1
2
```
---
# Shell
---
## Jitzu Shell
> The Jitzu shell is a feature-rich interactive environment that blends a Unix-style command line with the full Jitzu language.
# Jitzu Shell
The Jitzu shell is a feature-rich interactive environment that blends a Unix-style command line
with the full Jitzu language. You can run shell commands, write Jitzu expressions, and pipe
between them — all in one place.
## Launching the Shell
Start the shell by running `jz` with no arguments:
```shell
jz v0.2.0
• runtime : 10.0.0
• config : ~/.jitzu/config.jz
• platform : Unix
Type \`help\` to get started.
simon@dev ~/projects/api (main) * 14:23
>
```
The prompt shows your username, hostname, current directory (relative to the git root if inside a repo),
git branch with status indicators (`*` dirty, `+` staged, `?` untracked), and the current time.
Use `--no-splash` to skip the welcome banner.
## Mixing Code and Commands
The shell automatically detects whether your input is Jitzu code or a shell command.
Jitzu code is tried first; if parsing fails, the input is executed as an OS command.
### Jitzu Expressions
```jitzu
> 1 + 1
2
> let greeting = "hello from the shell"
> greeting.ToUpper()
"HELLO FROM THE SHELL"
> fun factorial(n: Int): Int {
| if n <= 1 { 1 } else { n * factorial(n - 1) }
| }
> factorial(10)
3628800
```
### OS Commands
Commands that aren't valid Jitzu code fall through to the system shell.
Many common commands like `ls`, `grep`, and `find` are
implemented as builtins with colored output, but any program on your PATH works too:
```shell
> git log --oneline -3
a1b2c3d Add pattern matching support
b2c3d4e Fix lexer edge case
c3d4e5f Initial commit
> dotnet build
Build succeeded.
```
## Command Substitution
Use `$(command)` to capture the output of a command and insert it inline.
Nesting is supported.
```shell
> echo "I am in $(pwd)"
I am in /home/simon/projects/api
> echo "Branch: $(git branch --show-current)"
Branch: main
```
## Environment Variables
Shell-style variable expansion works with `$VAR` and `\${VAR}` syntax.
Use `export` to set and `unset` to remove environment variables.
```shell
> export EDITOR=nvim
> echo $EDITOR
nvim
> echo \${HOME}
/home/simon
```
Single-quoted strings suppress expansion: `echo '$HOME'` prints the literal text `$HOME`.
## Multi-line Input
When a line ends with an unclosed brace, the shell continues reading on the next line
with a `|` continuation prompt:
```jitzu
> let person = {
| name = "Alice",
| age = 30,
| address = {
| city = "New York",
| zip = "10001"
| }
| }
> person.address.city
"New York"
```
## Glob Expansion
Arguments containing `*` or `?` are
expanded to matching file paths. Recursive `**` patterns are also supported.
```shell
> ls *.cs
Program.cs Lexer.cs Parser.cs
> find src/**/*.cs
src/Core/Compiler.cs
src/Core/Interpreter.cs
src/Runtime/Stack.cs
```
## Sourcing Scripts
The `source` command (or its shorthand `.`) executes a `.jz` file
line-by-line in the current session, so any variables or functions it defines remain available:
```shell
> source ~/scripts/helpers.jz
> my_helper_function("test")
"processed: test"
```
## Introspection
The shell includes commands to inspect the current session state:
- `vars` — list all defined variables and their types
- `types` — show available types (built-in, user-defined, imported)
- `functions` — show defined functions
- `reset` — clear all session state and start fresh
## Error Handling
Errors are displayed gracefully without crashing the shell. The prompt arrow turns red after a failed command:
```jitzu
> 10 / 0
Error: Division by zero
> cd nonexistent
No such directory: nonexistent
Did you mean src/?
```
---
## File System
> Built-in file system commands in the Jitzu shell.
# File System
| Command |
Description |
ls [dir] | List files with colored output, attributes, and sizes |
cd [dir] | Change directory (cd - for previous, cd for home) |
pwd | Print working directory |
mkdir [-cd] dir | Create directory (-cd to enter it immediately) |
touch [-d/-t] file | Create file or update timestamp |
rm [-r] path | Remove file or directory |
mv src dst | Move or rename file/directory |
cp [-r] src dst | Copy file or directory |
ln [-s] target link | Create hard or symbolic link |
stat file | Display file metadata |
chmod +/-r file | Toggle file attributes (r/h/s) |
find path [opts] | Recursive file search |
du [-sh] [dir] | Disk usage of files/directories |
df | Show disk space of mounted drives |
mktemp [-d] | Create temporary file or directory |
basename path [suffix] | Strip directory and optional suffix |
dirname path | Strip last component from path |
## ls
On Windows, `ls` is a builtin that shows file attributes, sizes, timestamps, and color-coded names by file type. On other platforms it falls through to the system `ls`.
```shell
> ls
d----- - Jan 15 09:44 src/
d----- - Jan 10 11:20 tests/
-a-r-- 2.5K Jan 15 14:23 Program.cs
-a-r-- 1.8K Jan 12 10:05 README.md
```
## find
Recursive file search with filtering by name pattern, type, and extension:
```shell
> find src -ext cs
src/Parser.cs
src/Lexer.cs
src/Interpreter.cs
> find . -name "*.json" -type f
./config.json
./package.json
```
---
## Text Processing
> Built-in text processing commands in the Jitzu shell.
# Text Processing
| Command |
Description |
cat file | Display file with line numbers |
head [-n N] file | Show first N lines (default 10) |
tail [-n N] file | Show last N lines (default 10) |
grep [flags] pattern [files] | Search files for pattern |
sort [-r/-n/-u] file | Sort lines |
uniq [-c/-d] file | Remove consecutive duplicate lines |
wc [-l/-w/-c] file | Count lines, words, or characters |
diff file1 file2 | Compare two files |
tr [-d] s1 s2 file | Translate or delete characters |
cut -d/-f/-c file | Extract fields or characters |
rev file | Reverse characters in each line |
tac file | Print file with lines in reverse order |
paste [-d] file file | Merge lines from multiple files |
view file | View file in pager with markdown rendering |
more/less | Paginated output viewer |
## view
Open a file in the interactive pager. Markdown files (`.md`, `.markdown`) are rendered with ANSI formatting — headers, bold, italic, inline code, code blocks, tables, lists, blockquotes, links, and horizontal rules all render with colors and box-drawing characters.
Non-markdown files are displayed as plain text.
```shell
> view README.md
┌──────────┬────────┬───────┐
│ Name │ Type │ Size │
├──────────┼────────┼───────┤
│ Parser │ Core │ 2.4K │
│ Lexer │ Core │ 1.8K │
└──────────┴────────┴───────┘
```
Navigation is the same as `more`/`less` — arrow keys, `j`/`k`, Page Up/Down, `/` to search, `q` to quit. The pager uses the alternate screen buffer so your scrollback history is preserved.
### Supported Markdown
| Element | Syntax |
|---------|--------|
| Headers | `#`, `##`, `###` — bold with distinct colors |
| Bold | `**text**` |
| Italic | `*text*` |
| Inline code | `` `code` `` |
| Code blocks | Fenced with ` ``` ` |
| Tables | Pipe-delimited with box-drawing borders |
| Bullet lists | `- item` rendered with `•` |
| Numbered lists | `1. item` |
| Blockquotes | `> text` with `│` bar |
| Links | `[text](url)` — text underlined, URL dimmed |
| Horizontal rules | `---` rendered as `─` line |
## grep
Search for patterns in files with highlighted matches. Supports recursive search, case-insensitive matching, line numbers, and match counting.
```shell
> grep -rn "TODO" src/
src/Parser.cs:42: // TODO: Handle forward references
src/Interpreter.cs:156: // TODO: Optimize stack layout
> grep -ic "error" logs/
logs/app.log:15
logs/server.log:3
```
Flags: `-i` case insensitive, `-n` line numbers, `-r` recursive, `-c` count only.
## sort
```shell
> sort -r names.txt
Zara
Mike
Alice
```
---
## Pipes & Redirection
> The Jitzu shell supports Unix-style pipes and I/O redirection, plus a unique hybrid pipe system that lets you chain OS command output into Jitzu functions.
# Pipes & Redirection
The Jitzu shell supports Unix-style pipes and I/O redirection, plus a unique hybrid pipe
system that lets you chain OS command output into Jitzu functions.
## Unix Pipes
Use `|` to pass the output of one command as input to another.
When both sides are OS commands, the shell delegates to the system pipe:
```shell
> git log --oneline | head -5
a1b2c3d Add pattern matching
b2c3d4e Fix lexer edge case
c3d4e5f Refactor parser
d4e5f6a Add shell mode
e5f6a7b Initial commit
```
## Hybrid Pipes
You can pipe OS command output into Jitzu pipe functions. The shell captures
stdout from the left side and passes it as text to the Jitzu function on the right:
```shell
> git log --oneline | first
a1b2c3d Add pattern matching
> ls | grep("cs")
Parser.cs
Lexer.cs
Interpreter.cs
> git log --oneline | nth(2)
c3d4e5f Refactor parser
```
### Available Pipe Functions
| Function |
Description |
first | First line of output |
last | Last line of output |
nth(n) | Nth line (0-indexed) |
grep("pattern") | Filter lines containing pattern |
head -n N | First N lines (default 10) |
tail -n N | Last N lines (default 10) |
sort [-r] | Sort lines alphabetically |
uniq | Remove consecutive duplicate lines |
wc [-l/-w/-c] | Count lines/words/chars |
tee [-a] file | Write to file and pass through |
more / less | View output in pager |
print | Print and pass through |
Pipe functions accept both Jitzu-style and shell-style argument syntax:
```shell
> ls | grep("test") // Jitzu-style parentheses
> ls | grep "test" // shell-style spaces
```
### Chaining Pipe Functions
Pipe functions can be chained together:
```shell
> git log --oneline | grep("fix") | sort
a1b2c3d Fix login timeout
c3d4e5f Fix parser edge case
> ls *.cs | sort | tee filelist.txt
```
## Builtin Pipes
Built-in commands can also be piped. Their output is captured and fed into the right side:
```shell
> diff file1.txt file2.txt | more
> cat server.log | grep("ERROR")
> find src -ext cs | sort
```
## Output Redirection
Redirect command output to a file with `>` (overwrite) or `>>` (append).
ANSI color codes are automatically stripped from redirected output.
```shell
> echo "hello world" > greeting.txt
> echo "another line" >> greeting.txt
> ls *.cs > filelist.txt
> grep -rn "TODO" src/ > todos.txt
```
## Input Redirection
Use `<` to feed a file's contents as stdin to a command:
```shell
> sort < names.txt
Alice
Bob
Charlie
```
## Tee
The `tee` command writes its input to a file and also passes it through
to stdout, so you can save intermediate results in a pipeline:
```shell
> ls | tee filelist.txt
src/
tests/
Program.cs
> git log --oneline | tee -a log.txt | first
a1b2c3d Add pattern matching
```
Use `-a` to append instead of overwriting.
## Command Chaining
Chain multiple commands together with logical operators:
| Operator |
Behavior |
&& | Run next command only if the previous succeeded |
|| | Run next command only if the previous failed |
; | Run next command unconditionally |
```shell
> mkdir build && cd build
> echo hello > file.txt && cat file.txt
hello
> cd nonexistent || echo "directory not found"
directory not found
> echo step1 ; echo step2 ; echo step3
step1
step2
step3
```
## Background Execution
Append `&` to run a command in the background. See the [Activity Monitor](/docs/shell/activity-monitor) page for more on background job management.
```shell
> dotnet build &
[1] 12345
> jobs
[1] Running dotnet build
```
## Call Operator
The `&` prefix (PowerShell-style call operator) forces a line to
be treated as an OS command instead of Jitzu code:
```shell
> & dotnet build
```
---
## System Information
> Built-in system information commands in the Jitzu shell.
# System Information
| Command |
Description |
whoami | Print current user name |
hostname | Print machine name |
uptime | Show system uptime |
env | List all environment variables |
export VAR=value | Set an environment variable |
unset VAR | Remove an environment variable |
where command | Locate all sources (alias, label, builtin, PATH) |
date [+format] | Print current date/time (-u UTC, -I ISO) |
---
## Completion & Editing
> The Jitzu shell includes a custom readline implementation with tab completion, history predictions, reverse search, text selection, and full line-editing support.
# Completion & Editing
The Jitzu shell includes a custom readline implementation with tab completion, history
predictions, reverse search, text selection, and full line-editing support.
## Tab Completion
Press **Tab** to trigger context-aware completions. The shell completes:
- **File paths** — files and directories in the current directory, with tilde (`~`) and label expansion
- **Built-in commands** — all 60+ shell builtins
- **Executables on PATH** — programs available in your system PATH
- **Jitzu identifiers** — variables, functions, and types from the current session
- **Label paths** — type a label prefix (e.g. `git:`) and Tab completes paths within the labeled directory
### Completion Workflow
If there's a single match, it's applied immediately. If there are multiple matches,
a dropdown appears:
- **Up/Down** — navigate the dropdown
- **Tab** — accept the highlighted completion
- **Escape** — dismiss
```shell
> gre⇥ → grep
> src/Pa⇥ → src/Parser.cs
> git:proj⇥ → git:projects/
```
## History Predictions
As you type, the shell shows matching entries from your command history in a dropdown.
Ghost text does not appear until you select an entry.
- **Down Arrow** — enter the history dropdown (ghost text appears for the selected entry)
- **Tab** — accept the selected prediction (or open completions if no entry is selected)
- **Right Arrow** — accept the ghost text
- **Delete** — remove the selected entry from history
- **Escape** — dismiss predictions
## Reverse History Search
Press **Ctrl+R** to enter reverse search mode. Type a substring to search
backward through history. Press **Ctrl+R** again to cycle to the next match.
```shell
(reverse-search): build
→ dotnet build --configuration Release
```
Press **Enter** to execute the match, **Escape** to cancel, or any
other key to exit search mode and edit the matched line.
## History Navigation
When no dropdown is visible, the Up and Down arrow keys navigate through your full command history.
History is persisted to disk across sessions.
- **Up Arrow** — previous command in history
- **Down Arrow** — next command in history
- `history` — display full command history with line numbers
Duplicate commands are deduplicated — only the most recent occurrence is kept.
## Line Editing
### Cursor Movement
| Shortcut |
Action |
Left / Right | Move cursor one character |
Ctrl+Left / Ctrl+Right | Jump by word |
Home / Ctrl+A | Move to beginning of line |
End | Move to end of line |
### Editing
| Shortcut |
Action |
Backspace | Delete character before cursor |
Ctrl+Backspace | Delete word before cursor |
Delete | Delete character after cursor |
### Text Selection
| Shortcut |
Action |
Shift+Left / Shift+Right | Extend selection by character |
Shift+Home / Shift+End | Select to beginning/end of line |
Ctrl+C (with selection) | Copy selection to clipboard |
Typing or pasting while text is selected replaces the selected region.
## Other Shortcuts
| Shortcut |
Action |
Ctrl+C (no selection) | Cancel current line |
Ctrl+R | Reverse history search |
Escape | Dismiss predictions/completions |
## Syntax Highlighting
The shell prompt applies live syntax coloring as you type, highlighting commands, keywords,
strings, flags, pipe operators, and boolean values. Colors are configurable via the [theme system](/docs/shell/customization).
---
## Utilities
> Built-in utility commands in the Jitzu shell.
# Utilities
| Command |
Description |
echo [text] | Print text |
sleep seconds | Pause for N seconds |
yes [text] | Repeat text (default: y) |
seq [first [inc]] last | Print a sequence of numbers |
true | Return success (exit code 0) |
false | Return failure (exit code 1) |
time command | Measure command execution time |
watch [-n s] command | Repeat command every N seconds |
wget url | Download a file from a URL |
history | Show command history |
clear | Clear the screen |
help | Show help with all commands |
reset | Reset the session state |
exit / quit | Exit the shell |
---
## Customization
> The Jitzu shell supports theme customization, startup configuration, aliases, and path labels to personalize your workflow.
# Customization
The Jitzu shell supports theme customization, startup configuration, aliases, and path labels
to personalize your workflow.
## Theme Configuration
Colors are controlled by `~/.jitzu/colours.json`.
A default configuration is written automatically on first launch. All values are hex color strings (e.g. `#87af87`).
```json
{
"syntax": {
"command": "#87af87",
"keyword": "#87afd7",
"string": "#afaf87",
"flag": "#87afaf",
"pipe": "#af87af",
"boolean": "#d7af87"
},
"git": {
"branch": "#808080",
"dirty": "#d7af87",
"staged": "#87af87",
"untracked": "#808080",
"remote": "#87afaf"
},
"prompt": {
"directory": "#87d7ff",
"arrow": "#5faf5f",
"error": "#d75f5f",
"user": "#5f8787",
"duration": "#d7af87",
"time": "#808080",
"jobs": "#87afaf"
},
"ls": {
"directory": "#87afd7",
"executable": "#87af87",
"archive": "#d75f5f",
"media": "#af87af",
"code": "#87afaf",
"config": "#d7af87",
"project": "#d7af87",
"size": "#87af87",
"dim": "#808080"
},
"error": "#d75f5f",
"prediction": {
"text": "#808080",
"selected": {
"bg": "#303050",
"fg": "#ffffff"
}
},
"selection": {
"bg": "#264f78",
"fg": "#ffffff"
},
"dropdown": {
"gutter": "#404040",
"status": "#5f87af"
}
}
```
### Color Categories
- **syntax** — live input highlighting (commands, keywords, strings, flags, pipes, booleans)
- **git** — prompt git status indicators (branch, dirty, staged, untracked, remote ahead/behind)
- **prompt** — prompt elements (directory, arrow, error state, user, duration, clock, job count)
- **ls** — file listing colors by type (directories, executables, archives, media, code, config, project files)
- **prediction** — history prediction ghost text and dropdown selection
- **selection** — text selection highlight
- **dropdown** — completion dropdown gutter and status bar
Edit any value and restart the shell to apply changes. Malformed entries are silently
ignored and fall back to defaults.
## Startup Configuration
The file `~/.jitzu/config.jz` is executed automatically when the shell starts,
similar to `.bashrc` or `.zshrc`.
Each line is run as a shell command, so you can set aliases, labels, environment variables,
and define Jitzu functions that will be available in every session.
```jitzu
// ~/.jitzu/config.jz
// Set up aliases
alias ll="ls -la"
alias gs="git status"
alias gp="git push"
// Set up path labels
label git ~/git
label docs ~/Documents
// Set environment variables
// Define helper functions
fun greet(): String {
\`Good morning, {whoami}!\`
}
```
Lines starting with `//` are treated as comments and skipped.
## Aliases
Aliases map short names to longer commands. They persist to disk across sessions
and are automatically expanded when the alias name appears as the first word of a command.
```shell
> alias ll="ls -la"
Alias set: ll → ls -la
> ll
d----- - Jan 15 09:44 src/
-a-r-- 2.5K Jan 15 14:23 Program.cs
> aliases
ll → ls -la
gs → git status
> unalias ll
Alias removed: ll
```
Aliases are stored in the application data directory
(e.g. `~/.local/share/Jitzu/aliases.txt` on Linux
or `%APPDATA%/Jitzu/aliases.txt` on Windows).
## Path Labels
Labels map short names to directory paths. Use a label by appending a colon, e.g. `git:`.
Labels work in `cd`, file arguments, and tab completion.
```shell
> label api ~/projects/api
Label set: api → /home/simon/projects/api
> cd api:
> pwd
/home/simon/projects/api
> cd api:src/controllers
> cat api:README.md
> labels
api → /home/simon/projects/api
docs → /home/simon/Documents
> unlabel api
Label removed: api
```
Labels expand transparently in file arguments, so commands
like `cat api:src/Program.cs` and `ls api:` work
as expected. Tab completion also understands label prefixes.
---
## Session Inspection
> Commands for inspecting the current Jitzu shell session state.
# Session Inspection
| Command |
Description |
vars | Show all defined variables and their types |
types | Show available types (built-in, user-defined, imported) |
functions | Show defined functions |
source file | Execute a .jz file in the current session |
---
## Activity Monitor
> The Jitzu shell includes a built-in full-screen activity monitor TUI, background job management, command timing, and process control commands.
# Activity Monitor
The Jitzu shell includes a built-in full-screen activity monitor TUI, background job management,
command timing, and process control commands.
## The Monitor Command
Run `monitor` to open a live-updating full-screen dashboard showing:
- **CPU usage** — overall percentage with per-core sparkline bars and gradient coloring (green through red)
- **Memory usage** — used/total with sparkline graph
- **Network** — send/receive rates with sparkline history
- **Disk usage** — per-drive gauge bars
- **Process list** — navigable tree view with PID, CPU%, memory, and command name
### Monitor Controls
| Key |
Action |
q / Escape | Quit the monitor |
Up / Down | Navigate process list |
k | Send SIGTERM to selected process |
kk (double tap) | Send SIGKILL to selected process |
/ | Filter processes by name |
f | Toggle: show only shell child processes |
The monitor renders with bordered panels, gradient sparklines, and color-coded metrics.
It refreshes automatically and adapts to terminal size changes.
## Background Jobs
Append `&` to any command to run it in the background.
The shell returns a job ID and process ID immediately, and the prompt stays responsive.
```shell
> dotnet build &
[1] 12345
> sleep 10 &
[2] 12346
```
### Managing Jobs
| Command |
Description |
jobs | List all background jobs with status (Running/Done) |
fg [%id] | Bring a job to the foreground (waits for completion, shows output) |
bg | List background jobs (alias for jobs) |
```shell
> jobs
[1] Running dotnet build
[2] Done sleep 10
> fg %1
[1] dotnet build
Build succeeded.
0 Warning(s)
0 Error(s)
```
Completed jobs are reported automatically at the next prompt. The prompt also shows the count of
active background jobs (e.g. `[2]`).
## Command Timing
Use `time` to measure how long a command takes to execute:
```shell
> time dotnet build
Build succeeded.
real 0m2.345s
```
Commands that take longer than 2 seconds also show their duration in the prompt
line automatically (e.g. `took 5s`).
## Watch
The `watch` command repeats a command at regular intervals.
Press `Ctrl+C` to stop.
```shell
> watch -n 5 date
Every 5.0s: date
Sat Feb 14 14:23:00 2026
```
Default interval is 2 seconds. Use `-n` to specify a different interval.
## Process Management
| Command |
Description |
kill [-9] pid | Kill a process by PID or %jobid |
killall [-9] name | Kill all processes matching a name |
```shell
> kill %1
[1] Terminated dotnet build
> kill 12345
Process 12345 terminated.
> kill -9 12345
Process 12345 killed.
> killall node
Killed 3 process(es) named 'node'.
```
The `-9` flag sends SIGKILL (force kill) instead of SIGTERM (graceful termination).
Use `%id` to reference background jobs by their job ID.
---
## Privilege Escalation
> Running commands with elevated privileges in the Jitzu shell.
# Privilege Escalation
| Command |
Description |
sudo command | Run a command with elevated privileges |
sudo -s | Open an elevated shell (replaces current session) |
sudo -i | Open an elevated login shell (resets to home directory) |
On Windows, `sudo` launches an elevated Jitzu shell process and attaches
it to the current console. The prompt shows `[sudo]` and uses `#` instead of `>` when elevated.
---
# Language
---
## Getting Started with Jitzu
> Welcome to Jitzu, a modern scripting language designed to be "Fast Enough™, Overengineered, and Unoriginal" - packed with syntax sugar to make scripting fun and expressive.
# Getting Started with Jitzu
Welcome to Jitzu, a modern scripting language designed to be "Fast Enough™, Overengineered, and Unoriginal" - packed with syntax sugar to make scripting fun and expressive.
## What is Jitzu?
Jitzu is a modern scripting language that combines features from Rust, C#, F#, Go, TypeScript, Scala, and Zig.
It's designed for both script execution and interactive shell usage, prioritizing developer productivity and expressiveness.
## Design Philosophy
Jitzu is designed to be:
- **Fast Enough™** - Optimized for developer productivity over raw performance
- **Overengineered** - Includes many language features for expressiveness
- **Unoriginal** - Borrows the best ideas from other languages
- **Fun to use** - Syntax sugar makes common tasks enjoyable
## Your First Jitzu Program
Let's start with the classic "Hello, World!" program:
```jitzu
// Simple Hello World
print("Hello, World!")
```
Save this as `hello.jz` and run it with the Jitzu interpreter.
## String Interpolation
One of Jitzu's most convenient features is string interpolation using template literals:
```jitzu
// With string interpolation
let name = "Jitzu"
print(\`Hello from {name}!\`)
// You can use expressions inside interpolation
let version = 1.0
print(\`Welcome to {name} version {version}!\`)
```
## Basic Program Structure
Jitzu programs are collections of expressions and statements:
```jitzu
// Variables
let greeting = "Hello"
let language = "Jitzu"
// Function definition
fun welcome(name: String): String {
\`{greeting} from {language}, {name}!\`
}
// Using the function
let message = welcome("Developer")
print(message)
```
## Key Language Features at a Glance
### Mutable and Immutable Variables
Use `mut` for mutable data:
```jitzu
let x = 42 // Immutable
let mut counter = 0 // Mutable
counter += 1
```
### Everything is an Expression
Functions automatically return the last expression:
```jitzu
fun add(a: Int, b: Int): Int {
a + b // No 'return' needed
}
```
### Strong Type System with Inference
Types are inferred when possible, but you can be explicit:
```jitzu
let age = 25 // Inferred as Int
let name: String = "Alice" // Explicit type
```
### Pattern Matching
Match expressions for control flow:
```jitzu
union Shape {
Circle(Double),
Square(Double),
}
let description = match shape {
Shape.Circle(r) => \`Circle with radius {r}\`,
Shape.Square(s) => \`Square with side {s}\`,
}
```
## Quick Reference
### Common Operations
```jitzu
// Variables
let x = 42
let mut y = 10
// String interpolation
print(\`x = {x}, y = {y}\`)
// Basic arithmetic
let sum = x + y
let difference = x - y
// Conditionals
if x > y {
print("x is greater")
}
// Loops
for i in 1..=5 {
print(\`Count: {i}\`)
}
```
### File Structure
- Source files use `.jz` extension
- Use `open` statements for imports
- Programs start executing from top-level expressions
## Next Steps
Now that you've seen the basics, explore these areas to learn more:
- [Basic Syntax](/docs/language/basic-syntax) - Comments, variables, and imports
- [Data Types](/docs/language/data-types) - Numbers, strings, vectors, and more
- [Functions](/docs/language/functions) - Function definition and error handling
- [Control Flow](/docs/language/control-flow) - Conditionals and loops
- [Types](/docs/language/object-oriented) - Custom types and composition
---
## Basic Syntax
> This page covers the fundamental syntax elements of Jitzu, including comments, variables, and the import system.
# Basic Syntax
This page covers the fundamental syntax elements of Jitzu, including comments, variables, and the import system.
## Comments
Jitzu supports both single-line and multi-line comments:
```jitzu
// Single-line comment
print("Hello") // End-of-line comment
/*
* Multi-line comment
* Can span multiple lines
*/
```
## Variables
### Immutable Variables (Default)
By default, variables in Jitzu are declared with `let`:
```jitzu
let x = 42
let name = "Alice"
let is_valid = true
```
### Mutable Variables
Use the `mut` keyword to create mutable variables:
```jitzu
let mut counter = 0
counter += 1
counter = counter * 2
let mut message = "Hello"
message = message + " World"
print(message) // "Hello World"
```
### Type Annotations
While Jitzu has type inference, you can explicitly annotate types:
```jitzu
// Type inferred
let age = 25 // Int
let height = 5.9 // Double
let name = "Bob" // String
// Explicit types
let age: Int = 25
let height: Double = 5.9
let name: String = "Bob"
let numbers: Int[] = [1, 2, 3]
```
## Variable Naming
Jitzu follows these naming conventions:
```jitzu
// Variables and functions: snake_case
let user_name = "alice"
let max_retry_count = 3
// Types: PascalCase
type UserProfile { ... }
```
## Scope and Shadowing
### Block Scope
Variables are scoped to their containing block:
```jitzu
let x = 1
if true {
let y = 2
print(x) // 1 - can access outer scope
print(y) // 2
}
// print(y) // Error: y is not in scope
```
### Variable Shadowing
You can shadow variables by declaring new ones with the same name:
```jitzu
let x = 5
print(x) // 5
let x = "hello" // Shadows the previous x
print(x) // "hello"
{
let x = true // Shadows again within this block
print(x) // true
}
print(x) // "hello" - back to the string version
```
## Import System
Jitzu uses `open` statements for imports.
### Basic Imports
Import from relative paths:
```jitzu
// Import entire module
open "./utils.jz"
// Import from parent directory
open "../shared_code/helpers.jz"
// Import from subdirectory
open "./math/calculations.jz"
```
### Selective Imports
Import specific functions or types:
```jitzu
// Import specific items
open "../shared_code/greet.jz" as { Greet }
// Import multiple items
open "./math.jz" as { add, subtract, multiply }
// Mix of functions and types
open "./models.jz" as { User, create_user, validate_user }
```
### Aliased Imports
Import with custom names to avoid conflicts:
```jitzu
// Import entire module with alias
open "./math.jz" as Math
// Use aliased import
let result = Math.add(5, 3)
```
### Import Example
Here's how you might structure imports in a Jitzu file:
```jitzu
// Local utilities
open "./utils/string_helpers.jz" as { capitalize }
open "./config.jz" as Config
// Models and types
open "./models/user.jz" as { User, UserRole }
// Business logic
open "./services/auth.jz" as Auth
// Now use the imported functionality
let user = User {
name = "Alice",
role = UserRole.Admin
}
if Auth.IsAuthorized(user) {
print("Access granted")
}
```
## String Literals
Jitzu supports multiple string literal formats:
```jitzu
// Regular strings
let simple = "Hello World"
let with_escape = "Hello\\nWorld\\tTab"
// Template literals (string interpolation)
let name = "Alice"
let age = 30
let message = \`Hello {name}, you are {age} years old\`
// You can use expressions in interpolation
let calculation = \`2 + 2 = {2 + 2}\`
```
## Semicolons
Semicolons are optional in Jitzu:
```jitzu
// These are equivalent
let x = 42;
let x = 42
// Useful for multiple statements on one line
let a = 1; let b = 2; let c = a + b
```
## Expression vs Statement
In Jitzu, almost everything is an expression that returns a value:
```jitzu
// if is an expression
let message = if age >= 18 { "adult" } else { "minor" }
// Blocks are expressions
let result = {
let x = 10
let y = 20
x + y // This value is returned from the block
}
```
## Best Practices
- Prefer `let` over `let mut` when possible
- Use descriptive names: `user_count` instead of `uc`
- Group related variable declarations together
- Group imports logically at the top of files
- Use selective imports to be explicit about dependencies
```jitzu
// Recommended file organization:
// 1. Imports first
open "./config.jz" as Config
open "./utils.jz" as { helper_function }
// 2. Main logic
let mut attempt_count = 0
let success = false
while attempt_count < 3 && !success {
success = try_operation()
attempt_count += 1
}
```
## Common Errors
### Mutating an immutable variable
```jitzu
let x = 10
x = 20 // Error: cannot assign to immutable variable 'x'
// Fix: declare with mut
let mut x = 10
x = 20
```
### Variable not in scope
```jitzu
if true {
let y = 42
}
print(y) // Error: unknown identifier 'y'
// Fix: declare y in the outer scope
let mut y = 0
if true {
y = 42
}
print(y)
```
### Unterminated string
```jitzu
let msg = "hello
// Error: String terminated abnormally
// Fix: close the string on the same line
let msg = "hello"
```
### Unterminated comment
```jitzu
/* this comment never closes
// Error: Non-terminated comment
// Fix: close the comment
/* this comment is closed */
```
This covers the essential syntax elements you'll use in every Jitzu program. Next, explore [Data Types](/docs/language/data-types) to learn about Jitzu's type system.
---
## Data Types
> Jitzu provides a set of built-in data types with strong typing and type inference to catch errors early while keeping code concise.
# Data Types
Jitzu provides a set of built-in data types with strong typing and type inference
to catch errors early while keeping code concise.
## Numbers
### Integer Types
```jitzu
// Integers (default: Int)
let x = 20
let y = 10
let negative = -42
// Basic arithmetic operations
print(x + y) // Addition: 30
print(x - y) // Subtraction: 10
print(x * y) // Multiplication: 200
print(x / y) // Division: 2
print(x % y) // Modulus: 0
```
### Floating-Point Numbers
```jitzu
// Double precision by default
let pi = 3.14159
let radius = 5.0
let area = pi * radius * radius
// Scientific notation
let large_number = 1.23e6 // 1,230,000
let small_number = 4.56e-3 // 0.00456
```
## Strings
### String Literals
```jitzu
// Simple strings
print("Hello World")
print("Hello\\nWorld") // With escape sequences
print("Hello\\tWorld") // Tab character
```
### String Interpolation
One of Jitzu's most convenient features is template literal interpolation:
```jitzu
// Basic interpolation
let greeting = "Hello"
let name = "Simon"
print(\`{greeting}, {name}!\`) // "Hello, Simon!"
// Expression interpolation
print(\`1 + 1 = {1 + 1}\`) // "1 + 1 = 2"
// Complex expressions
let count = 5
print(\`There are {count} items\`)
print(\`Math result: {count * 2 + 1}\`)
```
### String Concatenation
```jitzu
let greeting = "Hello"
let full_message = greeting + " World"
print(full_message) // "Hello World"
// String comparison
let name1 = "Alice"
let name2 = "alice"
print(name1 == name2) // false (case-sensitive)
```
## Vectors (Arrays)
Vectors are dynamic arrays that can grow at runtime.
### Creating Vectors
```jitzu
// Create empty typed vector
let strings = String[]
strings.push("Hello")
strings.push("World")
print(strings) // ["Hello", "World"]
// Initialize with values
let numbers = [1, 2, 3, 4, 5]
let names = ["Alice", "Bob", "Charlie"]
// Explicit typing
let ages: Int[] = [25, 30, 35]
let scores: Double[] = [95.5, 87.2, 92.8]
```
### Vector Operations
```jitzu
let numbers = [1, 2, 3]
// Adding elements
numbers.push(4)
numbers.push(5)
// Accessing elements
print(numbers[0]) // First element: 1
print(numbers[-1]) // Last element: 5
// Vector length
print(numbers.length) // 5
// Iteration
for item in numbers {
print(\`Number: {item}\`)
}
```
## Dynamic Objects
Jitzu supports dynamic object creation for flexible data structures:
```jitzu
// Simple object
let person = {
name = "John",
age = 30,
email = "john@example.com"
}
// Nested objects
let user = {
profile = {
name = "Alice",
avatar = "avatar.png"
},
settings = {
theme = "dark",
notifications = true
}
}
// Accessing fields with dot notation
print(person.name) // "John"
print(user.profile.name) // "Alice"
```
## Boolean Type
```jitzu
let is_active = true
let is_complete = false
// Boolean operations
let can_proceed = is_active && !is_complete
let should_stop = !is_active || is_complete
// Boolean from comparisons
let is_adult = age >= 18
```
## Option Types
Option types handle nullable values safely:
```jitzu
// Option types
fun find_user(id: Int): Option {
if id > 0 {
Some(User { id = id, name = "Found" })
} else {
None
}
}
match find_user(123) {
Some(user) => print(\`Found: {user.name}\`),
None => print("User not found")
}
```
This covers Jitzu's core data types. Next, explore [Functions](/docs/language/functions) to learn how to define and use functions.
---
## Numbers
> Integer and floating-point number types, arithmetic, parsing, and conversions in Jitzu.
# Numbers
Jitzu has two number types: `Int` for whole numbers and `Double` for floating-point values.
## Integers
```jitzu
let x = 20
let y = 10
let negative = -42
// Basic arithmetic
print(x + y) // 30
print(x - y) // 10
print(x * y) // 200
print(x / y) // 2
print(x % y) // 0 (modulus)
// Combined expressions follow standard precedence
print(x + y * 2) // 40 (multiplication first)
print((x + y) * 2) // 60 (parentheses override)
```
### Compound Assignment
```jitzu
let mut count = 0
count += 1 // count = 1
count -= 1 // count = 0
count += 10 // count = 10
count *= 2 // count = 20
count /= 4 // count = 5
```
## Floating-Point Numbers
```jitzu
// Double precision by default
let pi = 3.14159
let radius = 5.0
let area = pi * radius * radius
// Scientific notation
let large = 1.23e6 // 1,230,000
let small = 4.56e-3 // 0.00456
```
## Integer vs Double Division
```jitzu
// Integer division truncates
print(7 / 2) // 3
// Use a Double operand for decimal results
print(7.0 / 2.0) // 3.5
```
## Parsing Numbers from Strings
Use `.Parse()` on the .NET types to convert strings to numbers. These return a `Result` so you can handle invalid input safely.
```jitzu
// Parse integers
let parsed_int = try Int.Parse("42")
print(parsed_int) // 42
// Parse doubles
let parsed_double = try Double.Parse("3.14")
print(parsed_double) // 3.14
// Parsing can fail
let result = Int.Parse("not a number")
match result {
Ok(n) => print(n),
Err(e) => print(\`Failed: {e}\`),
}
```
## Comparisons
```jitzu
let a = 10
let b = 20
print(a == b) // false
print(a != b) // true
print(a < b) // true
print(a <= b) // true
print(a > b) // false
print(a >= b) // false
```
## Exponentiation
```jitzu
let squared = 5 ** 2 // 25
let cubed = 2 ** 10 // 1024
```
Numbers are one of Jitzu's primitive types. Next, explore [Strings](/docs/language/strings) for text handling.
---
## Strings
> String literals, interpolation, escape sequences, and common operations in Jitzu.
# Strings
Strings in Jitzu are UTF-8 text. You can create them with double quotes or backtick template literals.
## String Literals
```jitzu
let greeting = "Hello, world!"
print(greeting)
```
### Escape Sequences
```jitzu
print("Hello\\nWorld") // newline
print("Hello\\tWorld") // tab
print("She said \\"hi\\"") // escaped quotes
print("Path: C:\\\\Users") // backslash
```
## String Interpolation
Backtick strings support `{expression}` interpolation. Any expression works inside the braces.
```jitzu
let name = "Simon"
let age = 30
// Variable interpolation
print(\`Hello, {name}!\`) // "Hello, Simon!"
// Expression interpolation
print(\`Next year: {age + 1}\`) // "Next year: 31"
print(\`1 + 1 = {1 + 1}\`) // "1 + 1 = 2"
// Nested field access
let user = { name = "Alice", score = 95 }
print(\`{user.name} scored {user.score}\`)
```
## Concatenation
```jitzu
let first = "Hello"
let second = " World"
let combined = first + second
print(combined) // "Hello World"
// You can also concatenate numbers with strings
let count = 5
print(count + " items") // "5 items"
```
## String Comparison
Comparisons are case-sensitive:
```jitzu
let a = "Alice"
let b = "alice"
print(a == b) // false
print(a != b) // true
```
## .NET String Methods
Since Jitzu runs on .NET, you can call any `System.String` method directly using PascalCase:
```jitzu
let text = " Hello, World! "
// Case conversion
print(text.ToUpper()) // " HELLO, WORLD! "
print(text.ToLower()) // " hello, world! "
// Trimming whitespace
print(text.Trim()) // "Hello, World!"
print(text.TrimStart()) // "Hello, World! "
print(text.TrimEnd()) // " Hello, World!"
// Searching
let msg = "Hello, World!"
print(msg.Contains("World")) // true
print(msg.StartsWith("He")) // true
print(msg.EndsWith("!")) // true
print(msg.IndexOf("World")) // 7
// Splitting and joining
let csv = "one,two,three"
let parts = csv.Split(",") // ["one", "two", "three"]
// Replacing
let replaced = msg.Replace("World", "Jitzu")
print(replaced) // "Hello, Jitzu!"
// Substring
print(msg.Substring(0, 5)) // "Hello"
// Length
print(msg.Length) // 13
```
## Multi-line Strings
```jitzu
let poem = "Roses are red,\\nViolets are blue,\\nJitzu is fun,\\nAnd so are you."
print(poem)
```
## Common Errors
### Unterminated string
```jitzu
let msg = "hello
// Error: String terminated abnormally
// Fix: close the string on the same line
let msg = "hello"
```
### Invalid escape sequence
```jitzu
let ch = '\\x'
// Error: Invalid escape character sequence
// Valid escapes: \\n, \\t, \\\\, \\", \\'
```
### Invalid interpolation expression
```jitzu
let msg = \`value: {}\`
// Error: Not expecting this in an interpolated string
// Fix: put an expression inside the braces
let x = 42
let msg = \`value: {x}\`
```
Strings are one of Jitzu's most-used types. Next, explore [Vectors](/docs/language/vectors) for working with collections.
---
## Vectors
> Vectors are Jitzu's dynamic arrays — create, access, iterate, and transform collections of values.
# Vectors
Vectors are dynamic arrays that can grow at runtime. They are the primary collection type in Jitzu.
## Creating Vectors
```jitzu
// Initialize with values
let numbers = [1, 2, 3, 4, 5]
let names = ["Alice", "Bob", "Charlie"]
// Empty typed vector
let scores = Double[]
// Explicit type annotation
let ages: Int[] = [25, 30, 35]
```
## Accessing Elements
```jitzu
let colors = ["red", "green", "blue"]
// Index from the start (0-based)
print(colors[0]) // "red"
print(colors[1]) // "green"
print(colors[2]) // "blue"
// Negative indexing (from the end)
print(colors[-1]) // "blue"
print(colors[-2]) // "green"
```
## Adding Elements
```jitzu
let items = [1, 2, 3]
// push appends to the end
items.push(4)
items.push(5)
print(items) // [1, 2, 3, 4, 5]
```
## Length
```jitzu
let items = [10, 20, 30]
print(items.length) // 3
```
## Iterating
```jitzu
let fruits = ["apple", "banana", "cherry"]
// for-in loop
for fruit in fruits {
print(\`I like {fruit}\`)
}
// With index using a range
for i in 0..fruits.length {
print(\`{i}: {fruits[i]}\`)
}
```
## Safe Indexing
Indexing a vector returns an `Option` — out-of-bounds access returns `None` instead of crashing:
```jitzu
let items = [10, 20, 30]
match items[5] {
Some(value) => print(value),
None => print("Index out of bounds"),
}
```
## Mixed-Type Vectors
Vectors can hold mixed types when needed:
```jitzu
let things = [1, 'a', false, "hello"]
things.push(3.14)
print(things)
```
## Common Patterns
### Building a vector in a loop
```jitzu
let squares = Int[]
for i in 1..=10 {
squares.push(i ** 2)
}
print(squares) // [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```
### Checking if a vector is empty
```jitzu
let items = Int[]
if items.length == 0 {
print("No items yet")
}
```
Vectors are Jitzu's workhorse collection. Next, explore [Dates](/docs/language/dates) for working with dates and times.
---
## Dates
> Working with Date, Time, and Timestamp types in Jitzu for parsing, comparing, and combining temporal values.
# Dates
Jitzu has three temporal types: `Date` for calendar dates, `Time` for times of day, and `Timestamp` for a combined date and time.
## Date
```jitzu
// Parse a date from a string
let date = try Date.parse("2024-01-15")
print(date) // 2024-01-15
// Compare dates
let start = try Date.parse("2024-01-01")
let end = try Date.parse("2024-12-31")
print(start == end) // false
print(start < end) // true
```
## Time
```jitzu
// Parse a time from a string
let time = try Time.parse("14:30:00")
print(time) // 14:30:00
// Compare times
let morning = try Time.parse("08:00:00")
let evening = try Time.parse("20:00:00")
print(morning < evening) // true
```
## Timestamp (Date + Time)
Combine a `Date` and `Time` to create a `Timestamp`, or parse one directly:
```jitzu
// Combine date and time
let date = try Date.parse("2024-01-15")
let time = try Time.parse("12:00:00")
let timestamp = date + time
print(timestamp) // 2024-01-15 12:00:00
// Parse a timestamp directly
let ts = try Timestamp.parse("2024-01-15 12:00:00")
// They compare equal
print(timestamp == ts) // true
```
## Error Handling
Parsing returns a `Result`, so invalid input is handled safely:
```jitzu
let result = Date.parse("not-a-date")
match result {
Ok(d) => print(d),
Err(e) => print(\`Parse error: {e}\`),
}
```
Dates round out Jitzu's built-in types. Next, explore [Functions](/docs/language/functions) to learn how to define and use functions.
---
## Functions
> Functions are the building blocks of Jitzu programs. They support type annotations, automatic return of the last expression, recursion, and Result-based error handling.
# Functions
Functions are the building blocks of Jitzu programs. They support type annotations,
automatic return of the last expression, recursion, and Result-based error handling.
## Function Definition
### Basic Function Syntax
```jitzu
// Basic function with explicit return type
fun add(a: Int, b: Int): Int {
a + b
}
// Function with string return
fun greet(name: String): String {
\`Hello, {name}!\`
}
// Function with no parameters
fun get_pi(): Double {
3.14159
}
// Using functions
print(add(5, 3)) // 8
print(greet("World")) // "Hello, World!"
print(get_pi()) // 3.14159
```
### Everything is an Expression
Functions automatically return the value of their last expression - no `return` keyword needed:
```jitzu
fun calculate_area(radius: Double): Double {
let pi = 3.14159
pi * radius * radius // This value is automatically returned
}
// You can use explicit return for early exits
fun classify(n: Int): String {
if n < 0 {
return "negative"
}
if n == 0 {
return "zero"
}
"positive"
}
```
### Function Parameters
```jitzu
// Required parameters with types
fun format_name(first: String, last: String): String {
\`{first} {last}\`
}
// Parameters are typed
fun distance(x1: Double, y1: Double, x2: Double, y2: Double): Double {
let dx = x2 - x1
let dy = y2 - y1
(dx * dx + dy * dy)
}
```
## Recursive Functions
Jitzu supports recursive functions:
```jitzu
// Classic recursive factorial
fun factorial(n: Int): Int {
if n <= 1 {
1
} else {
n * factorial(n - 1)
}
}
// Power function
fun power(base: Int, exp: Int): Int {
if exp == 0 {
1
} else {
base * power(base, exp - 1)
}
}
// Fibonacci
fun fibonacci(n: Int): Int {
if n <= 1 {
n
} else {
fibonacci(n - 1) + fibonacci(n - 2)
}
}
print(factorial(5)) // 120
print(power(2, 8)) // 256
print(fibonacci(10)) // 55
```
## Error Handling with Result Types
### Returning Results
Use `Result` for functions that can fail:
```jitzu
fun divide(a: Double, b: Double): Result {
if b == 0.0 {
Err("Division by zero")
} else {
Ok(a / b)
}
}
// Pattern matching on Results
match divide(10.0, 2.0) {
Ok(result) => print(\`Result: {result}\`),
Err(error) => print(\`Error: {error}\`)
}
```
### The Try Operator
Use `try` to propagate errors early:
```jitzu
fun safe_sqrt(x: Double): Result {
if x < 0.0 {
Err("Cannot take square root of negative number")
} else {
Ok(x)
}
}
// try returns Err early if the operation fails
fun complex_calculation(a: Double, b: Double): Result {
let step1 = try divide(a, b)
let step2 = try safe_sqrt(step1)
Ok(step2)
}
match complex_calculation(100.0, 4.0) {
Ok(value) => print(\`Result: {value}\`),
Err(error) => print(\`Failed: {error}\`)
}
```
## Best Practices
- **Single responsibility** - Each function should do one thing well
- **Descriptive names** - Use clear, meaningful function names
- **Small functions** - Keep functions focused and concise
- Prefer `Result` for recoverable errors
- Use early returns with guard clauses to reduce nesting
```jitzu
// Good: Early returns reduce nesting
fun validate_and_process(input: String): Result {
if input == "" {
return Err("Input cannot be empty")
}
// Happy path - main logic
Ok(input)
}
```
## Common Errors
### Wrong argument types
```jitzu
fun add(a: Int, b: Int): Int { a + b }
add("hello", 2)
// Error: Cannot find function 'add' on '' with argument types: String, Int
// Fix: pass the correct types
add(1, 2)
```
### Calling a method that doesn't exist
```jitzu
let name = "Alice"
name.Foo()
// Error: Cannot find function 'Foo' on 'String'
// Fix: use a real String method
name.ToUpper()
```
### Mismatched Result types
```jitzu
fun check(x: Int): Result {
if x > 0 { Ok("positive") } else { 42 }
// Error: Couldn't resolve match to a single return type
// Fix: both branches must return the same type
if x > 0 { Ok("positive") } else { Err("not positive") }
}
```
Functions are the building blocks of Jitzu programs. Next, explore [Control Flow](/docs/language/control-flow) to learn about conditionals and loops.
---
## Control Flow
> Jitzu provides expressive control flow constructs including conditionals, loops, and early returns. Many control flow constructs are expressions, meaning they return values.
# Control Flow
Jitzu provides expressive control flow constructs including conditionals, loops, and early returns.
Many control flow constructs are expressions, meaning they return values.
## Conditionals
### Basic if Statements
```jitzu
// Simple if statement
if 2 > 1 {
print("2 is greater than 1")
}
```
### if-else Chains
```jitzu
// if-else chain
if 2 < 1 {
print("This won't print")
} else if 1 > 1 {
print("Nor this")
} else {
print("But this will")
}
```
### if Expressions
Since `if` is an expression, it returns a value:
```jitzu
// if expressions (return values)
let x = 10
let result = if x > 0 { "positive" } else { "non-positive" }
print(result) // "positive"
// Inline conditional
let message = if logged_in { "Welcome back!" } else { "Please log in" }
```
## Loops
### Range Loops
Jitzu provides convenient range-based loops:
```jitzu
// Inclusive range (1 to 5)
for i in 1..=5 {
print(\` > {i}\`)
}
// Output: 1, 2, 3, 4, 5
// Exclusive range (1 to 4)
for i in 1..5 {
print(\` > {i}\`)
}
// Output: 1, 2, 3, 4
// Character ranges
for c in 'a'..='z' {
print(\` > {c}\`)
}
// Output: a, b, c, ..., z
```
### Collection Iteration
```jitzu
// Iterate over vector elements
let numbers = [1, 2, 3, 4, 5]
for num in numbers {
print(\`Number: {num}\`)
}
```
### While Loops
```jitzu
// Basic while loop
let mut i = 0
while i < 10 {
print(\`Count: {i}\`)
i += 1
}
// While with complex condition
let mut attempts = 0
let mut success = false
while attempts < 3 && !success {
success = try_operation()
attempts += 1
}
// Infinite loop with break
let mut counter = 0
while true {
counter += 1
if counter > 100 {
break
}
}
```
### Loop Control
Control loop execution with `break` and `continue`:
```jitzu
// Using break and continue
for i in 1..=100 {
if i == 50 {
break // Exit the loop completely
}
if i % 2 == 0 {
continue // Skip to next iteration
}
print(i) // Only prints odd numbers up to 49
}
```
## Early Returns
```jitzu
// Early return from function
fun find_first_even(numbers: Int[]): Option {
for num in numbers {
if num % 2 == 0 {
return Some(num)
}
}
None // No even number found
}
// Guard clauses
fun process_user(user: User): Result {
if !user.is_active {
return Err("User is not active")
}
if user.age < 18 {
return Err("User must be 18 or older")
}
// Main processing logic here
Ok(\`Processing user: {user.name}\`)
}
```
## Best Practices
- Use guard clauses to handle edge cases first
- Reduce nesting by returning early
- Use `for` loops for known iterations
- Use `while` loops for condition-based iteration
- Combine conditions rather than deeply nesting
```jitzu
// Avoid deep nesting
// Bad:
if condition1 {
if condition2 {
if condition3 {
// deeply nested code
}
}
}
// Better: Combine conditions
if condition1 && condition2 && condition3 {
// main logic here
}
```
Control flow is fundamental to programming logic in Jitzu. Next, explore [Types](/docs/language/object-oriented) to learn about custom type definitions and composition.
---
## Types
> Jitzu lets you define custom types to group related data together. Types support public and private fields, nesting, and composition.
# Types
Jitzu lets you define custom types to group related data together.
Types support public and private fields, nesting, and composition.
## Type Definitions
### Basic Types
Define custom types to group related data:
```jitzu
// Basic type definition
type Person {
pub name: String,
pub age: Int
}
// Creating instances
let john = Person {
name = "John Doe",
age = 30
}
// Accessing fields
print(john.name) // "John Doe"
print(john.age) // 30
```
### Nested Types
Types can contain other types for complex data structures:
```jitzu
// Nested type definitions
type PersonName {
pub first: String,
pub last: String
}
type Address {
pub street: String,
pub city: String,
pub zip_code: String
}
type Employee {
pub name: PersonName,
pub id: Int,
pub department: String,
pub address: Address
}
// Creating nested instances
let employee = Employee {
name = PersonName {
first = "Alice",
last = "Johnson"
},
id = 12345,
department = "Engineering",
address = Address {
street = "123 Main St",
city = "Tech City",
zip_code = "12345"
}
}
// Accessing nested fields
print(\`Employee: {employee.name.first} {employee.name.last}\`)
print(\`Works in: {employee.department}\`)
```
### Private and Public Fields
Control field visibility with `pub`. Fields without `pub` are private:
```jitzu
type BankAccount {
pub account_number: String,
pub owner: String,
balance: Double, // Private field
pin: String // Private field
}
```
## Composition
Jitzu favors composition - build complex types by combining simpler ones:
```jitzu
// Base components
type Engine {
pub horsepower: Int,
pub fuel_type: String
}
type Transmission {
pub gear_type: String,
pub gears: Int
}
// Composed type
type Car {
pub make: String,
pub model: String,
pub engine: Engine,
pub transmission: Transmission
}
let my_car = Car {
make = "Toyota",
model = "Supra",
engine = Engine {
horsepower = 382,
fuel_type = "Gasoline"
},
transmission = Transmission {
gear_type = "manual",
gears = 6
}
}
print(\`{my_car.make} {my_car.model} - {my_car.engine.horsepower}hp\`)
```
## Best Practices
- **Small, focused types** - Keep types simple and focused on one responsibility
- **Use composition** - Build complex types from simpler ones rather than making one huge type
- **Public interface design** - Only mark fields as `pub` when they need to be accessed externally
- **Descriptive names** - Use PascalCase for type names and snake_case for field names
## Common Errors
### Type name must start with uppercase
```jitzu
type person { pub name: String }
// Error: Type names must start with an uppercase letter
// Fix: use PascalCase
type Person { pub name: String }
```
### Accessing a private field
```jitzu
type Account {
pub owner: String,
balance: Double, // private
}
let acc = Account { owner = "Alice", balance = 100.0 }
print(acc.balance)
// Error: Cannot find function 'balance' on 'Account'
// Fix: mark the field as pub, or access through a method
```
### Incompatible types in binary operation
```jitzu
let result = "hello" - 5
// Error: Operation sub not supported for types 'String' and 'Int'
// Fix: use compatible types
let result = 10 - 5
```
Next, explore [Traits & Methods](/docs/language/traits) to learn how to add behavior to your types.
---
## Traits & Methods
> Define methods on types and declare shared behavior with traits in Jitzu.
# Traits & Methods
Jitzu supports defining methods on types and declaring shared behavior contracts with traits.
## Type Methods
Define methods directly inside a `type` block. Methods that take `self` as the first parameter are instance methods — call them with dot notation.
```jitzu
type Circle {
pub radius: Double
fun area(self): Double {
3.14159 * self.radius * self.radius
}
fun describe(self): String {
\`Circle with radius {self.radius}\`
}
}
let c = Circle { radius = 5.0 }
print(c.area()) // 78.53975
print(c.describe()) // "Circle with radius 5"
```
### Methods with Parameters
```jitzu
type Rectangle {
pub width: Double,
pub height: Double
fun area(self): Double {
self.width * self.height
}
fun scale(self, factor: Double): Rectangle {
Rectangle {
width = self.width * factor,
height = self.height * factor,
}
}
fun is_larger_than(self, other: Rectangle): Bool {
self.area() > other.area()
}
}
let r = Rectangle { width = 10.0, height = 5.0 }
print(r.area()) // 50.0
let big = r.scale(2.0)
print(big.area()) // 200.0
print(big.is_larger_than(r)) // true
```
### Public and Private Methods
Like fields, methods can be marked `pub` for public access. Methods without `pub` are private to the type.
```jitzu
type BankAccount {
pub owner: String,
balance: Double
// Private method — only callable from other methods on this type
fun validate_amount(self, amount: Double): Result {
if amount <= 0.0 {
Err("Amount must be positive")
} else {
Ok(amount)
}
}
// Public methods
pub fun get_balance(self): Double {
self.balance
}
pub fun deposit(self, amount: Double): Result {
let valid = try self.validate_amount(amount)
self.balance = self.balance + valid
Ok(self.balance)
}
}
```
## Traits
Traits define a set of method signatures that a type must implement. They describe shared behavior without providing the implementation.
```jitzu
trait Describable {
fun describe(self): String
}
trait Resizable {
fun scale(self, factor: Double): Self
}
```
### Implementing Traits
Use `impl TraitName for TypeName` to implement a trait on a type:
```jitzu
type Person {
pub name: String,
pub age: Int
}
trait Greet {
fun greeting(self): String
}
impl Greet for Person {
fun greeting(self): String {
\`Hello, I'm {self.name}\`
}
}
```
> **Note:** Trait declarations and `impl` blocks are currently parsed but trait methods are not yet registered at runtime. For now, define methods directly inside the `type` block instead. Full trait dispatch is planned for a future release.
### Current Workaround
Until `impl` blocks are fully wired up, put methods inside the type definition:
```jitzu
// ✓ This works today
type Person {
pub name: String,
pub age: Int
fun greeting(self): String {
\`Hello, I'm {self.name}\`
}
}
let p = Person { name = "Alice", age = 30 }
print(p.greeting()) // "Hello, I'm Alice"
```
## Naming Convention
All methods use **snake_case** — both inline type methods and trait methods:
```jitzu
type User {
pub name: String
// ✓ snake_case for methods
fun get_display_name(self): String {
self.name.ToUpper()
}
}
// .NET methods keep their original PascalCase
// self.name.ToUpper() — this is a .NET call, not a Jitzu method
```
## Common Errors
### Method not found on type
```jitzu
type Dog { pub name: String }
let d = Dog { name = "Rex" }
d.bark()
// Error: Cannot find function 'bark' on 'Dog'
// Fix: define the method inside the type block
type Dog {
pub name: String
fun bark(self): String { \`{self.name} says woof!\` }
}
```
### Missing self parameter
```jitzu
type Counter {
pub value: Int
// This is a static-style method, not an instance method
fun create(): Counter {
Counter { value = 0 }
}
// Instance methods must take self
fun increment(self): Int {
self.value + 1
}
}
```
### Type name must start with uppercase
```jitzu
type person { pub name: String }
// Error: Type names must start with an uppercase letter
// Fix: use PascalCase
type Person { pub name: String }
```
Methods let you attach behavior to your types, keeping data and logic together. Next, explore [Pattern Matching](/docs/language/pattern-matching) to learn about union types and match expressions.
---
## Pattern Matching
> Pattern matching is one of Jitzu's most powerful features. Combined with union types and the built-in Result/Option system, it lets you handle different cases elegantly and safely.
# Pattern Matching
Pattern matching is one of Jitzu's most powerful features. Combined with union types and the
built-in Result/Option system, it lets you handle different cases elegantly and safely.
## Union Types
Union types allow a value to be one of several variants, providing type-safe alternatives to traditional enums.
### Defining Union Types
```jitzu
// Basic union type
union Pet {
Fish,
Cat(String), // Cat with name
Dog(String, Int), // Dog with name and age
Bird(String, Bool), // Bird with name and can_talk
None,
}
// Union for error handling
union FileResult {
Success(String),
NotFound,
PermissionDenied,
InvalidFormat(String),
}
```
### Creating Union Instances
```jitzu
// Creating union instances
let my_pet = Pet.Cat("Whiskers")
let family_dog = Pet.Dog("Rex", 5)
let goldfish = Pet.Fish
let no_pet = Pet.None
// Result instances
let success = FileResult.Success("File content here")
let error = FileResult.InvalidFormat("Not a valid JSON file")
```
## Match Expressions
Match expressions provide exhaustive pattern matching over union types.
### Basic Pattern Matching
```jitzu
// Basic match expression
let pet = Pet.Cat("Whiskers")
match pet {
Pet.Fish => print("Fish don't need names"),
Pet.Cat(name) => print(\`Hello cat {name}\`),
Pet.Dog(name, age) => print(\`Dog {name} is {age} years old\`),
Pet.Bird(name, can_talk) => {
if can_talk {
print(\`{name} the talking bird\`)
} else {
print(\`{name} the quiet bird\`)
}
},
Pet.None => print("No pets"),
}
// Match expressions return values
let pet_description = match pet {
Pet.Fish => "A silent swimmer",
Pet.Cat(name) => \`A cat named {name}\`,
Pet.Dog(name, age) => \`A {age}-year-old dog named {name}\`,
Pet.Bird(name, _) => \`A bird named {name}\`,
Pet.None => "No pet"
}
```
### Wildcard Patterns
Use `_` to ignore values you don't need:
```jitzu
match pet {
Pet.Dog(name, _) => print(\`Dog: {name}\`), // Ignore age
_ => print("Not a dog"), // Match anything else
}
```
## Result Types
Result types are a built-in union for handling operations that can succeed or fail.
### Working with Results
```jitzu
// Function returning Result
fun divide(a: Double, b: Double): Result {
if b == 0.0 {
Err("Division by zero")
} else {
Ok(a / b)
}
}
// Pattern matching Results
let result = divide(10.0, 2.0)
match result {
Ok(value) => print(\`Result: {value}\`),
Err(error) => print(\`Error: {error}\`)
}
```
### The Try Operator
Use `try` to propagate errors without nested match statements:
```jitzu
fun safe_sqrt(x: Double): Result {
if x < 0.0 {
Err("Cannot take square root of negative number")
} else {
Ok(x)
}
}
// Using try for early return on errors
fun complex_calculation(a: Double, b: Double, c: Double): Result {
let step1 = try divide(a, b) // Returns Err early if division fails
let step2 = try safe_sqrt(step1) // Returns Err early if sqrt fails
let step3 = try divide(step2, c) // Returns Err early if division fails
Ok(step3)
}
// Without try (more verbose)
fun complex_calculation_verbose(a: Double, b: Double, c: Double): Result {
match divide(a, b) {
Ok(step1) => {
match safe_sqrt(step1) {
Ok(step2) => divide(step2, c),
Err(e) => Err(e)
}
},
Err(e) => Err(e)
}
}
```
## Option Types
Option types handle nullable values safely.
### Option Patterns
```jitzu
// Function returning Option
fun find_user(users: User[], id: Int): Option {
for user in users {
if user.id == id {
return Some(user)
}
}
None
}
// Pattern matching Options
match find_user(users, 1) {
Some(user) => print(\`Found user: {user.name}\`),
None => print("User not found")
}
```
## Best Practices
- **Cover all cases** - Match expressions should be exhaustive
- **Use wildcard patterns** - Use `_` for cases you don't care about
- **Prefer Result/Option** - Use them instead of null checks for safer code
- **Use try** - The try operator keeps error propagation clean and readable
## Common Errors
### Mismatched branch types
```jitzu
let label = match status {
Ok(v) => \`Success: {v}\`,
Err(e) => 42, // returns Int, not String
}
// Error: Couldn't resolve match to a single return type
// Fix: all branches must return the same type
let label = match status {
Ok(v) => \`Success: {v}\`,
Err(e) => \`Error: {e}\`,
}
```
### Destructuring a type without a constructor
```jitzu
type Config { pub path: String }
match config {
Config(p) => print(p),
}
// Error: Type Config does not have a constructor
// Fix: use field access instead of destructuring
print(config.path)
```
### Ambiguous type name
```jitzu
// When two packages export the same type name
let s = JsonSerializer {}
// Error: Type 'JsonSerializer' is ambiguous. Did you mean:
// - System.Text.Json.JsonSerializer
// - Newtonsoft.Json.JsonSerializer
// Fix: use the fully qualified name
let s = System.Text.Json.JsonSerializer {}
```
Pattern matching makes Jitzu code more expressive and safer by ensuring all cases are handled.
It's particularly powerful when combined with union types and the Result/Option system. Next, explore [.NET Interop](/docs/language/dotnet-interop) to learn how to use NuGet packages and call .NET methods.
---
## .NET Interop
> Jitzu runs on .NET — call any .NET method, access properties, and install NuGet packages directly in your scripts.
# .NET Interop
Jitzu compiles to bytecode and runs on .NET 10. This means you can call any .NET method, access properties, create instances of .NET types, and install NuGet packages — all from Jitzu code.
## Built-in .NET Types
These types are available without any imports:
| Jitzu name | .NET type | Example |
|------------|-----------|---------|
| `Int` | `System.Int32` | `Int.Parse("42")` |
| `Double` | `System.Double` | `Double.Parse("3.14")` |
| `String` | `System.String` | `"hello".ToUpper()` |
| `Bool` | `System.Boolean` | `true` |
| `Char` | `System.Char` | `'a'` |
| `Date` | `System.DateOnly` | `Date.parse("2024-01-01")` |
| `Time` | `System.TimeOnly` | `Time.parse("12:00:00")` |
| `DateTime` | `System.DateTime` | `DateTime.Now` |
| `File` | `System.IO.File` | `File.Exists("config.json")` |
| `Path` | `System.IO.Path` | `Path.GetFileName("src/main.jz")` |
## Calling Instance Methods
Call .NET methods on any value using their original PascalCase names:
```jitzu
let msg = "Hello, World!"
// String instance methods
print(msg.ToUpper()) // "HELLO, WORLD!"
print(msg.ToLower()) // "hello, world!"
print(msg.Trim()) // "Hello, World!"
print(msg.Contains("World")) // true
print(msg.StartsWith("He")) // true
print(msg.Replace("World", "Jitzu")) // "Hello, Jitzu!"
print(msg.Substring(0, 5)) // "Hello"
print(msg.Split(",")) // ["Hello", " World!"]
print(msg.IndexOf("World")) // 7
```
## Accessing Properties
Access .NET properties with dot notation — just like fields:
```jitzu
let msg = "Hello"
print(msg.Length) // 5
let items = [1, 2, 3]
print(items.Count) // 3
```
## Calling Static Methods
Call static methods on a type name:
```jitzu
// Parsing
let n = try Int.Parse("42")
let pi = try Double.Parse("3.14159")
// File operations
let exists = File.Exists("config.json")
let ext = Path.GetExtension("script.jz") // ".jz"
let name = Path.GetFileName("src/Parser.cs") // "Parser.cs"
let dir = Path.GetDirectoryName("/home/user/file.txt")
```
## NuGet Packages
Any public NuGet package works in Jitzu. Add a `#:package` directive at the top of your script — no project files, no restore step.
```jitzu
#:package Newtonsoft.Json@13.0.4
let user = { name = "Alice", age = 30 }
let json = JsonConvert.SerializeObject(user)
print(json) // {"name":"Alice","age":30}
```
### Specifying Versions
The version follows the package name after `@`:
```jitzu
#:package Serilog@4.3.1
#:package Serilog.Sinks.Console@6.1.1
let logger_config = LoggerConfiguration { }
Log.Logger = logger_config.WriteTo.Console().CreateLogger()
Log.Information("Hello from Serilog!")
Log.CloseAndFlush()
```
Packages are downloaded to `~/.nuget/packages` and cached for future runs. Dependencies are resolved automatically.
### Creating .NET Instances
Construct .NET types with the object initializer syntax:
```jitzu
#:package Serilog@4.3.1
// Parameterless constructor + property assignment
let config = LoggerConfiguration { }
```
## Method Name Conversion
Jitzu functions use snake_case, but .NET methods use PascalCase. When calling .NET methods, use PascalCase — these are CLR calls, not Jitzu functions:
```jitzu
// ✓ .NET methods — PascalCase (their original names)
let upper = name.ToUpper()
let parts = line.Split(",")
let n = Int.Parse("42")
// ✗ Don't use snake_case for .NET methods
// name.to_upper() — won't find the method
// Int.parse("42") — won't find the method
```
## Namespace Resolution
Types from NuGet packages are registered with their full .NET namespace. If a type name is unique across all loaded packages, you can use just the short name:
```jitzu
#:package Newtonsoft.Json@13.0.4
// Short name works when unambiguous
let json = JsonConvert.SerializeObject(data)
```
If two packages export the same type name, Jitzu tells you:
```jitzu
// Error: Type 'JsonSerializer' is ambiguous. Did you mean:
// - System.Text.Json.JsonSerializer
// - Newtonsoft.Json.JsonSerializer
// Fix: use the fully qualified name
let s = System.Text.Json.JsonSerializer {}
```
## Common Errors
### Method not found
```jitzu
let name = "Alice"
name.Foo()
// Error: Cannot find function 'Foo' on 'String'
// Fix: check the method name and casing
name.ToUpper()
```
### Wrong argument types
```jitzu
Int.Parse(42)
// Error: Cannot find function 'Parse' on 'Int' with argument types: Int
// Fix: Parse expects a String
Int.Parse("42")
```
### Package not found
If a `#:package` directive specifies a version that doesn't exist, the script will fail at startup before any code runs. Double-check the package name and version on [nuget.org](https://www.nuget.org).
Next, explore the [Code Style](/docs/language/code-style) guide for naming conventions.
---
## Code Style
> Naming conventions and style guide for Jitzu code.
# Code Style
Jitzu has a small set of naming rules. Following them keeps your code consistent with the standard library, built-in types, and .NET interop.
## Naming Rules
| Element | Convention | Correct | Wrong |
|---------|-----------|---------|-------|
| Keywords | lowercase | `let`, `fun`, `type` | `Let`, `Fun` |
| Types | PascalCase | `Person`, `HttpClient` | `person`, `http_client` |
| Union variants | PascalCase | `Ok(value)`, `Circle(r)` | `ok(value)`, `circle(r)` |
| Traits | PascalCase | `Greet`, `Serializable` | `greet`, `serializable` |
| Functions | snake_case | `load_config()` | `LoadConfig()`, `loadConfig()` |
| Methods (impl) | snake_case | `get_name(self)` | `GetName(self)`, `getName(self)` |
| .NET methods | PascalCase | `str.ToUpper()` | `str.to_upper()` |
| Built-in functions | lowercase | `print()`, `rand()` | `Print()`, `Rand()` |
| Variables | snake_case | `first_name`, `is_valid` | `FirstName`, `firstName` |
| Parameters | snake_case | `max_retries`, `user_id` | `MaxRetries`, `userId` |
| Fields | snake_case | `pub name: String` | `pub Name: String` |
## Types, Traits, and Unions
All type-level declarations use PascalCase. This includes `type`, `trait`, `union`, and their variants.
```jitzu
type Person {
pub name: String,
pub age: Int,
pub is_active: Bool,
}
trait Greet {
fun greeting(self): String
}
union Shape {
Circle(Double),
Square(Double),
}
```
## Functions and Methods
Both standalone functions and `impl` methods use snake_case.
```jitzu
// ✓ Functions are snake_case
fun factorial(n: Int): Int {
if n <= 1 { 1 } else { n * factorial(n - 1) }
}
fun load_config(path: String): Result {
let file = try read_file(path)
Ok(try parse_json(file))
}
```
```jitzu
// ✓ Methods (with self) are also snake_case
impl Greet for Person {
fun greeting(self): String {
\`Hello, {self.name}!\`
}
}
impl Drop for Connection {
fun drop(self) {
print("closed")
}
}
```
```jitzu
// ✗ Don't do this
fun LoadConfig(): Config { } // PascalCase function
fun loadConfig(): Config { } // camelCase function
impl Greet for Person {
fun Greeting(self): String { } // PascalCase method
fun getGreeting(self): String { } // camelCase method
}
```
## .NET Methods
Since Jitzu runs on .NET, calling methods on .NET types uses their original PascalCase names. These are not Jitzu methods — they are CLR method calls.
```jitzu
// .NET string methods — PascalCase
let upper = name.ToUpper()
let trimmed = input.Trim()
let parts = line.Split(",")
// .NET static methods — PascalCase
let n = Int.Parse("42")
let exists = File.Exists("config.json")
```
## Built-in Functions
The runtime provides a small set of lowercase global functions.
```jitzu
print("Hello, world!")
let n = rand(1, 100)
let head = first(items)
let tail = last(items)
```
Single-word builtins like `print` and `rand` are lowercase without underscores. Your own functions should use underscores for multi-word names (e.g. `load_config`).
## Variables, Parameters, and Fields
All value-level names use snake_case. Boolean values typically use an `is_`, `has_`, or `can_` prefix.
```jitzu
// ✓ Variables — snake_case
let first_name = "Alice"
let is_valid = true
let max_retries = 3
let mut request_count = 0
// ✓ Fields — snake_case
type UserProfile {
pub display_name: String,
pub email_address: String,
pub is_verified: Bool,
mut login_count: Int,
}
// ✓ Parameters — snake_case
fun send_email(to_address: String, subject: String): Result {
// ...
}
```
```jitzu
// ✗ Don't do this
let FirstName = "Alice" // PascalCase variable
let firstName = "Alice" // camelCase variable
let IsValid = true // PascalCase variable
```
## Formatting
Jitzu uses 4-space indentation. Opening braces go on the same line. Single-expression bodies can stay on one line.
```jitzu
// ✓ Braces on same line, 4-space indent
fun fibonacci(n: Int): Int {
if n <= 1 {
n
} else {
fibonacci(n - 1) + fibonacci(n - 2)
}
}
// ✓ Short expressions can be one line
fun square(n: Int): Int { n * n }
// ✓ Match arms indented once
let label = match status {
Ok(value) => \`Success: {value}\`,
Err(e) => \`Error: {e}\`,
}
```
## Quick Reference
When in doubt:
- **Defining a type?** PascalCase: `type HttpResponse { }`
- **Defining a function?** snake_case: `fun parse_json()`
- **Defining a method with self?** snake_case: `fun get_name(self)`
- **Calling a .NET method?** PascalCase: `.ToUpper()`, `.Split()`
- **Naming a variable?** snake_case: `let response_body = ...`
- **Using a builtin?** lowercase: `print()`, `rand()`