Affordances: Arguments
This post is part of an ongoing series about Affordances and Programming Languages.
Programming languages provide different facilities for defining functions and methods. In particular, they provide more or less flexible ways of specifying parameters.
Smalltalk’s simple, consistent syntax provides only one option: ordered, required parameters. If you want to provide optional default values, arbitrary parameter ordering, or a variable number of arguments, you need to use separate explicit methods.
Smalltalk’s keyword method syntax makes for very regular, readable code and that is a significant advantage. But it gets tedious to define a flexible API, as you can see above.
C++ is more flexible, in that it allows for optional default values.
In C++11, there are also several ways to allow a variable number of
arguments, including
varargs
,
variadic templates,
and
std::initializer_list
.
I use the latter here:
Creating a flexible API in C++ involves less code than in Smalltalk, which is an advantage. But with a complex API, it can be hard to know what the various parameters mean because of the lack of keyword arguments.
Ruby provides the best of both worlds, especially in Ruby 2.0 with its
keyword arguments. It’s possible to use a Hash
in Ruby 1.9 and
earlier to have the same effect, but it involves a bit more code.
In Ruby, we only need one variant of the find_font
method, because
keyword arguments can be specified in any order and also have default
values. This allows for very flexible APIs. The cost is that, when
designing an API, you have to decide which facilities to use.
I’d be remiss if I didn’t give a nod to Common Lisp’s argument facilities here.
As with most things in programming languages, there are tradeoffs to be made. Smalltalk’s simple, consistent syntax makes for very clear, readable code. However, it doesn’t provide good affordances for flexible APIs. C++, Ruby, and Common Lisp provide more affordances, making it easier to write flexible APIs. However, that puts more pressure on the programmer to decide which facilities are best to use where. Doing that well takes experience.
With great power comes great responsibility.