Re: Re: Self-improvement and TMTOWTDI
by demerphq (Chancellor) on Jan 24, 2003 at 19:16 UTC
|
Actually, to be mildly heretical, I don't think perl offers more "extra" ways of doing things than many other languages.
Somebody _had_ to call you on this. :-)
I can think of a disturbing number of ways to iterate over the elements in an array in perl. In Pascal I can only think of a few, likewise for VB, and similarly for C/C++ (I mention this one last because I know it the least well and so might be suprised.)
Without using procedure calls I can think of the following notationally distinct means (and thats just at the moment, no doubt there are more, and i'm even ignoring the 'for' eq 'foreach' aspect that adds even more)
# 1.
... map { ... } @array;
# 2.
... grep { ... } @array;
# 3.
for my $item (@array) { ... }
# 4.
... for @array;
# 5.
for (my $i=0; $i<@array; $i++) { ... }
# 6.
my $i=0;
while ($i<@array) { ... $i++ }
# 7.
my $i=0;
while ($i<@array) { ... } continue { $i++ }
# 9.
my $i=0;
... , $i++ while $i<@array;
# 10.
my $i=0;
MARK:
...
$i++<@array and goto MARK;
# 11.
my $i=0;
{
...
$i++<@array and redo;
}
# 12.
... foreach 0..$#array;
# 13.
foreach (0..$#array) { ... }
# 14. Blame [tye]
for( pipe(IN,OUT) && do { local $,=$/; print IN @array,'' } && <OUT> )
+ { ... }
That makes thirteen so far.(!) And I bet as I ride the train home a few more will come to me too. (I will update this node with any contributions that are made so please send em in. Id like to see if we can hit 20. :-) So at least in this regard I think I would have to disagree with your claim.
Incidentally, I think that this is an interesting juxtapositioning (maybe the wrong word ill grant) of two key perl concepts. The first is "everything that is different should probably look different if at all possible", and the second is that "for everything that you can do there should be a few different looking variants available (TMTOWTDI)", which combine together nicely to match another generally held but certainly perlish imperitive which is that "code should look like it does what it does". So if we need to transform every element of a list to create a new one we use a different construct than we do if we want to apply a simple function to every element of the original, which is different from when we want to do something complicated with every element, and is also different from when we want to use the index, yada yada yada...
All in all i think this is great once you become used to it. When I see
my @array;
$_++ foreach @count;
I instictively understand that the intention of the other programmer was very different to
my @array=map $_+1,@count;
which I find very useful in dealing with old code.
Cheers,
--- demerphq
my friends call me, usually because I'm late....
| [reply] [d/l] [select] |
|
|
Just a couple of ideas ..
my $i = 0;
do {
$array[$i++] ..
} until $i > $#array;
do {
$array[$i++] ..
} while $i <= $#array;
JUMP:
do {
$array[$i++] ..
}
goto JUMP if $i <= $#array;
I reckon that's 17 .. 3 to go :)
-- Foxcub
Update: Couple of corrections. | [reply] [d/l] |
|
|
#1
while (@array) {
my $elem = shift @array;
...
}
#2
foo(@array);
...
sub foo {
my $elem = shift;
...
foo(@_) if @_;
...
}
#3
foo(@array);
...
sub foo {
my $elem = shift;
...
&foo if @_;
...
}
#4
{
my $elem = shift @array;
...
redo if @array;
}
Duplicate these for using pop or splice rather than shift if you want. Also with your existing ones do you count for as different than foreach? Beginners do.
I think we passed 20. :-) | [reply] [d/l] |
|
|
@a = 1 .. 10;
$i = $ENV{myI} || 10;
print $a[$ENV{myI} = --$i];
do $0 if $i>0;
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead. | [reply] [d/l] |
|
|
Somebody _had_ to call you on this. :-)
I knew somebody was going to slap me!
How about Common LISP (gotta (love (those (brackets))).
At the very least we have:
count, count-if, count-if-not, every, fill, find-if, find-if-not, map, map-into, merge, mismatch, notany, notevery, nsubstitute, nsubstitute-if, nsubstitute-if-not, position, position-if, position-if-not, reduce, remove, remove-duplicates, remove-if, remove-if-not, replace, search, some, substitute, substitute-if and substitute-if-not.
That's 30 - and I've probably missed some - different way of iterating over a sequence of elements.
(in case anybody hasn't realised - I am not being entirely serious here :-)
| [reply] |
|
|
| [reply] |
|
|
|
|
It would be interesting to see whether all these different ways to iterate over the elements of an array compile more or less to the same underlying code. Now that would be some optimising compiler! CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] |
|
|
> Without using procedure calls I can think of
> the following notationally distinct
Notationally distinct is not terribly important. A number
of your "different" ways are extremely minor
variations.
For example, 3 and 4 differ only in terms of the variable
used and whether the condition is placed before or after
the block; they not only do exactly the same thing, they
do it in exactly the same way. Counting them as different
is pedantic in the extreme; if you really think that's
clever, I can easily think of a couple hundred ways to do
it in line number BASIC.
More, some of your ways to do it are simply taking more
general mechanisms and applying them to a problem normally
solved with a more specific type of construct. For
example, using a while loop with a counter at the end
of it that is not used for anything else other than to
count out the iterations of the loop is something you can
do in any language that has while loops, because the for
loop is conceptually a special case of the while loop.
Congratulations, you discovered a general principle that
applies to all languages.
Perl does have a few more than other languages, but it's
not quite like you make out. Further, I'd say that these
extras (like map) are not "extra" per se but are part
of what makes a rich language such as Perl rich. I use
Emacs lisp, and it too has some of these higher-level
constructs that are essentially a specialised case of
something that with a bit more work on the programmer's
part could be done with standard flow control mechanisms,
but the higher-level features, where appropriate, are less
work to use. (And speaking of lisp, does anyone else
wish Perl had an equivalent for rassq? Or does it, and
I'm missing it for lack of knowing where to look?)
-- jonadab
| [reply] [d/l] |
|
|
Notationally distinct is not terribly important.
You dont think so? I disagree. The notational difference reads different and thus has a different psychological impact on a maintainence programmer. But each to their own. TMTOWTDI.
For example, 3 and 4 differ only in terms of the variable used and whether the condition is placed before or after the block; they not only do exactly the same thing, they do it in exactly the same way.
Do tell. :-) Im afraid there is a problem however, as only one of them involves a block they dont do the same thing. And this is of course beside the above point.
For example, using a while loop with a counter at the end of it that is not used for anything else other than to count out the iterations of the loop is something you can do in any language that has while loops, because the for loop is conceptually a special case of the while loop.
Well I think your claim "all languages" is a little broad. And just becuase you can do this kind of equivelency in most languages doesnt mean the point is any less relevent.
Congratulations, you discovered a general principle that applies to all languages.
You think I am unaware that the vast majority of languages support this equivelency? Hell while we are at it why dont we lose all the non GOTO examples as conceptually GOTO maps closest to "JMP" and all of the above are ultimately implement via a CMP and conditional JMP.
I'd say that these extras (like map) are not "extra" per se but are part of what makes a rich language such as Perl rich.
Er. I dont see how they can not be "extras" while at the same time being part of what makes the language rich. My earlier argument was that it was exactly these extras that do make the language so rich.
but the higher-level features, where appropriate, are less work to use.
I think the choice of one of the solutions over the next is related to both how easy it is to write and to how closely it maps onto the semantic context of the problem at hand. But I already said that didn't I.
--- demerphq
my friends call me, usually because I'm late....
| [reply] |
|
|
|
|
|
|
| [reply] |