Variables

Variables store values that can be used throughout your program.

Variable Declaration

Basic Declaration

let name = "JOEL"
let age = 24
let active = true

With Type Annotation

let name: str = "JOEL"
let age: i32 = 24
let active: bool = true

Variable Types

Mutable Variables

let x = 10
x = 20  # Reassignment (coming soon)

Constants

const PI: f64 = 3.14159
const MAX_SIZE: i32 = 100
const APP_NAME: str = "JOEL"

Constants cannot be reassigned and must have type annotations.

Variable Scope

Global Scope

let global = "I'm global"

fn main() {
  print(global)  # Can access global
}

Local Scope

fn example() {
  let local = "I'm local"
  print(local)  # Can access local
}

# print(local)  # Error: local not in scope

Block Scope

if true {
  let block_var = "I'm in a block"
  print(block_var)  # Can access
}
# print(block_var)  # Error: not in scope

Variable Naming

Rules

  • Must start with a letter or underscore
  • Can contain letters, numbers, and underscores
  • Case-sensitive
  • Cannot be a keyword

Valid Names

let name = "JOEL"
let user_name = "alice"
let _private = "hidden"
let count123 = 42

Invalid Names

# let 123count = 42      # Error: starts with number
# let user-name = "alice" # Error: contains hyphen
# let let = "keyword"     # Error: reserved keyword

Naming Conventions

  • Variables: snake_case (e.g., user_name)
  • Constants: UPPER_SNAKE_CASE (e.g., MAX_SIZE)
  • Functions: snake_case (e.g., calculate_total)

Variable Initialization

Immediate Initialization

let x = 10  # Initialized immediately

Deferred Initialization

# Coming soon
let x: i32
# ... later ...
x = 10

Multiple Variables

Separate Declarations

let x = 10
let y = 20
let z = 30

Tuple Destructuring

# Coming soon
let (x, y, z) = (10, 20, 30)

Shadowing

let x = 10
if true {
  let x = 20  # Shadows outer x
  print(x)    # Prints 20
}
print(x)      # Prints 10

Examples

Basic Usage

let name = "Alice"
let age = 25
let score = 95.5

print("Name:", name)
print("Age:", age)
print("Score:", score)

Constants

const TAX_RATE: f64 = 0.08
const MAX_USERS: i32 = 1000

fn calculate_tax(amount: f64) -> f64 {
  return amount * TAX_RATE
}

Scope Example

let global = "global"

fn example() {
  let local = "local"
  print(global)  # OK
  print(local)   # OK
}

print(global)  # OK
# print(local)  # Error

Best Practices

  1. Use descriptive names: user_count not uc
  2. Use constants for magic numbers: const MAX_SIZE = 100
  3. Initialize variables: Always give variables a value
  4. Use type annotations: Especially in compiled mode
  5. Keep scope minimal: Declare variables close to use

Next Steps