On 2010-02-15 08:59:43 -0500, Jonathan M Davis <[email protected]> said:
Clarity is very important, but if you have long names which are used
frequently, it can quickly result in long lines of code which end up on
multiple lines and can be hard to read. If a word isn't used very often,
then it's not that big a deal, but the more often it's used - especially
when it can be used multiple times on the same line - the worse it gets.
Well, the problem is that whether you're using something often or not
depends on the context. If in a context your function name is used once
or two, but in another it's used a lot, which prevails: shortness or
clarity?
I'd tend to put clarity over short names in D because the language
makes it very easy to create shorter aliases limited in scope when the
need arise. But you shouldn't repeat the argument types nor the
module's name: the language takes care of that for you.
Really, the ideal situation is to find words which are short and clear, but
a balance must be struck between the two regardless. Too long and it's
cumbersome. Too short and it's likely to be unclear.
There's no question that programmers often use words for variable names and
such which are ludicrously short and unclear, but long words can be a
problem too.
I think it's a question of locality. The broader is the scope of a name
the more self-explaining the name should be. As an extreme example, I
don't mind much seeing a local variable named 'x' in a short function,
but I wouldn't accept that as a member variable in a class, and even
less for a global variable.
It's easy for someone to create short names when he is all absorbed in
what he's doing. But I think it generally takes some detachment to get
the names right for a public API. Ideally, API names should be
understandable as soon as you understand the underlying concepts. But
even more important is that __functions should never be understood
wrong__, the name should be clear enough to ensure that.
I don't think std.range fare very well at this readability test. Take
this example:
int[] array = [1,2,3,4,5,6,7,8,9];
auto five = take(5, array);
writeln(array); // what are you expecting here?
In the case above, 'take' returns a range that lazily takes N elements
when you iterate over it. If you don't use the returned range, 'take'
is as good as a no-op. But this subtle interaction isn't very clear
when you just read the code.
Last week I defined my own function named 'take' for some kind of
parser, advancing the range by the number of specified elements and
returning an array of all the 'taken' elements. Then I realized it had
the same name as the one above but with this subtle difference in
semantics, subtle but very important for what I was doing. I renamed my
function since then to make things less confusing, but I'm still a
little shaken by this whole incident.
I think the lazy nature of 'take' should be visible when calling the
function. This could be achieved by a name change, or perhaps in
another way.
--
Michel Fortin
[email protected]
http://michelf.com/