|No such thing as a small change|
Some Insights from a Traveler Between Languagesby skyknight (Hermit)
|on Apr 23, 2005 at 17:15 UTC||Need Help??|
So, I've been writing a bit of Python recently, mostly just to be more multi-lingual, and last night I shifted gears to writing some serious Perl for the first time in about a week. I bumped up against some nasty weirdness as the result of my brain not having fully transitioned from Python mode to Perl mode, and I thought I'd share my thoughts as they seem to elucidate the dangers of some of Perl's more promiscuous inclinations.
Now, in Perl, you use () to construct an array, and  to construct an array but return the reference to it. In Python, () constructs a tuple, whereas  constructs a list, the former being the same as the latter except that it is immutable. So, in Python, imagine the following two lines of code...
In the first case, you get a tuple assigned to foo, and in the second case a list assigned to bar. There's nothing confusing about this. Now consider the following Perl code...
The first gives you an array as you'd expect, and the second is similar but you end up with a reference to such an array. So far, so good... In the third case, you end up with a variable that holds the length of the array on the RHS. In the fourth case, you end up with an array of just one element, and that element is a reference to the array that was on the RHS. Ugh...
Not having mentally transitioned from Python, I fell for the trap of the fourth case. I was perplexed to have an array whose length always seemed to be one. So, what is Perl's justification for having these latter two cases? In the third case, wouldn't it be a hell of a lot safer to have the "length" function have a list version that calculated the length of an array? Sure, the while($i<@foo) idiom is nice, but is it worth it? In the fourth case, why isn't this just an outright syntax error? I can't imagine ever intentionally wanting to do that.
This segues nicely into my second gripe of the day. Perl's built-in "length" function is downright silly. Its intended purpose is to take a string and return its length. The instructions for its usage go so far as to explicitly say that you should not try to use it to calculate the length of an array. So, why is length(@foo) perfectly acceptable syntax? Furthermore, since it is valid syntax, why does it do something so thoroughly dumbfounding? It turns out that length(@foo) coerces @foo to a scalar, which is to say its length, and then calculates the string length of the returned integer. If your array has length 0-9, the result will be 1, length 10-99 will yield 2, etc. Gah! Since in Python you do len(lst) to calculate the length of the list variable lst, back in Perl land last night I was carelessly doing length(@foo) and getting extremely erratic results. Why can't Perl's "length" function be reasonable? Either provide a list version of it, or make such an invocation a syntax error.
Mind you, I love Perl, and I find Python needlessly aggravating in many ways. Perl is easily my favorite language. However, it would clearly seem to have dropped the ball in these regards.