Renderingen-US

The Faber language

Everything you need to read Faber is on this page. The pages beneath it go deeper on each part, but nothing here is a placeholder — if you read this far and stop, you can read a Faber program.

A whole program#

fn saturate(int x) → int {
    if x ≺ 0 then return 0
    if x ≻ 255 then return 255
    return x
}

main {
    const int v ← saturate(300)
    print v
}

That is a complete, compilable package entry point. Reading it left to right:

PieceWhat it is
fndeclares a function
int xthe type comes before the name — always, everywhere
→ intthe return type
if … thena compact single-branch conditional
returnreturn
mainthe program entry point
constan immutable binding (var is the mutable one)
←bind this value to that name
printprint

Type before name, always#

This is the single rule that makes the rest of the grammar small:

main {
    # a declaration
    const int count ← 0
    # another
    const string name ← "Marcus"
    # a generic
    const list<int> scores ← [1, 2, 3]
    # a nullable
    const int ∪ none maybe ← null
    print count, name, scores, maybe
}

There is no name: type form to learn. A declaration is a type followed by a name, whether it is a parameter, a local, or a field. Bindings come in three words: const is write-once, var is freely reassignable, and let is the concise inferred immutable. See Types and values.

Six glyphs, and what they mean#

Faber uses a small fixed set of symbols for structure. They never localize — they are the same in every reader locale, which is what keeps a program recognizable across languages.

GlyphMeaning
←bind a value to a name
→function return type
∪union type, most often T ∪ none for nullable
⇥alternate exit — the error channel
∴closure joint, connecting a signature to its body
≡equality

Two more appear when you convert between types: ∷ for a compile-time ascription and ↦ for a runtime conversion that can fail. Full table in Glyphs and Latin.

The words you write, and the compiler's Latin#

The words in the program above — fn, if, return, const, int — are the spellings an English reader writes; every page on this site teaches the English reader surface. Latin is the compiler's canonical form: the identity key programs are stored and exchanged under. faber convert --to la prints any program in that canonical spelling, and reader locales render the same program in seven other languages. The glyphs and the type-first shape survive every rendering untouched — and identifiers like saturate are never translated.

Where the rest lives#

PageWhat it covers
Types and valuesprimitives, collections, strings, nullability, conversion, bindings
Functions and control flowparameters, returns, branching, loops, generics
Errors and testingthe ⇥ error channel, and inline describe/test/assert suites
Glyphs and Latinthe full glyph table, vocabulary rationale, canonical vs sugar
Reader localeshow one program renders in eight surfaces
Capabilities and framescall dispatch and the host I/O boundary