2020-11-03 15:52:04 -08:00
# Lambda Calculus
2021-03-18 00:00:43 -07:00
This is a simple programming language derived from lambda calculus,
using the Hindley-Milner type system, plus some builtin types, `fix` , and `callcc`
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` ).
2021-03-18 00:00:43 -07:00
Type in your expression at the prompt: `>> ` . This will happen:
* the type for the expression will be inferred and then printed,
* then, regardless of whether typechecking succeeded, 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)`
2021-03-18 00:00:43 -07:00
* Constructors: `()` , `(x, y)` (or `(,) x y` ), `Left x` , `Right y` , `Z` , `S` , `[]` , `(x :: xs)` (or `(:) x xs` ), `Char n` .
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
* The parentheses around the cons constructor are not optional.
* `Char` takes a natural number and turns it into a character.
2021-03-18 00:00:43 -07:00
* Pattern matchers: `case { Left a -> e ; Right y -> f }`
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
* Pattern matchers can be applied like functions, e.g. `{ Z -> x, S -> y } 10` reduces to `y` .
2021-03-18 00:00:43 -07:00
* Patterns must use the regular form of the constructor, e.g. `(x :: xs)` and not `((::) x xs)` .
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
* 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-18 00:00:43 -07:00
* Type annotations: there are no type annotations; types are inferred only.
## Types
Types are checked/inferred using the Hindley-Milner type inference algorithm.
* Functions: `a -> b` (constructed by `\x. e` )
* Products: `a * b` (constructed by `(x, y)` )
* Unit: `★` (constructed by `()` )
* Sums: `a + b` (constructed by `Left x` or `Right y` )
* Bottom: `⊥` (currently useless because incomplete patterns are allowed)
* The natural numbers: `Nat` (constructed by `Z` and `S` )
* Lists: `List a` (constructed by `[]` and `(x :: xs)` )
* Characters: `Char` (constructed by `Char` , which takes a `Nat` )
* Universal quantification (forall): `∀a b. t`
2021-03-05 23:38:21 -08:00
2021-03-18 00:00:43 -07:00
## Builtins
Builtins are variables that correspond with a built-in language feature
that cannot be replicated by user-written code.
They still are just variables though; they do not receive special syntactic treatment.
2021-03-05 23:38:21 -08:00
2021-03-18 00:00:43 -07:00
* `fix : ∀a. ((a -> a) -> a)` : an alias for the strict fixpoint combinator that the typechecker can typecheck.
* `callcc : ∀a b. (((a -> b) -> a) -> a)` : [the call-with-current-continuation control flow operator ](https://en.wikipedia.org/wiki/Call-with-current-continuation ).
2021-03-05 23:38:21 -08:00
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
Create a list by iterating `f` `n` times:
```
2021-03-18 00:00:43 -07:00
fix \iterate f x. { Z -> [] ; S n -> (x :: iterate f (f x) n) }
: ∀e. ((e -> e) -> (e -> (Nat -> [e])))
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
```
2021-03-18 00:00:43 -07:00
Use the iterate function to count to 10:
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
```
2021-03-18 00:00:43 -07:00
>> let iterate = fix \iterate f x. { Z -> [] ; S n -> (x :: iterate f (f x) n) }; countTo = iterate S 1 in countTo 10
: [Nat]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
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
```
Append two lists together:
```
2021-03-18 00:00:43 -07:00
fix \append xs ys. { [] -> ys ; (x :: xs) -> (x :: append xs ys) } xs
: ∀j. ([j] -> ([j] -> [j]))
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
```
Reverse a list:
```
2021-03-18 00:00:43 -07:00
fix \reverse. { [] -> [] ; (x :: xs) -> append (reverse xs) [x] }
: ∀c1. ([c1] -> [c1])
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
```
Putting them together so we can reverse `"reverse"` :
```
2021-03-18 00:00:43 -07:00
>> let 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"
: [Char]
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
"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
2021-03-18 00:00:43 -07:00
: Nat
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
5
```
This expression would loop forever, but `callcc` saves the day!
```
2021-03-18 00:00:43 -07:00
>> S (callcc \k. (fix \x. x) (k Z))
: Nat
1
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
```
2021-03-18 00:00:43 -07:00
And if it wasn't clear, this is what the `Char` constructor does:
```
>> { Char c -> Char (S c) } 'a
: Char
'b
```
Here are a few expressions which don't typecheck but are handy for debugging the evaluator:
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
```
>> 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'
```