perlmeditation
skyknight
<p>
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.
</p>
<p>
Now, in Perl, you use <code>()</code> to construct an array, and
<code>[]</code> to construct an array but return the reference to it.
In Python, <code>()</code> constructs a tuple, whereas <code>[]</code>
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...
</p>
<code>
foo = (1, 2, 3)
bar = [1, 2, 3]
</code>
<p>
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...
</p>
<code>
@foo = (1, 2, 3);
$bar = [1, 2, 3];
$baz = (1, 2, 3);
@biz = [1, 2, 3];
</code>
<p>
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...
</p>
<p>
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
<code>while($i<@foo)</code> 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.
</p>
<p>
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
<code>length(@foo)</code> perfectly acceptable syntax? Furthermore,
since it is valid syntax, why does it do something so thoroughly
dumbfounding? It turns out that <code>length(@foo)</code> coerces
<code>@foo</code> 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 <code>len(lst)</code> to calculate the length of the
list variable <code>lst</code>, back in Perl land last night I was carelessly doing
<code>length(@foo)</code> 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.
</p>
<p>
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.
</p>