diff options
author | JJ | 2024-05-15 01:32:38 +0000 |
---|---|---|
committer | JJ | 2024-05-15 06:33:29 +0000 |
commit | 3eb4346a1a250eca9e4cf52a9d7ba78ea8e11496 (patch) | |
tree | 5a933662a86a3be5aaf24bf40b9196a79c93dc34 /lc.rkt | |
parent | ff0746af8f430bbc70d5568858c980e2f141c0c0 (diff) |
implement the simply-typed lambda calculus
Diffstat (limited to 'lc.rkt')
-rw-r--r-- | lc.rkt | 24 |
1 files changed, 24 insertions, 0 deletions
@@ -0,0 +1,24 @@ +#lang racket +(require "lib.rkt") + +;; the untyped lambda calculus + +(define (interpret expr [ctx #hash()]) + (match expr + [val #:when (or (number? val) (string? val)) val] + [val #:when (symbol? val) + (with-handlers + ([exn:fail? (λ (exn) val)]) ; note: unbound identifiers are supported + (interpret (dict-ref ctx val) ctx))] + [`(λ ,id ,body) `(λ ,id ,body)] + [`(,body ,arg) + (match (interpret body ctx) + [`(λ ,id ,body) (interpret body (dict-set ctx id (interpret arg ctx)))] + [expr `(,(interpret expr ctx) ,(interpret arg ctx))])] + [expr (err (format "unknown expression ~a" expr))])) + +(require rackunit) +(check-equal? (interpret '(λ x x)) '(λ x x)) +(check-equal? (interpret '((λ a a) (x y))) '(x y)) +(check-equal? (interpret '((λ a (x y)) (λ z z))) '(x y)) +(check-equal? (interpret '((λ a (a y)) x)) '(x y)) |