# Expressions¶

Indigo has several builders of expressions (here generically called operators) and statements employing them. This appendix is meant to list the former and present the latter.

This will not explain the basics of expressions, because this is already the argument of some tutorial's chapters. In particular, if you haven't already, please read the tutorial's chapter about Expressions and operators.

As a reminder, for informations on types you can instead consult their reference material.

## Consulting the operators' tables¶

All operators listed in the following tables can have a certain amount of argument expressions and will always return a single resulting expression.

As a reminder the most basic expressions are the constant ones, for example you can write `True` or `42 int` in your contract code and know that these are expressions of type `Bool` or `Integer`, respectively.

Much like constants some of the following operators can be used on their own, because they have no inputs. For example, `sender` takes no arguments and is an expression of type `Address`.

However most operators have one or more inputs, in which case you can use them by writing the operator followed by its arguments, each separated by spaces. For example, these are valid expressions:

• `abs (1 int)` (`abs` takes 1 argument expression of type `Integer`)
• `pair () True` (`pair` takes 2 of any type instead)

Infix operators are all the ones that take 2 arguments and are made of symbols (as opposed to letters) and as such they are used between their arguments and not before them (e.g. `1 + 2`, `True || False`, etc.)

Many infix operator have a synonym prefix form, in which case you'll find them specified in the same row (e.g. `add` and `+`).

Compound operators are also infix, but are special in that they:

1. do require the first argument to be a variable
2. will replace the value of the variable with the result of the expression
3. do not return an expression, but a complete statement For example:
``````1 int += 2 int -- is invalid, this will not compile

a <- new\$ 1 int
a += 2 int -- "a" will have value of "3" after this expression

b <- new\$ a += 1 int -- is also invalid, because "(a += b)" is not an expression
``````

Type variables are used in the types of these tables as well, you can recognize them because they start with a lower-case letter.

Unless differently specified, they can be replaced by any other type, however remember that if the same variable is used in a line this means its type is the same everywhere it is used.

For example, if an operator says to accept an expression of type `[a]` as an input and return one of type `a`, it means it can operate on a list of any type and will return a single element, but of that same type (e.g. take a `[Integer]` and return an `Integer`, or a `[Natural]` and return a `Natural`, but not take `[Integer]` and return a `Natural`).

You'll notice also that some operators are overloaded, so you'll find them in multiple places, operating on and returning different types. For example you can sum 2 `Natural`s with `+` as well as 2 `Integer`s.

## Logical sections¶

Starting right below are the operators and statements for Indigo.

They are grouped in sections based on the logic they execute.

## Arithmetic¶

### Operators¶

