I came across to functional programming after years of mainstream OO
and had object-oriented values pretty deeply ingrained when I started
learning (Haskell/Scala flavored-) FP. It took me a while to see with
new eyes, and make my peace with this issue.
Going purely by Brain's quote, I think I have reached a different
formulation. To me, Haskellers and OOers as pursuing the same basic
and worthy goal, but employing different implementation techniques to
get there. The goal is "abstraction over data", that is, to write
common code (for example, a sort function) that works over different
"sortable" data.
OO uses classes & inheritance: Dispatch is at runtime based upon the
special asymmetric first argument (ie the "this" pointer), class
pointers are maintained for every object in in the heap, an object
cannot change its class , nor re-implement the same interface
differently, for different code contexts.
Haskell (and potentially Scala) use Typeclasses: Dispatch is at
compile time, based on the static types. It's Symmetric - ie the first
argument has no special status (no "this" pointer). Class pointers are
not required in the heap. Data can be operated on by different
instances of a type class in different contexts The same interface can
be re-implemented multiple times, for example, Monoid[Int] can be Max,
Min, Sum, Product. Unlike OO, the user of a data type is not locked
into using the implementation provided by the creator of the data
item; it's bring-your-own if you wish. On the downside, where type
information is "forgotten", eg a heterogeneous collection of unknown
types of sortable data, existential types are needed to encode the
equivalent of OO dispatch over the elements.
Overall, I've become convinced that the typeclass model is superior,
for most use cases.
I now see OO dispatch as a way of getting some abstraction over data,
that could be implemented with what was available back in the 80's
when it was developed. But around this "implementation trick", such a
self-reinforcing body of folklore has sprung up, that if all the books
of "object-oriented wisdom" ever printed were stacked together, they'd
stretch to the moon and back twice.
Whereas, to work well, typeclasses need a much more sophisticated
compiler and type-system than OO does, hence their later evolution in
the 90s. Being type-driven, they're also not an option for
"dynamically typed" FP languages like Clojure or Erlang.
But, you might reasonably wonder, if typeclasses are basically
equivalent to classes (but with a different dispatch mechanism), why
does Haskell's typeclass hierarchy look so different to say, Java's?
Monads and Monoids, vs Hashtables and ArrayLists..?
First, it reflect's the different programmer demographics. The high
abstraction of Haskell reflects its origin among academic and research
programmers.
Secondly, it reflects an advantages of typeclasses over OO: the
ability to support multiple different implementations in different
contexts. That in turn enables, and indeed rewards, focused
abstractions such as Monoids. Whereas on the OO side, such
abstractions provoke discomfort by revealing the flaws in the OO
paradigm, requiring the publication of more dogma to banish the
uncomfortable questions from discussion. Questions like "why do we
need both Comparable and Comparator in Java?"
-Ben
On Sat, Jan 26, 2013 at 6:34 AM, aidy lewis <
aidy....@gmail.com> wrote:
> I have been reading Brian Marick's "Functional Programming for the Object
> Oriented Programmer". He states that one of the key elements of FP, is that
> functions operate on basic data types, and we shouldn't increase types
> through classes.
>