PatLang for Java Programmers
Java trains you to think in classes, static types, and checked exceptions. PatLang has none of the three. This page maps Java habits onto what PatLang actually offers, and is upfront about where the two languages simply don't have an equivalent.
The quick mental model
Think of PatLang as dynamically typed all the way down, with no compile-time type checker at all — the returns hint clause on a function definition is a documentation comment, not a contract the compiler enforces. There's no class, no interfaces, no generics, no access modifiers. In exchange, PatLang gives you an exact numeric tower (no silent int overflow, no float-precision surprises), real logic and goal-planning engines built into the language, and three genuinely interchangeable ways to run the same program: interpreted, compiled to a native executable, or compiled by a self-hosted compiler written in PatLang itself.
Syntax, side by side
// Java
public static int add(int a, int b) {
return a + b;
}
int x = 5;
if (x > 0) {
System.out.println("positive");
} else if (x < 0) {
System.out.println("negative");
} else {
System.out.println("zero");
}
int i = 0;
while (i < 10) {
i++;
}
# 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
No type annotations anywhere — parameters, return values, and variables are all just names. No semicolons required (statements are separated by newlines, semicolons, or a handful of other terminators; see the Statement separators reference). No braces required either: the example above uses the Ruby-style then/do/end form, but a brace form exists too — see the Grammar's compatibility table.
Things Java has that PatLang doesn't
- No static type system at all. No compile-time type errors, no generics, no interfaces, no overloading by parameter type. Everything is checked, if at all, at runtime.
- No classes, no inheritance, no access modifiers. See the object model section below.
- No checked exceptions, no
try/catchat all. A failing host call (a bad file path, a refused connection) is fatal to the entire program — there is no way to catch it and recover. This is a real, deliberate limitation, not an oversight: it shapes how PatLang programs are structured (avoid the failure rather than handle it after the fact) and is one of the more surprising things for anyone arriving from an exception-heavy language. - No
forloop, nobreak/continue. Onlywhile; structure early-exit logic with a boolean flag instead. - No packages, no visibility modifiers. Splitting code across files is one mechanism —
include "relative/path.patlang"— with no namespacing at all; everything included ends up in one flat scope.
Objects, without a class system
Where Java gives you class, constructors, fields, and methods with real dispatch, PatLang gives you four host functions operating on a shared, string-keyed store:
let acct = new("Account")
set_var(acct, "balance", 100)
send(acct, "deposit", [50])
print(get(acct, "balance"))
There is no inheritance, no interfaces, no method overriding, and send's only genuinely dispatched verb today is "set" — this is intentionally minimal, "a thin, inspectable layer over the same object store everything else uses, rather than a parallel type system" (the Paradigms Guide's own framing). If your instinct coming from Java is "this needs a class," the PatLang instinct is closer to "this needs a named object in the store plus some plain functions that operate on it."
Numbers are exact, not int/long/double
Java forces you to pick a numeric type up front and live with its overflow/precision behaviour (a silently-wrapped int, a lossy double). PatLang has one numeric "type" from the programmer's point of view — plain digits — and promotes automatically and exactly: an int-shaped value that overflows becomes an arbitrary-precision BigInt rather than wrapping; 7 / 2 is the exact fraction 7/2 (a Rational), never a truncated 3 and never a lossy 3.5; sqrt of a negative number promotes to Complex rather than throwing. See the Numeric Tower section — this is one of the first things that will surprise a Java programmer testing integer division.
What PatLang has that Java doesn't
- Real logic programming, built in.
rule_add/solveis genuine Prolog-style backward-chaining resolution with backtracking — no external rules-engine dependency needed. - Real goal-oriented action planning (GOAP).
action_add/planfinds a genuinely cost-optimal ordered sequence of actions via forward search — the technique behind a lot of game AI, available as two function calls rather than a library you'd have to integrate. - Runtime signals with no message broker, no Kafka, no separate process manager. A running program answers a named signal from a second CLI invocation or a local network call directly — see the signals demo.
- A compiler you can read and modify without leaving the language. PatLang's own compiler is written in PatLang and compiles itself — a genuine self-hosting fixpoint, unlike the JVM/javac split.
- Design by contract as real language grammar (
require/ensure/assert), not annotations bolted on via a separate framework like JML.
See the build daemon exemplar for several of these working together in one real program.
See also
Grammar & Syntax for the full, precise rules. Paradigms Guide for depth on every capability mentioned above. Capabilities & Honest Limitations for a direct list of what's missing. If you know another language too, see PatLang for Python Programmers, PatLang for Ruby Programmers, or PatLang for C Programmers.