# Egison Quick Tour¶

This section introduces basic functionalities of Egison for pattern-match-oriented programming.

`matchAll`

and matchers¶

Egison provides some syntactic constructs for expressing pattern matching.
The most basic one among them is `matchAll`

.

```
matchAll [1,2,3] as list something with
| $x :: $xs -> (x, xs)
-- [(1,[2,3])]
```

A `matchAll`

expression consists of the following elements.

- a
**target**(`[1,2,3]`

in the above example) - a
**matcher**(`list something`

) - more than one
**match clauses**(`$x :: $xs -> (x, xs)`

)

A match clause contains a **pattern** (`$x :: $xs`

in the above example) and a **body** (`(x, xs)`

).
Just like the pattern matching in other programming languages, the `matchAll`

expression attempts pattern matching of the target and the pattern, and if it succeeds, evaluates the body of the match clause.

The unique feature of the `matchAll`

expression is twofold: (1) it returns a list, and (2) it takes additional argument called matchers.

(1) is for supporting pattern matching with multiple results.
Since there can be multiple ways to match the pattern for the target data, the `matchAll`

expression evaluates the body for all of these pattern-matching results and returns a list of the evaluation results.
In the above example, the `::`

is what we call a **cons pattern** which decomposes a list into the first element and the others.
Because there is only one way to decompose the list `[1, 2, 3]`

in this manner, the `matchAll`

returns a singleton list.

The feature (2) realizes extensible pattern-matching algorithm and pattern polymorphism. Matcher is an Egison-specific object that retains pattern-matching algorithms. See Ad-hoc polymorphism of patterns by matchers for the description of pattern polymorphism.

Lines starting with `--`

are comments.
In this tutorial, a line comment right after a program shows the execution result of the program.

We will explain more on the syntax of `matchAll`

.
A matcher is sandwitched between two keywords `as`

and `with`

.
A `matchAll`

expression can take multiple match clauses.
Match clauses are precedented with `|`

, which enhances the readability of program when a match clause occupy multiple lines.
In a match clause, the pattern and the body is separated with `->`

.

```
matchAll target as matcher with
| pattern1 -> body1
| pattern2 -> body2
...
```

When there is only one match clause, we can omit the `|`

before the match clause.

```
matchAll target as matcher with pattern -> body
```

The following is an example of pattern matching with multiple results.
`++`

is called **join pattern**, which splits a list into two segments.
The `matchAll`

evaluates the body for every possible matching result of the join pattern.

```
matchAll [1,2,3] as list something with
| $hs ++ $ts -> (hs, ts)
-- [([], [1, 2, 3]), ([1], [2, 3]), ([1, 2], [3]), ([1, 2, 3], [])]
```

## Non-linear pattern with value pattern and predicate pattern¶

`matchAll`

gets even more powerful when combined with non-linear patterns.
For example, the following non-linear pattern matches when the target collection contains a pair of identical elements.

```
matchAll [1,2,3,2,4,3] as list integer with
| _ ++ $x :: _ ++ #x :: _ -> x
-- [2,3]
```

**Value patterns** play an important role in representing non-linear patterns.
A value pattern matches the target if the target is equal to the content of the value pattern.
A value pattern is prepended with `#`

and the expression after `#`

is evaluated referring to the value bound to the pattern variables that appear on the left side of the patterns.
As a result, for example, `$x :: #x :: _`

is valid while `#x :: $x :: _`

is invalid.

Let us show pattern matching for twin primes as a sample of non-linear patterns.
A twin prime is a pair of prime numbers of the form \((p, p+2)\).
`primes`

is an infinite list of prime numbers which is defined in one of Egison standard libraries.
This `matchAll`

extracts all twin primes from this infinite list of prime numbers in order.

```
def twinPrimes := matchAll primes as list integer with
| _ ++ $p :: #(p + 2) :: _ -> (p, p + 2)
take 8 twinPrimes
-- [(3, 5), (5, 7), (11, 13), (17, 19), (29, 31), (41, 43), (59, 61), (71, 73)]
```

There are cases that we might want to use more general predicates in patterns than equality.
**Predicate patterns** are provided for such a purpose.
A predicate pattern matches the target if the predicate returns true for the target.
A predicate pattern is prepended with `?`

, and a unary predicate follows after `?`

.

```
def twinPrimes := matchAll primes as list integer with
| _ ++ $p :: ?(\q -> q = p + 2) :: _ -> (p, p + 2)
```

## Efficient pattern matching with backtracking¶

The pattern-matching algorithm inside Egison includes a backtracking mechanism for efficient non-linear pattern matching.

```
matchAll [1..n] as list integer with _ ++ $x :: _ ++ #x :: _ -> x
-- returns [] in O(n^2) time
matchAll [1..n] as list integer with _ ++ $x :: _ ++ #x :: _ ++ #x :: _ -> x
-- returns [] in O(n^2) time
```

