Named parameters for humanity!

I had a little insight today.

Many modern languages, including my current favourite toy C#, support passing parameters by name. For example, consider a method like this:

public State MoveRobotArm(
    double position, 
    bool throwOnErrorState = true, 
    bool simulated = false)
{
    ...
}

Notice how its last two parameters have default values, which means we can omit them if we want. We can now call this method like this:

    var state = MoveRobotArm(50.0, simulated: false);

We’re skipping the second parameter and assigning a value to the third. This is what named parameters were intended for. However, it’s also remarkably readable! Now, if you came across code like this:

    MoveRobotArm(50.0, true, true);
    var state = MoveRobotArm(0.0, false, true);
    if(state != State.OK) ...  // handle errors

Would you be able to guess what the MoveRobotArm calls do? There’s some things to deduct. The number is probably a position, and given that we throw away the return value of the second MoveRobotArm call, we’re either crappy coders or one of the booleans help manage unexpected situations.

Recently, I started writing such code like this instead:

    MoveRobotArm(50.0, throwOnError: true, simulated: true);
    var state = MoveRobotArm(0.0, throwOnError: false, simulated: true);
    if(state != State.OK) ...  // handle errors

It’s a minor difference, but it makes the code much more readable. You don’t need to look up the signature of MoveRobotArm to figure out what’s going on.

The self-documenting power of named parameters works especially well when booleans are used as flags. You could also write an Enum for each option and have it be equally self-documenting, but that feels like a lot of boilerplate. This is the same, but with comparably little boilerplate. Similarly, when methods take many parameters of the same type, it is very helpful to the reader if the parameters are named on invocation.

Down the rabbit hole

Note from the editor: That was the end of the blog post. The rest is just mindless rambling.

I’m starting to think that it would be a nice idea for some new programming language to force callers to name arguments be default. I think it’d make 80% of code more readable (and hardly more cumbersome to write, assuming you have a decent IDE). But not always: you wouldn’t want to have to write Math.sin(value: 5.0) for instance, it’s ridiculous.

So you need an escape for allowing unnamed parameters, but we can leave it up to the author of the function to decide whether to allow that or not, using some extra syntax.

Essentially, for most current programming languages, function parameters are an ordered list of mixed types. I’m proposing that it’s, by default, an unordered collection of name-value pairs (i.e. a struct, object, record, whatever). You can then have syntax to allow one or more unnamed, ordered, parameters as well, if you really want to. You’d get maybe something like:

    void CallMyMother(int phoneNumber, string message) ...
    // OK:    CallMyMother(phoneNumber: 123456, message: "Hi Mom!");
    // OK:    CallMyMother(message: "Hi Mom!", phoneNumber: 123456);
    // ERROR: CallMyMother(123456, "Hi Mom!");

    string Diff([string a, string b], bool caseSensitive = false) ...
    // OK:    var diff = Diff("aaabb", "aaacc");
    // OK:    var diff = Diff("aaabb", "aaacc", caseSensitive: true);
    // ERROR: var diff = Diff("aaabb", "aaacc", true);

    double Sin([double value]) ...
    // OK:    var slope = Sin(2.0);
    // ERROR: var slope = Sin(value: 2.0);

Something like that. I’d like that.

Advertisements

4 thoughts on “Named parameters for humanity!

  1. Interesting proposal. Note that the added value of named parameters goes hand in hand with non-specific typing of those parameters. Booleans are the worst offenders, especially when using default values.

    Objective-C uses named parameters for everything. It’s verbose… but not that bad, really.

    • Yeah, good point. In fact, I’d love a language that disallows (or strongly discourages) using any primitive types and makes it very easy to define (and explicitly convert between) more semantic types. E.g. Name and UIText instead of string, Millimeters and Volts instead of double, etc. And of course gigantic bucketloads of enums instead of booleans, except in conditionals maybe.

      • I like your proposal. I know how you feel about Scala…but it does have the case class for this latter purpose. And it also supports named parameters.

        Ruby does something similar, btw, by simply passing in hashes (dictionaries) as parameters. It looks kind of like this:
        move_robot_arm 0.0, :throwOnError => false, :simulated => true
        The (huge) downside (apart from dynamic typing) is that the method signature is pretty non-descript; you need to rely on documentation or good memory:
        def move_robot_arm(position, hash) … end
        Give me Scala or C# any time 😉

      • Jan, I’m not sure how you think I feel like Scala? I mean, I love it (if only it would compile a little faster).

        Yeah Scala’s case classes would match pretty well as semantic versions of primitive types. The only thing it misses then, as a language (or maybe as a standard library, at least) is actively discouraging using primitive types.

        Wrt Ruby, yeah, you really do want a compile error of sorts when calling stuff with named parameters “just” for readability’s sake. Otherwise, when some library author decides to change the name of a parameter, you’ll get a very unexpected runtime error. Good luck covering that with tests!

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