In this and the next chapters, we briefly explain the syntax of Egison. This chapter explains an aspect of Egison as an ordinal purely functional programming language. We will explain patterns and pattern-matching, the most important feature of Egison in the next chapter. The readers familiar to other functional programming languages can skip this chapter.

Top Expressions

define and test Expressions

We first explain two kinds of top expressions, define expressions and test expressions. A define expression binds the variable to the value or the function. A test expression evaluates the given expression. We can try a function defined with a define expression using a test expression. We can omit test.

load and load-file Expressions

We can load Egison libraries with load expressions.

To load your own program, we can use load-file expressions. A load-file expression takes a full-path to the Egison program file.

Built-in Data

Boolean values, integers, float numbers, and characters are implemented as built-in data in Egison.

Boolean Values

#t represents true.
#f represents false.


A string which consists of only numbers is a number literal. An integer literal is a number literal or concatenation of - and a number literal. We support complex numbers as built-in data.

Rational Numbers

We are supporting rational numbers.


A floating-point literal is concatenation of an integer literal, ., and a number literal.


A character literal is a character enclosed in single quotes.


A string literal is a string enclosed in double quotes.


As shown follows, you can use an array in Egison. You can access any index in an array, even if it is out of range of array. For example, you can try to get the 123456th element of an array whose size is 10. In such a case, you get undefined. Of course, you can use undefined in any other case.


Six Enclosures

First of all, we explain the enclosures of Egison. Perhaps you are surprised at how many kinds of enclosures in Egison when you first see code of Egison. In Egison, there are five kinds of enclosures, i.e. parentheses ( ), brackets < >, square brackets [ ], braces { }, double brackets [| |], and double braces {| |}. They represents procedure call, an inductive datum, a tuple, a collection, an array, and a hash. Roughly speaking, you should use parentheses as LISP, brackets when you want to create patterns or your own data, double brackets to create an array, and double braces to create an hash. Square brackets and braces are both used to collect values. The difference between them is the number of values. The former are used to collect the fixed number of values, but the latter are used to collect the others.

Inductive Data

  <Identifier value ...>

We can create an new object combining objects. It is called an inductive datum. An inductive datum can have values. In particular, it can have any inductive data. This is why it is called "inductive". Note that the name has to start with uppercase.

Tuples (Multiple Values)

  [value ...]

A tuple is expressed as a sequence of elements enclosed in square brackets.

If a tuple consists of an element, the tuple and the element are the same.


  {value ...}

A collection is a sequence of elements enclosed in braces. Unlike a tuple, a collection of an element and its unique element differ.

A collection may contain a collection as its element. Generally, an element of a collection that is an element of a collection isn't an element of the outer collection. @ placed before a collection breaks the collection. Then, an element of a collection with @ that is an element of a collection is an element of the outer collection. Using this notation, you can construct a collection from subcollections.


  [|value ...|]

An array is a sequence of elements enclosed in double brackets. Adding an underscore _ and an index at the end, you can get the associated element of an array. If the index is larger than the size of an array, you will get undefined.

We can get the size of an array with array-size.

An array can have another array as its element. It allows us to use multi-dimensional arrays.

Egison prepares special syntax for arrays. They are generate-array, array-size. The former gives an easy way to create complicated arrays, and the latter shows the size of arrays. The details are described in each subsection.


  {|[key value] ...|}

A hash is a sequence of key-value pairs enclosed in double braces. Adding an underscore _ and an index at the end, we can get the associated element of a hash. If the index is not a key of a hash, we will get undefined.

Syntax of Egison

lambda expressions

  (lambda [variable ...] formula)

Lambda expressions make functions as other functional programming languages. It takes two arguments. The first one is a tuple of variables, which are the dummy variables of the function. Note [$x] and $x are the same. The second argument is a formula, which is the body of the function.

From ver.3.0, a lambda expression is equipped with simpler notation. In this notation, you can omit to write "lambda" and the arguments of the function. You can refer to the i-th argument by writing concatenation of $ and i. If the order of occurrences of the arguments is the same as the order of the arguments and their occurrences are exactly one, then you can omit a number after $. That is, (lambda [$x $y] (+ x y)), (+ $1 $2), and (+ $ $) are the same. Although this notation is so powerful, it is limited to specific functions. The body of such a function has to be simple. Namely, it is application of a function and its arguments, and all occurrences of $i are the arguments. For example, you can't write (+ $1 (* $2 2)) or (if $1 #f #t)

let expressions

  (let {[variable formula] ...} formula)

A let expression takes two arguments. The first argument is a collection of binary tuples, which are pairs of a variable and a formula. These formulas will be evaluated when the associated variable is needed in an evaluation of the second argument, and then the variable is bound to them. Since a formula in the first argument is evaluated with the original environment, you can't use variables in the first argument in the formula.

let* expressions

  (let* {[variable formula] ...} formula)

A let* expression is a syntax suger to avoide nested let expressions. This expression is desugared as follow.

letrec expressions

  (letrec {[variable formula] ...} formula)

A letrec expression is the same as a let expression except the fact that you can use recursive definition in the first argument. Mutual recursion is also allowed.

if expressions

  (if boolean formula formula)

It's ordinary if. But, note the result of an evaluation of the first argument must be a boolean value (i.e. #t or #f).

apply expressions

  (apply function [value ...])

If you have a function and its arguments as a tuple, and want to get the result of the application, then you should use this expression. The result of the evaluation of an apply expression is the result of application of the function with the arguments. That is, (apply f [x0 x1 x2]) is the same thing as (f x0 x1 x2).

generate-array expressions

  (generate-array [variable ...] [integer ...] formula)

Egison is equipped with two ways to generate an array. One is to write elements explicitly using double brackets [| |]. The other is this generate-array expression.

The first argument is the index variable, the second is the size of each dimension, and the third argument determines each element of the array. Note the first argument and the second argument have the same number of elements. For example, the above and the followings are examples to create an array whose size is 5 and 5×3, respectively.

array-size expressions

  (array-size array)

An array-size expression tells us the number of elements in a given array.

seq expressions

  (seq expr expr)
Egison's seq expression derives from Haskell's seq expression. The first argument of seq is strictly evaluated. The most popular use case of seq is in the definition of the foldl function.

What to do next...

Next Chapter: Basic of Patterns Top of Manual Back to Home