A block is an expression that has the general form:
statement_1
statement_2
…
statement_n
expression
A block can have zero or more statements, and the value of the whole block is the value of the finalexpression
.A statement is either:
- Aterm definitionwhich defines a term within the scope of the block. The definition is not visible outside this scope, and is bound to a local name. Unlike top-level definitions, a block-level definition does not result in a hash, and cannot be referenced with ahash literal.
- AUnison expression.In particular, blocks often containaction expressions,which are expressions evaluated solely for their effects. An action expression has type
{A} T
for some abilityA
(seeAbilities and Ability Handlers)and some typeT
. - A
use
clause.
An example of a block:
A number of language constructs introduce blocks. These are detailed in the relevant sections of this reference. Wherever Unison expects an expression, a block can be introduced with thelet
keyword:
let <block>
Where<block>
denotes a block as described above.
The lexical syntax of blocks
The standard syntax expects statements to appear in a line-oriented layout, where whitespace is significant.
The opening keyword (''let'',if
,then
,orelse
,for example) introduces the block, and the position of the first character of the first statement in the block determines the top-left corner of the block. The beginning of each statement in the block must be lined up exactly with the left edge of the block. The first non-whitespace character that appears to the left of that edge (i.e. outdented) ends the block. Certain keywords also end blocks. For example,then
ends the block introduced byif
.
A statement or expression in a block can continue for more than one line as long as each line of the statement is indented further than the first character of the statement or expression.
For example, these are valid indentations for a block:
let
x = 1
y = 2
x + y
let x = 1
y = 2
x + y
Whereas these are incorrect:
let x = 1
y = 2
x + y
let x = 1
y = 2
x + y
Syntactic precedence
Keywords that introduce blocks bind more tightly thanfunction application.Sof let x
is the same asf (let x)
andf if b then p else q
is the same asf (if b then p else q)
.
Block keywords bind more tightly thandelayed computationssyntax. So'let x''
is the same as_ -> let x
and!if b then p else q
is the same as(if b then p else q) ()
.
Blocks eagerly consume expressions, soif b then p else q + r
is the same asif b then p else (q + r)
.