Python or PHP?

Mike Meyer mwm at mired.org
Sun Apr 24 04:39:04 EDT 2005


John Bokma <postmaster at castleamber.com> writes:

> Mike Meyer wrote:
>> Depends on the problem. If it's one of the things for which Python has
>> an obvious solution (sort a list; split a string on whitespace; pull
>> select list elements based on a criteria of some kind; search a file
>> for lines with a given word in them; etc.) you'd get back the same
>> answer from almost all of them.
>
> And what makes you doubt it would be different with Perl? :-D

Perl's "There's more than one way to do it" attitude.

> ( sort @alist, split ' ', $astring, grep criteria, @list, etc )

In the one case where perl provides you two ways to do things, you
chose the one that doesn't solve the problem. You want map, not grep.

You also chose the wrong way to do things globally, by leaving off the
optional parens on the function invocations. That makes the list a
PITA to parse, in that you have to know the number of arguments to
each function in order to parse the list you provided.

Consider the python version:

         (alist.sort(), astring.split(), [x for x in alist if criteria(x)])

This list can be parsed by a machine. Given proper bindings for all
the variables, Python will turn it into a tuple.

N.B.: split(' ', $astring) is wrong as well. In this case, Perl
doesn't provide the right tool for the job; you have to build it from
parts.

>> As I've said a number of times, this has changed lately as new
>> features have been added without removing their older counterparts.
>
> The only variation I expect for the above Perl solutions is the use of 
> (), and the first argument of split. However, the last one might show 
> some exotic solutions :-)

And those trivial variations are enough that you chose the wrong
ones. And you're (by your own admission) an experienced Perl
programmer.

>>>>>> to do things means developers only have to
>>>>>> worry about impact on that way when making improvements, which
>>>>>> will speed them up.
>>>>> Yeah, Perl programmers are extremely slow ;-)
>>>> Nah, they aren't slow. They just have to worry about more things
>>>> than the Python developers.
>>> Do you have references to this? I would love to see if indeed 100
>>> Python programmers do implement, say 5 CS tasks faster compared to
>>> 100 Perl programmers, on average.
>> 
>> I'm talking about the people developing the language, not the ones
>> developing in the language. And this is just my impression from
>> watching the developers lists.
>
> I have no idea, since I read neither list. I have the idea that Perl is 
> indeed more fat, especially since the (too big) number of built in 
> stuff, that Python has in libraries (where it should be IMNSHO).

If you think Perl is fat now, read the apocalypses for Perl 6. Perl 6
is going to make Common LISP look small.

> One could say (and should) that the regular expression thingy in Perl is 
> a language on its own :-)

It is. For what Perl was designed for, having that be part of the
grammar of the language makes sense. For a general-purpose programming
language, I'm not so sure.

> But you probably agree, that if speed is an issue, and the programmer's 
> skills are not the issue, that the only thing one can do is code it in a 
> different language (probably by another programmer).

I don't agree. The better alternative is to look for a faster
algorithm. Programming "in the large" (as allowed by Python, Perl,
etc. when compared to C) sometimes makes that easier.

Changing languages is a potshoot. I once recoded a Python program into
Eiffel (which is compiled), only to have it slow down by a factor of
4. The program used a large collection of static objects - hundreds of
thousands of them - which the SmallEiffel garbage collector would scan
every time it ran. Python's reference counting ignore them, so the
Python version ran noticably faster even though the basic operations
were all faster in Eiffel.

Now, I could have recoded it in C and gotten *much* faster. But then
I'd have to deal with all the dynamically allocated objects (millions
of them!) by hand, plus writing the code to deal with the trie and
such like. Ugly.

Oh yeah - this algorithm was the third crack at the problem. Changing
the algorithms had sped things up noticably.

>>> I know to little about Python, especially about old Python, to have
>>> an idea of what you mean. I only saw, quite recently, someones
>>> solution to a problem that used 30 lines of Python, and I am sure I
>>> could have written it in 3-4. And I doubt that's because he was
>>> using, or I was thinking in, new Python
>>> :-D.
>> 
>> Just because there's only one obvious way to do things doesn't mean
>> it's obvious to everyone.
>
> My point. Moreover, most skilled Perl programmers (or at least the ones 
> I know) fall back to a shared common set of idioms, which probably are 
> not always the fastest one (which I consider a good thing)). So to them 
> there are often obvious ways to do things. Put them together, and for 
> the small problems you gave they very likely will come up with similar 
> results.
> So restrictions on the number of ways fails for beginners, because: life 
> will find a way. And skilled programmers don't need it, because they 
> somehow stick together.

