Skip to content
Ridgun
English

Ridgun

The language itself: a compiler that compiles itself, the stable project tool, the specification and the book

01-welcome-to-ridgun.md195 lines · 11.0 KBRaw
1# Chapter 01: Your First Contact with Ridgun (No Boilerplate, No Braces, No Semicolons)
2
3Alright, Chapter 00 convinced you that we weren't crazy for creating Ridgun. Right now you're probably thinking:
4
5> *"Nice speech about tables and 16 cores, but show me real code. How long does it take to write something that actually works without fighting the compiler?"*
6
7Let's get right to it!
8
9---
10
11## 1.1. "Hello, World!", But with Teeth
12
13Most programming books show you a bland `print("Hello world")` and turn the page. We are going to jump straight into a function with real logic so you can see how Ridgun breathes from minute one.
14
15Create a file named `hello.rg` and write this:
16
17```ridgun
18greet String => String
19greet "" = "Hello, mysterious traveler! (You didn't tell me your name)"
20greet "Root" = "Hey there, Root! Careful what you delete today."
21greet name = "Hello, {name}! Welcome to Ridgun."
22
23main => ()
24main =
25 echo (greet "Ada")
26 echo (greet "Root")
27 echo (greet "")
28```
29
30To run it right now:
31
32```bash
33ridgunc run hello.rg
34```
35
36And you will see in your terminal:
37
38```text
39Hello, Ada! Welcome to Ridgun.
40Hey there, Root! Careful what you delete today.
41Hello, mysterious traveler! (You didn't tell me your name)
42```
43
44Pause for a moment and look at the `greet` block above. Notice what is **NOT** there?
45- **No `function`, `def`, or `pub fn`** (you can put `fn ::` before the signature if you like, but it's optional).
46- **No parentheses `(String name)` or curly braces `{ ... }`** cluttering the screen.
47- **No `if (name == "") ... else if (name == "Root") ... else ...`**.
48- **No `return`**.
49
50---
51
52## 1.2. How Your Brain Reads an `.rg` File
53
54Let's dissect those four lines of `greet`, because 50% of Ridgun's philosophy is already right here:
55
56```ridgun
57greet String => String
58greet "" = "Hello, mysterious traveler! (You didn't tell me your name)"
59greet "Root" = "Hey there, Root! Careful what you delete today."
60greet name = "Hello, {name}! Welcome to Ridgun."
61```
62
631. **The first line is the contract (`greet String => String`)**:
64 It says: *"My name is `greet`, I take a `String`, and I give you back (`=>`) another `String`"*. Period. If someone tries to call me with the number `42`, the compiler will tap them on the shoulder before the program even runs.
652. **The lines below are the cases (top to bottom)**:
66 - Did you pass me the empty string `""`? I return the first sentence.
67 - Did you pass me the exact string `"Root"`? I return the second sentence.
68 - Did you pass me anything else? I bind it to the variable `name` and interpolate it directly into the string using `{name}`.
693. **And what is `main => ()`?**:
70 Since `main` takes no arguments, we place `=>` right after its name. And it returns `()` (the empty or *Unit* type), because its only job is to print things to the screen with `echo`.
71
72---
73
74## 1.3. "Wait... do I have to align those spaces by hand like a medieval scribe?"
75
76Not a chance! If you had to hit the spacebar counting columns by eye, you would quit Ridgun in ten minutes (and rightfully so).
77
78You type your code quickly, with just a single space between words:
79
80```ridgun
81greet String => String
82greet "" = "Hello, mysterious traveler!"
83greet name = "Hello, {name}!"
84```
85
86And when you run **`stable format`** (or press `TAB` / save the file in Emacs with `ridgun-mode`), the canonical formatter places every parameter directly beneath its type and aligns every `=` with pinpoint precision. You write fast; the machine typesets the table.
87
88---
89
90## 1.4. From Quick Script to Battle-Ready Binary in One Command
91
92When you run `ridgunc run hello.rg`, you are compiling and launching the program on the fly. But imagine you've finished your tool and want to deploy it to a production server or share it with a teammate who doesn't have Ridgun installed.
93
94You run:
95
96```bash
97ridgunc build hello.rg -o hello
98```
99
100And now you have `./hello`: a **native Linux x86_64 ELF executable**, lean, stripped of dead code (*Tree-Shaking*), built with full link-time optimization (*LTO*), and completely independent of any external interpreter.
101
102---
103
104## 1.5. The Honest Cheat Sheet: Where Does Every Idea in Ridgun Come From?
105
106Ridgun doesn't try to reinvent the flat tire; it unapologetically borrows the best ideas from four traditions:
107
108| From Whom | What Ridgun Borrows | What It Leaves Behind (For Your Sanity) |
109|---|---|---|
110| **Haskell / ML** | Pure functions, case-by-case *pattern matching*, algebraic data types (`Option`, `Result`), and polymorphism (`A`..`Z`). | Abstract monad transformers, 40 `LANGUAGE` pragmas, and the garbage collector. |
111| **J / APL** | Obsession with tabular code layout, native tensors, and sequence masks (`s(_ + _)`). | Hieroglyphic symbols that are impossible to type on a normal keyboard. |
112| **Rust / C** | Tiny native ELF binaries, zero GC, deterministic memory control (`with region`), and POSIX system calls. | Constant battles with the *borrow checker*, `'a` *lifetimes*, and syntactic verbosity. |
113| **Erlang / Go** | Isolated agents (`agent`, `send ... to`, `receive from`) and channel-based concurrency (`new bounded channel`). | `nil` pointers and accidental shared mutable state. |
114
115---
116
117## 1.6. Most Importantly: What Does Ridgun Do That Nobody Else Has?
118
119Giving credit to the classics is good manners, but if Ridgun were just a "greatest hits album" of other languages, you wouldn't be reading this book.
120
121There are **eight things** we designed and integrated into Ridgun that you won't find together—and many of them not even separately—in any other language today:
122
123### 1. Parallel `||` blocks with `->` that are true parallel graphs, not mere syntactic sugar
124In other functional languages, a local binding block merely orders expressions that are then evaluated on a single thread.
125In Ridgun, **a `||` block with `->` arrows is a parallel-execution Directed Acyclic Graph (DAG)** without even needing extra keywords like `where`:
126```ridgun
127annual report Int => Int
128annual report id = revenue - expenses
129 || compute sales id -> revenue
130 || compute costs id -> expenses
131```
132You draw the dataflow arrows (`->`). The compiler analyzes what depends on what, **statically verifies that you haven't created any infinite dependency cycles**, and launches independent branches in parallel without you writing a single `async`, `await`, `Future`, or `Mutex`.
133
134### 2. Zero-friction Native Agent Model (`agent`) with smart compile-time thread selection
135In other languages, programming with actors or agents forces you to define special classes, implement traits, juggle locks, or infect your functions with `async`.
136In Ridgun, **any ordinary pure function (`fn ::` or `op ::`) turns directly into an autonomous agent—stateless or with isolated state—using `agent`**:
137```ridgun
138serve http (Session, String) => (Session, String)
139...
140server = agent serve http initial_session
141send "GET /profile" to server
142reply = receive from server
143stop server
144```
145Better yet: the compiler **statically analyzes function call depth and computational cost at compile time** across `agent`, `||`, and `||map`. If a function is lightweight, it executes as an instant *green-thread* step without paying OS thread warmup overhead; if it is a heavy or deeply recursive computation, it is automatically dispatched in parallel across real OS kernel threads (`SYS_clone`) over your CPU cores.
146
147### 3. Code as a two-dimensional table where the signature is the column header
148In every other language, the type signature lives on its own line and the function body sits below it like an ordinary paragraph of text.
149In Ridgun, **the type signature is literally the header of a table**, and every clause below aligns each pattern vertically under its type and each `=` under the `=>`:
150```ridgun
151divide Int Int => Option
152divide _ 0 = None
153divide a b = Some (a / b)
154```
155No other language treats the signature and its equations as a single visual matrix verified by the compiler and automatically typeset by `stable format`.
156
157### 4. Typed and aligned N-ary phrase operators (*Mixfix* `op ::`)
158In most languages, you either settle for `+`, `-`, `*` or at best define a cryptic binary operator like `<|>` that nobody can read.
159In Ridgun you can create **operators that read like natural phrases with as many typed slots as you want** (even using contextual words like `type` or `with`):
160```ridgun
161op :: Int clamped between Int and Int => Int
162 x clamped between min and max =
163 | x < min = min
164 | x > max = max
165 | otherwise = x
166```
167And then in your code you write `speed clamped between 0 and 120`. It reads like plain English, yet it is 100% statically typed and compiled to native machine code.
168
169### 5. Visual sequence masks (`s(_ + _)` and `-> (+ _ _ +) ->`)
170Have you ever had to write an index salad like `filter(\(i, x) -> i % 2 == 0)` or unpack a tuple with dummy variables just to keep two specific positions?
171In Ridgun you pass a **visual mask** directly:
172- `data(_ + _)`: drops the first (`_`), keeps the second (`+`), drops the third (`_`).
173- `parse packet "v0.9.9" -> (+ _ _ +) -> combine code -> summary`: filters a 4-element tuple right inside a pipeline and unpacks the 1st and 4th elements directly into the next function.
174Zero index arithmetic, zero *off-by-one* bugs.
175
176### 6. "Zero-noise" polymorphism (`A`..`Z`) governed by your domain
177In Rust, TypeScript, or Java, making a function generic means littering the line with angle brackets: `fn swap<A, B>(pair: (A, B)) -> (B, A)`.
178In Ridgun you simply use a standalone uppercase letter:
179```ridgun
180swap (A, B) => (B, A)
181swap (x, y) = (y, x)
182```
183*"What if I want a real type in my program called `type A`?"* — No problem: in Ridgun **your `type` declarations win**. If `type A` does not exist, `A` is a generic type variable; the instant you define `type A = ...`, it becomes your concrete type across the module.
184
185### 7. Zero foreign configuration files: `build.rg` is pure Ridgun
186Forget learning TOML for Cargo, JSON for npm, XML for Maven, or the arcane tab-sensitive syntax of a `Makefile`. In Ridgun, the recipe that builds your project (`build.rg`) **is just another `.rg` file**, using the exact same pure functions and *pattern matching* as the rest of your code.
187
188### 8. The "Holy Trinity" that seemed impossible: Haskell-level expressiveness + RMM memory without GC or Lifetimes + ~350 KB binaries
189Until today you had to choose:
190- If you wanted pure functional expressiveness (Haskell, OCaml, Elixir), you paid for it with a garbage collector and a heavy runtime.
191- If you wanted tiny GC-free systems binaries (C, Rust, Zig), you paid for it by juggling raw pointers or wrestling with the *borrow checker* while writing imperative code full of `let mut`.
192
193Ridgun breaks that dilemma by combining **Ridgun Memory Management (`RMM`: static `RMM1` and cascading assignment-counted `RMM2`)**, **lexical regions (`with region`)** that free entire arenas in $O(1)$, **tail recursion compiled into native `loop`s**, and **call-graph dead-code elimination (*Tree-Shaking*)** starting from `main`. The result: you write high-level declarative code and get a self-contained **~350 KB** ELF executable ready to go toe-to-toe with tools written in C.
194
195Now that all cards are on the table, let's head to **Chapter 02** and put **`ridgunc`** and **`stable`** to work.