2020-11-03 15:52:04 -08:00
# Lambda Calculus
Add support for many data types, pattern matching, and literals.
* Data types: products, sums, naturals, lists, characters
* Literals: naturals, lists, characters, and strings
I also updated the description with examples of how to use all these new features.
The code's a bit messy and will need cleanup, but for now, it works!
2021-03-17 00:20:17 -07:00
This is a simple programming language derived from lambda calculus.
2019-08-15 10:42:24 -07:00
## Usage
2021-03-05 23:38:21 -08:00
Run the program using `stack run` (or run the tests with `stack test` ).
2019-08-15 10:42:24 -07:00
Type in your expression at the prompt: `>> ` .
2021-03-05 23:38:21 -08:00
The expression will be evaluated to normal form using the call-by-value evaluation strategy and then printed.
2020-11-02 15:59:35 -08:00
Exit the prompt with `Ctrl-c` (or equivalent).
2019-08-19 15:08:45 -07:00
Add support for many data types, pattern matching, and literals.
* Data types: products, sums, naturals, lists, characters
* Literals: naturals, lists, characters, and strings
I also updated the description with examples of how to use all these new features.
The code's a bit messy and will need cleanup, but for now, it works!
2021-03-17 00:20:17 -07:00
## Syntax
The parser's error messages currently are virtually useless, so be very careful with your syntax.
2019-08-15 10:42:24 -07:00
Add support for many data types, pattern matching, and literals.
* Data types: products, sums, naturals, lists, characters
* Literals: naturals, lists, characters, and strings
I also updated the description with examples of how to use all these new features.
The code's a bit messy and will need cleanup, but for now, it works!
2021-03-17 00:20:17 -07:00
* Variable names: any sequence of letters.
* Function application: `f x y`
* Lambda abstraction: `\x y z. E` or `λx y z. E`
* Let expressions: `let x = E; y = F in G`
* Parenthetical expressions: `(E)`
* Constructors: `()` , `(x, y)` (or `(,) x y` ), `Left x` , `Right y` , `Z` , `S` , `[]` , `(x : xs)` (or `(:) x xs` ), `Char n` .
* The parentheses around the cons constructor are not optional.
* `Char` takes a natural number and turns it into a character.
* Pattern matchers: `{ Left x -> e ; Right y -> f }`
* Pattern matchers can be applied like functions, e.g. `{ Z -> x, S -> y } 10` reduces to `y` .
* Patterns must use the regular form of the constructor, e.g. `(x : xs)` and not `((:) x xs)` .
* There are no nested patterns or default patterns.
* Incomplete pattern matches will crash the interpreter.
* Literals: `1234` , `[e, f, g, h]` , `'a` , `"abc"`
* Strings are represented as lists of characters.
2021-03-05 23:38:21 -08:00
## Call/CC
This interpreter has preliminary support for
[the call-with-current-continuation control flow operator ](https://en.wikipedia.org/wiki/Call-with-current-continuation ).
However, it has not been thoroughly tested.
To use it, simply apply the variable `callcc` like you would a function, e.g. `(callcc (\k. ...))` .
Continuations are printed as `λ!. ... ! ...` , like a lambda abstraction
with an argument named `!` which is used exactly once;
however, continuations are *not* the same as lambda abstractions
because they perform the side effect of modifying the current continuation,
and this is *not* valid syntax you can input into the REPL.
Add support for many data types, pattern matching, and literals.
* Data types: products, sums, naturals, lists, characters
* Literals: naturals, lists, characters, and strings
I also updated the description with examples of how to use all these new features.
The code's a bit messy and will need cleanup, but for now, it works!
2021-03-17 00:20:17 -07:00
## Example code
The fixpoint function:
```
(\x. x x) \fix f x. f (fix fix f) x
```
Create a list by iterating `f` `n` times:
```
fix \iterate f x. { Z -> x ; S n -> iterate f (f x) n }
```
Create a list whose first element is `n - 1` , counting down to a last element of `0` :
```
\n. { (n, x) -> x } (iterate { (n, x) -> (S n, (n : x)) } (0, []) n)
```
Putting it all together to count down from 10:
```
>> let fix = (\x. x x) \fix f x. f (fix fix f) x; iterate = fix \iterate f x. { Z -> x ; S n -> iterate f (f x) n }; countDownFrom = \n. { (n, x) -> x } (iterate { (n, x) -> (S n, (n : x)) } (0, []) n) in countDownFrom 10
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
```
Append two lists together:
```
fix \append xs ys. { [] -> ys ; (x : xs) -> (x : append xs ys) } xs
```
Reverse a list:
```
fix \reverse. { [] -> [] ; (x : xs) -> append (reverse xs) [x] }
```
Putting them together so we can reverse `"reverse"` :
```
>> let fix = (\x. x x) \fix f x. f (fix fix f) x; append = fix \append xs ys. { [] -> ys ; (x : xs) -> (x : append xs ys) } xs; reverse = fix \reverse. { [] -> [] ; (x : xs) -> append (reverse xs) [x] } in reverse "reverse"
"esrever"
```
Calculating `3 + 2` with the help of Church-encoded numerals:
```
>> let Sf = \n f x. f (n f x); plus = \x. x Sf in plus (\f x. f (f (f x))) (\f x. f (f x)) S Z
5
```
This expression would loop forever, but `callcc` saves the day!
```
>> y (callcc \k. (\x. (\x. x x) (\x. x x)) (k z))
y z
```
A few other weird expressions:
```
>> let D = \x. x x; F = \f. f (f y) in D (F \x. x)
y y
>> let T = \f x. f (f x) in (\f x. T (T (T (T T))) f x) (\x. x) y
y
>> (\x y z. x y) y
λy' z. y y'
>> { Char c -> Char (S c) } 'a
'b
```