Skip to main content



The conditional branching instruction if e then i executes instruction i if the bool expression e is true.

For example, instr1 is executed if expr1 is true:

if expr1 then

The instruction to execute when expression expr1 is false follows the else keyword:

if expr1 then

A sequence of instructions is delimited by begin ... end and instructions are separated by ;:

if expr1 then begin
end else begin

A dangling else is attached to the last if. For example in the following expression, the else branch is attached to if b = 1 then a := 42 instruction:

if a = 1 then
if b = 1 then
a := 42
b := 42

That is that it is equivalent to:

/* 'begin end' is optional here, it is to emphasis the logical structure */
if a = 1 then begin
if b = 1 then
a := 42
b := 42

Note that there is no need for parenthesis in the bool expression; for example:

var max : nat = 0;
if a < b then
max := b
max := a

A conditional if expression is also available.

match with

The match with instruction, inspired by the Ocaml language, desconstructs a value of enumerated type to extract data from it. Enumerated types are option, or, list, states and composite type enum.

Its generic syntactic structure is presented below, given that E1 ... En are the named values of the enumerated type of expr1:

match expr1 with
| E1 -> instr1 /* instruction when expr1 is E1 */
| E2 -> instr2 /* instruction when expr1 is E2 */
/* ... */
| En -> instrn /* instruction when expr1 is En */

If one named type Ei is missing, the compiler fails with the message:

Partial match (missing "Ei")

It is possible to escape the enumeration with the _ keyword; for example:

match expr1 with
| E1 -> instr1
| E2 -> instr2
| _ -> instr3 /* instruction when expr1 is E3 or E4 ... or En */


An option value has two named values: some and none.

For example, suppose opt is typed option<string>:

match opt with
| some(s) -> instr1 /* declares constant 's' typed 'string' in instr1 */
| none -> instr2


An or value has two named values: left and right.

For example, suppose o is typed or<string, nat>:

match o with
| left(s) -> instr1 /* declares constant 's' typed 'string' in instr1 */
| right(n) -> instr2 /* declares constant 'n' typed 'nat' in instr2 */


A list value has two named values: [] for empty list and :: for recursive composition.

For example, suppose l is typed list<bytes>:

match l with
| h::tl -> instr1 /* declares constants h typed 'bytes' and tl typed 'list<bytes' */
| [] -> instr2 /* when l is empty */

In the example above, h is the first element of the list l, and tl is the list l without the first element.

Note that Archetype does not support recursive calls, hence the match instruction cannot be used to fold a list as in Ocaml; it is rather used to retrieve the first element of a list and manage the case of an empty list. The for instruction is used to iterate over list elements.


Contract's states may be interrogated with the match instruction.

Consider the states declaration:

states =
| Pending initial
| Shipped
| Accepted
| Canceled

The following enables acting based on contract's state:

match state with
| Pending -> instr1 /* when in Pending state */
| Shipped -> instr2 /* when in Shipped state */
| Accepted -> instr3 /* when in Accepted state */
| Canceled -> instr4 /* when in Canceled state */


An enum value has a user-defined list of values.

Consider the following declaration:

enum color =
| RGB<nat * nat * nat>
| Hex<bytes>
| Css<string>

The following enables acting based on color's values:

match color with
| RGB(rgb) -> instr1 /* declares 'rgb' as a tuple of 3 values typed 'nat' in instr1 */
| Hex(h) -> instr2 /* declares 'h' as a bytes value in instr2 */
| Css(css) -> instr3 /* declares 'css' as a string value in instr3 */


The for instruction iterates the elements of a container (set, list, map and asset).

The generic syntax structure is presented below, given c is a container:

for e in c do
instr1 /* declares constant element 'e' in instr1 */

The type of element e above depends on the type of the container. See below for more information.

Note that it is not possible to break an iteration. See the fold builtin for an iteration process with a possiblity to break.


Elements of a set are iterated in the element's type natural order.

For example, suppose set s is typed set<string>:

for e in s do
instr1 /* constant e is typed 'string' and is an element of s */


Elements of a list are iterated in the order of the list's construction process. See prepend and concat instructions.

For example, suppose list l is typed list<nat>:

for e in l do
instr1 /* constant 'e' is typed `nat` */


Elements of a map big_map or iterable_big_map are iterated in the natural order of the key.

For example, suppose map m is typed map<string, bytes>:

for (k, v) in m do

In the example above:

  • k is a key of the map typed string
  • v is the associated value typed bytes


Elements of a asset are iterated in the natural order of the asset identifier.

Consider the following visitor asset declaration identified by login field:

asset visitor identified by login {
login : address;
fullname : string;
nbvisits : nat = 0

The following iterates on the visitor asset collection:

for log in visitor do
instr1 /* 'log' is the visitor 'login' typed 'address' */

Since log is the iterated visitor's login, visitor data is accessed with [] operator, like for example:

var nbv = visitor[log].nbvisits


The while instruction executes an instruction as long as a condition holds true.

The generic syntax is:

while expr1 do

where expr1 is a bool typed expression.

For example:

var i = 0;
while i < 20 do
i += 1

There is no guarantee that the iteration terminates. In such a case the entrypoint fails with a gas exceeded error.


The iter instruction iterates over a integer value in a specified range. The generic syntax is:

iter i from expr1 to expr2 do
instr1 /* declares an integer constant 'i' between expr1 and expr2 included */

In the instruction above, expr1 and expr2 are expressions typed int. It does not iterate if expr1 is greater than expr2.

The initial from value may be omitted, it is then defaulted to 1:

iter i to expr2 do
instr1 /* declares an integer constant 'i' between 1 and expr2 included */