Variables and Constants¶
Language: Español | English
In Crespi, you can store values using mutable variables or immutable constants.
Variables¶
Use var to declare values that can change:
var name = "Ana"
var age = 25
var active = true
print(name) // Ana
print(age) // 25
Reassignment¶
Variables can change their value at any time:
var counter = 0
print(counter) // 0
counter = 1
print(counter) // 1
counter = counter + 1
print(counter) // 2
Type Inference¶
When the optional static type checker runs, Crespi uses type inference to determine variable types from their initial values:
var x = 42 // inferred as Int
var y = "hello" // inferred as String
var z = [1, 2, 3] // inferred as List[Int]
// You can also add explicit type annotations
var count: Int = 0
var name: String = "Alice"
With the checker enabled, a variable's inferred or annotated type must remain consistent. Without it, reassignment can use any type at runtime.
Constants¶
Use let for values that should not change:
let PI = 3.14159
let MAX_ATTEMPTS = 3
let APP_NAME = "My Application"
print(PI) // 3.14159
Note: PI and E are built-in constants. In native-compiled code they are lowered to pi() and e() built-ins.
Immutability¶
Attempting to reassign a constant produces an error:
let LIMIT = 100
// LIMIT = 200 // Error: cannot reassign a let constant
let also freezes collections. Lists and dictionaries bound to let cannot be mutated (no index assignment, push, or pop), and tuples are always immutable:
let ids = [1, 2, 3]
// ids[0] = 9 // Error: cannot modify a let list
// ids.push(4) // Error: cannot modify a let list
let profile = { "name": "Ana" }
// profile["name"] = "Bea" // Error: cannot modify a let dictionary
When to Use Constants¶
Use constants for: - Mathematical values (PI, E) - Fixed configurations - Threshold or limit values - Any value that should not change
let GRAVITY = 9.81
let TAX_RATE = 0.21
let DAYS_PER_WEEK = 7
fn calculate_weight(mass) {
return mass * GRAVITY
}
fn calculate_price_with_tax(price) {
return price * (1 + TAX_RATE)
}
Assignment Operators¶
Simple Assignment¶
var x = 10
Compound Assignment¶
Crespi supports compound assignment operators:
| Operator | Equivalent | Description |
|---|---|---|
+= |
x = x + value |
Add and assign |
-= |
x = x - value |
Subtract and assign |
*= |
x = x * value |
Multiply and assign |
/= |
x = x / value |
Divide and assign |
var points = 100
points += 50 // points = 150
print(points) // 150
points -= 30 // points = 120
print(points) // 120
points *= 2 // points = 240
print(points) // 240
points /= 4 // points = 60
print(points) // 60
Use in Loops¶
Compound operators are useful in loops:
var sum = 0
var numbers = [1, 2, 3, 4, 5]
for n in numbers {
sum += n
}
print(sum) // 15
Variable Scope¶
Variables have lexical scope. A variable declared inside a block only exists in that block:
var global = "I am global"
if true {
var local = "I am local"
print(local) // OK: I am local
print(global) // OK: I am global
}
print(global) // OK: I am global
// print(local) // Error: undefined variable
Shadowing¶
An inner variable can "shadow" an outer one with the same name:
var x = 10
if true {
var x = 20 // New variable, shadows outer
print(x) // 20
}
print(x) // 10 (original unchanged)
Closures¶
Functions capture variables from their environment:
var factor = 2
fn multiply(x) {
return x * factor // Uses 'factor' from outer scope
}
print(multiply(5)) // 10
factor = 3
print(multiply(5)) // 15 (uses new value)
Naming Conventions¶
- Use
camelCasefor both variables and constants so naming stays consistent. - Choose descriptive names that indicate an identifier's purpose.
var userName = "ana123"
let maxAttempts = 3
let connectionTimeout = 30
Initialization¶
With Literal Value¶
var integer = 42
var decimal = 3.14
var text = "Hello"
var boolean = true
var list = [1, 2, 3]
var dictionary = {"key": "value"}
With Expression¶
var sum = 10 + 20
var len = "Hello World".length()
var doubled = [1, 2, 3][0] * 2
With Function Result¶
fn calculate() {
return 42
}
var result = calculate()
print(result) // 42
With Null Value¶
var pending = null
// Later...
pending = fetch_data()
Practical Examples¶
Counter¶
var counter = 0
fn increment() {
counter += 1
}
fn get() {
return counter
}
increment()
increment()
increment()
print(get()) // 3
Accumulator¶
var total = 0
var prices = [10.50, 25.00, 8.75, 12.25]
for price in prices {
total += price
}
print("Total: " + str(total)) // Total: 56.5
Value Swap¶
var a = 10
var b = 20
// Swap using temporary variable
var temp = a
a = b
b = temp
print(a) // 20
print(b) // 10
Visibility¶
Top-level declarations (variables, constants, functions, and classes) can use visibility modifiers to control how they are accessed from other modules:
public(default): Accessible from any other module.internal: Accessible only from modules in the same directory.fileprivate: Accessible only from within the same file.private: Same asfileprivate(for backward compatibility).
public var siteName = "Crespi"
internal var localCount = 0
fileprivate fn helper() { ... }