I was perusing the first programming book I ever bought - SAM’s Teach Yourself Perl in 21 Days”
and came upon this classic code example on page 10 (listing 1.13):
$cookie = "";
while ($cookie ne ‘cookie’) {
print ‘Give me a cookie: ‘;
chomp($cookie = <STDIN>);
}
print "Mmm. Cookie.\n";
That got me thinking - how would this look in Python and what kind of differences would there be?
My first attempt was to mimic the Perl example pretty much verbatim:
cookie = ''
while cookie != “cookie”:
cookie = input("Give me a cookie: ”)
print(“Mmm. Cookie.”)
but something about that felt off. Not exactly pythonic, is it. So I arrived at this:
while input("Give me a cookie: ”) != "cookie":
pass
else:
print(“Mmm. Cookie.”);
The “pass” in the True block looks a bit counter-intuitive. It's almost like it’s
not doing anything, until you realise that the test actually does two things at the same time - assignment and test.
I guess the weirdest part for me about the Perl listing is the variable assignment
as an argument to chomp() (chomp($cookie = <STDIN>);)
I also feel like the final Python equivalent seems more explicit
since it clearly covers both cases (cookie being “cookie” or something else).
What if something weird happened while reading input?
I tried to trip them up with Ctrl-C, but I guess the interpreters outsmarted me.
Notice how the first Python attempt has the same flaw.
Notice also, that this doesn’t work:
while (chomp($cookie = <STDIN>) ne "cookie") {
print 'Give me a cookie: ';
}
print "Mmm. Cookie.\n";
because chomp() doesn’t actually return the chomped string,
but rather the number of removed newlines. Hence the endless loop -
you’re endlessly comparing “1” and “cookie”. Never the two shall match.
I do like the fact that Perl still lets me write print "" and print("").
It's easy to think stuff like that makes a language messy, but does it really?
It's just one more way of saying the same thing and I'm beginning to think that it simply speaks to a language's maturity.
Older languages, especially as widespread as Perl are just more nuanced.
This might have something to do with Larry Wall's background in linguistics.
One last thing - it takes roughly 4x longer to load the Python interpreter:
time perl -e ''
________________________________________________________
Executed in 7.76 millis fish external
usr time 2.60 millis 291.00 micros 2.31 millis
sys time 3.42 millis 700.00 micros 2.72 millis
time python -c ''
________________________________________________________
Executed in 28.25 millis fish external
usr time 15.92 millis 256.00 micros 15.66 millis
sys time 10.23 millis 745.00 micros 9.49 millis
So if you ever need to "find --exec ..." on millions of files, the choice is pretty obvious.
PHP is somewhere in between:
time php -r ''
________________________________________________________
Executed in 23.17 millis fish external
usr time 8.50 millis 228.00 micros 8.27 millis
sys time 7.35 millis 648.00 micros 6.70 millis
By the way, Pragprog is giving away Modern Perl.Older posts