Using combinators to derive functional paradigms

(defn list-length-nr \
(fn \
(if (empty? l)
0
(inc (rec (rest l)))) ))

;; How about reversing a list? This one’s really recursive (quadruply)!
;; ((Y (fn \
;; (fn \
;; (cond (empty? l) ‘()
;; (empty? (rest l)) (list (first l))
;; :else (cons (first (rec (rest l)))
;; (rec (cons (first l)
;; (rec (rest (rec (rest
;; l)))) )))) )))
;; ‘(a b c d e))
;; => (e d c b a)

(defn list-reverse-nr \
(fn \
(cond (empty? l) ‘()
(empty? (rest l)) (list (first l))
:else (cons (first (rec (rest l)))
(rec (cons (first l)
(rec (rest (rec (rest l)))) )))) ))

;; There’s even an experimental version of Y that can handle anonymous
;; functions with multiple parameters:
;; (defn Y2 \
;; ((fn \
;; (m (fn \
;; (apply (future future) args))))
;; (fn \
;; (m (fn \
;; (apply (future future) args)))) ))

;; Using this we can remove elements that we don’t want from a list:
;; ((Y2 (fn \
;; (fn \
;; (cond (empty? l) ‘()
;; (= (first l) obj) (rec obj (rest l))
;; :else (cons (first l) (rec obj (rest l)))) )))
;; ‘pung
;; ‘(pung foo bar baz pung baz bar pung foo))
;; => (foo bar baz baz bar foo)

;; Replace certain elements in a list:
;; ((Y2 (fn \
;; (fn \
;; (cond (empty? l) ‘()
;; (= (first l) old) (cons new (rec new old (rest l)))
;; :else (cons (first l) (rec new old (rest l)))) )))
;; ‘pung
;; ‘foo
;; ‘(pung foo bar baz pung bar foo))
;; => (pung pung bar baz pung bar pung)

;; Or in an arbitrary tree:
;; ((Y2 (fn \
;; (fn \
;; (cond (= obj old) new
;; (and (coll? obj) (seq obj)) (cons (rec new old (first
;; obj))
;; (rec new old (rest
;; obj)))
;; :else obj))))
;; ‘a
;; ‘b
;; ‘(a ((b) c (a b c)) d (a b)))
;; => (a ((a) c (a a c)) d (a a))

;; Now here’s the exciting part. I’m trying to work out some sort of
;; licensing deal for us. If the price is right we can use APRiL 1.0 to
;; streamline Clojure code. For instance, we won’t need ‘map’ anymore:
;; ((Y2 (fn \
;; (fn \
;; (if (empty? l)
;; ‘()
;; (cons (f (first l)) (rec f (rest l)))) )))
;; inc
;; (range 10))
;; => (1 2 3 4 5 6 7 8 9 10)

(defn custom-map-nr \
(fn \
(if (empty? l)
‘()
(cons (f (first l)) (rec f (rest l)))) ))
;; viksit.explorations> ((Y2 custom-map-nr) inc (range 10))
;; (1 2 3 4 5 6 7 8 9 10)

;; ((Y2 (fn \
;; (fn \
;; (if (empty? l)
;; ‘()
;; (cons (f (first l)) (rec f (rest l)))) )))
;; #(.toUpperCase %)
;; ‘(“Is” “this” “not” “pung?”))
;; => (“IS” “THIS” “NOT” “PUNG?”)

;; But wait, there’s more!! We won’t need ‘reduce’ either:
;; ((Y2 (fn \
;; (fn \
;; (if (empty? l)
;; start
;; (f (first l) (rec f start (rest l)))) )))
;; +
;; 0
;; )
;; => 15

(defn custom-reduce-nr \
(fn \
(if (empty? l)
start
(f (first l) (rec f start (rest l)))) ))

;; viksit.explorations> ((Y2 custom-reduce-nr) + 0 (range 10))
;; 45

;; ((Y2 (fn \
;; (fn \
;; (if (empty? l)
;; start
;; (f (first l) (rec f start (rest l)))) )))
;; *
;; 1
;; )
;; => 720

;; I hope that you can start to see the potential here! There are no
;; doubt many other superfluous operators just clogging up Clojure that
;; you’d rather live without (No offense, Rich. I’m sure you tried your
;; best. :-) ). I’m eager to hear your suggestions!!

;; I’m optimistic that the company is willing to work with us, but if
;; their price is too high they do have another cheaper option. There is
;; a reduced rate anonymous Y function as well. Even Y doesn’t need a
;; name–we just use it directly. Cut out the middleman and everyone wins!

;; Here’s ‘length’ again:
;; (((fn \
;; ((fn \
;; (m (fn \
;; ((future future) arg))))
;; (fn \
;; (m (fn \
;; ((future future) arg)))) ))
;; (fn \
;; (fn \
;; (if (empty? l)
;; 0
;; (inc (rec (rest l)))) )))
;; ‘(a b c d e))
;; => 5

;; And ‘reverse’:
;; (((fn \
;; ((fn \
;; (m (fn \
;; ((future future) arg))))
;; (fn \
;; (m (fn \
;; ((future future) arg)))) ))
;; (fn \
;; (fn \
;; (cond (empty? l) ‘()
;; (empty? (rest l)) (list (first l))
;; :else (cons (first (rec (rest l)))
;; (rec (cons (first l)
;; (rec (rest (rec (rest l)))) )))) )))
;; ‘(a b c d e))
;; => (e d c b a)

;; Breathtaking in its elegance!

--

If you have any questions or thoughts, don't hesitate to reach out. You can find me as @viksit on Twitter.