In Rich Hickey's thought-provoking goto conference keynote "The Value of Values" at 29 minutes he's talking about the overhead of a language like Java and makes a statement like, "All those interfaces kill your reuse." What does he mean? Is that true?

In my search for answers, I have run across:

The Principle of Least Knowledge AKA The Law of Demeter which encourages airtight API interfaces. Wikipedia also lists some disadvantages.

Clearly, anything written badly enough will be useless. But how would the interface of a well-written API prevent that code from being used? There are examples throughout history of something made for one purpose being used more for something else. But in the software world, if you use something for a purpose it wasn't intended for, it usually breaks.

I'm looking for one good example of a good interface preventing a legitimate but unintended use of some code. Does that exist? I can't picture it.

Thanks for the links! I didn't find Jack Diederich's talk particularly illuminating (watch how he fails to answer the audience's genuine questions convincingly.. "uh, yeah, maybe in that case...". I did like he seems to be arguing for Functional Programming without even noticing it ;) ), but the "Imperial Clothing Crisis" is very good and insightful.
– Andres F.May 25 '13 at 18:44

1

MPO is that people who don't believe in reuse don't break things down into small enough units. A big thing that is built for one specific purpose can't be reused. However, small things usually have a small enough purpose that the small purpose is useful in more than one context.
– Amy BlankenshipMay 26 '13 at 1:45

1

@AmyBlankenship I found the "Imperial Clothing Crisis" linked above to be insightful. The author considers "reuse" a false idol (something which hasn't been proven useful in practice, and also most people don't even understand it even though they use the word). He also doesn't consider libraries "reuse"; you use a library, you don't reuse it. He also considers designing something for reuse "a double-edged sword"; something that people usually consider a win-win situation but which really isn't: when you design something for reuse, it's always a compromise (e.g. you may lose in simplicity)
– Andres F.May 26 '13 at 23:23

4 Answers
4

Haven't watched the full Rich Hickey presentation, but if I understand him correctly, and judging from what he says about the 29-minute mark, he seems to be arguing about types killing reuse. He is using the term "interface" loosely as a synonym for "named type", which makes sense.

If you have two entities { "name":"John" } of type Person, and { "name": "Rover" } of type Dog, in Java-land they probably cannot interoperate unless they share a common interface or ancestor (like Mammal, which means writing more code). So the interfaces/types here are "killing your reuse": even though Person and Dog look the same, one cannot be used interchangeably with the other, unless you write additional code to support that. Note Hickey also jokes about projects in Java needing lots of classes ("Who here has written a Java application using just 20 classes?"), which seems one consequence of the above.

In "value-oriented" languages, however, you won't assign types to those structures; they are just values which happen to share the same structure (in my example, they both have a name field with a String value) and therefore can easily interoperate, e.g. they can be added to the same collection, passed to the same methods, etc.

BTW, Jack Diederich's talk "Stop Writing Classes" seems unrelated to this topic, and is more about YAGNI and "don't write code until you need it, and then only write simple code".
– Andres F.May 25 '13 at 22:47

9

ERROR: Object doesn't have a property called "name" is often the result of value-oriented languages, and the other problem is when you want to no longer call that property name. Good luck refactoring because there are likely hundreds of objects with a property name but not all are Person or Dog.
– ReactgularMay 25 '13 at 23:18

2

@MathewFoscarini Yeah, I don't necessarily agree with it, it's just my interpretation of what I think Hickey was saying :) I like types and static typing; I'm just starting to dislike Java. And my dislike is unrelated to interfaces but to the mess that is the typical Java project.
– Andres F.May 25 '13 at 23:24

1

Java is the programming language for those who prefer to think too much. It's one of the few languages that allows a developer to easily hide his attempts to over engineer a project.
– ReactgularMay 25 '13 at 23:34

"In 'value-oriented' languages you won't assign types to those structures" - I think you need to say "In dynamic 'value-oriented'..." Haskell and Scala are value-oriented, but their static type system gives them the exact problem you are describing. I think that the solution to this problem is not values so much as using maps to pass parameters to functions. Using immutable maps (values) is just safer.
– GlenPetersonJun 13 '13 at 12:03

He is likely referring to the basic fact that an interface can not be instantiated. You can not reuse an interface. You can only implement code that supports it, and when you write code for an interface there is no reuse.

Java has a history of providing frameworks of many API(s) that take an interface as arguments, but the team who developed the API never implement a wide range of classes for you to reuse with those interfaces.

It's kind of like a GUI framework that has an IWindow interface for a dialog box, and then you can add IButton interfaces for controls. Except, they never gave you a good Button class that implements IButton. So you're left creating your own.

Abstracted frameworks that have a wide range of base classes providing core functionalities are more reusable, and that works best when those abstracted classes are accessible to those using the framework.

Java developers started doing this thing where their API layers exposed only interfaces. You could implement those interfaces, but you could never reuse classes from the developer that implemented those interfaces. It's kind of like a cloak and dagger style of API development.

Thank you for this answer. I now feel like I understand the question and the answer :)
– MetaFightMay 24 '13 at 7:59

