Type System
Six built-in types. Strict rules. Compile-time safety. Here's how Dorpn's static type system works, from annotations to the underlying C memory model.
Core Types
Dorpn has four primary types, plus 32-bit counterparts for the two numeric ones — six built-in types in total.
Purpose: Whole numbers (positive, negative, or zero)
Characteristics: 64-bit signed integer, no decimal point
Examples: 42, -100, 0, 1_000_000
Purpose: The 32-bit counterpart to Int — a whole number with a smaller
memory footprint
Characteristics: 32-bit signed integer; must be declared explicitly with
:Int32 — never inferred from a bare literal
Examples: tag id :Int32 = 1000
Purpose: Decimal numbers and scientific notation
Characteristics: Double-precision floating point, includes decimal point
Examples: 3.14, -2.5, 0.0, 1.23e-4
Purpose: The 32-bit counterpart to Float — single-precision, smaller memory
footprint
Characteristics: 32-bit floating point; must be declared explicitly with
:Float32 — never inferred from a bare literal
Examples: tag ratio :Float32 = 1.5
Purpose: Text data and character sequences
Characteristics: UTF-8 encoded, mutable via methods, automatic memory management
Examples: "hello", "Line 1\nLine 2", "" (empty)
Purpose: Logical/boolean values
Characteristics: Binary true/false state, used in conditions and logic
Values: Only true or false (case-sensitive)
Bool32/String32 variants. They were removed in v0.4.1 — Bool and
String are the only boolean/text types now. See the Changelog for details.
Key Rules Summary
Case sensitivity
Int, Int32, Float, Float32,
String, Bool
int, int32, FLOAT, float32,
string, BOOL
Type annotations (optional)
You can optionally specify types explicitly (case-sensitive). The 32-bit variants are always written explicitly — there's no shorthand for them:
tag score: Int = 100
tag userId: Int32 = 20481
tag temperature: Float = 36.6
tag ratio: Float32 = 1.5
tag greeting: String = "Hello"
tag is_ready: Bool = false
Type inference
Dorpn automatically infers types from values when no annotation is given:
- Literal numbers without a decimal point →
Int - Literal numbers with a decimal point →
Float - Text in quotes →
String true/false→Bool
tag x = 10 # Inferred as Int
tag y = 3.14 # Inferred as Float
tag z = "text" # Inferred as String
tag flag = true # Inferred as Bool
Int or Float. If
you want the 32-bit variant, you must annotate it explicitly — tag x: Int32 = 10, not
tag x = 10.
Type Safety & Promotion
Once declared or inferred, a variable's type cannot change. Mixed numeric operations promote Int
to Float; combining any value with a String via + converts it to a
string.
Numeric types working together
tag a = 5 # Int
tag b = 5.0 # Float
tag c = a + b # Result: Float (10.0)
# Int and Float can work together
tag result = a * b # Float (25.0)
Type safety violations
tag x: Int = "hello" # ERROR: Type mismatch!
tag y = 10
y = 3.14 # ERROR: Int cannot become Float!
tag z: Int32 = 10
z = 10 # ERROR: Int cannot become Int32 — types must match exactly!
| Rule | Behavior |
|---|---|
Division (/) |
Always returns Float |
Floor division (fld) |
Always returns Int |
Exponentiation (**) |
Always returns Float |
| String concatenation | Uses the + operator |
| String manipulation | Uses .method() calls |
Memory & Performance Notes
Every Dorpn type maps directly onto a native C type in the generated code — this is what gives Dorpn its performance profile. The 32-bit variants exist specifically to halve the footprint of the numeric types when you don't need the full 64-bit range or double precision.
| Dorpn Type | C Representation | Size |
|---|---|---|
Int |
long long |
8 bytes |
Int32 |
int32_t |
4 bytes |
Float |
double |
8 bytes |
Float32 |
float |
4 bytes |
String |
char* |
heap allocated, manually managed |
Bool |
bool |
1 byte |
32-bit Variants — When to Use Them
Reach for Int32 / Float32 over the default Int / Float
when you're working with large arrays of numbers and want to cut memory usage in half, matching a fixed-width
format from another system, or optimizing for cache/word-alignment in performance-sensitive code. For everyday
variables, the default 64-bit Int and Float remain the simplest choice.
tag a :Int = 1000
tag b :Int32 = 1000
tag c :Float = 3.141592
tag d :Float32 = 3.141592
print(type(a), type(b))
print(type(c), type(d))
Bool32 and String32 were deprecated in earlier
pre-releases and have now been fully removed from the lexer, parser, and type system —
using either name now correctly fails to compile with a clear error, instead of silently continuing.
Replace Bool32 with Bool and String32 with String.
Int32 and Float32 are not affected and remain valid 32-bit
types.
