Language Basics β
This chapter covers the fundamental building blocks of Kettle programs.
Variables β
Variables are declared with = and are immutable by default:
name = "Alice"
age = 30
pi = 3.14159Kettle uses type inference, so you rarely need to write type annotations. The compiler figures out that name is a String, age is an Int, and pi is a Float.
Rebinding with <- β
To update a variable, use the rebind operator <-:
count = 0
count <- count + 1
count <- count + 1
print(to_string(count)) -- prints "2"This isn't mutation in the traditional senseβit creates a new binding that shadows the previous one.
Rebind with Function Application β
A powerful pattern is rebinding a variable through a function:
fn double(n: Int) -> Int
n * 2
end fn
x = 5
x <- double(x) -- x is now 10
x <- double(x) -- x is now 20When the variable being rebound is the argument to a function, Kettle provides syntactic sugarβyou can omit the argument:
x = 5
x <- double -- equivalent to: x <- double(x)This "apply and rebind" pattern is especially elegant for transformations. You'll see it extensively in quantum computing, where gates transform qubits:
q = qubit()
q <- hadamard -- equivalent to: q <- hadamard(q)
q <- pauli_x -- equivalent to: q <- pauli_x(q)The same <- operator works for both classical and quantum codeβit's Kettle's unified way of expressing "transform this value".
Compound Assignment β
Kettle also supports compound assignment operators for common updates:
x = 10
x += 5 -- x is now 15 (same as x <- x + 5)
x -= 3 -- x is now 12
x *= 2 -- x is now 24Available compound operators:
+=,-=β addition, subtraction*=,/=β multiplication, division (forFloat)^=β XOR (forInt)
These are particularly useful in loops and are required for reversible computations.
Basic Types β
Kettle has several built-in types:
| Type | Description | Examples |
|---|---|---|
Int | Integer numbers | 42, -17, 0 |
Float | Floating-point numbers | 3.14, -0.5, 1.0 |
String | Text | "hello", "Kettle" |
Bool | Boolean values | True, False |
Unit | No meaningful value | (used for side-effect functions) |
String Interpolation β
Use ${} to embed expressions in strings:
name = "Bob"
age = 25
print("${name} is ${to_string(age)} years old")Functions β
Functions are defined with fn and end fn:
fn greet(name: String) -> String
"Hello, ${name}!"
end fn
fn add(a: Int, b: Int) -> Int
a + b
end fnThe last expression in a function is its return valueβno return keyword needed.
Calling Functions β
message = greet("Alice")
sum = add(2, 3)Functions Without Parameters β
fn get_answer() -> Int
42
end fnFunctions Returning Unit β
Functions that perform side effects typically return Unit. Functions that print require the IO effect:
fn say_hello() -> Unit with IO
print("Hello!")
end fnControl Flow β
Match Expressions β
Pattern matching with match:
fn describe(n: Int) -> String
match n
0 -> "zero"
1 -> "one"
_ -> "many"
end match
end fnThe _ pattern matches anything (wildcard).
Boolean Matching β
A common pattern for conditional logic:
fn abs(n: Int) -> Int
match n >= 0
True -> n
False -> -n
end match
end fnLoops β
For Loops with Accumulators β
Kettle's for loops use accumulators instead of mutation:
-- Sum numbers 1 to 10
total = for i in range(1, 11) with sum = 0
sum + i
end for
-- total = 55The with clause initializes the accumulator. Each iteration produces a new value that becomes the accumulator for the next iteration.
Expression Sequencing β
Use semicolons to sequence multiple expressions, returning the last one:
-- Sequence expressions; the last value is returned
result = (print("computing..."); 42) -- result is 42
-- Useful in lambdas that need side effects
numbers | map(fn(x: Int) -> print(to_string(x)); x * 2)In function bodies, expressions are automatically sequenced by newlines:
fn process(x: Int) -> Int
print("Processing...") -- executed first
print("Value: ${to_string(x)}") -- executed second
x * 2 -- returned
end fnComments β
Single-line comments start with --:
-- This is a comment
x = 42 -- inline commentNote: Kettle only has single-line comments. For longer explanations, use multiple -- lines.
Operators β
Arithmetic β
+,-,*,/β basic math%β modulo (remainder)
Comparison β
==,!=β equality<,>,<=,>=β ordering
Logical β
&&β and||β or!β not (prefix)
Example β
fn is_valid_age(age: Int) -> Bool
age >= 0 && age <= 150
end fn
fn main() -> Unit using file_io
ages = [25, -5, 200, 42]
for age in ages
valid = is_valid_age(age)
print("${to_string(age)}: ${to_string(valid)}")
end for
end fnNext Steps β
- Data Types β Records, variants, and collections
- Functional Programming β Closures and pipelines