Operator Infix Input type I Input type II Result type Compound Description
`add` `+` `Natural` `Integer` `Integer` Sums the two values
`add` `+` `Integer` `Natural` `Integer` `+=` Sums the two values
`add` `+` `Natural` `Natural` `Natural` `+=` Sums the two values
`add` `+` `Integer` `Integer` `Integer` `+=` Sums the two values
`add` `+` `Timestamp` `Integer` `Timestamp` `+=` Increments/decrements the `Timestamp` by the given number of seconds
`add` `+` `Integer` `Timestamp` `Timestamp` Increments/decrements the `Timestamp` by the given number of seconds
`add` `+` `Mutez` `Mutez` `Mutez` `+=` Sums the two values
`sub` `-` `Natural` `Integer` `Integer` Subtracts the second value from the first
`sub` `-` `Integer` `Natural` `Integer` `-=` Subtracts the second value from the first
`sub` `-` `Natural` `Natural` `Integer` Subtracts the second value from the first
`sub` `-` `Integer` `Integer` `Integer` `-=` Subtracts the second value from the first
`sub` `-` `Timestamp` `Integer` `Timestamp` `-=` Subtracts a number of seconds from the `Timestamp`
`sub` `-` `Timestamp` `Timestamp` `Integer` Subtracts the second value from the first
`sub` `-` `Mutez` `Mutez` `Mutez` `-=` Subtracts the second value from the first
`mul` `*` `Natural` `Integer` `Integer` Multiplies the two values
`mul` `*` `Integer` `Natural` `Integer` `*=` Multiplies the two values
`mul` `*` `Natural` `Natural` `Natural` `*=` Multiplies the two values
`mul` `*` `Integer` `Integer` `Integer` `*=` Multiplies the two values
`mul` `*` `Natural` `Mutez` `Mutez` Multiplies the two values
`mul` `*` `Mutez` `Natural` `Mutez` `*=` Multiplies the two values
`div` `/` `Integer` `Integer` `Integer` Divides the first value by the second
`div` `/` `Integer` `Natural` `Integer` Divides the first value by the second
`div` `/` `Natural` `Integer` `Integer` Divides the first value by the second
`div` `/` `Natural` `Natural` `Natural` Divides the first value by the second
`div` `/` `Mutez` `Mutez` `Natural` Divides the first value by the second
`div` `/` `Mutez` `Natural` `Mutez` Divides the first value by the second
`mod` `%` `Integer` `Integer` `Natural` Modulo of the first value by the second
`mod` `%` `Integer` `Natural` `Natural` Modulo of the first value by the second
`mod` `%` `Natural` `Integer` `Natural` Modulo of the first value by the second
`mod` `%` `Natural` `Natural` `Natural` Modulo of the first value by the second
`mod` `%` `Mutez` `Mutez` `Mutez` Modulo of the first value by the second
`mod` `%` `Mutez` `Natural` `Mutez` Modulo of the first value by the second
`neg` `Integer` `Integer` Negates the input value
`neg` `Natural` `Integer` Negates the input value
`abs` `Integer` `Natural` Absolute value of the input

## Comparison¶

NOTE: the `comparable` type variable in this section can be replaced only by a type that can be compared and not any arbitrary type, for more information see tezos's documentation.

### Operators¶

Operator Infix Input type I Input type II Result type Description
`eq` `==` `comparable` `comparable` `Bool` Equal to
`neq` `/=` `comparable` `comparable` `Bool` Not equal to
`le` `<=` `comparable` `comparable` `Bool` Less than or equal to
`ge` `>=` `comparable` `comparable` `Bool` Greater than or equal to
`lt` `<` `comparable` `comparable` `Bool` Less than
`gt` `>` `comparable` `comparable` `Bool` Greater than

## Bits and boolean¶

### Operators¶

Operator Infix Input type I Input type II Result type Compound Description
`lsl` `<<<` `Natural` `Natural` `Natural` `<<<=` Bitwise left shift
`lsr` `>>>` `Natural` `Natural` `Natural` `>>>=` Bitwise right shift
`and` `&&` `Integer` `Natural` `Natural` Bitwise `and`
`and` `&&` `Natural` `Natural` `Natural` `&&=` Bitwise `and`
`and` `&&` `Bool` `Bool` `Bool` `&&=` Boolean `and`
`or` `||` `Natural` `Natural` `Natural` `||=` Bitwise `or`
`or` `||` `Bool` `Bool` `Bool` `||=` Boolean `or`
`xor` `^` `Natural` `Natural` `Natural` `^=` Bitwise `xor`
`xor` `^` `Bool` `Bool` `Bool` `^=` Boolean `xor`
`not` `Integer` `Integer` Bitwise complement
`not` `Natural` `Integer` Bitwise complement
`not` `Bool` `Bool` Boolean `not`

## Serialization¶

### Operators¶

Operator Input type I Result type Description
`packRaw` `any` `ByteString` Serializes a piece of data to its binary representation
`unpackRaw` `ByteString` `Maybe any` Returns `some` deserialized piece of data if valid, `none` otherwise
`pack` any `a` `Packed a` Type-safer version of `packRaw`
`unpack` `Packed a` `Maybe a` Type-safer version of `unpackRaw`

## Pairs¶

### Operators¶

Operator Input type I Input type II Result type Description
`pair` `a` `b` `(a, b)` Constructs a pair of values
`car` `(a, b)` `a` Extracts the left-side value from a pair. Synonym of `fst`.
`cdr` `(a, b)` `b` Extracts the right-side value from a pair. Synonym of `snd`.
`fst` `(a, b)` `a` Extracts the left-side value from a pair. Synonym of `car`.
`snd` `(a, b)` `b` Extracts the right-side value from a pair. Synonym of `cdr`.

