Objects
Objects, like records, are like a collection of named (possibly mutable) variables packaged in curly braces {}
. But there are four key differences:
- We define an object by using the
object
keyword. - We specify the visibility of the named variables with either the
public
orprivate
keyword. - We specify the mutability of the named variables with either the
let
orvar
keyword. - Only
public
variables are part of the type of an object.
Here's a simple example:
let obj = object {
private let x = 0;
};
We declared an object by using the object
keyword before the curly braces. We also declared the variable x
with the let
keyword.
The type of this object is the empty object type { }
. This is because the x
variable was declared private
.
A typed object with a public field could look like this:
type Obj = { y : Nat };
let obj : Obj = object {
private let x = 0;
public let y = 0;
};
We defined the type beforehand, which consists only of one named variable y
of type Nat
. Then we declared an object with a public
variable y
. We used the object type to annotate the name of the variable obj
.
Notice that x
is not part of the type, therefore it is not accessible from outside the object.
The values of the variables inside objects (and inside records as well) could also be a function. As we saw in functions, functions also have a type and they could be assigned to a named variable.
let obj = object {
private func f() {};
private let x = f;
};
Inside the object, we first define a private function and then assign that function to a private
immutable variable x
. The type of this object is the empty object type { }
because there are no public variables.
Lets change the visibility of our x
variable:
let obj = object {
private func f() {};
public let x = f;
};
This object now has the following type:
{ x : () -> () }
This is the type of an object with one field named x
, which is of function type () -> ()
. We could access this public field like this:
let result = obj.x();
let f = obj.x;
The first line actually calls the function and assigns the result to result
. The second line only references the function and renames it.
Public functions in objects
Lets look at a useful object:
let balance = object {
private let initialBalance = 100;
public var balance = initialBalance;
public func addAmount( amount : Nat ) : Nat {
balance += amount;
balance
};
};
The first field is a private immutable variable named initialBalance
with constant value 100
. The second field is a public mutable variable named balance
initiated with the value of initialBalance
.
Then we encounter a declaration of a public function named addAmount
, which takes one argument amount
of type Nat
and returns a value of type Nat
. The function adds the value of amount
to balance
using the 'in place add' assignment operator and finally returns the new value of balance
.
This object has the following type:
{
addAmount : Nat -> Nat;
var balance : Nat;
}
This object type has two fields. The addAmount
field has function type Nat -> Nat
. And the second field is a var
mutable variable of type Nat
.