(though of course with tuples and multimethods...)
(Remember the whole "sending a message to an object" thing? You do that with both variants. In the single-dispatch case, the method is a structure in the metaclass instance. In the multiple-dispatch case, some other helper object finds the right method. Same idea, though.)
OO:
class SomeType {
<data> ;
SomeOtherType function1() {
this.whatever ;
...
}
}
FP: data SomeType ...
f1 :: SomeType -> SomeOtherType
f1 this = whatever this >> ...
Same idea, different syntax. (Type classes will allow polymorphism, if that's what you're after.)You are thinking of the abstraction in terms of its implementation. There is no reason why a method in a class would physically be in that class; the class just acts as a namespace:
class Foo { method }
Foo.method();
and (defmethod Foo.method ...)
(Foo.method)
are the same.I don't know about Clojure, but Common Lisp's "multimethods" are OOP on steroids; you could layout your code vertically in a parent/child class heirarchy and it would look no different than a "normal" class-based inheritance tree; all you have to do is visualize the method call in prefix mode:
object.method (arguments) = method (object arguments)
In essence, you could model Java and similar languages with a fixed and constrained Common Lisp. You just have to take its wheels off and lay it flat on bricks.Interested parties can go and learn CLOS for the full story. Spoiler, though: not long after, Lisp will start to hover! you just can't hold somethings down. If you thought of objects in terms of a vertical class heirarchy, or a side-ways call chain or what have you; CLOS will make your visualization planes intersect and show you new dimensions you never imagined..
CLOS has had multimethods for years, and that is indeed OO.