2

+1 I really appreciate your answer and it adds a fascinating layer of interesting information to this question. But I think Andreas F.'s answer is likely closer to the heart of what Mr. Hickey meant, so I accepted his instead.
– GlenPetersonMay 27 '13 at 18:00

@GlenPeterson no problem, I think he might be on the mark as well.
– ReactgularMay 27 '13 at 18:01

1

Well this and the accepted answer highlight two slightly different, but equally interesting, interpretations. I'm curious which one Mr. Hickey had in mind when talking about this..
– David CowdenMay 28 '13 at 22:12

You cannot reuse an interface , but you can extends it (and give valuable version number) without changing old classes. You can also inherit from many interfaces to add new job for new classes, or do add new inheritence in old recompiled classes . You can also extends the class that implements this interface for new job.
– cl-rJun 13 '13 at 13:21

Values

My understanding is, Hickey suggests that if I need to, say, double the value you sent to me, I simply write code looking like

MyValue = Double(YourValue)

You see, above code is the same, no matter what kind value you sent - sort of a perfect reuse.

Now, how this would look like in the language having objects and interfaces?

Doublable MyValue = YourValue.Double()

oh wait! what if YourValue doesn't implement Doublable? not that it can't be doubled, it may perfectly be but... what if there's just no methodDouble? (what if there's a method called say TwiceAsMuch?)

Uh oh we've got a problem. YourValue.Double won't work, it can't be reused anymore. Per my reading of above slide, this is about what Hickey meant when he said, "All those interfaces kill your reuse!"

You see, interfaces assume that objects are passed around "along with their methods", along with code that operates on these. To use objects, one need to understand how to invoke that code, what method to call.

When expected method is missing, there is a problem, even though semantically, desired operation makes perfect sense for an object. As stated in the presentation, values don't need methods ("I can send you values without code and you are fine"), allowing to write code dealing with them in a generic manner.

Side note: notion of passing around code-less values somehow reminds me of a Flyweight pattern in OOP.

an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory... Flyweight objects are by definition value objects. The identity of the object instance is of no consequence therefore two Flyweight instances of the same value are considered equal...

Flyweight usages I've seen typically followed the same approach of stripping off the code (methods, interfaces) from objects and passing stuff around around as, well, code-less values, expecting that receiving code has means necessary to operate on these.

This feels pretty much as at the slide, "values don’t need methods. I can send you values without code and you are fine".

Generics would pretty much take care of that problem. Doubling makes sense on some objects, but not on others. In the Go language, there is implicit interface implementation (a form of duck typing), so you don't have all those interfaces to worry about. On the other hand, you sorta have to know which object is going to be hit by your method signature; otherwise, you might get unexpected results. There are always tradeoffs.
– Robert Harvey♦May 23 '13 at 23:09

The flyweight pattern is not what Rich is talking about. As the second sentence of the article states, the purpose of the flyweight pattern is to conserve memory. Rich's approach does not seek to do that.
– user39685May 24 '13 at 12:41

5

MyValue = Double(YourValue) doesn't make sense if YourValue is a String, an Address, a User, a Function, or a Database. Otherwise, your missing-method argument is a strong one. OTOH, accessor methods let you enforce various constraints so that your Values are valid, and that only sensible operations are used to produce new Values. If you later decide to separate the Address from your User and Company, accessor methods mean that you don't break all the clients of your code. So they can help reuse in the long-term even if they sometimes hinder it in the short-term.
– GlenPetersonMay 24 '13 at 13:24

4

(On the other hand, I do agree that in Java-land, the explosion of classes, interfaces and frameworks is a nightmare. The simplest "enterprisey" solution in Java is a mess of code. So I do take a valuable lesson from this question & answer, without necessarily agreeing with the dynamic typing stuff)
– Andres F.May 24 '13 at 15:23

In an (i.e. my) ideal world classes and interfaces would always describe behavior, but the fact is that all too often they really just end up describing data. Only yesterday I watched video of someone build a so-called BankAccount class that was nothing more than a glorified int (indeed it was much less useful than an int, thus 'killing' the reuse I would've had had it simply been left as an int), all in the name of 'good' design. The amount of code, sweat and tears wasted on continually reinventing convoluted representations of data is staggering; if you're not using the data in a meaningful way then please just let it be.

Now, this is the stage where Rich Hickey is content to throw the baby out with the bathwater and say that we should all go live in the land of values (a neighbor to the kingdom of nouns). I think, on the hand, that OOP can and does promote reuse (and importantly discoverability, which I find lacking in functional programming) when employed judiciously. If you're looking for an OOP principle that best captures this tension I think it might be http://c2.com/cgi/wiki?TellDontAsk (which of course is a close cousin of Demeter)

What do you mean by discoverability? Is it similar to this?
– user39685Jun 27 '13 at 15:20

1

Yes, I think that touches on a lot of the main points. It's a subtle point but discoverability is a balancing act, making things too transparent is undesirable as well because you'll get a bad signal to noise ratio.
– CurtainDogJun 28 '13 at 3:51