ラムダがあれば何でもできる!元気d(ry

ただ(型なし)ラムダ計算を用いて形式的に記述してゆくだけの遊びです。
言語はSchemeを選択しました。(途中までPythonを使っていたのは秘密)

(define true  (lambda (x y) x))
(define false (lambda (x y) y))
(define if_   (lambda (p x y) (p x y)))
;; マクロで遅延評価。(マクロは式の変換だから使ってもOK?)
(define-syntax if.
  (syntax-rules ()
    ((if. p x y)
     ((if_ p (lambda () x) (lambda () y))) )))

(define and. (lambda (p q) (if. p q false)))
(define or.  (lambda (p q) (if. p true q)))
(define not. (lambda (p) (if. p false true)))

;; 部分適用できないので、手動でカリー化
(define pair (lambda (x y)
               (lambda (f) (f x y)) ))
(define fst  (lambda (p) (p true)))
(define snd  (lambda (p) (p false)))

(define nil   (lambda (x) x))
(define null  fst)
(define cons. (lambda (x y) (pair false (pair x y))))
(define hd    (lambda (x) (fst (snd x))))
(define tl    (lambda (x) (snd (snd x))))

;; ただのIコンビネータ
(define I nil)

(define lisp
  (lambda (f lst end)
    (if. (null lst)
         end
         (cons. (f (hd lst)) (lisp f (tl lst) end)) )))

(define append. (lambda (x y) (lisp I x y)))
(define map.    (lambda (f lst) (lisp f lst nil)))

(define fold-left
  (lambda (f e lst)
    (if. (null lst)
         e
         (fold-left f (f e (hd lst)) (tl lst)) )))
         
;; ネストしたリストには対応してない
(define (print-list x)
  (if. (null x)
       (display "nil")
       (begin (display (hd x))
              (display " ")
              (print-list (tl x)) )))

;; 本当はチャーチ数を使うべきだけど割愛!
(define (list*2 x)
    (map. (lambda (x) (* 2 x)) x) )

(define (length. x)
    (fold-left + 0 (map. (lambda (_) 1) x)) )

;; tests
(define a (cons. 1 (cons. 2 nil)))
(define b (cons. 3 (cons. 4 nil)))
(define c (append. a b))
(define d (list*2 c))
(define e (length. c))

> (print-list c)
1 2 3 4 nil
> (print-list d)
2 4 6 8 nil
> e
4