Skip to content

jogrms/kin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kin

A simple implementation of the function inheritance mechanism described in the paper by Daniel Brown and William R. Cook.

Traditionally, an unrelated quote:

A great doom awaits you, either to rise above the height of all your fathers since the days of Elendil, or to fall into darkness with all that is left of your kin. Many years of trial lie before you.

Lord Elrond

Installation

Clojars Project

Usage

(use 'kin.core)
(use 'kin.mixins)

Suppose that you are trying to define a recursive version of fib and apply memoization to it. You can start by defining a recursive fib generator using the defgen macro:

(defgen fib [x]
  (if (< x 2)
    1
    (+ (fib (dec x))
       (fib (- x 2)))))

defgen uses the same syntax as defn but produces a generator along with the function. There is also the fgen macro which substitutes fn in a similar way. You can use fib as a regular function:

(map fib (range 6))
;; => (1 1 2 3 5 8)

Or you can extract the generator using the gen function and compute the fixed point using fix:

((-> fib gen fix) 4)
;; => 5

Now let's define a version of fib that traces all the calls and parameters using the trace mixin:

(def fib-trace (inherit fib (trace 'fib)))

(fib-trace 4)
;; (fib 4)
;; (fib 3)
;; (fib 2)
;; (fib 1)
;; (fib 0)
;; (fib 1)
;; (fib 2)
;; (fib 1)
;; (fib 0)
;; => 5

And memoization using the memo mixin:

(def fib-trace-memo (inherit fib-trace (memo)))
;; or
(def fib-trace-memo* (inherit fib (trace 'fib) (memo)))

(fib-trace-memo 4)
;; (fib 4)
;; (fib 3)
;; (fib 2)
;; (fib 1)
;; (fib 0)
;; => 5

(fib-trace-memo 4)
;; => 5

Writing your own mixins

Suppose that you want to implement some custom logger that logs all calls to a function and stores them in a vector:

(defn logger [l]
  (fn [self]
    (fn [& args]
      (swap! l conj (str "args: " args))
      (apply self args))))

Let's try it:

(def log (atom []))
(def fib-logger (inherit fib (logger log)))
(fib-logger 4)
;; => 5
(pprint @log)
;; ["args: (4)"
;;  "args: (3)"
;;  "args: (2)"
;;  "args: (1)"
;;  "args: (0)"
;;  "args: (1)"
;;  "args: (2)"
;;  "args: (1)"
;;  "args: (0)"]

About

A simple function inheritance library for Clojure

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published