Language
Variables & Types
Variables are declared with let. Types are optional — you can add them for safety or leave them out for flexibility.
Variables
Use let to declare a variable. Reassign it with plain = — no let again:
let name = "Sergio" let count = 20 let active = true count = count + 1 // reassignment name = "Ana" // also fine
Variables declared inside a block { } are invisible outside it. You can still mutate variables from an outer scope:
let total = 0
{
let local = 42 // only lives inside this block
total = local // outer variable — allowed
}
out total // → 42
// out local ❌ ERROR: Variable not found: localConstants
Use const for values that should never change. Any attempt to reassign is an error:
const PI = 3.14159 const MAX = 100 PI = 3.0 // ❌ ERROR: Cannot reassign const 'PI'
Types
Serez Code has five primitive types and several compound types:
| Type | Example | What it is |
|---|---|---|
int | 42, -7, 0 | 64-bit whole number |
decimal | 3.14, 0.5, 2.0 | 64-bit floating point |
bool | true, false | Boolean value |
string | "hello" | UTF-8 text |
null | null | Absence of a value |
any | — | Accepts any value, skips type checks |
void | — | Return type for functions that return nothing |
Type annotations
Add types to function parameters and return values. When present, they're enforced at every call:
fn int add(int a, int b) {
return a + b
}
add(1, 2) // ✅
add(1, "hello") // ❌ TYPE ERROR: Parameter 'b' expected 'int' but received 'string'Skip annotations when you want flexibility — the parameter accepts any value:
fn multiply(a, b) {
return a * b
}
multiply(3, 4) // ✅
multiply(2.5, 4.0) // ✅Nullable types
Append ? to any type to allow null as a valid value:
fn int? findIndex(string target, [string] list) {
for (let i = 0; i < list.length; i++) {
if (list[i] == target) { return i }
}
return null
}
let idx = findIndex("Ana", ["Bob", "Ana", "Lee"])
if (idx != null) {
out "Found at index {idx}" // → Found at index 1
} else {
out "Not found"
}String interpolation
Embed any expression directly inside a string with {}:
let name = "Sergio"
let age = 28
out "My name is {name} and I'm {age} years old."
let result = add(3, 7)
out "3 + 7 = {result}"
// Works with method calls too
out "Upper: {name.toUpperCase()}" // → Upper: SERGIOTip: Use
\{ to write a literal brace inside a string: "Empty dict: \{\}"Operators
Arithmetic
out 10 + 3 // → 13 out 10 - 3 // → 7 out 10 * 3 // → 30 out 10 / 3 // → 3 (integer division, truncates) out 10 % 3 // → 1 (remainder) out 2 ** 10 // → 1024 (power) // int and decimal mix freely out 1 + 0.5 // → 1.5
Comparison & logical
out 5 > 3 // → true out 5 == 5 // → true out 5 != 3 // → true out true && false // → false (AND) out true || false // → true (OR) out !true // → false (NOT)
Compound assignment
let n = 10 n += 5 // n = 15 n -= 3 // n = 12 n *= 2 // n = 24 n /= 4 // n = 6 n++ // n = 7 n-- // n = 6
Ternary
let x = 10 let label = x > 5 ? "big" : "small" out label // → big // Chain them let n = 2 let name = n == 1 ? "one" : n == 2 ? "two" : "other" out name // → two
Null coalescing
let value = null
out value ?? "default" // → default
let maybeNum = findIndex("Ana", names)
let safe = maybeNum ?? -1 // -1 if not foundType check
out 42 is int // → true
out "hi" is int // → false
out 3.14 is decimal // → true
// Useful for functions that accept any
fn string describe(any v) {
if (v is int) { return "int: {v}" }
if (v is string) { return "string: {v}" }
return "other"
}Comments
// Single-line comment /* Multi-line comment */ let x = /* inline */ 42
Type conversions
// String → int
out parseInt("42") // → 42
out parseInt(3.99) // → 3 (truncates)
// String → decimal
out parseDecimal("3.14") // → 3.14
out parseDecimal(5) // → 5.0
// Any type → string
out 42.toString() // → "42"
out true.toString() // → "true"
// Read from stdin
let input = readLine("Enter a number: ")
let num = parseInt(input)