Expressions
Calor uses Lisp-style prefix notation for all operations. This eliminates operator precedence ambiguity.
Prefix Notation
Instead of infix a + b, Calor uses prefix (+ a b):
| Infix | Calor Prefix |
|---|---|
a + b | (+ a b) |
a * b + c | (+ (* a b) c) |
a + b * c | (+ a (* b c)) |
(a + b) * c | (* (+ a b) c) |
Arithmetic Operators
| Operator | Meaning | Example |
|---|---|---|
+ | Addition | (+ a b) |
- | Subtraction | (- a b) |
* | Multiplication | (* a b) |
/ | Division | (/ a b) |
% | Modulo | (% a b) |
Examples
Plain Text
(+ 1 2) // 3
(- 10 3) // 7
(* 4 5) // 20
(/ 15 3) // 5
(% 17 5) // 2Nested Expressions
Plain Text
// (1 + 2) * 3 = 9
(* (+ 1 2) 3)
// 1 + (2 * 3) = 7
(+ 1 (* 2 3))
// ((a + b) * c) - d
(- (* (+ a b) c) d)Comparison Operators
| Operator | Meaning | Example |
|---|---|---|
== | Equal | (== a b) |
!= | Not equal | (!= a b) |
< | Less than | (< a b) |
<= | Less or equal | (<= a b) |
> | Greater than | (> a b) |
>= | Greater or equal | (>= a b) |
Examples
Plain Text
(== x 0) // x equals 0
(!= y "") // y is not empty string
(< age 18) // age less than 18
(>= score 70) // score at least 70Logical Operators
| Operator | Meaning | Example |
|---|---|---|
&& | Logical AND | (&& a b) |
|| | Logical OR | (|| a b) |
! | Logical NOT | (! a) |
Examples
Plain Text
(&& (> x 0) (< x 100)) // x > 0 AND x < 100
(|| (== a 1) (== a 2)) // a == 1 OR a == 2
(! (== x 0)) // NOT (x == 0)Complex Conditions
Plain Text
// (x > 0 && x < 100) || y == 0
(|| (&& (> x 0) (< x 100)) (== y 0))
// !(a == b && c == d)
(! (&& (== a b) (== c d)))Using Expressions
In Return Statements
Plain Text
§R (+ a b)
§R (* (- x 1) 2)
§R (>= score 70)In Bindings
Plain Text
§B{sum} (+ a b)
§B{product} (* x y)
§B{isValid} (&& (> x 0) (< x 100))In Print Statements
Plain Text
§P (+ 1 2) // prints 3
§P (* x x) // prints x squaredIn Conditions
Plain Text
§IF{if1} (> x 0) → §P "positive"
§EI (< x 0) → §P "negative"
§EL → §P "zero"
§/I{if1}In Contracts
Plain Text
§Q (>= x 0) // Requires: x >= 0
§Q (!= divisor 0) // Requires: divisor not zero
§S (>= result 0) // Ensures: result >= 0
§S (<= result (* x x)) // Ensures: result <= x^2In Loop Bounds
Loop bounds can be expressions:
Plain Text
§L{for1:i:0:(- n 1):1} // i from 0 to n-1
§L{for2:j:1:(* 2 n):2} // j from 1 to 2n, step 2Collection Expressions
Calor provides expressions for querying collections.
Contains Check (§HAS)
Check if a collection contains an element.
| Syntax | Description | C# Equivalent |
|---|---|---|
§HAS{coll} value | Element in list/set | coll.Contains(value) |
§HAS{dict} §KEY key | Key in dictionary | dict.ContainsKey(key) |
§HAS{dict} §VAL value | Value in dictionary | dict.ContainsValue(value) |
Examples:
Plain Text
// Check if list contains element
§IF{if1} §HAS{numbers} 5
§P "Found 5"
§/I{if1}
// Check if key exists in dictionary
§IF{if2} §HAS{ages} §KEY "alice"
§P "Alice found"
§/I{if2}
// Use in binding
§B{hasItem} §HAS{inventory} "sword"Collection Count (§CNT)
Get the number of elements in a collection.
| Syntax | Returns | C# Equivalent |
|---|---|---|
§CNT{coll} | i32 | coll.Count |
Examples:
Plain Text
// Get count
§B{size} §CNT{items}
// Use in condition
§IF{if1} (> §CNT{queue} 0)
§P "Queue not empty"
§/I{if1}
// Use in loop bound
§L{for1:i:0:(- §CNT{list} 1):1}
§P list[i]
§/L{for1}Using Collection Expressions in Contracts
Plain Text
§F{f001:ProcessItems:pub}
§I{List<i32>:items}
§O{i32}
§Q (> §CNT{items} 0) // Requires: items not empty
§S (>= result 0)
// ...
§/F{f001}Why Prefix Notation?
1. No Precedence Ambiguity
Infix:
JavaScript
a + b * c // Is this (a+b)*c or a+(b*c)?Calor:
Plain Text
(+ a (* b c)) // Clearly a + (b * c)
(* (+ a b) c) // Clearly (a + b) * c2. Easy AST Manipulation
The structure (op arg1 arg2) directly represents the AST node.
3. Uniform Syntax
Every operation follows the same pattern: (operator arguments...)
Common Patterns
FizzBuzz Check
Plain Text
(== (% i 15) 0) // i divisible by 15
(== (% i 3) 0) // i divisible by 3
(== (% i 5) 0) // i divisible by 5Range Check
Plain Text
(&& (>= x min) (<= x max)) // min <= x <= maxNull Check
Plain Text
(!= value null) // value is not nullEquality with Multiple Values
Plain Text
(|| (== x 1) (|| (== x 2) (== x 3))) // x is 1, 2, or 3Next
- Control Flow - Loops and conditionals