My experience with Perl is just the opposite. Everytime I have to
maintain Perl code, I come across a different set of idioms - with no
obvious downside to them. You can, of course, define "skilled
programmers" as those who use your idiom set. This makes the set of
skilled Perl programmers very small. That few programmers are skilled
is a downside of TMTOWTDI, as the only time I see new idioms in Python
are newbies doing very odd things here.

I will conceede that the itertools module puts the lie to me. It
provides a lot of list manipulation functions that I haven't
thoroughly explored, which represent new idioms. However, those aren't
part of the grammar of the language, and are a recent addition. It's
not clear how Python should evolve with them added to the language.

>> Witness the recent spate of people asking
>> for "goto".
> I was a witness, moreover I stated my opinion, which in short stated 
> that there is nothing wrong with goto as a statement. Keeping a 
> statement from a language because beginners don't understand it, and 
> write bad code with it, is wrong. Moreover, every time I see some kind 
> of protection in a language, I see people who consider them safe, and 
> make other, equally bad (or worse) mistakes. (See my other replies in 
> this thread regarding the special "protection" PHP has).

I, on the other hand, feel that adding something to the language just
because you can is a *really* bad idea. Unless the new construct
solves a real problem, there's no point in adding it. It just bloats
the language processor and increases the mental load on people who
program in the language. The best you can do is ignore it in your
code, meaning you're going to have pause and think about it every time
you run into it in someone elses code. I never saw a good use case for
goto in Python (as opposed to C, where it's clearly needed).

Adding things just because you can leads to monstrosities like Common
LISP, PL/I, Algol 68 and Perl 6. Adding features only when they add
functionality (or better yet, by removing restrictions) leads to
jewels like Python, Scheme and Eiffel.

> You either understand why something is bad at a given moment, or not. If 
> a language must make up for the understanding a programmer lacks, 
> something is very very wrong.

There's a difference between "making up for the understanding a
programmer lacks" and "handicapping the programmer". Missing gotos is
like missing explicit pointer manipulation. Carefully designed
features added to the language (or restrictions removed from it) can
provide the same functionality as those features, without exposing
programmers to all the potential bugs that can occur when those
features are used.

Adding something that doesn't extend the language and creates
potential bugs is a *mistake*. You run that risk every time you add
just another way to do something.

> I doubt that Python needs a goto, since I am sure it has enough "syntax 
> sugared" versions of goto to solve most, if not all things that one 
> needs a goto for.

Exactly.

>>> After 5 years one gets comfortable with most constructions in a 
>>> language. I am more often uncomfortable with the way someone
>>> translates a problem into code. And there is no way how you can force
>>> people with a language that is, to do that the same, not even close.
>> 
>> Of course not. The best you can do is provide one obvious way to do
>> things, and then hope most people find that.
>
> Beginners get lost anyway, experienced programmers don't need it

I disagree. If there's not one obvious way to do things, experienced
programmers tend to choose the one they are most comfortable with, and
will have to work out what all the others mean. This has been my
experience with Perl and Common LISP, and from what I hear is true of
C++ as well.

On the other hand, my experience with languages that provide one
obvious way to do things (Python, Scheme, Eiffel) is that experienced
programmers tend to find that way, and beginners quickly become
frustrated when they fight the language.

>>>> My Perl evolved from very shell script like (lots of
>>>> backticks and passing around the full text of files)
>>> I am sure you can do that with Python too.
>> That hasn't happened in 9 years of Python.
> That was not what I wrote: I am sure one can program that way in Python 
> too.

No, you said "one can do that with Python", leaving the word "that"
open to interpretation. I assumed you meant "migrate from writing sh
to writing C", which, as I said, hasn't happened.

If you meant writing sh or C in Python, try it. You'll find it clumsy
and frustrating. Python wasn't *designed* to make it comfortable to
write that way. Perl was - just a couple of more ways to do things.


>> Some of the idioms have
>> changed because the language has changed, but not because my
>> perceptions/expectations/etc have changed.
> In 9 years? I learned so much in 9 years about programming that I 
> probably am ashamed to show Perl code I wrote 9 years back :-) (Even if 
> I left out the Perl 4 syntax). Moreover, I think that my current Perl 
> code is quite different from 3-4 years back. And no, not all is related 
> to the "there are more ways to do things". I changed my mind on certain 
> things (mostly style issues), learned new modules (some are really new, 
> others I just didn't know about), but also: I learned new programming 
> techniques, or other ways to look at a problem, and hence, write a 
> different solution (but using the same idioms as 3-4 years back).

The only one of those that really matters is "changing your mind on
certain things". The only way to do that is if there's more than one
way to do those things in the first place. My Perl style changed
radically over the years. My python style has as well, but only
because the language has changed as time passed. In the cases where a
new construct/module hasn't been added, the idiom that was obvious
with Python 1.4 is still the right choice with Python 2.4. With Perl,
there's no obvious right choice, so you and I could both change our
minds.

>>>> to one more
>>>> C-like as I used the language. That change was largely driven by
>>>> performance concerns as my understanding of the language grew.
>>> Yup, in Perl one should program Perl, not bash, not C. Same for
>>> Python. 
>> 
>> Right. But Perl makes it *easy* to program in bash or C while staying
>> in Perl, and provides no obvious drawbacks from doing so - all because
>> it's trying to be comfortable to sh and C programmers by providing
>> ways to do things that those users are comfortable with. Trying to
>> write sh or C in Python is painfull, and you usually run into
>> problems/drawbacks fairly quickly - because that's not the obvious way
>> to do things.
>
> But again, it doesn't keep people who want to do this.

Um - this sentence isn't complete. It doesn't keep those people from
*what*?

A langauge can make it easy to write ugly code, or it can make it hard
to write ugly code. After all, "You can write FORTRAN in any
language(*)". If I have to maintain the code, I'd *much* prefer that
the language make it hard to write ugly code, as I'm that much less
likely to get ugly code to maintain. TMTOWTDI makes it easy to write
ugly code. TOOWTDI makes it hard to write ugly code.

> Also, Perl borrows a lot of its syntax from C, which Python (as far as I 
> have seen) does extremely little, if at all. So it's already easier to 
> program C-like in Perl, by design, even if Perl was as "restrictive" as 
> Python.

If Perl only borrowed a lot of it's syntax from C, this wouldn't be a
problem. But it borrows a lot of it's syntax from sh as well,
sometimes supporting both (because TMTOWTDI). If it had done one or
the other, it would have been a better language.

> If the current direction of Python means relaxing it a bit, I personally 
> think that is a good thing. Sometimes more than one way makes it 
> possible to introduce a construction that's well known in another 
> language, and turn it into an idiom for the "more than one way" 
> language, and hence, teach "new" ideas to people.

Considering that I've been arguing all along that "more than one way"
is a bad thing, I have to disagree with you.

I will agree that adding new idioms from other programming paradigms
is a good thing (see <URL:
http://en.wikipedia.org/wiki/Programming_paradigm >). In theory, the
reason for that is that changing paradigms changes the set of things
you do, so you aren't adding more ways to do things, you're adding
more things to do.

The reality is that such changes often do introduce new ways to do
things that already exist. There have already been threads where it's
been argued (by others - I just read them) that this is detrimental to
Python.

> And my quick peek at http://www.xml.com/pub/a/2004/03/31/pycon.html 
> gives me the impression that the current direction of Python is to make 
> such things available (for example more lazy, which I like thanks to my 
> functional programming experience :-) )

Right. But read <URL: http://www.python.org/peps/pep-3000.html > and
you'll see that many of the things that are now redundant are
scheduled to go away when we break backwards compatability. The
philosophy is still that "There should be one-- and preferably only
one --obvious way to do it." (from "import this"), even if we are
drifting from that in the current implementations.

         <mike

*) I still remember seeing FORTRAN programmers writing ALGOL-W
conditionals as:

             if not condition then
             else
                begin
                code
                end

Because they learned to write the FORTRAN version:

        if (.not. condition) goto 100
           code
  100   continue             

They even had the gall to bitch about it when I marked them down for
it.
-- 
Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.



More information about the Python-list mailing list