## Maybe¶

### Operators¶

Operator Input type I Result type Description
`some` `a` `Maybe a` Wraps a value in a `some`
`none` `Maybe a` Creates a `none`

## Either¶

### Operators¶

Operator Input type I Result type Description
`right` `a` `Either b a` Wraps a value in a `right`
`left` `b` `Either b a` Wraps a value in a `left`

## Conversion¶

### Operators¶

Operator Input type I Result type Description
`isNat` `Integer` `Maybe Natural` Converts an `Integer` to `some` `Natural` if possible, `none` otherwise
`toInt` `Natural` `Integer` Converts a `Natural` to an `Integer`
`nonZero` `Integer` `Maybe Integer` Returns `some` of the given value if it is not `0`, `none` otherwise.
`nonZero` `Natural` `Maybe Natural` Returns `some` of the given value if it is not `0`, `none` otherwise.
`coerce` `a` `b` Safely converts between two types that have the same Michelson representation and are explicitely cleared for conversion.
`forcedCoerce` `a` `b` Forcefully converts between any two types that have the same Michelson representation.

## Bytes and String¶

### Operators¶

Operator Infix Input type I Input type II Result type Description
`slice` `(Natural, Natural)` `MText` `Maybe MText` Returns `some` sub-string by the given `(offset, length)` pair if one exists, `none` otherwise
`slice` `(Natural, Natural)` `ByteString` `Maybe ByteString` Returns `some` sub-bytestring by the given `(offset, length)` pair if one exists, `none` otherwise
`concat` `<>` `MText` `MText` `MText` String concatanation, the first value is pre-pended to the second one
`concat` `<>` `ByteString` `ByteString` `ByteString` Byte-strings concatanation, the first value is pre-pended to the second one

## List¶

### Operators¶

Operator Infix Input type I Input type II Result type Description
`cons` `.:` `a` `[a]` `[a]` Prepends/cons the given value to the given list
`concatAll` `[MText]` `MText` Concatenates all the strings in the list into a single one
`concatAll` `[ByteString]` `ByteString` Concatenates all the bytestrings in the list into a single one
`size` `[a]` `Natural` Returns the size of the given list
`nil` `[a]` Creates an empty list

## Set¶

### Operators¶

Operator Input type I Input type II Result type Description
`!:` `Set a` `(a, Bool)` `Set a` If the `Bool` is `True` it inserts the given value in the set, otherwise it remove it.
`+:` `Set a` `a` `Set a` Inserts the given value into the set
`-:` `Set a` `a` `Set a` Removes the given value from the set
`?:` `Set a` `a` `Bool` Checks for the presence of the given value in the set
`update` `(a, Bool)` `Set a` `Set a` If the `Bool` is `True` it inserts the given value in the set, otherwise it remove it.
`insert` `a` `Set a` `Set a` Inserts the given value into the set
`remove` `a` `Set a` `Set a` Removes the given value from the set
`mem` `a` `Set a` `Bool` Checks for the presence of the given value in the set
`size` `Set a` `Natural` Returns the size of the given set
`empty` `Set a` Creates an empty set
`emptySet` `Set a` Alias for `empty` to resolve ambiguousness in some cases

## Map¶

### Operators¶

Operator Input type I Input type II Result type Description
`#:` `Map k v` `k` `Maybe v` Looks up the key in the map and returns its value in `some` if found, `none` otherwise
`!:` `Map k v` `(k, Maybe v)` `Map k v` Updates the value associated to a key in a map. Inserts/replaces it with a value in `some` or removes it with `none`.
`+:` `Map k v` `(k, v)` `Map k v` Inserts the value associated to a key in a map. If there was one already, this gets overridden
`-:` `Map k v` `k` `Map k v` Removes the value associated to a key in a map
`?:` `Map k v` `k` `Map k v` Checks for the presence of the given key in the map
`get` `k` `Map k v` `Maybe v` Looks up the key in the map and returns its value in `some` if found, `none` otherwise
`update` `(k, Maybe v)` `Map k v` `Map k v` Updates the value associated to a key in a map. Inserts/replaces it with a value in `some` or removes it with `none`.
`insert` `(k, v)` `Map k v` `Map k v` Inserts the value associated to a key in a map. If there was one already, this gets overridden
`remove` `k` `Map k v` `Map k v` Removes the value associated to a key in a map
`mem` `k` `Map k v` `Bool` Checks for the presence of the given key in the map
`size` `Map k v` `Natural` Returns the size of the given map
`empty` `Map k v` Creates an empty map
`emptyMap` `Map k v` Alias for `empty` to resolve ambiguousness in some cases

