; Can you rewrite your function for the ycombinator?
; ------------------------------
; The Little Lisper 3rd Edition
; Chapter 9
; Exercise 3
; Common Lisp
; http://t...content-available-to-author-only...r.com/thelittlelisper
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper-chapter-9-lamdba-ultimate.html
; http://t...content-available-to-author-only...t.com/2010/06/little-lisper.html
; ------------------------------

;Y-combinator for functions of two arguments
;rewritten for lisp-2 namespace - and removed first lambda
(defun Y2 (M)
      ((lambda (future)
         (funcall M (function (lambda (arg1 arg2)
                                (funcall (funcall future future) arg1 arg2)))))       
                                
       (function (lambda (future)                                      
                   (funcall M (lambda (arg1 arg2)                                
                                (funcall (funcall future future) arg1 arg2)))))))

                                
; Note that we have to use symbol-fucntion to get around the lisp-2 namespace                                

(setf (symbol-function '_=)
  (Y2 (function (lambda (recurring-function)
                 (function (lambda (m n)
                                   (cond
                                    ((> n m) nil)                                    
                                    ((< n m) nil)                                    
                                    (t t))))))))

(_= 1 2)
;NIL false

(_= 2 2)
;T

(setf zero 0)

(defun zero (n)
  (cond
   ((null n) '())
   ((= zero n) t)
   (t '())))

(defun sub1 (n)
  (cond
   ((null n) '())
   ((- n 1))))

(setf (symbol-function 'pick)
  (Y2 (function (lambda (recurring-function)
                 (function (lambda (n lat)
                             (cond
                              ((null lat) nil)
                              ((zero (sub1 n)) (car lat))
                              (t (funcall recurring-function (sub1 n) (cdr lat))))))))))
 
(print (pick 3 '(a b c d e f g h i j))                           )

(setf (symbol-function 'rempick)
  (Y2 (function (lambda (recurring-function)
                 (function (lambda (n lat)
                             (cond
                              ((null lat) '())
                              ((zero (sub1 n)) (cdr lat))
                              (t (cons (car lat)
                                       (funcall recurring-function (sub1 n)(cdr lat)))))))))))

(print (rempick 3 '(a b c d e f g h i j)))



#This is the definition from Rosetta - but we're not using it here in order to match the
#idomatic style of the book
#http://r...content-available-to-author-only...e.org/wiki/Y_combinator#Common_Lisp

(defun Y (f) 
  ((lambda (x) (funcall x x)) 
   (lambda (y) 
     (funcall f (lambda (&rest args) 
		  (apply (funcall y y) args))))))
 
(defun fac (f) 
  (lambda (n) 
    (if (zerop n) 
	1 
	(* n (funcall f (1- n))))))
 
(defun fib (f) 
  (lambda (n) 
    (case n
      (0 0) 
      (1 1) 
      (otherwise (+ (funcall f (- n 1)) 
		    (funcall f (- n 2)))))))
 
;; CL-USER> (loop for i from 1 to 10 collect (list i (funcall (Y #'fac) i) (funcall (Y #'fib) i)))
;; ((1 1 1) (2 2 1) (3 6 2) (4 24 3) (5 120 5) (6 720 8) (7 5040 13)
;;  (8 40320 21) (9 362880 34) (10 3628800 55))
