Variables & Constants
Every program needs to store data. GX gives you two tools: var for values that change, and const for values that don’t.
Variables with Type Inference
GX can figure out the type from the value you assign:
fn main() {
var x = 10 // i32 (integer)
var pi = 3.14 // f32 (float)
var name = "Alice" // str (string)
var alive = true // bool
print("x = {x}\n")
print("pi = {pi}\n")
print("name = {name}\n")
print("alive = {alive}\n")
}
The compiler sees 10 and knows it’s an i32. Sees 3.14 and knows it’s an f32. You don’t have to spell it out.
Explicit Types
Sometimes you want to be specific:
fn main() {
var x:i32 = 100
var y:f64 = 3.14159265358979
var big:i64 = 9999999999
var name:str = "GX"
print("x = {x}\n")
print("y = {y}\n")
print("big = {big}\n")
print("name = {name}\n")
}
The type comes right after the variable name with a colon: var x:i32. No space needed (though you can add one if you prefer).
Reassignment
Variables declared with var can be changed:
fn main() {
var score = 0
print("Score: {score}\n")
score = 100
print("Score: {score}\n")
score = score + 50
print("Score: {score}\n")
}
Constants
Use const for values that should never change:
const MAX_PLAYERS = 64
const PI = 3.14159265358979
const GAME_TITLE = "Space Blaster"
fn main() {
print("Title: {GAME_TITLE}\n")
print("Max players: {MAX_PLAYERS}\n")
print("PI = {PI}\n")
}
Constants can also have explicit types:
const MAX_HEALTH:i32 = 100
const GRAVITY:f64 = 9.80665
Try to assign to a constant and the compiler will stop you:
const X = 10
fn main() {
X = 20 // Error: Cannot assign to constant
}
Constants Build on Constants
Constants can reference other constants — the compiler evaluates everything at compile time:
const WIDTH = 1920
const HEIGHT = 1080
const AREA = WIDTH * HEIGHT
const HALF_WIDTH = WIDTH / 2
fn main() {
print("Resolution: {WIDTH}x{HEIGHT}\n")
print("Area: {AREA}\n")
print("Half width: {HALF_WIDTH}\n")
}
The generated code contains the final numbers (2073600, 960) — no multiplication happens at runtime.
Try it — Define your own constants and use them in the Playground.
Local Constants
Constants work inside functions too:
fn main() {
const LIMIT = 5
for (i = 0:LIMIT) {
print("{i} ")
}
print("\n")
}
Expert Corner
Constant folding is not just a convenience — the compiler has a full constant evaluator that handles arithmetic, bitwise ops, comparisons, unary operators, and references to other constants. When you write const TAU = PI * 2.0, the compiler computes 6.28318... and emits the literal value in the generated C. Zero runtime cost.
Why var is mutable by default: GX takes the pragmatic approach. Most local variables get modified (loop counters, accumulators, state). Making mutability the default avoids the let mut ceremony of Rust or the const everywhere pattern of modern C++. If you want immutability, use const — it’s one word and it’s enforced.
Global constants emit as static const in C, which avoids multiple-definition errors across translation units. Local constants emit as const — the C compiler can further optimize them away entirely.