Skip to main content

Named Parameters

Posted by brucechapman on September 30, 2008 at 8:59 PM PDT

Recently Alex Buckley blogged about a possible language change to allow Named Parameters in method calls.

Today I had need for such a feature. I was calling this method

public void startOperatorSimulation(int pos, int stepDelay, int opNumber) { ... } 

multiple times, which matches Alex's first use case for named parameters 'When a method has adjacent parameters with the same type but different semantics'.

My code looked like this

mocker.startOperatorSimulation(103, 4000, 5051);
mocker.startOperatorSimulation(104, 5000, 5052);
mocker.startOperatorSimulation(106, 6000, 5053);

and I didn't like it because it was not readable.

I quickly considered then discarded the idea of declaring a bunch of static final ints in order to give names to the parameters as that would merely change the unreadably terse code into unreadably verbose code.

Then I realised that there was a way to do this with the existing language features. Now the code looks like this.

int pos, stepDelay, op;
mocker.startOperatorSimulation(pos=103, stepDelay=4000, op=5051);
mocker.startOperatorSimulation(pos=104, stepDelay=5000, op=5052);
mocker.startOperatorSimulation(pos=106, stepDelay=6000, op=5053);

This is an idiom I have not seen before, and showing it to a colleague, he thought I'd been hacking the compiler or Netbeans again (more about that in a future blog). But no, this is just Plain Old Java. For this case with three method calls, the overhead of declaring the local variables is well worth it, and if you ignore Checkstyle's protestations about using inner assignments, and hope that hotspot will deal to any minor performance penalties then all is sweet and dandy.

- postscript - I've just discovered some Prior Art by Eric Armstrong.

Related Topics >>

Comments

I understand the need and appreciate the try, but I don't think it works in perspective: as soon as you refactor the method parameters, no IDE that I'm aware of would rename your variables. This means that the code will be still readable, but misleading. I'm using another approach, that I described here: http://weblogs.java.net/blog/fabriziogiudici/archive/2008/03/designing_f... - but I think it's ok in some cases, not for every single method call, otherwise you will need too much code. BTW, this is the area while I think some language improvements are needed and useful (and they have a limited risk), rather than the closure stuf... :-)

Item 2:Consider a builder when faced with many constructor items !! (Page.11 /Effective Java 2nd Edition/Joshua Bloch) if you apply the conseil given by the author you could implement something like: mocker.setOperatorSimulation.Builder().pos(103).stepDelay(4000).op(5051).build();

This approach increases readability but doesn't prevent stupid bugs. I blogged about both variants a logn time ago: http://gestalt.monoid.net/blog/2007/08/named-arguments-pure-danger-tech-...

Nice proposal, I love it! Although you're screwed, when the method switches the order or naming/semantics of the parameter. But then you're also screwed if you don't name them from where you call it :)

Alternatively, you could say int pos, stepDelay, op; pos=103; stepDelay=4000; op=5051; mocker.startOperatorSimulation(pos, stepDelay, op); However, the whole point of parameter names is that you should be able to say mocker.startOperatorSimulation(stepDelay=4000, op=5051,pos=103); and get what you expect.

Nice and the compiler should eliminate the unused assignments, one would hope. Normally, I'd do this: mocker.startOperatorSimulation(/*pos*/ 103, /*stepDelay*/ 4000, /*op*/ 5051); but that's not so readable.