Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

  • Kevlin Henney's Imperial Clothing Crisis which argues that use, not reuse is the appropriate goal.

  • Jack Diederich's "Stop Writing Classes" talk which argues against over-engineering in general.

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.

share|improve this question
1  
Haven't watched/read the stuff (I've added "Stop Writing Classes" to my to-watch list :) ), but maybe they are arguing from a dynamic vs static typing angle? ...again? –  Andres F. May 23 '13 at 22:56
    
o.O Application programming interface interfaces –  Thomas Eding May 23 '13 at 23:02
    
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 Blankenship May 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
show 1 more comment

4 Answers 4

up vote 21 down vote accepted

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.

To sum up, all this seems to be something about structural equality vs explicit type/interface equality. Unless I missed something from the portions of the video I haven't watched yet :)

share|improve this answer
2  
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
6  
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. –  Mathew Foscarini May 25 '13 at 23:18
1  
+1 by the way. Good answer. –  Mathew Foscarini May 25 '13 at 23:19
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. –  Mathew Foscarini May 25 '13 at 23:34
show 3 more comments

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.

share|improve this answer
4  
Thank you for this answer. I now feel like I understand the question and the answer :) –  MetaFight May 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. –  GlenPeterson May 27 '13 at 18:00
    
@GlenPeterson no problem, I think he might be on the mark as well. –  Mathew Foscarini May 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 Cowden May 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-r Jun 13 '13 at 13:21
add comment

I think slide 13 at his presentation (The Value of Values) helps to understand this:

http://i.stack.imgur.com/LVMne.png


Values

  • Don’t need methods
    • I can send you values without code
      and you are fine

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 method Double? (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".

share|improve this answer
4  
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
1  
An interesting take. Good answer! –  maple_shaft May 24 '13 at 0:57
2  
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. –  Matt Fenwick May 24 '13 at 12:41
3  
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. –  GlenPeterson May 24 '13 at 13:24
3  
(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
show 7 more comments

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)

share|improve this answer
    
What do you mean by discoverability? Is it similar to this? –  Matt Fenwick Jun 27 '13 at 15:20
    
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. –  CurtainDog Jun 28 '13 at 3:51
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.