Python or PHP?

Mike Meyer mwm at mired.org
Sun Apr 24 19:07:43 EDT 2005


John Bokma <postmaster at castleamber.com> writes:

> Mike Meyer wrote:
>> 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.
> There's doesn't mean that you have to use or know them all. I think 
> every language here and there more ways to do something. And at a 
> broader scope, e.g. a simple algorithm, it doesn't matter that much 
> anymore.

Except that, as I said elsewhere, that having more than one way to do
it bloats the language processor and increases the semantic load on
the programmer. The best the programmer can do, as you imply, is to
ignore the extraneous methods. Then the poor programmer has to puzzle
over them every time they show up in someone else's code.

>>> ( 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 think? Please read perldoc -f grep (and map).

I did, and could have sworn that grep modifed the list in place. Mia
culpa.

>> 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,

> First of all, who cares? Not the programmer.

Of course the programmer doesn't care. They jyust have to deal with it
for the rather short development period. The *maintainer* cares,
though - as they have to deal with it for the life of the program.

> But I doubt if you are  correct; why is 
> OP PARAMETER, LIST
> a PITA to parse, and
> OP( PARAMETER, LIST )
> not? I would even say that the former is easier to parse, since there is 
> no need for checking the ( and ) (and matching them).

Look at the *context*. You wrote

word word, word word, word, word word, word, word.

Unless you know what the words mean, this is nearly impossible to
parse out into proper perl expressions. Putting in the parens makes
it:

word(word, word), word(word, word), word(word, word), word.

This is trivial to parse into perl expressions without having to know
the meaning of any of the words.

>> in that you have to know the number of arguments to
>> each function in order to parse the list you provided.
>
> It has been a while since I wrote a lexer, but uhm, you set up a rule?
>
> LIST := ITEM
> LIST := LIST,ITEM

Right. So is

item, item, item, item

one list or two seperated by an English-level comma?

> (I made up the syntax, but I guess it's clear)
>
>> Consider the python version:
>> 
>>          (alist.sort(), astring.split(), [x for x in alist if
>>          criteria(x)])
>
> ( told you it was grep ;-) )
>  
>> This list can be parsed by a machine. Given proper bindings for all
>> the variables, Python will turn it into a tuple.
>
> What makes you think a machine can not parse Perl? I didn't get a Larry 
> Wall with my version of Perl :-D 

What would it take to get Perl to parse the line you typed in?

>> 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.
> You either misread your own problem specifications, or you should read 
> perldoc -f split (near the end, it starts with "As a special case," )

No, I missed the wart hiding under the "special case". How, pray tell,
do you do the equivalent of Python's string.split(' ') in Perl?

>> And those trivial variations are enough that you chose the wrong
>> ones. And you're (by your own admission) an experienced Perl
>> programmer.
> And you don't even come close :-D.

No, one I blew. One you still got wrong.

>>> 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.
>
> Same could be said of floating point numbers, or complex numbers, or 
> lists, dictionaries, etc. etc.

Right. And for each of those, there are languages that don't have them
as a built in type.

>>> 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.
>
> "The programmer's skills are not the issue"

Good point. I should have skipped the whole thing, as the programmers
skills are *never* not the issue.

> [ skilled Perl programmers use similar or same idioms ]
>
>> 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.
> If I could have a peek at the Perl code you maintained I could tell you 
> (often by just seeing 3-5 lines) the status of the programmer who wrote 
> it :-)

So you'd either say you were wrong, or that my second contention was
right. Either one would be a bad side effect of TMTOWTDI.

> As I wrote before, I have little experience with Python (one could say I 
> only read 2 books on it, and haven't written a stand alone piece of code 
> myself). But I have the feeling that the percentage of badly skilled 
> Perl programmers is way higher compared to Python for two reasons:
>
> Quite some people have been "tweaking" CGI scripts
> Quite some people "know" PHP, and hence consider themselves Perl 
> programmers.

Quite right. Neither is in the set of Perl things I maintain. The
first you can recognize by occasional style oddities in the middle of
the script. The second I'm not sure I'd recognize, as I don't do PHP.

>> 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.
> More fat: so I would say: learn to live with it. I only see advantages. 
> If you want a minimal set of operations, I recommend programming ARM 
> assembly, and don't go beyond ARM3 :-D.

You could also say more bloat. It's not a good thing. I don't want a
minimal set of operations; I want an orthogonal 1-1 coverage of
operations. That's will account for the least bloat in the processor,
the least load on the programmer, and the least bad code.

>>> 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.
>
> Neither has ever handicapped me in any way. I remember how Sun claimed 
> that their language was safe from memory leaking. I could come up with a 
> simple example that leaked memory like crazy in a few seconds. Moreover, 
> garbage collection gives newbies the impression that everything is 
> handled automatically, and hence, they forget that other resources are 
> less unforgiven, and *have to be* released.

