2019-08-29 20:46:42 -07:00
|
|
|
# James Martin's Lambda Calculus
|
|
|
|
An implementation of various type systems and evaluation strategies
|
|
|
|
for the lambda calculus.
|
2019-08-15 10:42:24 -07:00
|
|
|
|
2019-08-29 20:46:42 -07:00
|
|
|
This project is a work-in-progress, and currently lacks many essential features
|
|
|
|
that would be necessary to be a useful programming language.
|
2019-08-15 10:42:24 -07:00
|
|
|
|
|
|
|
## Usage
|
|
|
|
Type in your expression at the prompt: `>> `.
|
|
|
|
The result of the evaluation of that expression will then be printed out.
|
|
|
|
Exit the prompt with `Ctrl-C` (or however else you kill a program in your terminal).
|
|
|
|
|
|
|
|
Bound variables will be printed followed by a number representing the number of binders
|
|
|
|
between it and its definition for disambiguation.
|
2019-08-19 15:08:45 -07:00
|
|
|
|
2019-08-21 15:18:25 -07:00
|
|
|
### Example session
|
2019-08-15 10:42:24 -07:00
|
|
|
```
|
2019-08-21 15:18:25 -07:00
|
|
|
>> let D = (\x. x x) in let F = (\f. f (f y)) in D (F ())
|
2019-08-15 10:42:24 -07:00
|
|
|
y y
|
2019-08-21 15:18:25 -07:00
|
|
|
>> let T = (\f x. f (f x)) in (\f x. T (T (T (T T))) f x) () y
|
2019-08-15 13:11:17 -07:00
|
|
|
y
|
2019-08-15 10:42:24 -07:00
|
|
|
>> \x. \y. y x
|
|
|
|
\x. \y. y:0 x:1
|
2019-08-21 15:18:25 -07:00
|
|
|
>> ^C
|
2019-08-15 10:42:24 -07:00
|
|
|
```
|
|
|
|
|
2019-08-21 15:18:25 -07:00
|
|
|
## Notation
|
|
|
|
[Conventional Lambda Calculus notation applies](https://en.wikipedia.org/wiki/Lambda_calculus_definition#Notation),
|
|
|
|
with the exception that variable names are mmultiple characters long,
|
|
|
|
and `\` is used in lieu of `λ` for convenience.
|
|
|
|
|
|
|
|
* Variable names are alphanumeric, beginning with a letter.
|
|
|
|
* Outermost parentheses may be dropped: `M N` is equivalent to `(M N)`.
|
|
|
|
* Applications are left-associative: `M N P` may be written instead of `((M N) P)`.
|
|
|
|
* The body of an abstraction extends as far right as possible: `\x. M N` means `\x.(M N)` and not ``(\x. M) N`.
|
|
|
|
* A sequence of abstractions may be contracted: `\foo. \bar. \baz. N` may be abbreviated as `\foo bar baz. N`.
|
|
|
|
* Variables may be bound using let expressions: `let x = N in M` abbreviates `(\x. N) M`.
|
|
|
|
|
|
|
|
### Violations of convention
|
|
|
|
* I use spaces to separate variables in abstractions instead of commas because I think it looks better.
|
|
|
|
|
|
|
|
### Additional extensions to notation
|
|
|
|
Since `\x. x` is the left identity of applications and application syntax is left-associative,
|
|
|
|
I (syntactically) permit unary and nullary applications so that `()` is `\x. x`, and `(x)` is `x`.
|
2019-08-15 10:42:24 -07:00
|
|
|
|
2019-08-21 15:18:25 -07:00
|
|
|
On the same principle, the syntax of a lambda of no variables `\. e` is `e`.
|
2019-08-29 20:46:42 -07:00
|
|
|
|
|
|
|
## Roadmap
|
|
|
|
### Complete
|
|
|
|
* Type systems:
|
|
|
|
* Untyped
|
|
|
|
* Representations:
|
|
|
|
* The syntax tree
|
|
|
|
* Reverse de Bruijn
|
|
|
|
* Syntax:
|
|
|
|
* Basic syntax
|
|
|
|
* Let expressions
|
|
|
|
* Evaluation strategies:
|
|
|
|
* Lazy (call-by-name to normal form)
|
|
|
|
|
|
|
|
### In-progress
|
|
|
|
* Type systems:
|
|
|
|
* Simply typed
|
|
|
|
* Representations:
|
|
|
|
* De Bruijn
|
|
|
|
|
|
|
|
### Planned
|
|
|
|
My ultimate goal is to develop this into a programming language
|
|
|
|
that would at least theoretically be practically useful.
|
|
|
|
I intend to do a lot more than this in the long run,
|
|
|
|
but it's far enough off that I haven't nailed down the specifics yet.
|
|
|
|
|
|
|
|
* Built-ins:
|
|
|
|
* Integers
|
|
|
|
* Type systems:
|
|
|
|
* Hindley-Milner
|
|
|
|
* System F
|
|
|
|
* Representations:
|
|
|
|
* A more conservative syntax tree that would allow for better error messages
|
|
|
|
* Evaluation strategies:
|
|
|
|
* Complete laziness
|
|
|
|
* Optimal
|
|
|
|
* Syntax:
|
|
|
|
* Top-level definitions
|
|
|
|
* Type annotations
|
|
|
|
* `let*`, `letrec`
|
|
|
|
* More syntax (parsing and printing) options:
|
|
|
|
* Also allow warnings instead of errors on disabled syntax.
|
|
|
|
* Or set a preferred printing style without warnings.
|
|
|
|
* Or print in an entirely different syntax than the input!
|
|
|
|
* Disable empty `application`: `()` no longer parses (as `\x. x`).
|
|
|
|
* Forbid single-term `application`: `(x)` no longer parses as `x`.
|
|
|
|
* Disable empty `variable-list`: `λ. x` no longer parses (as just `x`).
|
|
|
|
* Disable block arguments: `f λx. x` is no longer permitted; `f (λx. x)` must be used instead.
|
|
|
|
* Except for at the top level, where an unclosed lambda is always permitted.
|
|
|
|
* Configurable `variable-list` syntax:
|
|
|
|
* Mathematics style: One-letter variable names, no variable separators.
|
|
|
|
* Computer science style: Variable names separated by commas instead of spaces.
|
|
|
|
* Configurable `λ` syntax: any one of `λ`, `\`, or `^`, as I've seen all three in use.
|
|
|
|
* Currently, either `λ` or `\` is permitted, and it is impossible to disable either.
|
|
|
|
* Disable `let` expressions.
|
|
|
|
* Disable syntactic sugar entirely (never drop parentheses).
|
|
|
|
* Pedantic mode: forbid using more parentheses than necessary.
|
|
|
|
* Pedantic whitespace (e.g. forbid ` ( a b c)`).
|
|
|
|
* Pretty-printing mode.
|
|
|
|
* Indentation-based syntax.
|
|
|
|
* Features:
|
|
|
|
* A better REPL (e.g. the ability to edit the line buffer)
|
|
|
|
* The ability to import external files
|
|
|
|
* The ability to choose the type system or evaluation strategy
|
|
|
|
* Better error messages for parsing and typechecking
|
|
|
|
* Reduction stepping
|