Skip to content

Chained Expressions

by on October 17, 2012

I have noticed that chained expressions become more and more popular at CoreMedia. I don’t like this fashion at all for several reasons.

While IMHO

MyClass a = new MyClass();
a.doThis();
a.doThat();

is just as well readable as

MyClass a = new MyClass()
 .doThis()
 .doThat();

the first notation has the advantage that it is easier to maintain if you need interim computations or want to handle an exception of one particular method. Moreover, I think (have not tried, though) that the debugger is statement-oriented, not line-oriented, and if I’m right, the second notation is hard to debug.

The style of chained expressions originates from functional languages, the most popular of which (namely Lisp and its derivates) are dynamically typed. However, in combination with a static OO type scheme chained expressions are less flexible than the classical “object.method()” notation.

Imagine two classes

class Base {
  public Base baseMethod() {... return this;}
}
class Special extends Base {
  public Special specialMethod() {... return this;}
}

You can simply write

Special s = new Special();
s.baseMethod();
s.specialMethod();

but you cannot write

Special s = new Special()
  .baseMethod()
  .specialMethod();

This limitation prevents a consequent usage of chained expressions and ends up with a mixture of code style which is hard to read. Or you have to override baseMethod in Special just for the return type. Both is worse than the classical notation.

In functional programming side effects are strongly discouraged, and the return value of a function is its only result. So every function has an inherent return value, not just a dummy result. In OO programming it is perfectly good style to provide methods which only modify the state of an object and return “void”. Such methods are invoked like

object.doSomething();

which is straight forward and easy to understand for the reader. If you give doSomething() a return type for the only purpose of enabling chained expressions, code checkers will complain that the result is ignored in the above statement. So you have to assign the result to a dummy variable, which makes the code harder to understand.

Conclusion: Patterns which are elegant in functional programming are not necessarily useful in OO programming. So, why are chained expressions suddenly so popular with Java?

From → Dev

One Comment
  1. Mark Michaelis permalink

    Wikipedia: The pattern of method chaining is the core concept behind building a fluent interface. This again is first coined by Eric Evans and Martin Fowler (see Martin Fowler on FluentInterface in 2005). And I think this might be the answer to your last question, why it is becoming more and more popular.

    The Wikipedia entry also clearly states the context, where especially the last one is the most violated one:

    • defined through the return value of a called method
    • self-referential, where the new context is equivalent to the last context
    • terminated through the return of a void context.

    The Wikipedia entry also refers to the problems you mentioned. Debugging is one of those. Although the entry suggests that debugging might work if you break the chained call to multiple lines at least the IDE I tried failed doing so. It even marked the breakpoint as “not reachable”.

    What actually really is a problem in Java is (as you mentioned) if you try to provide a fluent interface with a non-final (thus extensible) class. As you suggested my approach is just to override the method in the subclasses redefining the method again and again. But I can tell: This is horror not to forget about it and subclass-methods typically look like this:

    @Override
    public MySubClass doThat(Object o) {
      super.doThat(o);
      return this;
    }
    

    What also seems to be a bad pattern in fluent design is to use the prefixes “set” and “get”. This at least would help to give API users a hint that those methods have side-effects.

    I actually like fluent interfaces – but I think there is a lot to learn how to use them right and some static code analysis tools seem to require an update to cope with the new requirements from fluent interfaces.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s