Factual/drake — pull request #92 by stanistan (2013-09-14 18:57:26+00:00)
Title: drake.fs cleanup

Hey!

I was looking through the code and noticed these todos:

```
;; TODO(artem)
-;; I tried a lot of things but still don't know how to create a common
-;; ancestor in Clojure and inherit two other classes from it
-;; TODO(artem)
-;; We have to figure it out somehow, since adding direct calls to these
-;; functions in all descendants is a bit tiring.
```

And I've totally been there :)

The method for sharing method implementations in clojure is not the same as inheritance, you're actually using the function as a value itself. When looking at type definitions it's not completely obvious.

I also had to change `(.invoke fs path)` to `(invoke fs path)` in a bunch of places (but I think this is more idiomatic clojure) for the unit tests to pass (I'm not specifically sure why this behavior is different but probably because of usage of `extend`), and I tested basic functionality just in case, as I'm not really a user of your software.

Idea example of what the change is:

```clj
(defn common-method
[foo bar]
bar)

(defprotocol IIdentity
(id [this value] "should always return value passed in"))

(deftype MyType [])

(extend MyType
IIdentity
{:id common-method})

;; you can also do overrides or automatically do this
(def common-methods
{:id common-method})

(deftype MyOtherType [])
(extend MyOtherType
IIdentity
common-methods)

(deftype MyOtherValueOverrides [])
(extend MyOtherValueOverrides
IIdentity
(merge common-methods {:id (fn [this _] 2)}) ;; pointless, but w/e
```

__TLDR:__ Value based programming is awesome :)

Thanks for building a cool data workflow library and hope this is helpful.