## BigMap¶

### Operators¶

Operator Input type I Input type II Result type Description
`#:` `BigMap k v` `k` `Maybe v` Looks up the key in the bigMap and returns its value in `some` if found, `none` otherwise
`!:` `BigMap k v` `(k, Maybe v)` `BigMap k v` Updates the value associated to a key in a bigMap. Inserts/replaces it with a value in `some` or removes it with `none`.
`+:` `BigMap k v` `(k, v)` `BigMap k v` Inserts the value associated to a key in a bigMap. If there was one already, this gets overridden
`-:` `BigMap k v` `k` `BigMap k v` Removes the value associated to a key in a bigMap
`?:` `BigMap k v` `k` `BigMap k v` Checks for the presence of the given key in the bigMap
`get` `k` `BigMap k v` `Maybe v` Looks up the key in the bigMap and returns its value in `some` if found, `none` otherwise
`update` `(k, Maybe v)` `BigMap k v` `BigMap k v` Updates the value associated to a key in a bigMap. Inserts/replaces it with a value in `some` or removes it with `none`.
`insert` `(k, v)` `BigMap k v` `BigMap k v` Inserts the value associated to a key in a bigMap. If there was one already, this gets overridden
`remove` `k` `BigMap k v` `BigMap k v` Removes the value associated to a key in a bigMap
`mem` `k` `BigMap k v` `Bool` Checks for the presence of the given key in the bigMap
`size` `BigMap k v` `Natural` Returns the size of the given bigMap
`empty` `BigMap k v` Creates an empty bigMap
`emptyBigMap` `BigMap k v` Alias for `empty` to resolve ambiguousness in some cases

## Constructor¶

Note

To `wrap`/`unwrap` a value in a constructor the type (here `sumType`) needs to have multiple constructors, all with a single field each, see types.

Note

Just like we have seen in the statements chapter to identify a constructor (e.g. `First`) we need a label prepended with a `c` (e.g. `#cFirst`).

### Operators¶

Operator Input type I Input type II Result type Description
`wrap` `Label` `field` `sumType` Creates a `sumType` from the constructor specified by the given `Label` and a value for its field
`unwrap` `Label` `sumType` `field` Retrieves the value from the field of the `sumType` constructor specified by the given `Label`

## Record¶

### Operators¶

Operator Input type I Input type II Result type Description
`!!` `record` `(Label, field)` `record` Sets the record field for the given `Label` to the given value
`#!` `record` `Label` `field` Retrieves the value associated with the given `Label` from the record
`name` `Label` `field` `record` Creates a record with one field, set to the given value, associated with the given `Label`
`unName` `Label` `record` `field` Retrieves the value associated with the given `Label` from the record that has only one field
`!~` `field` `Label` `record` Creates a record with one field, set to the given value, associated with the given `Label`
`#~` `record` `Label` `field` Retrieves the value associated with the given `Label` from the record that has only one field
`construct` `(record, record, ...)` `record` Creates a bigger record starting from a tuple of smaller ones

## Auxiliary¶

### Operators¶

