# The Calculus¶

Egel is based upon a small combinator calculus with a limited number of constructs. Below, that calculus is introduced with small examples.

## Constants¶

The smallest Egel expression is a constant.

```>> 0
0
```

Multiple constants compose.

```>> 1 2 3
(1 2 3)
```

Egel supports integers, floats, characters and Unicode strings.

```>> 'a' 3.14 "Hello!"
('a' 3.14 "Hello!")
```

You can define your own constant combinators. Constants are lower-case.

```>> data one, two, three
>> two
two
```

## The nameless pattern-matching abstraction¶

The basic work-horse of Egel is the nameless pattern-matching combinator. Roughly similar to an untyped lambda abstraction, where variables are uppercase.

```>> [ X -> X ] 5
5
```

The nameless pattern-matching combinator may consist of multiple alternatives which pattern match from left to right. You can mix variables and constants in patterns.

```>> [ 0 -> "zero" | 1 -> "one" | X -> "a lot" ] 1
"one"
```

You can match against multiple values.

```>> [ X Y -> X - Y ] 4 1
3
```

Caution

Often, you will want to put a space after a - symbol. Can you guess why? It’s because constants compose, so 2-1 are the two constants 2 and -1. Make sure to insert the space!

You can define combinators as named abstractions for terms.

```>> def id = [ X -> X ]
>> id "Hi!"
"Hi!"
```

Definitions may mention themselves, then they are recursive.

```>> def fac = [ 1 -> 1 | N -> N * fac (N - 1) ]
>> fac 3
6
```

Note

If you don’t understand the above definition then try replacing fac in the term fac 3. Like this, fac 3 = 3 * fac (3 - 1) = 3 * fac 2 = 3 * 2 * fac 1 = 3 * 2 * 1 = 6. Otherwise, look up ‘recursion’ on the Internet. Good luck!

Egel refuses to rewrite, or reduce, definitions where none of the patterns matched.

```>> def z = [ 0 -> 0 ]
>> z 1
(z 1)
```

In the example above, the combinator z can only reduce a 0, when given a 1 as an argument the interpreter refuses to reduce the term.

With let/in you can bind a variable to a value.

```>> let X = 3 in X + 2
5
```

A condition consists of an if/then/else statement.

```>> if 3 < 5 then "smaller" else "larger"
"smaller"
```

## Exceptions and exception handling¶

Egel supports exceptions, throw any value anywhere.

```>> 1 + throw "don't go here"
exception("don't go here")
```

You can also catch exceptions in a try/catch block. It reduces the try part, any exception thrown in there will handled by the provided catch handler.

```>> try 1 + throw "don't go here" catch [ E -> "caught:" E ]
("caught:" "don't go here")
```

That’s the whole calculus, you can now program in Egel.