hello there,
I want share an headache with you due to the Perl's loop control until structure.
I'm currently happily reading, with some profit i hope, High Order Perl and so far, apart from some math base i do not have, i can quite afford it. and i very like it.
While explaining iterators apllied to permutations the author, with the usual kindness, come back a little to present a simpler problem: an odometer.
Realized that the odometer is that set of little wheels showing how many kilometers my kawasaki GPZ 750 divoured in his history, i looked at the subroutine proposed with a "ah ok... is very simple. i can get it.." approach.
This line, clear in the result wanted, mazed and puzzled me:
until ($odometer[$wheel] < 9 || $wheel < 0)
This is the original code of the sub with a little prepended code just to call it, putted by me.
use strict;
use warnings;
my @odometer = qw(0 0);
for (1..$ARGV[0]) {
print "was: @odometer\t";
@odometer = increment_odometer(@odometer);
@odometer ? (print join ' ', @odometer) : (print "No more Wheels t
+o turn! $!" and exit) ;
print "\n";
}
sub increment_odometer {
my @odometer = @_;
my $wheel = $#odometer; # start at rightmost wheel
until ($odometer[$wheel] < 9 || $wheel < 0)
{
$odometer[$wheel] = 0;
$wheel--; # next wheel to the left
}
if ($wheel < 0) {
return; # fell off the left end; no more sequences
} else {
$odometer[$wheel]++; # this wheel now turns one no
+tch
return @odometer;
}
}
The semantic translated
Now come in count another think, i'm not eng-native (as my name suggest i speak latin..).
Every word in english have an attached logical translation in my mind and, while i read some perl code, this is used as logical unit to build up the scenario: i cannot think in english..
I know that until simply invert the condition of the same while loop.
The 'while' in my native language is 'mentre' and the reverse 'until' is 'finché'.
But while the first transaltion fit well in any circumstance, the second does not apart from trivial case of the condition.
I took the english-italian dictionary and i found that until is translated as 'finché (non)'. This beacuse in english until want a positive sentence but in italian 'finché' bring the possibility to use a negative form of the sentence after it, and in this way is commonly used: 'i wait until you arrive' can be translated as 'aspetto finché arrivi' but also sounds good as 'aspetto finché NON arrivi'.
In italian the double negation is admitted and correct: 'Non c'è nessuno' is 'There is nobody' but have a double negation ('non' and 'nessuno') but sound as 'there is not nobody'.
Inverting the condition
Naturally the original code is correct (this was never in doubt) but now i want a valid logical representation of it in my mind so i played with the line with the until condition:
until ($odometer[$wheel] < 9 || $wheel < 0) #ok original
#negated direct form also ok
while ( !($odometer[$wheel] < 9 || $wheel < 0) )
while ($odometer[$wheel] > 9 || $wheel < 0) # NO
while ($odometer[$wheel] > 8 || $wheel < 0) # OK but NOT for greter th
+an limit of the odometer!
#Use of uninitialized value in numeric eq (==) at C:\SCRIPTS
+\odometer.pl line 27.
#Modification of non-creatable array value attempted, subscr
+ipt -3 at C:\SCRIPTS\odometer.pl line 26.
#getting: 9 9->
while ($odometer[$wheel] == 9 || $wheel < 0) # OK but NOT for greter
+than limit of the odometer!
#Use of uninitialized value in numeric eq (==) at C:\SCRIPTS
+\odometer.pl line 27.
#Modification of non-creatable array value attempted, subscr
+ipt -3 at C:\SCRIPTS\odometer.pl line 26.
#getting: 9 9->
while ($odometer[$wheel] == 9 && $wheel >= 0) # OK
It does not appear the first attempt using an 'LABEL if redo' solution because i think i'm too young to use LABELs.
But really the negation of
($odometer[$wheel] < 9 || $wheel < 0) is
($odometer[$wheel] == 9 && $wheel >= 0) ?
This is not a critic to Perl or about the choice of words in the language or a request to abolish the poor until is only something i want to share about the problematic enlace between a logical language and a spooken one.
L*
there are no rules, there are no thumbs..
Reinvent the wheel. Then learn The Wheel and use it!