Design Philosophy
Goblin is built around a simple belief:
Code should communicate intent.
Programming languages are often obsessed with mechanisms. They teach you how to build things from lower-level pieces, but they rarely help you express what you're actually trying to accomplish.
Goblin takes a different approach.
When an operation is common, meaningful, and easy to describe in plain language, Goblin tries to make that operation a first-class citizen of the language.
The goal is not to create the shortest code possible.
The goal is to create code that says what it means.
Code as Communication
Programs are read far more often than they are written.
Most developers spend more time understanding existing code than creating new code. Future-you is no different.
Goblin is designed so that code reads like a clear description of intent.
Instead of:
const selected = enemies .sort(() => Math.random() - 0.5) .slice(0, 3);
const selected = enemies .sort(() => Math.random() - 0.5) .slice(0, 3);
Goblin allows:
selected | pick 3 from enemies
selected | pick 3 from enemies
The operation is obvious.
You are picking three enemies.
No implementation details are required to understand the goal.
Intent Over Mechanism
Many languages force programmers to describe every mechanical step required to achieve a result.
Goblin prefers to describe the result itself.
For example, generating a collection of values:
rolls | collect 10 of roll 1d20
rolls | collect 10 of roll 1d20
Produces:
[18, 7, 3, 2, 9, 7, 8, 2, 2, 12]
[18, 7, 3, 2, 9, 7, 8, 2, 2, 12]
The programmer's intent is:
Roll a d20 ten times and give me the results.
Compare that to:
roll 10d20
roll 10d20
Which produces:
119 /// or some other sum of 10 20-sided dice
119 /// or some other sum of 10 20-sided dice
In this case, Goblin treats the roll as a single operation and returns the total.
Without collect, generating ten individual results becomes:
rolls | [] repeat 10 value | roll 1d20 :put_last!(rolls, value) xx
rolls | [] repeat 10 value | roll 1d20 :put_last!(rolls, value) xx
Both versions work.
The second describes the mechanism.
The first describes the intent.
Goblin favors the first whenever possible.
Safe by Default
Goblin attempts to eliminate common mistakes before they become bugs.
Unknown names are errors.
Invalid operations are errors.
Type mismatches are errors.
Goblin would rather stop and explain the problem than silently continue with incorrect behavior.
name | "Dan" say naem
name | "Dan" say naem
Produces an error rather than guessing what you meant.
Goblin v0.45.2 — type 'exit'/'quit' or press Ctrl+Z (Windows) to exit gbln(1): name | "Dan" gbln(2): naem error: R0101: unknown-ident: unknown identifier naem ┌─ <repl>:1:1 = help: Declare the variable before use or check the spelling. = link: https://goblinlang.org/docs/errors#R0101
Goblin v0.45.2 — type 'exit'/'quit' or press Ctrl+Z (Windows) to exit gbln(1): name | "Dan" gbln(2): naem error: R0101: unknown-ident: unknown identifier naem ┌─ <repl>:1:1 = help: Declare the variable before use or check the spelling. = link: https://goblinlang.org/docs/errors#R0101
The goal is not to restrict programmers.
The goal is to make mistakes obvious.
Consistency Matters
A language should not require dozens of ways to express the same idea.
Goblin favors consistent vocabulary across the entire language.
If something can be:
pick collect pack unpack update delete
pick collect pack unpack update delete
then that same pattern should appear everywhere it makes sense.
This reduces memorization and makes new features easier to learn.
Once you understand a pattern, you can usually predict how related features behave.
Practical Batteries
Goblin is designed for real projects.
It includes built-in support for many operations that developers repeatedly need:
roll 2d6+3
roll 2d6+3
pick 5 from goblins
pick 5 from goblins
price | $19.99
price | $19.99
tax | 8.25% of subtotal
tax | 8.25% of subtotal
data | :read_json("config.json")
data | :read_json("config.json")
Instead of forcing developers to hunt for external libraries for common tasks, Goblin attempts to provide sensible tools out of the box.
Programming Should Be Fun
Programming is difficult.
The language should not make it harder.
Goblin embraces a sense of personality.
You will find goblins, treasure, dice, glams, hoards, and occasional jokes throughout the language and documentation.
This is not because Goblin is unserious.
It is because software can be serious without being sterile.
Programming should be enjoyable.
The Goblin Way
Goblin is not trying to be the fastest language.
It is not trying to be the most academic language.
It is not trying to be the most minimal language.
Goblin aims to be:
- Readable
- Consistent
- Practical
- Safe
- Expressive
- Fun
The language exists to help developers communicate ideas clearly.
When reading Goblin code, the reader should spend less time decoding syntax and more time understanding the problem being solved.
That is the Goblin way.
Who These Docs Are For
These docs are written for two audiences.
New Programmers
If you are new to programming, the documentation explains both the programming concept and the Goblin syntax.
You do not need prior experience.
The documentation is designed to teach programming through Goblin.
Experienced Developers
If you already know how to program, the documentation respects your time.
Examples are plentiful.
Reference pages are concise.
Most concepts can be learned quickly by scanning examples and comparisons.
One Set of Docs
Goblin does not maintain separate beginner and advanced documentation.
Instead, concepts are introduced progressively.
Beginners can learn the fundamentals.
Experienced developers can jump directly to the information they need.