Syntax overview
This page explains the canonical surface of Draton as it exists in the repository today. It is the fastest way to understand how Draton code is meant to look.
For design intent, see language-manifesto. For hard style rules, see canonical syntax rules.
If you need the full parser-facing syntax broken down by category, use the syntax reference.
The organizing rule
Draton is easiest to read when each surface layer stays in its own place:
- executable code expresses behavior
@typeexpresses contracts- class and layer structure express organization
That is why the language rejects the idea that every declaration should carry inline type noise.
Variables
Canonical variable bindings use let:
let count = 0
let name = "Draton"
let items = [1, 2, 3]
Mutable bindings still start from the same surface:
let mut total = 0
Not canonical:
let total: Int = 0
If a binding needs an explicit contract, the canonical place is a type block:
@type {
total: Int
}
Functions
Executable functions keep parameter lists visually light:
@type {
add: (Int, Int) -> Int
}
fn add(a, b) {
return a + b
}
Canonical function rules:
- parameter names are not typed inline in executable definitions
- explicit
returnremains the canonical control-flow style - contracts belong in
@type
Imports
Draton uses brace imports as the one canonical import form:
import { read_line } from std.io
import { http as nethttp } from std.net
Imports are meant to be readable and explicit at the top of a file.
Contracts with @type
@type blocks are the contract surface of the language:
@type {
greet: (String) -> String
retries: Int
}
They are supported at multiple scopes:
- file scope
- class scope
- layer scope
- interface scope
- function scope
The goal is precision without turning ordinary executable code into annotation-heavy markup.
Classes and layers
The structural model is not “all methods in one flat bag”. Draton splits structure from capability grouping:
class User {
let name
layer display {
fn greeting() {
return f"hello {name}"
}
}
@type {
name: String
greeting: () -> String
}
}
Read it like this:
classanswers what the thing islayeranswers what related capability this part of the class provides
Control flow
Draton prefers visible control flow:
fn choose(flag) {
if flag {
return "yes"
}
return "no"
}
The language deliberately avoids making an implicit-return-only style canonical.
System builtins
Core interactive system builtins remain explicit and minimal:
print("working...")
println("done")
let name = input("Name: ")
Current input semantics:
input("Prompt: ")is a builtin, not a library import- it prints the prompt without a newline
- it reads one line from stdin
- it trims trailing line endings
- it returns a
String
Compatibility syntax
Compatibility syntax still exists for migration support, but it is not a co-equal design direction.
Strict mode exists to stop syntax drift:
drat build --strict-syntax
drat run --strict-syntax
When writing new examples, docs, tests, or migrated self-host code, stay on the canonical surface.
Full syntax reference
For complete syntax coverage, continue with:
- Syntax reference index
- Literals and values
- Bindings and assignment
- Functions, calls, and lambdas
- Expressions and operators
- Control flow and pattern matching
- Top-level items and modules
- Types and contracts
- Classes, interfaces, enums, and errors
- Concurrency and channels
- Low-level and compile-time syntax