;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "reader.ss" "plai" "lang")
; The following is a set of rules for implementing basic higher language
; functionality using only LAMBDA. It demonstrates the power of the Lambda
; Calculus, but is implemented in Scheme so that it can actually be
; evaluated.
;
; To make the result more readable, I use multiple argument procedures.
; These can be further reduced to single argument procedures by Currying.
;
; Note that there are many ways of implementing these functions in Lambda
; Calculus. I have chosen a representation that maps the most directly to
; the corresponding Scheme forms:
;
; Lists:
;
; (cons a b) -> (PAIR a b)
; (car p) -> (FIRST p)
; (cdr p) -> (REST p)
;
; Booleans and Conditionals:
;
; #t -> TRUE
; #f -> FALSE
; (if t c a) -> (IF t (λ() c) (λ() a))
; (not x) -> (NOT x)
; (and a b) -> (AND a (λ() b))
; (or a b) -> (OR a (λ() b))
;
; A pair is a represented as procedure that takes a 'which' function that
; itself selects one of the stored values to return.
(define PAIR (λ (a b) (λ (which) (which a b))))
; Alternatively, with Currying:
; (define PAIR (λ (a) (λ (b) (λ (which) (which a b)))))
; FIRST and REST are the selector procedures that can be used with a PAIR.
(define FIRST (λ (p) (p (λ (a b) a))))
(define REST (λ (p) (p (λ (a b) b))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Supports eager evaluation, but IF, AND, OR args must be
; wrapped in procedures. This is necessary to prevent infinite
; recursion later since Scheme is an eager evaluation language.
(define TRUE (λ (t f) t))
(define FALSE (λ (t f) f))
(define IF (λ (test t-proc f-proc)
((test t-proc f-proc))))
; Switch the order of arguments on NOT
(define NOT (λ (b) (λ (t f) (b f t))))
; Alternative by Mike Gerbush:
; (define NOT (λ (b) (b FALSE TRUE)))
(define AND (λ (a b-proc) (IF a b-proc (λ () FALSE))))
(define OR (λ (a b-proc) (IF a (λ () TRUE) b-proc)))
; Note that we can now redefine FIRST and REST as:
;(define FIRST (λ (p) (p TRUE)))
;(define REST (λ (p) (p FALSE)))