Object-Oriented Dispatch is the Dual of Functional Dispatch

March 11, 2015

Summary: Object-oriented dispatch is contrasted with functional dispatch, but they are shown to be two one-dimensional views of the same two-dimensional data. Clojure does not provide the two-dimensional representation, but does interesting things to transcend the one-dimensional views.

About a month ago, I wrote a post about how OO-style is the dual of functional-style. OO focuses on the data first, while functional focuses on the code. It is cool that the correspondence between the two is fairly clear and mechanical. It means that they're equivalent in a way. The distinction is mostly important when choosing how to represent a problem. A language should provide ways to express both (as Clojure does), and a way to translate between the two (which Clojure does not).

But it goes further than data vs code. In OO, the object is the unit of data (which manifests as the principle of encapsulation). But the object is also the unit of dispatch. Objects know their class, and classes know the implementations of their methods. Class first, behavior second. In a functional style of programming, the function is the unit of dispatch. A function knows how to react to all possible classes of arguments. Behavior first, class second.

Example:

(defn foo [x]
  (cond
    (string? x)
    ...
    (integer? x)
    ...
    (vector? x)
    ...

So again, we have a kind of duality. The classic way to explain this is to show it in a table.

method/class String Integer Vector ...
toString . . .
length . x .
+ x . x
* x . x
...

A dot represents an implementation, whereas an x represents an undefined operation.

In OO style, the class represents a single column. In functional style, the function represents a single row. Logically, however, the information is a two-dimensional table. That brings up a question: why don't languages store the information in this form internally? It is easy to project a column view or a row view from a table. And the x's in the table seem to be really useful for static checks.

Clojure does not represent its functions this way. But it does allow you to express your code in either a column view or a row view. The row view is the standard functional approach shown above. The column view is using deftype.

Example:

(deftype Person
  Object ;; indicating I'm overriding methods from Object
  (toString [p]
    ...)
  java.util.Comparable
  (compareTo [p]
    ...)
  ...)

Clojure goes a step further: instead of having to write out the entire column (all methods given a class) in one place, you can essentially index directly into the table given a method/class pair, and define the implementation directly. This only works with protocol methods (not methods on classes/interfaces due to limitations in the JVM).

Example:

(extend-type Object
  MyProtocol
  (mymethod [x o]
    ...))

OO-style and functional-style are duals in terms of dispatch. It's very related to the data-first or code-first duality I wrote about before. Clojure again straddles both sides of the duality and lets you write code in both styles, as well as transcend the column/row distinction entirely when using protocols.

How does your language deal with dispatch? Can you express the problem in the best way? If you're interested in this kind of topic, you would probably enjoy the Clojure Gazette. It's a weekly newsletter filled with content to inspire Clojure programmers. It's completely free and it's easy to unsubscribe.

Thanks to Marcus Blankenship for the inspiration for this article.

For more inspiration, history, interviews, and trends of interest to Clojure programmers, get the free Clojure Gazette.

Learn More

Clojure pulls in ideas from many different languages and paradigms, and also from the broader world, including music and philosophy. The Clojure Gazette shares that vision and weaves a rich tapestry of ideas from the daily flow of library releases to the deep historical roots of computer science.

You might also like

Object-Oriented Programming is the Dual of Functional Programming

February 08, 2015

Summary: Object-Oriented Programming is often shown in contrast to Functional Programming. But they are so exactly opposite that they are duals, and so equivalent in important ways. Which one to use should be left up to the programmer, as is done in Clojure and Javascript.

Let's take a quick look at programming from an interesting perspective. Let's say that programs are divided into code and data. 1 These are the two main axes: structuring code and structuring data.

Now, let's design a language. First decisions: which axis is primary, which is secondary?

Style Data Code
OOP Primary Secondary
FP Secondary Primary

In an OOP-style approach, we have a pointer to an object which is the data. And the data also tells you where the code is to access it (methods in the vtable). An FP-style approach will make functions (code) primary, with data referred to by the closures (the captured lexical environment).

I'm positive I'm not the first person to remark on this, but I think it's pretty cool that they are duals of each other. A simple transformation will switch one in the table with the other.

Perhaps the next obvious question is "which one is better?". Many arguments about OOP vs FP focus on this choice, about which axis should be primary. Because a compiler could easily transform between them, the decision is not quite so important as we might think at first. I think that a language should make both available and let the programmer choose. The programmer is then free to choose whichever best models the problem.

For instance, in Clojure, fns are closures, so they are really FP-style -- code meant to be executed which happens to refer to some data. But collections are data which refer to code which knows how to access the data. Both coexist quite cooperatively.

And Clojure gives you, the programmer, ways of expressing both styles. When you want to create some code to be executed, fn lets you define lexical closures. But sometimes you want to make a new data structure which acts like others. For instance, a new type of sequence. deftype lets you define data with interface and protocol implementations. I use both fn and deftype very often.

Interestingly, Javascript gives you these two options as well. function defines lexical closures, making code primary. But very often you define an object which contains (or refers to) data and secondary accessor functions. It's one of the nicer things about Javascript, included in Javascript, the Good Parts.

How does your language prioritize these two axes? Is there a way to choose which to use to best implement your design? If you're interested in this kind of topic, you would probably enjoy the Clojure Gazette. It's a weekly newsletter filled with content to inspire Clojure programmers. It's completely free and it's easy to unsubscribe.

For more inspiration, history, interviews, and trends of interest to Clojure programmers, get the free Clojure Gazette.

Learn More

Clojure pulls in ideas from many different languages and paradigms, and also from the broader world, including music and philosophy. The Clojure Gazette shares that vision and weaves a rich tapestry of ideas from the daily flow of library releases to the deep historical roots of computer science.

You might also like


  1. I don't want to go down the code-is-data rabbit hole. Let's stick to one floor in the tower of languages model.