; Y-combinator for descartes Lisp/ 

;; Y-combinator

(define Y 
  fp (f a ((p p) a))
     p (f a ((p p) a)))


;; factorial
(define fact 
  fn 
        (cond 
          ((<= n 1) 1) 
           (T (* n (f (- n 1))))))

((Y fact) 5) 

;; Factorial by  type 1
((( (f) (( (p) (f ( (a) ((p p) a)))) ( (p) (f ( (a) ((p p) a))))))
  ( (f) ( (n) (cond ((<= n 1) 1) (T (* n (f (- n 1))))))))
  6)

;; Factorial by  type 2
(( (n) (cond ((<= n 1) 1) (T (* n (( (n) (cond ((<= n 1) 1) (T (* n (( (a)
((( (p) (( (f) ( (n) (cond ((<= n 1) 1) (T (* n (f (- n 1))))))) (p p) a))
 ( (p) (( (f) ( (n) (cond ((<= n 1) 1) (T (* n (f (- n 1))))))) (p p) a)))
 a)) (- n 1)))))) (- n 1))))))
7)

;; list length

(define length
  fl
        (cond 
          ((equal l ()) 0) 
          ((atom l) 1)
          (T (+ (f (cdr l)) 1))))

((Y length) '(a b c)) 

;; length by  type1
((( (f) (f (( (p) (f ( (a) ((p p) a)))) ( (p) (f ( (a) ((p p) a))))) a))
 ( (f) ( (l) (cond ((equal l ()) 0) ((atom l) 1) (T (+ (f (cdr l)) 1))))))
 '(1 2 3 4 5 6 7))

;; length by  type2
(( (l) (cond ((equal l ()) 0) ((atom l) 1) (T (+ (( (l) (cond ((equal l ()) 0) ((atom l) 1) (T (+ (( (a) ((( (p) (( (f) ( (l) (cond ((equal l ()) 0) ((atom l) 1) (T (+ (f (cdr l)) 1))))) (p p) a)) ( (p) (( (f) ( (l) (cond ((equal l ()) 0) ((atom l) 1) (T (+ (f (cdr l)) 1))))) (p p) a))) a)) (cdr l)) 1)))) (cdr l)) 1))))
 '(1 2 3 4 5 6 7))

;; Fibonacci number

(define fib
  fn 
        (cond 
          ((= n 0) 0) 
          ((= n 1) 1) 
          (T (+ (f (- n 1)) (f (- n 2))))))


((Y fib) 3)

;; Fibonacci by  type1
((( (f) (f (( (p) (f ( (a) ((p p) a)))) ( (p) (f ( (a) ((p p) a))))) a))
  ( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))))
  4)

;; Fibonacci by  type2
(( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (( (a) ((( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a)) ( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a))) a)) (- n 1)) (( (a) ((( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a)) ( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a))) a)) (- n 2)))))) (- n 1)) (( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (( (a) ((( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a)) ( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a))) a)) (- n 1)) (( (a) ((( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a)) ( (p) (( (f) ( (n) (cond ((= n 0) 0) ((= n 1) 1) (T (+ (f (- n 1)) (f (- n 2))))))) (p p) a))) a)) (- n 2)))))) (- n 2))))))
  5)


