# OBJECT introduce simple form of typing, for ease of documentation.
# An object is simply a function that takes an argument.
# The argument is the method to call on the object.
# Types are here taken to be just the existence of a particular method,
# with that method returning an object of the appropriate type.
[hear] (define make-integer
(lambda (v)
(lambda (x)
(if (= (x) int)
(v)
0))));
[hear] (define objectify
(? x
(if (number? (x))
(make-integer (x))
(x))));
[hear] (define instanceof
(lambda (T t)
(if (number? (t))
(= (T) int)
(not (number? ((objectify (t)) (T)))))));
# add version of lambda that allows types to be declared
[hear] (define prev-translate (translate));
[hear] (define translate
(let ((prev (prev-translate)))
(? x
(if (number? (x))
(prev (x))
(if (= (head (x)) lambda)
(let ((formals (head (tail (x))))
(body (head (tail (tail (x))))))
(if (> (list-length (formals)) 0)
(if (number? (last (formals)))
(translate
(vector
lambda
(except-last (formals))
(vector ? (last (formals)) (body))))
(let ((formal-name (first (last (formals))))
(formal-type (second (last (formals)))))
(translate
(vector
lambda
(except-last (formals))
(vector
?
(formal-name)
(vector
let
(vector (vector
(formal-name)
(vector
(vector objectify (vector (formal-name)))
(formal-type))))
(body)))))))
(translate (body))))
(prev (x)))))));
# add conditional form
[hear] (define prev-translate (translate));
[hear] (define translate
(let ((prev (prev-translate)))
(? x
(if (number? (x))
(prev (x))
(if (= (head (x)) cond)
(let ((cnd (head (tail (x))))
(rem (tail (tail (x)))))
(if (> (list-length (rem)) 0)
(translate
(vector
if
(first (cnd))
(second (cnd))
(prepend cond (rem))))
(translate (cnd))))
(prev (x)))))));
[hear] (= 99 (cond 99));
[hear] (= 8 (cond ((true) 8) 11));
[hear] (= 11 (cond ((false) 8) 11));
[hear] (= 7 (cond ((false) 3) ((true) 7) 11));
[hear] (= 3 (cond ((true) 3) ((true) 7) 11));
[hear] (= 11 (cond ((false) 3) ((false) 7) 11));
[hear] (define remove-match
(lambda (test lst)
(if (> (list-length (lst)) 0)
(if (test (head (lst)))
(remove-match (test) (tail (lst)))
(prepend (head (lst)) (remove-match (test) (tail (lst)))))
(lst))));
[hear] (define remove-element
(lambda (x)
(remove-match (lambda (y) (= (y) (x))))));
[hear] (list= (vector 1 2 3 5) (remove-element 4 (vector 1 2 3 4 5)));
[hear] (list= (vector 1 2 3 5) (remove-element 4 (vector 1 4 2 4 3 4 5)));
[hear] (define return
(lambda (T t)
(let ((obj (objectify (t))))
(obj (T)))));
[hear] (define tester
(lambda ((x int) (y int))
(return int (+ (x) (y)))));
[hear] (= 42 (tester (make-integer 10) (make-integer 32)));
[hear] (= 42 (tester 10 32));
[hear] (define reflective
(lambda (f)
((lambda (x)
(f (lambda (y) ((x (x)) (y)))))
(lambda (x)
(f (lambda (y) ((x (x)) (y))))))));