The above expressions match a collection that consists of integers from 1 to n as a list of integers for enumerating identical pairs and triples, respectively. Since this target collection contains neither identical pairs nor triples, both expressions return an empty collection.

When evaluating the second expression, Egison interpreter does not try pattern matching for the second `#x`

because pattern matching for the first `#x`

always fails.
Therefore, the time complexities of the above expressions are identical.
The pattern-matching algorithm inside Egison is discussed in this paper in detail. .. TODO: write a manual page for algorithm

## Ad-hoc polymorphism of patterns by matchers¶

Another merit of matchers, in addition to the extensibility of pattern-matching algorithms, is the **ad-hoc polymorphism of patterns**.
The ad-hoc polymorphism of patterns allows us to use the same pattern constructors such as `::`

and `++`

for different matchers like `list`

and `multiset`

.
It is important for non-free data types because some data are pattern-matched as various non-free data types at the different parts of a program.
For example, a list can be pattern-matched as a multiset or a set.
Polymorphic patterns reduce the number of names for pattern constructors.

In the following sample, a **collection** `[1,2,3]`

is pattern-matched using different matchers with the same cons pattern.
The “collection” is actually what we have been calling “list” so far.
In Egison, collection refers to the sequential data that can be pattern-matched as lists, multisets or sets.

When we use `multiset`

matcher, the cons pattern decomposes a collection into one element and the others ignoring the order of the elements.
When we use `set`

matcher, the right hand side of the cons pattern is matched with the original collection.
This behavior comes from the idea that a set can be seen as a collection which contains infinitely many copies of each element.

```
matchAll [1,2,3] as list something with $x :: $xs -> (x,xs)
-- [(1,[2,3])]
matchAll [1,2,3] as multiset something with $x :: $xs -> (x,xs)
-- [(1,[2,3]),(2,[1,3]),(3,[1,2])]
matchAll [1,2,3] as set something with $x :: $xs -> (x,xs)
-- [(1,[1,2,3]),(2,[1,2,3]),(3,[1,2,3])]
```

## Controlling the order of pattern matching¶

The `matchAll`

expression is designed to enumerate all countably infinite pattern-matching results.
For this purpose, users sometimes need to care about the order of pattern-matching results.

Let us start by showing a typical example.
The `matchAll`

expression below enumerates all pairs of natural numbers.
We extract the first 8 elements with the `take`

function.
`matchAll`

uses breadth-first search to traverse all the nodes in the reduction tree of pattern matching. .. TODO: Refer to the chapter of pattern-matching mechanism
As a result, the order of the pattern-matching results is as follows.

```
take 8 (matchAll [1..] as set something with
| $x :: $y :: _ -> (x,y))
-- [(1,1),(1,2),(2,1),(1,3),(2,2),(3,1),(2,3),(3,2)]
```

The above order is suitable for traversing an infinite reduction tree.
However, sometimes this order is not preferable. .. (see section 3.1.2 and section 3.4.1).
`matchAllDFS`

, which traverses a reduction tree in depth-first order, is provided for this reason.

```
take 8 (matchAllDFS [1..] as set something with
| $x :: $y :: _ -> (x,y))
-- [(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8)]
```

For instance, think about defining `concat`

with pattern matching.
If we use `matchAll`

, the outcome will be the alternation of the elements in the sublists, which is not what we expect of `concat`

.

```
def concat' xss := matchAll xss as list (list something) with
| _ ++ (_ ++ $x :: _) :: _ -> x
concat' [[1,2,3],[4,5,6],[7,8,9]]
-- [1, 2, 4, 3, 5, 7, 6, 8, 9]
```

To fix this, we should use `matchAllDFS`

instead.

```
def concat xss := matchAllDFS xss as list (list something) with
| _ ++ (_ ++ $x :: _) :: _ -> x
concat [[1,2,3],[4,5,6],[7,8,9]]
-- [1, 2, 3, 4, 5, 6, 7, 8, 9]
```

## Logical patterns: and-, or-, and not-patterns¶

Logical patterns such as **and-patterns**, **or-patterns** and **not-patterns** play an important role in enriching the expressivity of patterns.

An and-pattern `p1 & p2`

pattern-matches when *both* of the patterns `p1`

and `p2`

succeeds in pattern matching.
Similarly, an or-pattern `p1 | p2`

pattern-matches when *either* of the patterns `p1`

and `p2`

succeeds in pattern matching.
A not-pattern `!p`

pattern-matches when the pattern `p`

fails to pattern-match.

