PatLang for Ruby Programmers
Of the four languages covered in this series, Ruby is the closest relative — PatLang's do/end blocks and word-form keywords are a deliberate nod to Ruby's own readability-first syntax, and PatLang even ships a working Ruby transpiler as a self-hosted portfolio demo. But the resemblance is skin-deep in places that matter: no classes, no blocks-as-values, no method_missing, and a very different relationship with metaprogramming.
The quick mental model
If Ruby's whole philosophy is "everything is an object, and objects can redefine how they respond to messages," PatLang's is closer to "everything is a value, and a small set of host functions gives you object-shaped mutable state when you actually want it." Ruby's flexibility comes from a rich, late-bound object model; PatLang's comes from real logic and goal-planning engines built into the language, and from a genuine runtime-extensible syntax mechanism that plays a similar role to Ruby's metaprogramming without touching the object model at all.
Syntax, side by side
# Ruby
def add(a, b)
a + b
end
x = 5
if x > 0
puts "positive"
elsif x < 0
puts "negative"
else
puts "zero"
end
i = 0
while i < 10
i += 1
end
# PatLang
make a function called add takes a, b returns sum
return a + b
end
let x = 5
if x > 0 then
print("positive")
elif x < 0 then
print("negative")
else
print("zero")
end
let i = 0
while i < 10 do
let i = i + 1
end
The family resemblance is real — do/end, word-form elif instead of elsif, no braces required — but PatLang requires an explicit return (Ruby's implicit last-expression return doesn't apply) and requires parentheses on calls like print(...) where Ruby would let you drop them.
Things Ruby has that PatLang doesn't
- No classes, no modules, no mixins, no
method_missing. See the object model section below — PatLang's answer to "give me object-shaped state" is much smaller and much less dynamic than Ruby's. - No blocks as a language feature (
{ |x| ... }/do |x| ... endpassed implicitly to a method and invoked withyield). PatLang has closures (|x| { x + 1 }) as ordinary first-class values you pass explicitly — powerful, but a different mechanism with noyield-style implicit block. - No string interpolation (Ruby's
"#{x}"). Build strings with+concatenation; double-quoted strings support only\n \t \r \" \\escapes. - No
for/each/times/map-as-a-loop-construct, nobreak/next. Onlywhile. Ruby's whole enumerable-and-block iteration idiom doesn't have a direct equivalent — you write the loop and index yourself, or reach for the handle-based collection functions. - No exceptions (
begin/rescue/raise). A failing host call is fatal to the whole program; there's no way to catch and recover. - No open classes, no monkey-patching, no true metaprogramming in the Ruby sense (defining methods dynamically, reflecting on and modifying the object model at runtime). PatLang's nearest equivalent — genuinely extending what the language itself understands — is the syntax DSL mechanism below, which works at the grammar level, not the object model.
Objects, without Ruby's object model
Where Ruby gives you class, attr_accessor, inheritance, mixins, and a fully open, redefinable method-dispatch system, PatLang gives you four host functions over a shared, string-keyed store:
let acct = new("Account")
set_var(acct, "balance", 100)
send(acct, "deposit", [50])
print(get(acct, "balance"))
There's no inheritance, no method_missing-style dynamic dispatch, and send's only genuinely dispatched verb today is "set" — a deliberately thin, inspectable layer, not Ruby's rich runtime-malleable object system reimplemented. If your Ruby instinct is to open a class and add a method, the PatLang instinct is closer to writing an ordinary function that takes the object's name as its first argument.
Runtime-extensible syntax instead of metaprogramming
Ruby programmers reach for metaprogramming — define_method, method_missing, DSL gems built on blocks — to make code read like the problem domain. PatLang's equivalent lives one level up, in the grammar itself: syntax NAME { ... } blocks genuinely extend what the parser understands, expanded at runtime before the ordinary lexer/parser ever sees the result. See the router DSL demo and the dynamic syntax demo — it's a different mechanism solving a similar "make this read naturally" problem, working on source text rather than on the object model.
Numbers are exact, not float-by-default
Ruby's / on two integers truncates (7 / 2 == 3) unless you explicitly use floats. PatLang's / on two integers that don't divide evenly produces the exact fraction — 7 / 2 is the Rational 7/2, never a truncated 3 and never a lossy 3.5. Integer overflow promotes automatically to an arbitrary-precision BigInt (closer to Ruby's own automatic Integer/Bignum unification than to C-family wraparound), and sqrt of a negative number promotes to Complex rather than raising. See the Numeric Tower section.
What PatLang has that Ruby doesn't
- Real logic programming, built in.
rule_add/solveis genuine Prolog-style backward-chaining resolution with backtracking — no external gem needed. - Real goal-oriented action planning (GOAP).
action_add/planfinds a genuinely cost-optimal ordered plan via forward search over actions with preconditions/effects/cost. - Real, verified parallelism. Ruby's MRI has a GIL limiting true parallel threading; PatLang's
parallel_mapspawns genuine OS threads with real concurrent execution, verified cross-thread-safe. - Runtime signals with no external process/IPC library. A running program answers a named signal from a second CLI invocation or a local network call directly — see the signals demo.
- Design by contract as real grammar (
require/ensure/assert), closer to Eiffel than to a Ruby gem. - A self-hosting compiler you can read. PatLang's own compiler is written in PatLang and compiles itself — genuinely legible in a way MRI's C internals aren't to most Ruby programmers.
See the build daemon exemplar for several of these working together in one real program, and the Ruby transpilation demo for the other direction — PatLang's own AST translated into idiomatic Ruby.
See also
Grammar & Syntax for the full, precise rules. Paradigms Guide for depth on every capability mentioned above. If you know another language too, see PatLang for Python Programmers, PatLang for Java Programmers, or PatLang for C Programmers.