Operator Input type I Input type II Input type III Result type Description
`checkSignature` `PublicKey` `Signature` `ByteString` `Bool` Checks that the given bytestring has been signed the given key
`blake2b` `bs` (e.g. `ByteString`) `Hash Blake2b bs` Returns the cryptographic hash of the given value using the `blake2b` hash function
`sha256` `bs` (e.g. `ByteString`) `Hash Sha256` Returns the cryptographic hash of the given value using the `sha256` hash function
`sha512` `bs` (e.g. `ByteString`) `Hash Sha512` Returns the cryptographic hash of the given value using the `sha512` hash function
`sha3` `bs` (e.g. `ByteString`) `Hash Sha3` Returns the cryptographic hash of the given value using the `sha3` hash function
`keccak` `bs` (e.g. `ByteString`) `Hash Keccak` Returns the cryptographic hash of the given value using the `keccak` hash function
`hashKey` `PublicKey` `KeyHash` Returns the `b58check` of the public key
`now` `Timestamp` The current time
`amount` `Mutez` Amount of the current transaction
`sender` `Address` Address that initiated the current transaction
`chainId` `ChainId` The chain identifier
`balance` `Mutez` Current balance held by the executing contract
`level` `Natural` ID of the block that the current transaction is included into
`votingPower` `KeyHash` `Natural` Voting power of the given baker
`totalVotingPower` `Natural` Overall voting power of all the bakers

## Never¶

### Operators¶

Operator Input type I Input type II Result type Description
`never` `Never` Marks the current execution branch as impossible

## Contract¶

As a reminder chapter 05 explains and shows with an example how to use the result of the following operators and statements to perform side effects.

### Operators¶

Operator Input type I Result type Description
`contract` `Address` `Maybe (ContractRef param)` Casts the address to `some` `ContractRef param` if possible, `none` otherwise
`implicitAccount` `KeyHash` `ContractRef ()` Returns a default contract with the given public/private key pair, which cannot execute code
`contractAddress` `ContractRef p` `Address` Cast the given `ContractRef param` to its `Address`
`contractCallingString` `MText` `Address` Make an unsafe reference to a contract from the given entrypoint
`self` `ContractRef param` `ContractRef param` of the current contract
`selfAddress` `Address` `Address` of the current contract. When in a lambda - refers to the contract eventually executing it.

### Statements¶

For improved type safety Indigo internally uses some types in addition to `Address` and `ContractRef param` (the only ones listed in Appendix A: types).

Among these types the only one necessary to use the following statements is `EntrypointRef mname`. As the name might suggest this is an identifier for the entrypoint we want to call, there are two possibile choices for it: - `CallDefault` for the default entrypoint of a contract - `Call @"<entrypointname>"` where `<entrypointname>` is the name of the entrypoint we want to call

`selfCalling` is a statement that returns a `ContractRef param` variable given an `EntrypointRef mname` for the contract is executed in. For example, supposing we want to use this statement in the example `controlContract` of chapter 03, which defines its parameter type `IncrementIf` with entrypoints `IsZero` and `HasDigitOne`, each of the following is a valid use:

``````contractRef <- selfCalling CallDefault
contractRef <- selfCalling Call @"IsZero"
contractRef <- selfCalling Call @"HasDigitOne"
``````

`contractCalling` is just like `selfCalling`, except it points at a different contract and because of this it also needs an expression for its address. For example, supposing this time we want to call the `controlContract` above from a different one (and that we already have a `ccAddr` variable for it), each of the following is a valid use:

``````mContractRef <- contractCalling CallDefault ccAddr
mContractRef <- contractCalling (Call @"IsZero") ccAddr
mContractRef <- contractCalling (Call @"HasDigitOne") ccAddr
``````

Note that another difference with `selfCalling` is that it returns `Maybe (ContractRef param)` because it may fail to lookup the contract and return `none`.

## `view`s and `void`s¶

### Operators¶

Operator Input type I Input type II Result type Description
`makeView` `a` `ContractRef param` `View a param` Creates a `View` entrypoint parameter
`makeVoid` `a` `Lambda param param` `Void_ a param` Creates a `Void_` entrypoint parameter

### Statements¶

The `view_` statement allows to implement a `View` entrypoint by using a function. For example, let's say we have a contract that takes a `View Integer Bool` `param` for an entrypoint we could implement it like this:

``````  -- previous contract code to select the entrypoint
view_ greaterThan0 param

greaterThan0 :: Var Integer -> IndigoFunction Bool
greaterThan0 val = defFunction do
return (val >. 0 int)
``````

As you can see we only need the function to take an `Integer` as parameter and return a `Bool` to satisfy the `View Integer Bool` requirement.

