princepawn has asked for the wisdom of the Perl Monks concerning the following question:
Note that the first word in the title is apparent, meaning that the rest of the title is thing as they appear to me, not necessarily the way they are.
Ok, let's do this storybook style. I'm sitting in my office and my boss says "how do you find out the length of an array in Perl?" So I tell him
1+$#array
#or
scalar @array
A week later I'm reading comp.lang.perl.misc and Uri Guttman says to someone asking a similar question about strings: To take the length of a string, you use length. Larry did a good job of naming the Perl functions.
So then I, the nobody, have the nerve to email Uri Guttman, one of the Perl 5 Porters and lead author on one of the best Perl papers ever (on sorting) and tell him he isn't right about Larry naming the functions... Larry didn't do so great a job... why? Take a look:
Desired operation
|
Perl datatype
|
Perl function
|
length | string | length |
length | array | scalar |
<length | list | ? |
length | hash | scalar keys |
In other words, the desired operation is the same in each case, but the way it is done in Perl is not... while one may say: "RTFM", one thing that reduces the learning curve for a language is for it to be intuitive. That's why I'm in awe when I hear people (even Damian Conway) say: "my brain thinks like Perl"... I have to stop,drop my jaw and say: "why in the world would you want different names for the exact same conceptual operation and what is it about your brain that seeks diversity in the function names for the exact same thing?
Example 2
Operation: Taking a "slice" of something in Perl
A string |
substr $STRING, $OFFSET, $LENGTH |
An array |
@array[$OFFSET..$LENGTH+OFFSET] |
Again while a logical person would say "how do I take subseries of something, regardless of whether it is a string or an array", we have the questionable brilliance involved in creating two radically different syntactic mechanisms for doing so.
And again, one must think seriously about offering a CAT scan to anyone who proclaims that such unwarranted non-homogeneity is "how their brain thinks".
Conclusion
Perl makes simple things simple, and hard things possible, but also makes consistent operations possible through highly inconsistent means.
And of course we cant forget the recent interview on Perl.COM with Ilya Zakharavich handled by BigJoe about how FILEhandle information is inconsistently handled by Perl.
Re: Apparent Inconsistencies in Perl Function Naming
by merlyn (Sage) on Nov 24, 2000 at 18:13 UTC
|
One thing that Perl most definitely is not is "orthogonal": that every kind of thing has every kind of operation applicable to it. Perl is optimized for the tasks you will be performing most often.
Larry said in one presentation I saw him make (can't recall which one now) that orthogonality isn't even for the birds... you don't see a bird go from northwest to southeast by flying one square south then one square east then one square south...
Birds take the direct route, and so does Perl. Perl has operations for the things
you do, and they're convenient in the domain of the thing you're working on.
The length of an array has no operator name, by the way. It's the name of the array
in a scalar context. Nearly every time I do that, I don't have to say scalar,
because I'm already in a scalar context. And I never think of substr as
a "slice" of a string. It's a substring.
Get your terminology straight, and Perl makes sense. Try to look for artificial
order along an axis not present, and you'll be no better than the scientists who
claim that the drains drain clockwise in the Northern Hemisphere.
-- Randal L. Schwartz, Perl hacker | [reply] |
|
Scientists?
I do not believe that scientists ever
had anything to do with this particular myth.
The basic facts about weather and spin that it is based on
were widely known. In the northern hemisphere hurricanes
blow counter-clockwise, in the southern clockwise. I do
not remember when this was first discovered, but from fairly
shortly afterwards on any competent sea captain had to know
it because if they encountered high winds at sea it told
them which way to turn to avoid the worst of the storm.
Therefore any scientist should have known that the effect
was too small to be measured, but many others - including
sailors - knew that. But note that sailors knew the fact
but did not really understand the principles. Mix that
with an inclination to tall tales and...
Incidentally I didn't remember or look up the correct
direction. Rather I remembered that the East Coast sees
the sun rise 3 hours before the West. So draw a mental
globe and visualize what way you have to move to get that
to happen. OK, from the North Pole the Earth turns
counter-clockwise. Now the cause of hurricanes turning is
that when air comes together towards the eye, that from
the equator moves faster than that near the pole. So
visualize that and the hurricane turns counter-clockwise.
In the Southern hemisphere the faster air comes (viewed
from the North Pole) from on top so visualize...it goes
clockwise.
Now if you want to blame scientists for a myth, you can
blame some in the Victorian era (sorry I forget names) for
the widespread belief that in the Middle Ages people
believed that the Earth was flat. No. They believed that
the Earth was round and even knew the diameter fairly
accurately. Indeed the main argument against Columbus was
not that he would fall of the edge, but that it was too
far to China and he would starve. And he would have had
he not encountered a small obstacle in the way... :-)
| [reply] |
|
| [reply] |
|
| [reply] |
|
|
If I were on an ocean liner, crossing the equator, how far from the equator would I start to notice a change in direction, if I flushed a toilet? Would there be a gradual slowing down of the direction and then at a specific point in time would it just kind of "glug" with no rotation? Also where would this change take place in miles? I take it from what you said that water drains the same way in both hemispheres...how is it that this doesn't change if in fact it doesn't?
Reta, Maine, USA
| [reply] |
Re: Apparent Inconsistencies in Perl Function Naming
by chromatic (Archbishop) on Nov 24, 2000 at 22:03 UTC
|
A list is different from a scalar.
A list is different from a scalar.
(I had to repeat that to myself many times when first learning Perl.)
I don't see length as cut and dried as you do. It's easy to say, "What's the length of that piece of lumber?" and people understand what you mean. That's unambiguous. It's harder to say "What's the length of that pile of lumber over there?" and get a good answer.
Do you mean, "Please measure the base of the pile?" or "How long is the average piece of wood?" or "What's the expiration date?"
Perl goes to great lengths (pardon the pun) to express the differences between a thing and a pile of stuff. Unlike C, a string-in-a-scalar isn't the same as an array of characters. It's something fundamental to the language. You can chop it up in little pieces. You can build a birdhouse out of it. You can whack someone in the head with it for not using strict.
I'm not going to say that everything in Perl is 100% okay yes sir perfect, but I will say that once you understand context, things make a lot more sense. | [reply] |
(Ovid - Why are you doing this?)
by Ovid (Cardinal) on Nov 24, 2000 at 23:31 UTC
|
And this is relevant how?
Whether or not you believe that Perl is consistent, my response is "so what?" Find me a perfect language. All languages evolve and Perl is one of them. Now if you said "Perl has some problems and Larry Wall and co. are never going to deal with them", then I might have sat up and taken notice. Then I would have asked myself "do these problems have an impact on Perl's usefulness?"
Perl is the richest language that I have used, but I acknowledge that there are areas in the language that can use some improvement. Again I ask, so what? Perl 6, as you may be aware, is being worked on as we speak.
Some comments:
- Did you post this in "Seekers" or did some one move it here? You didn't ask a question and this is more appropriate for Meditations.
- Do you go around trying to dissect other languages like this, or have you singled out Perl for your displeasure? You have made so many posts critical of the language that if one of your cries of "Wolf!" turns out to be true...
- Why do you bother with Perl? You truly seem to be unhappy with the language and are intent upon spreading your displeasure.
princepawn: would you go to a church service, stand up and ask everyone about the inconsistencies in the Bible? Would you sign up for a poultry cooking class and spend every session criticizing people for eating meat? There is a time and a place to be so heavily critical of something, but coming to a place dedicated to it is not one of them. No one here mind an occasional discussion of problems with Perl, but a full-scale assault on the language is another thing. I'm sure you don't view it that way, but I can't help but wonder what you hope to accomplish by this.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] |
Re: Apparent Inconsistencies in Perl Function Naming
by Dominus (Parson) on Nov 25, 2000 at 20:44 UTC
|
I think you're right about the length() function.
People are surprised all the time when
length() fails to work on arrays.
Nat Torkington
put in a proposal for Perl 6 that suggests that
length(@array) be made to work properly instead of its
bizarre current behavior, so you're certainly not the
only person to have thought of this. I don't know whether
Larry will decide to change it, however.
As for the slicing issue, it's tempting to ask that
the positions in a string should be accessed by index
as if the string were an array. You can do this in some
other languages like C and Pascal where a string is
an array. But it's hard to see how to arrange it in Perl,
for syntactic reasons if nothing else. (Also, in Perl,
a string is not an array.)
But if your suggestion were followed, it would still be
inconsistent. @array[3..5] produces a list of
three items. But presumably you want your string-slice
to produce a single string, not a list. Then in your
alternate universe, PawnPrince comes along and asks why
the slice notation sometimes produces a list and sometimes an
string, and why it isn't consistent. So it's not clear that there's any benefit from your suggestion
anyway.
| [reply] |
|
Nat's suggestion fails to meet my expectations. Mine would
be that length should work something like this:
sub length {
if (1 == @_) {
return CORE::length(shift);
}
else {
return map {CORE::length($_)} @_;
}
}
IOW return a list of lengths instead of the number of things
in the array. (Which I can easily get anyways.)
Perl can't match both my expectations and princepawn's... | [reply] [d/l] |
|
IOW return a list of lengths instead of the number of things in the array. (Which I can easily get anyways.)
Really then, shouldn't length return a list or a scalar depending on the context in which it was called? :)
Note to all: If you don't see the humor in this, reread the thread
| [reply] |
|
|
ok, I was confused about length too but I did a test program up, once I realized what it's doing i said "DUH!!! Of course!"
Here's the deal
@a=qw(joe bob dude cool);
print length @a;
this returns 1. Why? length returns the length of a string in characters. the string you gave it was @a which is the # of elements in the array @a. in this case 4
since 4 has a length of 1 character it returns 1. if you push the array so it's 10 elements it'll return 2.
But I am forced to wonder, if you were asked to count all the letters on a page, this is simple.
But what if you were told to count all the letters on this page and handed a book. what would you do? count the letters on the cover, on all the pages within the book, or count the number of pages.
which of these is most logical?
My mind thinks in perl all the time, and to me this is all perfectly logical and exactly how I'd expect it to be. course everyone thinks diffrently.
| [reply] [d/l] |
|
sub length {
if (1 == @_) {
return CORE::length(shift);
}
else {
my @lengths = map {CORE::length($_)} @_;
if (wantarray) {
return @lengths;
}
else {
my $tot = 0;
$tot += $_ foreach @lengths;
return $tot;
}
}
}
Note how this falls naturally out of length being the
length of a string, and thinking of Perl as being
list-oriented... | [reply] [d/l] |
|
That does let you get approximate lenths:
my $length_ish = 10 ** (length(@array) -1)
But then again, that's not the length, it's still just the number of elements in the array. This is nearly an Infrequently Asked Question but not quite.
| [reply] [d/l] |
|
Re: Apparent Inconsistencies in Perl Function Naming
by Jonathan (Curate) on Nov 24, 2000 at 17:57 UTC
|
Guess I'm in the queue for a CAT scan princepawn. To my mind Larry has named functions well. To a degree it is a matter of opinion - perhaps even background. But I don't accept your arguments on the length function (which seems to have been inherited from awk anyway), 'length' does what it says on the tin and returns the length of a scalar value. While the 'scalar' operator forces scalar context - it is not a function to return the number of elements in a list. The same thing can be said for your second example you are looking at it from two sides - scalar and list
BTW do you never tire of playing the devil's advocate? ;-)
When I grow up I want to be a boy genius
My son Harry | [reply] |
Re: Apparent Inconsistencies in Perl Function Naming
by princepawn (Parson) on Nov 26, 2000 at 19:01 UTC
|
Several things have been said above. Summarily, I can reply with
- intuitiveness --- like I said, to a person versed in Perl's concept of context-sensitivity, something like scalar makes sense. But, to my C++-programming boss who simply wanted the length of an array, then looked in perlfunc under length and then asked me, it was a hassle. So, it may be best for a trained Perl programmer, but think from the mind of your boss or your secretary or someone else who just wants something simple and fast and you will see what the most intuitive thing is.
Now of course, the first thing that people say is "RTFM"... and my reply to that is: "the manual is very very big." there are much simpler languages out there. REBOL (a next-generation forth) is nothing but English concepts mapped to simple words.... the length word in REBOL works on all series types --- ports, blocks, strings, etc.But there is no industry acceptance of REBOL. So I write modules like Net::FTP::Common and advocate Quantum::Superpositions which bring Perl use nearer to the readability, succinctness, and ease-of-use of REBOL. And I am developing a parser for REBOL in Perl... then the power of REBOL will be available to Perl developers.
- uniformity/genericity --- you know those generic sorting algorithms that need the length of the data and a generic comparision operator? How easy is this in a non-orthogonal language like Perl?
| [reply] |
|
Says princepawn:
> uniformity/genericity --- you know those generic sorting algorithms that
>need the length of the data and a generic comparision operator? How easy
>is this in a non-orthogonal language like Perl?
Since you asked, it works really well. Perl achieves a lot
more genericity than C++, which you meantioned earlier.
The specific feature you brought up doesn't cause any
problems in practice. Let's take your example and
suppose that you wanted to write a sorting function.
You write it, but it only works on arrays.
In C++ it might also work on a string, because a string is
an array.
But in Perl, if you pass a
string, expecting the characters in the string to be
sorted into order, it doesn't work.
Is this a big deal?
No. Why not? Two reasons:
First, sorting the
characters in a string is a very unusual operation, so
it does not come up very often. But primarily because
if someone did want to use your function to sort the characters
in a string, they would just use split to turn the
string into an array and pass the array of characters.
Perl's genericity mechanisms are a lot stronger
than those in C++. Consider several C++ classes where objects
in each class will be joined to gether in linked lists.
Each class has a 'next' member which will be used
to point to the next
object in the list. Now you want to write a C++ function
that will traverse a list of objects of any class. Oops, you can't.
The only solution is to use the ridiculous templating mechanism to tell
C++ how to generate one separate traversal function for
each class!
But in Perl this task is trivial:
sub traverse {
my ($head, $function) = @_;
while (defined $head) {
$function->($head);
$head = $head->{next};
}
}
That's all. One function handles every possible kind of object,
as long as the object has a next member.
It even handles the classes that haven't been defined yet.
It can even be made to handle classes where the link member
is named something other than next.
(That's a one-line change.) This is
impossible in C++. Even the humongous templating
feature does not help.
I'm going to stop picking on C++ now. It's unfair,
because C++ is such a shoddy language.
The short answer to your dig about
Perl being a 'non-orthogonal' language
is that Larry is really smart, and
he put in the orthogonality in the places
where it was important, and not in places where it wasn't. | [reply] [d/l] |
|
Perl is intuitive, but not for casual programmers. If you're needing to look up how to get the length of an array, Perl is not for you. Perl is an expert language: very powerful in the hands of experts, but perhaps dangerous to the casual programmer. It's more like a chainsaw than a knife. You must be this tall to program in Perl. Remember the adage: "Make a language that any fool can use, and only fools will want to use it." I'm glad Perl is not for fools.
Perl does offer genericity at the OO level, provided you follow standard OO design techniques. The low-level things in Perl are not objects, by design. Think of it in physical terms. I can tug on a bed or a desk or a car in a uniform way, but when I get down to the atomic level, the way I attract a proton is different from the way I attract an electron. You're trying to look for orthogonality at the "atomic" level of Perl. No. Stop looking there. Build it at the higher levels, and all will be well. Perl lets you make interesting things, but Perl also lets you make crappy things too.
-- Randal L. Schwartz, Perl hacker
| [reply] |
|
| [reply] |
|
Programming is the practice of converting human thought to computer syntax. Programming has seen an evolution from punched cards, to machine language, to assembler language, to C and to Perl. In each case, the language has moved further from "speaking to the CPU" to "here's what I want to do."
An acid test of such evolution is the ability of the commoner to codify his thoughts in working programs. While Window-based menu systems go a long way towards providing such functionality, to date they are not as configurable as a scripted program and hence the need for a language allowing for expressiveness by everyone, not just the person trained to convert human thought to computer syntax.
| [reply] |
|
|
|
A reply falls below the community's threshold of quality. You may see it by logging in. |
|
|