Declaring values
Basic Declaration
In Fa, you declare values using a declarative statement:
letto declare an immutable valuemutableto declare a mutable valuefunctionto declare an immutable hoisted functionreactiveto declare a mutable value that can be observed for changesderivedto declare a value that is computed from other reactive values
All these statements have the same syntax:
<declaration> <identifier>[: <type>] = <value>
The type annotation is optional if it can be inferred from the value.
Basic examples:
-- declaring an immutable number
-- with a type annotation
let myNumber: Integer = 12
-- type can be inferred, so annotations are optional
let myInferredNumber = 42
-- declaring an immutable string
let myString: String = "hello"
-- declaring an immutable array
let myArray = [1, 2, 3]
let myArray: Array(Integer) = [1, 2, 3]
let myArray = Array(Integer)[1, 2, 3]
-- declaring an immutable object
let myObject = {
foo = 12
bar = "hello"
nested = {
baz = 42
}
}
-- you can add type information to fields within an object
let myObject = {
foo: Number = 12
bar: String = "hello"
nested: { baz: Number } = {
baz = 42
}
}
-- you can declare an optional value with `?` or `Optional`
-- an optional can take the value `none`
let myOptionalNumber: Number? = 12
let myOptionalNumber: Number? = none
let myOptionalNumber: Optional(Number) = 24Mutable Values
By default, all values declared with let are constants with "deep immutability":
- you cannot re-assign the value
- you cannot change any fields in the object
- you cannot add or remove items in a collection
-- by default, "let" declares a constant value
let myValue = 12
myValue += 1 -- error: cannot reassign constant value
let myObject = { foo = 12 }
myObject.foo += 1 -- cannot change the field of an immutable objectTo create a mutable value, declare it with the mutable keyword:
mutable myValue = 12
myValue += 1 -- this works
mutable myObject = { foo = 12 }
myObject.foo += 1 -- this works too
myObject = { foo = 14 } -- and this works as wellFunction Parameters
Function parameters are immutable references by default.
function increaseFoo = (input: { foo: Number, bar: Number }) => {
-- compiler error: cannot mutate immutable reference
input.foo += input.bar
}Again, you have to use the mutable keyword to declare it as mutable reference:
function increaseFoo = (mutable input: { foo: Number, bar: Number }) => {
input.foo += input.bar -- this works
}You cannot pass an immutable value to a mutable function parameter:
let myValue = { foo = 12, bar = 2 }
-- compiler error: cannot pass immutable value to mutable parameter
increaseFoo(myValue)
mutable myMutableValue = { foo = 12, bar = 2 }
-- this works
increaseFoo(myMutableValue)For mutable function parameters, only interior mutability is allowed. This means you can update the fields of an object or the elements of a container, but you cannot replace the object or container itself:
function increaseFoo = (mutable input: { foo: Number, bar: Number }) => {
-- compiler error: cannot reassign function parameter
-- even if it's mutable
input = {
foo = input.foo + input.bar
bar = input.bar
}
-- this works
input.foo += input.bar
}