Another way to do so is by using the `project` statements, which is like `view_` with the arguments inverted. This may seem pointless, but allows to define the function in place, so the previous example could be written as:

``````  -- previous contract code to select the entrypoint
project param \$ \val ->
return (val > 0 int)
``````

This is more compact and does not require the definition of a specific function.

Just like for `View`s there are statements for `Void`s that work in a matching way to the ones above: `void_` and `projectVoid`.

## Conditional¶

### Statements¶

The most common conditional statement is the `if ... then ... else ...` construct. This specifies two branches of code to execute based on a `Bool` condition. Note that the branches can return a value, in which case this can be captured as a variable, but both branches need to return the same type. For example, these are valid statements:

``````if 1 int <= 2 int
then do
storage =: 1 int -- this will be executed
return ()
else do
return () -- this will not

resVal <- if 1 int == 2 int
then do
return False
else do
a <- new\$ 1 int == 1 int
return a
-- we can now use the `resVal` `Bool` variable
``````

From the first example statement above you can see than in its second branch we do not do anything (`return ()`), for these cases Indigo has a convenience statement called `when` that only takes the `Bool` condition and a single branch, that will be executed only if the condition is `True`. The first statement above could so be rewritten as:

``````when (1 int <= 2 int) do
storage =: 1 int
``````

In other cases we might want to do exactly the opposite and execute some code only when a `Bool` condition is `False`. Indigo has a convenience statement for this too, called `unless`. The previous example for instance could also be written as:

``````unless (1 int > 2 int) do
storage =: 1 int
``````

When we have to deal with `Maybe a`s we often want to know if they are `some a` or `none` and execute a different code in each case. For this reason Indigo has the `ifSome` statement, that based on a `Maybe a` it executes one of its two branches. The first branch is executed in case the value is `some a` and takes that `a` as an input, the second one takes no input and is executed if the value is `none` For example, let's suppose to have a `val` variable containing `some 1` of type `Maybe Integer`, these would be a valid statement:

``````ifSome val
(\n -> storage =: n)
(return ())
``````

Just as for `if` we can have both branches return a value and assign it to a variable.

We have the reverse of `ifSome` as well, `ifNone`, whose first branch is executed only when the value is `none` and second branch is executed in case the value is`some a` and takes that `a` as an input.

We also two have statements similar to `when` for convenience: - `whenSome` whose single branch is executed only if the value is `some a` - `whenNone` whose single branch is executed only if the value is `none`

Similar to `Maybe` we also have conditional statement that work with `Either` as well: - `ifRight` whose: - first branch is executed only if the value is `right a` and takes `a` as input - second branch is executed in case the value is `left b` and takes `b` as an input - `ifLeft` which is the reverse of `ifRight` - `whenRight` whose single branch is executed only if the value is `right a` - `whenLeft` whose single branch is executed only if the value is `left b`

We also have another conditional statement that works with `List a` which is `ifCons` whose: - first branch is executed only if the value is not an empty list and takes the first element `a` and the rest of the elements `List a` as inputs - second branch is executed only if the value is an empty list

## Loop¶

### Statements¶

`while` is the statement that will execute a piece of code as long as a `Bool` condition holds. For example, this loop would execute twice:

``````i <- new\$ 0 int
while (i int < 2 int) do
-- more code can be here
i += 1 int
-- the code following will get executed after the loop
i =: 0 int
``````

`whileLeft` is another statement that will execute a function as long as the condition is a `Left a` and the function will take `a` as the argument. The statement will exit the loop when the condition is a `Right b` and return the `b` as the result.

`forEach` is instead a way to execute a piece of code over each of the elements of a container (a list, set or map). For example, given a `numList` variable of type `[Integer]` this will compute the sum of all its elements:

``````sum <- new\$ 0 int
forEach numList \$ \number -> do
sum += number
``````

## Case¶

### Statements¶

`case_` is the statement that allows use to pattern-match on the constructors of a custom data-type to execute a different piece of code depending on the value of an expression.

To know about what types `case_` can be used with, please refer to the types reference page. An example of a valid type and `case_` usage can be found in the Tutorial's statements chapter.