How to learn a language - do stupid things

Since Java still gets managers all hot and bothered, I decided that I would dive into yet another programming language (when will I ever learn?). Playing with Swing, I discovered that mutators have void return types. That seems like a waste. Why not return the object? Since chained mutators seem to be something that no one can agree on, I've just decided to come down on the "I likes 'em" side of the fence. Which leads me to my problem.

You cannot overload Java methods by changing the return type.

After that serious let down, I realized I would have to change method names to get what I want. Now, instead of this:

I have a feeling that this will one of my less popular hacks, but with better exception handling and polymorphic dispatch based on method signatures, it seems that Java is a better fit for this idiom than Perl.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Without JavaScript enabled, you might want to
use the classic discussion system instead. If you login, you can remember this preference.

I'm afraid I'm on the "chained setters are stupid" side of things. What exactly are you accomplishing? Mostly, folks who think it's cool seem to be rationalizing an attempt to fit more junk on one line. There's nothing intuitive about it and it's probably just going to cause confusion down the road.

What I'm accomplishing is grouping things together that logically belong together. Plenty of times I've seen cut-n-drool programmers slap some code in the middle of a chunk that shouldn't be split up only to break things and scratch their heads trying to figure out why. This makes it tougher to do that.

No offense, but I don't buy the "confusion down the road" argument. Why is this confusing? Because it's new? No one has a problem chaining accessors and they do it every day in Java. The first time I saw chained mutators, I saw what was going on and thought that it was a nice tool. Accessors return different objects and mutators return this. It's pretty straighforward.

As for whether or not it's intuitive, there is very little in any language (computer or spoken) that's intuitive. I can't tell you how many times I've read in computer books something along the lines of "ternary (or unary) operators confuse some programmers so you may want to avoid them". That's FUD. Would you really want to hire someone who thinks that ++variable is confusing? If you want confusing, consider context in Perl. Many of the rules seem arbitrary and are merely a matter of rote memorization. That's confusing. "Mutators return the object" is the only thing that needs to be remembered with chained mutators. That's simple.

When I was doing mainframe programming, there was a huge section in our programming standards manual about COBOL keywords we weren't allowed to use because they weren't often used. That's just a silly self-fulfilling prophecy and I have first hand experience fixing stupid bugs caused by the contortions some programmers went through just to avoid some of those keywords.

So restating all of this: the pro (to me) is that logically grouped constructs are distinctive. If I'm refactoring or debugging some code, it's immediately apparent that a chained mutator construct is a logical group that probably shouldn't be split up. This, like indenting to show scope, is not strictly necessary, but is very convenient for a quick visual understanding of the code (and when I first went from BASIC to C back in the 80s, I didn't grok indentation, either). I think that anything that improves visual comprehension of code is a good thing.

So what are the cons? I hear some arguments against this in Perl and those arguments go both ways. Much of those arguments, however, struggle with Perl's lack of structured exceptions. That argument goes away with Java. As for being unintuitive or confusing, most who come from procedural languages would argue that about the signature of the main() function in Java programs (public static void main(String[] args)????). It's merely a matter of learning it.

Now if you can point to real problems with this syntax, I'd love to hear them -- that's why I posted:)

The main problem with chained mutators is that it requires cooperation of all the mutators to work properly. It adds extra complexity to all of the mutator implementation to gain a little convenience for the caller.

Also, sometimes it makes sense for mutators to return something. For example, returning the previous value can be useful. Or if the mutator constructs an internal object, then returning that object might make sense. In Perl, the lack of exceptions frequently means returning error indicator

It adds extra complexity to all of the mutator implementation to gain a little convenience for the caller.

Surely that's a good thing! When you make it easy for the implementor at the expense of the user, you end up with something like Ant [apache.org] where you have to write XML. I'd much rather use Module::Build or even ExtUtils::MakeMaker for all their faults (and the former has many fewer faults than the latter), they're easier to use than either writing my own Makefile or writing an XML file.

As I said last week on Perlmonks when this came up there, "chaining" is a poor substitute for "cascading". In a cascade, a designated object reference is guaranteed to be the recipient for all messages (invocations of member functions). Smalltalk syntax supports cascading. Perl syntax doesn't.

Without first-class support for cascading, a simulated cascade (i.e., a chain) is hard to distinguish from a gross violation of the Law of Demeter.

I don't really want to try and describe this in Smalltalk terms. This isn't Smalltalk and shouldn't be viewed as such. Even though the idea appears to come from Smalltalk, it's simply not the same thing as a cascade. That seems like saying for (@array) shouldn't be used in Perl because it's not an OO iterator. In this case, it would not be helpful to insist on a full implementation of the GoF Iterator pattern. It's certainly an iterator, but it's implemented in a Perlish way. The case of the chained

Put simply, the Law of Demeter (LoD) says "You should only talk directly to your friends, and not to their friends." This reduces coupling, and simplifies testing. To test your code, the most you have to do is provide mock objects for your code's direct collaborators.

Violations of the Law of Demeter are characterized by chains of method calls, where the target object changes along the way as the code reaches through its friends and into their friends (and perhaps into their friend's friends). Lots of coup