Prism’s syntax is designed to be readable at a glance and unambiguous to parse. There is no significant whitespace, no macros hiding syntax, and no operator overloading beyond what the standard library defines.
Bindings
let creates an immutable binding. Types are inferred but always explicit in intent:
let name = "prism" // str
let port: int = 8080 // annotated
let mut retries = 0 // mutable
Functions
Functions are declared with fn. Parameters are typed; return types come after an arrow:
fn add(a: int, b: int) -> int {
return a + b
}
Returns are explicit — use the return keyword:
fn clamp(value: int, lo: int, hi: int) -> int {
if value < lo { return lo }
if value > hi { return hi }
return value
}
Control flow
if is a statement, not an expression:
let mut status = "busy"
if ok { status = "ready" }
match is exhaustive — the compiler rejects a match that does not cover every case:
match http_code {
200 => println("ok"),
404 => println("not found"),
_ => println("unexpected: " + int_to_str(http_code)),
}
Structs and enums
struct User {
name: str,
admin: bool
}
enum Platform {
Windows,
Linux,
MacOS,
Unknown(str)
}
Everything is a module
Files map to modules by path. src/net/http.prism is net.http. There is no separate module
declaration and no include guard — the path is the identity, which keeps resolution deterministic.
Conventions
- 4-space indentation. The formatter enforces it; the language server reformats anything that disagrees on save.
- Named types are
UpperCamelCase; builtin value types (str,int,bool) are lowercase. Functions and variables aresnake_case. Constants areSCREAMING_SNAKE_CASE. - Errors are returned, not thrown. Builtins that can fail return a status code or a value you check explicitly.
Note: the language server applies these conventions live. If you type in a supported editor, formatting runs on save automatically.
Next: Functions.