Other resources are less forgivving only if they are badly
designed. That means they *should* be released, but not *have to be*
released. Consider the file type in Python. It'll be closed after
you're through with it, guaranteed. However, garbage collection isn't
triggered by running out of file descriptors, so you *should* close
them.

>> 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.
> A beginner will find a way. A nice example is garbage collection, 
> beginners think they don't have to think. And then suddenly things pop 
> up like: memory leaking, how are circular references handled, and oops, 
> suddenly things like weak references are needed. Add, things like 
> threading, and shared resources, resources that are limited in one way 
> or another and I doubt programming has become easier, or less error 
> prone.

Having dealt with memory leaks in C (and other such languages) for a
decade, I'd say programming is *much* easier than it would be if you
didn't have some form of garbage collection. Sure, programming in the
typical piss-poor threading model you find in popular languages and
etc. may be harder than programming in C without those things, but
it's still easier than programming in C *with* those things.

In fact, as the programming environment becomes more complicated, the
need for eliminating certain classes of errors by proper language
design increases, not decreases.

> Has anyone ever did serious research to the number of bugs per 10k lines 
> for several programming languages?

Yeah. The LISP community did some research on garbage collection
vs. explicit allocate/free a couple of decades ago. The explicit
allocate/free methodology was found to be noticably more bug
prone. Like I said, those date from a couple of decades ago, so I've
lost the reference and google didn't turn anything up.

> I remember to have read that air bags makes people drive more reckless. 
> I am quite convinced the same holds for programming languages. A 
> language can't cover your behind, so to speak.

Could you provide examples of what kind of behavior you're talking
about? What would be the analog of "driving more reckless" given that
I've got a garbage collector?

Of course, if you really believe that all the protections are a waste
of language spec, you should be writing assembler.

>> 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.
> potential bugs is often equal to something people *think* a beginner is 
> going to make.

Yes, but potential bugs even more often turn up in *real*
programs. I've fixed enough bogus pointer/using free'd memory/memory
leaks in C to know that.

>>>> 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
>
> and if they are not hermits, they choose the ones they see the most 
> often used (unless it's Perl golf).

Which means they adopt to their subset of the community. Which means
that supporting code from another community will in practice require
learning a new programming language that happens to have a syntax they
are familiar with.

>> 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.
> If I look at which things I have to work out the most: libraries. It 
> sounds a lot like you want an extremely pure language. I almost get the 
> impression that you hand code almost everything yourself. It doesn't 
> matter how clean you make the language, the libraries will be fat. I 
> rarely have to "work out" a piece of Perl. The "there is more than one 
> way to do it" is much more about the combination of basic blocks. Perl 
> is like legos. What you want sounds a lot like legos that can instead of 
> round thingies to connect them uses triangles, so there is only one way 
> to stack them. Oh, and you want them dull grey.

Nope, I make heavy use of libraries. The Python standard library isn't
exemplary, and it some cases provides overlapping functionality. But
it does try to avoid that. It also tries to come with "batteries
included". You can get an aweful lot done in Python without ever going
to third party libraries. With Perl, you wind up going to CPAN for a
lot of things - which puts you back into TMTOWTDI land.

Haven't you heard the story of the professor who had seven identical
suites, one for each day of the week? It saved him the work of having
to decide what to wear each day. If you've ever been married, you may
be familiar with how much work that can involve given a large
wardrobe.

I want programming to be the professors route. I don't want to worry
about which for loop to use - I want there to be just one for loop, so
I take that one and *get on with solving the problem*. Having multiple
for loops (or other TMTOWTDI things) bloats the language
processor/library and increases the load on the programmer to no
benefit.

>> 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.
> I wonder how much this has to do with how you learned Perl, and how you 
> learned Python.

True. The WWW was extant when I learned Python, so I could learn it by
reading the documention on the web site, and looking through the
library. Perl, on the other hand, I had to learn from the
documentation that shipped with it, and the library that shipped with
it. Come to think of it, Python has a larger library than Perl as
well. Given that, one would expect that the variance in idioms would
be larger than Perl, but it ain't.

>>>>>> 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.
> But it doesn't mean that one can't do ;-)

I guess if you can write FORTRAN in anything, you can write C or sh in
anythin as well.

>> If you meant writing sh or C in Python, try it.
>
> You talked about "lots of backticks and passing around etc." I am sure 
> one do things that are similar to backticks in Python, and also do the 
> passing around thing.
>
>> You'll find it clumsy and frustrating.
>
> Yes, most languages make it clumsy and frustrating. Perl is a rare 
> exception.

Right - Perl makes writing ugly, slow code easy. Python makes it
hard. I think this makes python the superior language.

