Algosim documentation: ≔

≔ (colon equals)

The assignment operator.

Syntax

Description

is the assignment operator. It is most easily inserted by typing a colon (:) followed by an equals sign (=) and then any whitespace or punctuation.

In its simplest form, a ≔ X, it assigns the value X to the variable a. If there isn’t already a variable named a, it is created with value X; otherwise, its current value is discarded and replaced with X. a must be a valid identifier.

The expression a ≔ X returns X, so it is possible to write a ≔ b ≔ X, parsed as a ≔ (b ≔ X) because the operator is evaluated right-to-left, to assign X to both a and b. Consequently, the value of a ≔ b ≔ X is also X.

It is possible to assign the same value to multiple lvalues at once without having to use multiple assignment operators:

a, b, c ≔ X

will assign the value X to all lvalues to the left of the operator – in this case, to a, b, and c. Again, the expression a, b, c ≔ X returns X.

Finally, it is possible to assign several different values to different destination lvalues. For example (n = 3),

a, b, c ≔ X, Y, Z

will assign X to a, Y to b, and Z to c. If the number of values to the right is greater than one, then the number of lvalues on the left must be the same number. The value of the expression a, b, c ≔ X, Y, Z is Z; in general (any n), it is the right-most value.

The expression

a, b, c ≔ X, Y, Z

is similar to

a ≔ X; b ≔ Y; c ≔ Z.

Assuming no error occurs (and no flow-control value is returned), the side effects and returned value are the same.

If an error is generated, however, the side effects differ. While

a ≔ 10; b ≔ 100; c ≔ 1000/0

will set a and b before the error occurs,

a, b, c ≔ 10, 100, 1000/0

will not set any variable, because the assignment operator’s right-hand-side values are evaluated before any assignment takes place.

Another consequence of this is that it is possible to use the assignment operator to swap two values:

a, b ≔ b, a.

In general, an lvalue (left-hand-side operand) need not be a variable name. It can also be a subscripted member of a variable, nested to any level.

For example,

X ≔ struct("a": 10, "b": struct("first": '(4, 1, '(2, 6)), "second": 20))
a: 10
b.first: (4, 1, (2, 6))
b.second: 20
X.b.first[3][1] ≔ 20
20
X
a: 10
b.first: (4, 1, (20, 6))
b.second: 20

Some functions also return lvalues, such as MainDiagonal and row:

A ≔ ❨❨5, 1, 2❩, ❨2, 5, 7❩, ❨0, 1, 2❩❩
⎛5  1  2⎞
⎜2  5  7⎟
⎝0  1  2⎠
MainDiagonal(A) ≔ ❨10, 100, 1000❩
 ⎛ 10 ⎞
e⎜100 ⎟
 ⎝1000⎠
A
⎛  10     1     2⎞
⎜   2   100     7⎟
⎝   0     1  1000⎠
row(A, 1) ≔ ❨−1, −2, −3❩
 ⎛−1⎞
e⎜−2⎟
 ⎝−3⎠
A
⎛  −1    −2    −3⎞
⎜   2   100     7⎟
⎝   0     1  1000⎠

Note that planar containers (such as matrices and pixmaps) have two-dimensional indices that can function like lvalues:

A[3, 1] ≔ π
3.14159265359	(=π)
A
⎛           −1             −2             −3⎞
⎜            2            100              7⎟
⎝3.14159265359              1           1000⎠

If a variable is protected, it cannot be assigned a new value. It is also not possible to assign a new value to any subscript of the variable.

The operator is implemented by the assign function.