We start by showing pattern matching for prime triples as an example of and-patterns and or-patterns.
A prime triple is a triple of primes of the form \((p, p + 2, p + 6)\) or \((p, p + 4, p + 6)\).
The or-pattern `#(p + 2) | #(p + 4)`

is used to match \(p+2\) or \(p+4\).
The and-pattern `(#(p + 2) | #(p + 4)) & $m`

binds the value matched by `(#(p + 2) | #(p + 4))`

to a new variable `m`

.
This usage of and-pattern is similar to the as-pattern in Haskell.

```
def primeTriples := matchAll primes as list integer with
| _ ++ $p :: ((#(p + 2) | #(p + 4)) & $m) :: #(p + 6) :: _
-> (p, m, p + 6)
take 6 primeTriples
-- [(5,7,11),(7,11,13),(11,13,17),(13,17,19),(17,19,23),(37,41,43)]
```

As an example of not-patterns, the following `matchAll`

enumerates sequential pairs of prime numbers that are not twin primes.
The not-pattern `!#(p + 2)`

matches values other than \(p + 2\).

```
take 10 (matchAll primes as list integer with
| _ ++ $p :: (!#(p + 2) & $q) :: _ -> (p, q))
-- [(2,3),(7,11),(13,17),(19,23),(23,29),(31,37),(37,41),(43,47),(47,53),(53,59)]
```

## Loop Patterns¶

A loop pattern is a pattern construct for representing a pattern that repeats itself multiple times. It is an extension of Kleene star operator of regular expressions for general non-free data types.

Let us start by considering pattern matching for enumerating all combinations of two elements from a target collection.
It can be written using `matchAll`

as follows.

```
def comb2 xs := matchAll xs as list something with
| _ ++ $x_1 :: _ ++ $x_2 :: _ -> [x_1, x_2]
comb2 [1,2,3,4] -- [[1,2],[1,3],[2,3],[1,4],[2,4],[3,4]]
```

Egison allows users to append indices to a pattern variable as `$x_1`

and `$x_2`

in the above sample.
They are called **indexed variables** and represent \(x_1\) and \(x_2\) in mathematical expressions.
The expression after `_`

must be evaluated to an integer and is called an **index**.
We can append as many indices as we want like `x_i_j_k`

.
When a value is bound to an indexed pattern variable `$x_i`

, the system initiates an abstract map consisting of key-value pairs if `x`

is not bound to a map, and bind it to `x`

.
If x is already bound to a map, a new key-value pair is added to this map.

Now, we generalize `comb2`

. The loop patterns can be used for this purpose.

```
def comb n xs := matchAll xs as list something with
| loop $i -- index variable
(1, n) -- index range
(_ ++ $x_i :: ...) -- repeat pattern
_ -- final pattern
-> map (\i -> x_i) [1..n]
comb 2 [1,2,3,4] -- [[1,2],[1,3],[2,3],[1,4],[2,4],[3,4]]
comb 3 [1,2,3,4] -- [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
```

A loop pattern consists of the following four elements.

- An
**index variable**is a variable to hold the current repeat count. - An
**index range**is a tuple of an initial number and final number which specifies the range of the index variable. - A
**repeat pattern**is a pattern repeated when the index variable is in the index range. - A
**final pattern**is a pattern expanded when the index variable gets out of the index range.

Inside of the repeat patterns, we can use the ellipsis pattern `...`

.
The repeat pattern or the final pattern is expanded at the location of the ellipsis pattern.
The repeat pattern is expanded replacing the ellipsis pattern incrementing the value of the index variable.
For example, when `n`

is 3, the above loop pattern is unfolded into as follows.

```
(loop $i (1, 3) (_ ++ $x_i :: ...) _)
_ ++ $x_1 :: (loop $i (2, 3) (_ ++ $x_i :: ...) _)
_ ++ $x_1 :: _ ++ $x_2 :: (loop $i (3, 3) (_ ++ $x_i :: ...) _)
_ ++ $x_1 :: _ ++ $x_2 :: _ ++ $x_3 :: (loop $i (4, 3) (_ ++ $x_i :: ...) _)
_ ++ $x_1 :: _ ++ $x_2 :: _ ++ $x_3 :: _
```

The repeat count of the loop patterns in the above example is constant. However, we can also write a loop pattern whose repeat count varies depending on the target by specifying a pattern instead of an integer as the final number. When the final number is a pattern, the ellipsis pattern is replaced with both the repeat pattern and the final pattern, and the repeat count when the ellipsis pattern is replaced with the final pattern is pattern-matched with that pattern. The following loop pattern enumerates all initial prefixes of the target collection.

```
matchAll [1,2,3,4] as list something with
| loop $i (1, $n) ($x_i :: ...) _ -> map (\i -> x_i) [1..n]
-- [[],[1],[1,2],[1,2,3],[1,2,3,4]]
```

