mutable - pannous/warp GitHub Wiki
There are two kinds of mutability:
- mutable variables can point to different objects during their lifetime.
- mutable objects can change during their lifetime.
x="hello"
x+=" world" # ok, value was mutable
x="bye" # ok, variable was mutable
- immutable variables point to the same object during their lifetime.
- immutable objects stay completely unchanged during their lifetime.
syntax
A let (or final, val) variable is never changed again: assigning, +=, ++ and item updates are errors whose fix is var x.
# fails on purpose: the errors it shows
let x="hello"
x="bye" # error: x is immutable, use var x
x+=" world" # error
A var variable is mutable:
var x="hello"
x+=" world" # ok
x="bye" # ok
Both properties can be combined with the constant keyword or with the := sigil:
# fails on purpose: the errors it shows
constant x = "hello"
x := "hello" # ok redundant redeclaration
x+="ok" # error: immutable value
x="hi" # error: constant variable
See keyword 'constant' on how to finetune semantics.
This is near identical to JavaScript's:
Uncaught SyntaxError: Identifier 'x' has already been declared
Uncaught TypeError: Assignment to constant variable.
The differences being:
- In Angle it is allowed to re-declare a variable IF the value is identical.
- In JavaScript it is allowed to modify the values of constant variables
- In JavaScript it is allowed to re-declare variables without let:
# Angle beside JavaScript
const x=7
x=7 # ok in Angle, error in JS
const y=[1,2,3]
y.remove(1) # ok in JavaScript, error in Angle
[ 2, 3 ]
let x=1
x=2 # ok in JavaScript
let x=2 # error
Immutable lists are equivalent to tuples in other languages and can be defined as such:
# not yet: immutable / tuple declarations (card immutable-tuple)
immutable a=(1,2,3)
const b=(1,2,3)
tuple c(1,2,3)
a==b==c
self mutation
It is very important to distinguish between returning mutated data and self mutation.
All self mutating functions must end with exclamation point and do so automatically! Todo: Make the compiler enforce this rule!
x="hello"
print uppercase x
"HELLO"
print x
"hello"
uppercase x!
print x
"HELLO"
mutating syntax
The following are identical:
# sketch: alternative mutating calls
x.uppercase!
uppercase x!
uppercase! x
Discarding a non-mutating “pure” function results in a warning or error.
uppercase x // “Unused pure function value, did you mean to assign it or self mutate via '!'
Assigning a mutated function value results in a warning or error.
y = x.uppercase! // “⚠️ self mutating function, did you mean to call pure function without '!' ?