Saturday, June 14, 2008

What is a fluent interface?

I just saw this on reddit, and I have no clue. Whatever a "fluent interface" is though, seems Factor doesn't need one, because their 21 line example can be written a million times more clearly in 4 lines of Factor:
USING: sequences strings math.ranges io ;
{ "i" "can" "has" "cheezburger" "plz" "?" } [ " " append ] map concat "\n" append
CHAR: A CHAR: Z [a,b] reverse [ CHAR: M > ] filter [ 1string ] map "," join
append print


Samuel A. Falvo II said...

Because Serendipity's trackback functionality is so broken as to be useless, I just wanted to let you know that I reviewed the concept of fluent interfaces, found it utterly worthless, and blogged about it on my own blog.

See!!.html for details. Thanks.

delvinj said...

Java... so much to type :)

Anonymous said...

It would appear a "fluent interface" is a poor man's stack.

Nat Pryce said...

A "fluent" API is just one so that code written to the API clearly expresses what the composed objects do, rather than just how the objects are composed.

In your Factor example, the words could have meaningless names and be written so that the code example is much longer and difficult to read. But that's not the way you've written the Factor APIs. They are written so that the resulting code is "fluent".

Some languages (LISP, Smalltalk, Forth) make it much easier to write code that expresses the "what" and hides irrelevant details of the "how". Java makes it much harder than it should be. That's why "fluent APIs" are seen as a big deal in Java.

But saying that fluent APIs are worthless is disingenuous. Why did you design a language that makes code so readable if you don't think that making code readable is a worthwhile aim? Factor makes it easy to write "fluent" code; it doesn't make "fluent" code unnecessary.

Samuel A. Falvo II said...

Nat, I had to re-read the blog article twice, and both times, I couldn't find anywhere that Slava indicated that fluent interfaces were "worthless."

Please elaborate on why you thought this was the case.

Instead, Slava reported rather unequivocally that Factor didn't need anything distinct with a label of "fluent interface." It just happens naturally.

In other words, and this is what I object to in my article, that something like this needs a name at all means that (1) someone is undoubtedly going to get credit for it, (2) no credit will be given to the founding engineers who devised this kind of interface to begin with, and (3) such an absolute common sense approach to coding will be reduced to a mere "fad" if this kind of marketing gets further out into the public.

Please be careful of what you read. To say that Slava (or I) claim that "fluent interfaces" are worthless is not only disingenuous, but is outright disinformation.

Nat Pryce said...

You're right. Sorry. I missed what you (Samuel) were trying to say amid the insults and name calling in your blog post.

But I still think you're wrong on several fronts.

Java has features that are not present other, more expressive languages like LISP, Smalltalk, and Forth. E.g. safe execution of mobile code from untrusted sources; state-of-the art tool support. People choose Java because they have evaluated the engineering trade-offs and found it to be the best fit to their needs.

Because the language is not perfect they need to apply techniques to make their code readable, which are not necessary in other languages. And because they work in teams they need to name those techniques so they can talk about them. Hence the name "fluent interface". [Which, by the way, is *not* just chaining method calls together; even Martin Fowler's article is clear about that.]

People who have written about this (and I am among them, being a co-author of have been quite clear that these techniques are inspired by other languages. JMock is one of the examples in Martin's article and was written by ex- Smalltalk, Tcl and functional programmers. We deliberately (ab)used Java to try and get some of the benefits of those languages.

The writing about "fluent interfaces" is not being presented as research. Martin Fowler is documenting current practice as he observes it. We wrote up our techniques for the practitioners track at OOPSLA, not for the research tracks. Nobody is pretending to have invented anything new.

I don't understand why you're worried that giving a widely used technique a name means that someone is going to get credit for it. If they do, who cares? The fact that there is a name is useful. The Design Patterns "Gang of Four" got credit for documenting patterns, not inventing them. And if someone wants to spend the rest of their life trying to get free drinks for being "Mr Fluent Interface", more fool them!

Samuel A. Falvo II said...


safe execution of mobile code from untrusted sources

Fundamentally, this is not impossible to support in any other language. The reason Java supports this out of the box is because it was developed specifically with the intent to run in web browsers as Java Applets.

Java's safety in this area also has been surpassed, and with far greater performance and liberty, by the Juice system, in the Oberon-2 language, for example. Unfortunately, by the time Juice rolled out of the research phase, Java was already well entrenched.

state-of-the art tool support.

Again, this exists only for two reasons: first, Java needs that kind of tool support because it is so unexpressive, and second, people use Java because those tools exists. In other words, it's a positive feedback loop that, like a flame, self-sustains.

People choose Java because they have evaluated the engineering trade-offs and found it to be the best fit to their needs.

I've worked for enough software companies to know that this simply isn't true. In Google, we used Java because it was the most mature language environment available for the JVM. What we really wanted was, therefore, the JVM, not the language itself. The engineers there strongly preferred other languages. They wanted to use something else, such as Scala (which, as your research shows, also uses the JVM), Lisp, and yes, even Haskell. A few even expressed strong interest in learning Forth and Factor.

At Attributor, we also use Java because the JVM is a managed environment that runs uniformly across all installed platforms. While a number of nice things have been said about Java, at the end of the day, every engineer I've spoken with on this topic preferred to use another language over Java.

I think it important that you dissociate the JVM from Java, the language. As is mentioned on the C2 wiki, Java is the new Cobol. This is a most profound observation.

As far as the remainder of your article is concerned, it seems we're in agreement for the most part. However, I have to admit that having read Fowler's article on fluent interfaces, I saw no mention of any historical precedent. As such, anyone who is "new" to fluent interface design will think that this is Fowler's creation.