## Sequential Patterns¶

The pattern-matching system of Egison processes patterns from left to right.
However, there are some cases where we want to change this order, for example, to refer to a pattern variable bound in the right side of a pattern.
**Sequential patterns** are provided for such cases.

Sequential patterns allow users to control the order of the pattern-matching process. A sequential pattern is represented as a list of patterns. Pattern matching is executed for each pattern in order. In the following sample, the target list is pattern-matched from the third, first, and second element in order.

```
matchAll [2,3,1,4,5] as list integer with
| [ @ :: @ :: $x :: _,
(#(x + 1), @ ),
#(x + 2)]
-> "Matched"
-- ["Matched"]
```

`@`

that appears in a sequential pattern is called **later pattern variable**.
The target data bound to later pattern variables are pattern-matched in the next sequence.
When multiple later pattern variables appear, they are pattern-matched as a tuple in the next sequence.

Sequential patterns allow us to apply not-patterns for different parts of a pattern at the same time.
For example, the following pattern matches when `xs`

and `ys`

have only one element in common.
The use of the sequential pattern in this example allows us to first check that the two collections have at least one element in common, and then make sure that there is no more common element in the remaining part of the collections.
Such combination of sequential patterns and not patterns is often useful when writing a mathematical algorithm.

```
def singleCommonElem :=
match (xs, ys) as (multiset eq, multiset eq) with
| [($x :: @, #x :: @),
!($y :: _, #y :: _)] -> True
```

Some readers might wonder if sequential patterns can be implemented using nested `matchAll`

expressions.
There are at least two reasons why it is impossible.
First, a nested `matchAll`

expression breaks breadth-first search strategy:
the inner `matchAll`

for the second result of the outer `matchAll`

is executed only after the inner `matchAll`

for the first result of the outer `matchAll`

is finished.
Second, a later pattern variable retains the information of not only a target but also a matcher.
There are cases that the matcher of `matchAll`

is a parameter passed as an argument of a function, and a pattern is polymorphic.
Therefore, it is impossible to determine the matchers of inner `matchAll`

expressions syntactically.

## Pattern functions¶

It is sometimes the case that the same combination of patterns appears at multiple locations of a program.
In such case, we can use **pattern functions** to give names to the combinations of patterns and avoid repetition.

A pattern function is a function which takes patterns as its argument and returns a pattern.
Its syntax is similar to that of lambda functions except that it uses `=>`

instead of `->`

.

The `twin`

in the following program is a pattern function and modularizes the double nested cons pattern.
The argument of pattern functions are called **variable patterns**, which are `pat1`

and `pat2`

in the following case.
Variable patterns must be prefixed with `~`

when referred to in the body of pattern functions.
This is necessary for distinguishing variable patterns from nullary pattern constructors.

```
def twin := \pat1 pat2 => (~pat1 & $x) :: #x :: ~pat2
match [1, 1, 2, 3] as list integer with
| twin $n $ns -> [n, ns]
-- [1, [2, 3]]
```

## Matcher compositions¶

All the matchers presented so far can be defined by users, except for the only built-in matcher `something`

.
Matchers are usually defined by the `matcher`

expressions, but users can define matchers by composing the existing matchers.
This way, we can for example define matchers for tuples of multisets and multisets of multisets.

First, we can define a matcher for tuples by a tuple of matchers. A tuple pattern is used for pattern matching using such a matcher. For example, we can define the intersect function using a matcher for tuples of two multisets.

```
def intersect xs ys := matchAll (xs,ys) as (multiset eq, multiset eq) with
| ($x :: _, #x :: _) -> x
```

`eq`

is a user-defined matcher for data types for which equality is defined.
When it is used, equality is checked for a value pattern.
By passing a tuple matcher to a function that takes and returns a matcher, we can define a matcher for various non-free data types.
For example, we can define a matcher for a graph as a set of edges as follows, where the nodes are represented by integers.

```
def graph := multiset (integer, integer)
```

A matcher for adjacency graphs can also be defined. An adjacency graph is defined as a multiset of tuples of an integer and a multiset of integers.

```
def adjacencyGraph := multiset (integer, multiset integer)
```

Egison provides a handy syntactic sugar for defining a matcher for algebraic data types,
while it can also be defined with `matcher`

expressions.
For example, a matcher for binary trees can be defined using `algebraicDataMatcher`

.

```
def binaryTree a := algebraicDataMatcher
| bLeaf a
| bNode a (binaryTree a) (binaryTree a)
```

Matchers for algebraic data types and matchers for non-free data types also can be composed. For example, we can define a matcher for trees whose nodes have an arbitrary number of children whose order is ignorable.

```
def tree a := algebraicDataMatcher
| leaf a
| node a (multiset (tree a))
```