Skip to content

Variables

Tova takes a clear stance on mutability: variables are immutable by default. If you want a variable that can change, you opt in explicitly with var. This makes your code easier to reason about and helps prevent accidental mutations.

Immutable Variables

A plain assignment creates an immutable binding. Once set, it cannot be reassigned:

tova
name = "Alice"
age = 30
pi = 3.14159

Attempting to reassign an immutable variable produces a compile-time error:

tova
name = "Alice"
name = "Bob"    // Error: cannot reassign immutable variable 'name'

Mutable Variables

Use var when you need a variable that can change over time:

tova
var count = 0
count += 1        // OK
count = count + 5 // OK

var name = "Alice"
name = "Bob"      // OK — var allows reassignment

Mutable variables support all compound assignment operators:

tova
var x = 10
x += 5    // x is now 15
x -= 3    // x is now 12
x *= 2    // x is now 24
x /= 4    // x is now 6
Try "Variables" in Playground

Multiple Assignment

Tova supports assigning multiple variables in a single statement:

tova
a, b = 1, 2
x, y, z = "hello", true, 42

This is particularly handy for swapping values without a temporary variable:

tova
var a = 1
var b = 2
a, b = b, a   // a is now 2, b is now 1

Destructuring

Destructuring pulls values out of objects and arrays into individual variables. No keyword prefix is needed -- just write the pattern on the left side of the assignment.

TIP

Tova does not use let for destructuring or for anything else. Use plain x = 10 for immutable bindings, var x = 10 for mutable ones, and { a, b } = obj for destructuring.

Object Destructuring

Extract fields from an object by name:

tova
person = { name: "Alice", age: 30, email: "alice@example.com" }

{ name, age } = person
print(name)   // "Alice"
print(age)    // 30

You can rename the bindings:

tova
{ name: userName, age: userAge } = person
print(userName)   // "Alice"
print(userAge)    // 30

Array Destructuring

Pull elements out of arrays by position:

tova
coords = [10, 20, 30]

[x, y, z] = coords
print(x)   // 10
print(y)   // 20

Rest Patterns

Use the spread operator ... to capture remaining elements:

tova
items = [1, 2, 3, 4, 5]

[first, ...rest] = items
print(first)   // 1
print(rest)    // [2, 3, 4, 5]

[head, second, ...tail] = items
print(head)    // 1
print(second)  // 2
print(tail)    // [3, 4, 5]

Nested Destructuring

Destructuring can go multiple levels deep:

tova
data = {
  user: { name: "Alice", scores: [95, 87, 92] }
}

{ user: { name, scores: [first_score, ...other_scores] } } = data
print(name)          // "Alice"
print(first_score)   // 95
print(other_scores)  // [87, 92]
Try "Destructuring" in Playground

Type Annotations

Type annotations in Tova are used on function parameters and return types, not on variable declarations. Tova infers variable types from their assigned values:

tova
// Variables — types are inferred automatically
x = 42              // inferred as Int
name = "Alice"      // inferred as String
is_active = true    // inferred as Bool
scores = [90, 85, 92]  // inferred as [Int]

Use type annotations on function signatures for documentation and type checking:

tova
fn add(a: Int, b: Int) -> Int {
  a + b
}

fn greet(name: String) -> String {
  "Hello, {name}!"
}

Practical Tips

Prefer immutable by default. Only reach for var when the value genuinely needs to change -- loop counters, accumulators, state that evolves over time. Immutable bindings make code easier to follow and less prone to bugs.

Use destructuring to keep code clean. Instead of accessing response.data.user.name repeatedly, destructure it once:

tova
{ data: { user: { name, email } } } = response
// Now use 'name' and 'email' directly

Multiple assignment shines for swaps and coordinate work:

tova
// Swap without a temp variable
var left = "hello"
var right = "world"
left, right = right, left

// Return multiple values from a function using a tuple
fn min_max(items) {
  min_val = items |> min()
  max_val = items |> max()
  (min_val, max_val)
}

[lo, hi] = min_max([3, 1, 4, 1, 5, 9])

Released under the MIT License.