Syntax & Types
Lexical structure, core expressions, and the Stage-0 dynamic value model.
1. Lexical structure
#starts a comment and runs to the end of line.- Indentation is significant. Blocks start after
:and end on dedent. - Newlines inside
()/[]are treated as implicit continuation.
2. Bindings and scope
name = exprcreates an immutable binding.mut name = exprmakes the binding reassignable in that scope.
x = 1
# x = 2 # error in the same scope
mut y = 10
y = 20
3. Primitive values in Stage-0
| Kind | Literal / form |
|---|---|
Int |
42, -7 |
Float |
3.14, 2.0 |
Bool |
true, false |
String |
"hi" |
List |
[1, 2, 3] |
Record |
{x: 1, y: 2} |
Unit |
() |
Unit is the non-informative value. It is printed as () and returned by statements such as
print when it is the last value.
4. Operators and precedence
Vela uses normal arithmetic and comparison operators:
- Arithmetic:
+ - * / % - Power:
^(right-associative) - Comparison:
== != < <= > >= - Logic:
and,or,not - Pipelines and broadcast:
|>,.+ .- .* ./ .^
From spec/GRAMMAR.md and SPEC_BY_EXAMPLE.md, precedence is:
|> < or < and < not < comparison < addition/subtraction < multiplication/division/modulo < unary - < ^ < postfix.
5. Arithmetic, division, and negatives
print(7 / 2)
print(7.0 / 2)
print(7 % 3)
print(-2 ^ 2)
print((-2) ^ 2)
3
3.5
1
-4
4
Int / Int truncates toward zero.
6. Expressions are first-class
if can be used where a value is expected.
value = if 1 < 2:
"left"
else:
"right"
That form is common in recursive and functional style.
7. Bool-only conditions
if, while, and logical operators require Bool conditions. Numeric values do not coerce.
# if 1:
# print("wrong")
# -> condition must be Bool, got Int
8. Lists and indexing
- Zero-based indexing.
- Negative indexing counts from the end:
xs[-1]is the last element. - Out-of-range index is a runtime error.
xs = [10, 20, 30]
print(xs[0], xs[-1], xs.len)
9. Record values and map style
Records are immutable but behave as string-keyed maps when you use map builtins.
p = {x: 1, y: 2}
print(p.x)
10. Arrays in Stage-0
array() and array_from([...]) return mutable arrays with array_set, array_push, and friends.
a = array_from([1, 2, 3])
array_push(a, 4)
array_set(a, -1, 99)
print(to_list(a))
11. What is staged in Stage-0
- Runtime is dynamic; values are typed at execution time.
mutis a runtime storage rule, not a static type rule.- Static typing and typed inference are design work in progress for the self-hosted compiler.
- Type declarations in user code are limited to ADT definitions (
type) in Stage-0.