>> Python wasn't *designed* to make it comfortable to
>> write that way. Perl was - just a couple of more ways to do things.
> But not clumsy, nor frustrating ;-) Perl is like a nice toolbox, and you 
> want Python to be just one of this tools. Moreover, written on it: 
> guarantee is void if used in any other way then stated in the manual.

Um, Perl isn't like a nice toolbox. Python is like a nice,
well-organized toolbox where everything is easy to find and use (well,
it used to be that way. It's gotten cluttered of late). Perl is like a
cluttered workbench with tools stacked on top of tools, with the
metric and english wrenches dumped in a heap - what ones aren't
scattered elsewhere on the workbench, anyway.

>> 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,
> To a newbie, nothing is obvious right, and a skilled programmer is able 
> to find the obvious right choice. You make it sound like the perl 
> community leaves people in the dark, and they have to find out what 
> everything means and does by trial and error. As I already wrote: the 
> more than one way is more often the *combination* of well known building 
> blocks.

Now you're trying to change the story. But I know better. Perl
provides multiple ways to do things at the syntactic level, and that's
the root of the problem. There are two iterative loops. There are two
conditional loops. There are two conditional execution statements, not
counting the variants that conditionalize the execution of a single
statement. There are two different syntaxes for invoking builtin
functions (though I don't think one of them works on user-defined
functions; never tried it).

>> A langauge can make it easy to write ugly code, or it can make it hard
>> to write ugly code.
>
> But who writes this code? The language, or the programmer? A programmer 
> who writes ugly Perl code is suddenly going to be a skilled Python 
> programmer? Are you serious?

No, he's not going to be a skilled Python programmer. But you avoiding
ugly code in Python doesn't take a skilled programmer. It's not clear
that even skilled Perl programmers can avoid writing code that some
other community won't find ugly.

>> 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.
> Nonsense.

I make that claim based on experiene maintaing both Perl and Python
code. What basis do you have for calling it nonsense.

>> TMTOWTDI makes it easy to write
>> ugly code. TOOWTDI makes it hard to write ugly code.
> And the funny thing is: it shouldn't matter to a skilled programmer. And 
> an unskilled programmer will make up for the TOOWTDI restriction in more 
> ways than you and I can imagine.

I don't agree. It doesn't say "There's one obvious to the skilled
programmer way to do it." It says "There's one obvious way to do it."
And it's usually obvious to anyone who's read the tutorials. The
newbie postings on c.l.python back that up - an amazingly small
percentage contain code that does things in the non-obvious way. A lot
of them are trying to do baroque things, usually because they are
trying to write in their last language. They wind up asking on the
list because they get frustrated trying to write something that isn't
Python in Python. If Python allowed all those things to work, they'd
wind up writing ugly code without having a clue that they had done
anything to be ashamed of. It's all to the good.


>>> 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,
> You can not borrow only a lot. Where is the rest coming from?

sh.

>> this wouldn't be a
>> problem. But it borrows a lot of it's syntax from sh as well,
> Yeah, it has to come from somewhere. So either borrow it from some well 
> know "language", or make up a new syntax.  It doesn't matter either way.

But Perl didn't do either one of those. It borrowed from *two*
languages, including overlapping functionality. Then it threw in a
bunch of stuff from other places, possibly fabricated from thin air -
again adding overlapping functionality.

>> sometimes supporting both (because TMTOWTDI). If it had done one or
>> the other, it would have been a better language.
> In your opinion, which sounds quite restrictive.

It's no more restrictive than not having goto or explicit pointers.

> [ new things ]
>> 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.
>
> Which is no problem at all. The new way is either better, or the old 
> way. One way will be picked up more. As I already stated: the more than 
> one way is more the combination of basic blocks.

Nope. The new things in Python are distinct new things, not just new
combinations of basic blocks. For instance, list comprehensions
replace both map and filter. Those are all three basic blocks.

If the new way isn't better, it shouldn't have been added. It just
adds bloat to the language processor and mental load on the
programmer.

>> There have already been threads where it's
>> been argued (by others - I just read them) that this is detrimental to
>> Python.
> There are always language purists, who prefer a minimal set of 
> statements, 1001 restrictions, and move everything to libraries. Often I 
> have the idea that they don't use libraries at all, but prefer to write 
> their own, pure, language.

Well, I'm certainly not that language purist. I like a minimal set of
statements that do the job, as redundancies just make my job harder. I
hate restrictions - and consider removing restrictions to be an
excellent way to extend the functionality of a language. Compared to
other languages, Python is a joy because of the lack of restrictions:
functions are first-class objects; built-in types can be inheritied
from; user defined classes can be called like functions; in fact, most
of the built-in syntax elements can be made to do something usefull on
user-defined functions. Sure, it's missing some things - like there's
no way to define new operators - but it has fewer restrictions than
most of the languages I've worked with.

          <mike
-- 
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