Tuesday, August 6, 2013

Structured arguments

The problem with unstructured arguments

In all programming languages (or at least most of them), arguments are passed to a method declaration via a method call.

  someMethod (x, y, z);

This requires that the method declaration on the other end accept the data-types as well.

  someMethod (x, y, z) {
    // This is the method code

Now let's imagine, that you've called the method a few dozen times throughout your code:

  someMethod(x, y, z); // line 22
  someMethod(x, y, z); // line 246
  someMethod(x, y, z); // line 588
  someMethod(x, y, z); // line 612

That was 2 months ago (or maybe yesterday). And, now you'd like to re-factor the method; maybe, the second argument is no longer needed, maybe it's more logical if the arguments are arranged in a different order, or maybe you'd like to rename an argument... of course this means re-factoring your method declaration and method calls as well... Zzzzz

  someMethod (x, z, ab) {
    // This is the method code

  someMethod(x, z, ab); // line 22
  someMethod(x, z, ab); // line 246
  someMethod(x, z, ab); // line 588
  someMethod(x, z, ab); // line 612

Here are your three options: (1) manually rename all arguments, (2) use the Find and Replace script built into most text editors, or (3) redesign the programming language. Today, we're going with the third option. 

Redesign the programming language

Lately, I've been been avoiding unstructured arguments all together, and now pass them as a single structured data-type (struct in C, object literal in Ruby). For example:

  someMethod (object) {
    // This is the method code

This way, I don't need to re-factor the method declaration or the method calls. The method call should look like the following:

  struct object {
    type key;
    type key;

  // ~ OR ~

     object = {
    key: value,
    key: value

  // Pass object to method call
  someMethod (object);

In dynamic languages (like Javascript), functions can also be passed as an arguments. Typically, I add those callback functions directly to the object as well.

In the end we're faced with a final question...
why doesn't the programming language do this for me?

All programming languages lack this fundamental design. Arguments should be implicit to the method. It's unnecessary to repeat the information both in the method declaration and the method call, because the method should only accept a single structured data-type that holds all the arguments.

  // Method Declaration

  someMethod (x, y, z) {     // non-ideal
    print x;
    print y;

  someMethod {               // ideal - Any arguments?
    print arg.x;
    print arg.y;

But, wait... couldn't this allow developers to pass arguments to the method that might never be accessed? Yes. But, methods that accept unstructured arguments "suffer" from this issue as well. It's the role of the compiler and the software developer to check for vestigial arguments.

In conclusion, method declarations should not list the arguments passed by the method call, these arguments should be passed implicitly via a structured argument.

Timothy Franklin Montague