Re: comments on Python

Guido.van.Rossum@cwi.nl
Sat, 23 Nov 91 16:35:12 +0100

[To get some discussion going on the list, I post (with permission) a
reply I sent to a message from one of my beta testers, which discusses
various aspects of Python. Almost the entire original message is quoted
using ">" in the left margin.]

>From: amdcad!bitblks!bvs@uunet.UU.NET
>
>The package:
> mode_t is not defined for sunos-3
> waitpid is not defined for sunos-3
>
> That is, these two do not exist for sunos-3 so fake defns
> should be provided.

I'll try. Is there some predefined symbol by which I can recognize
sunos-3 from SunOS 4?

> The error message when you forget to indent (as in the
> example below) is very cryptic.
> while b<10:
> print b,
> Not sure what you can do though.

True, all too true. In fact there is only a single error message for
syntax errors. Some day I'll put in a decent parser.

> You really should number pages in tut.tex. A pain to keep
> them sorted.

When I print it the pages are numbered. Maybe you should shorten the
page height in "myformat.sty" -- I set it for European paper size,
which is about 12 inches high, while yours is likely to be 11 inches.

>I like python on the whole and don't like perl. Perl lacks in
>data structures (one can't have an array of an array or an array
>of dictionaries) and has a very irregular syntax. Lack of
>explicit declarations means you can misspell a word and not know
>it until the program mis-behaves. It has dynamic scoping and uses
>lexical hooks like & @ $ etc. to mean different things.

Actually, Python lacks explicit declarations as well -- and indeed it
is one of its weaknesses that a misspelled variable is only detected
when the actual line of code is executed (or never, if an *assignment*
is misspelled and there was a previous assignment to the same name).
Clever compile-time checking can relieve this in part, although for
instance variables (assignable attributes in Python's parlance) it
gets tough.

>BUT.... the fact remains that perl is still a lot easier to hack
>something in, due to the conciseness of its notation, some very
>powerful operators, multiple features for doing the same thing,
>pattern matching operators, and lots of examples. If you try to
>translate some existing perl scripts to python, you can see for
>yourself what I am saying. Or may be, what is needed is lots of
>useful text munging examples.

Python on purpose gives you one way to do most things (one way for
each things, not one way for all things together!), on the account
that it makes the choice easier, and makes programs more readable --
you are less likely to encounter unobvious code for obvious actions.
There is a demo directory in the distribution which tries to give the
examples, and part of the library is also intended as such -- but more
examples always help. Text munging wasn't the first purpose of the
language, although it is an important tool for many applications, just
like arithmetic.

>Anyway, here are some suggestions. I believe python can be made
>significantly friendlier by adding a few choice features but
>without sacrificing its clean and sound design. May be a lot of
>the things user might want can be added to the library.

I will resist creeping featurism wherever I can, but I have indeed
been adding features lately (e.g., shift/mask operators).

>How about providing assignment operators? Some time one has to
>build a thing piece-meal and this sort of operators are very
>handy. The semantics are clear:
>
> <var> <op>= <expr> === <var> = <var> <op> <expr>
>
>Example:
> a = 'ba '
> a *= 2 # a = 'ba ba'
> a += 'black sheep' # a = 'ba ba black sheep'

Agreed. Now that the parser can actually recognize two-character
operators, adding these wouldn't be so hard (except that the grammar
tables will grow again :-( ).

>I would also like the capability of overloading standard operators
>for predefined and user defined classes. Thus instead of
> result.append(b)
>I should be able to say
> result += b
>or better still,
> result += [a,b,c]

The latter should automatically work if we let x += y be syntactic
sugar for x = x+y. Note that result = result + [x] has a different
meaning than result.append(x), although in many cases it doesn't
matter: result.append(x) modifies the existing object that result is
bound to, while result = result+[x] creates a new list (the
concatenation of result and [x]) and binds result to it, forgetting
the object to which result was bound previously. If there was another
reference to that object, e.g., through an assignment "z = result"
earlier on, the value of z is unchanged by the second form, but
modified by the first form. Confusing? Yes, but this is a lot better
than allowing arbitrary pointers!

>How come python doesn't have structures? Do I have to use classes
>for this ala C++? Ugh!

For simple cases you can use tuples -- this keeps values together but
you reference them by position. For larger cases you indeed have to
use classes -- but what's ugly about that?

>As in perl I would like to be able to assign elements of an array
>to individual variables or vice-versa. This is very handy. For
>example, the following code picks out size and name of all the
>files in the current directory.
>
> open(LS, "ls -l|") || die "ls failed";
> for (<LS>) {
> ($perm,$links,$user,$size,$Mon,$day,$YorT,$name) = split;
> print "$size\t$name\n";
> }
>
>Granted that a list is not the same as a tuple so perhaps we
>need a special `coercion' operator or assignment. I am hoping
>for something like
>
> ls = open('ls -l', '<')
> if not ls: die('ls failed')
> while line = ls.readline():
> perm,links,size,mon,day,YorT,name =~ tuple split(line)
> print size, '\t', name, '\n'
>
> Notes:
> '<' in open implies pipe-from
> '>' in open should imply pipe-to
> operator tuple coerces a list to a tuple.
> operator =~ allows mismatched tuples on the LHS and RHS.

You can do this! If a is a list of three elements, just write
[x, y, z] = a
A working version of this program is:

import posix, string
pipe = posix.popen('ls -l', 'r')
for line in pipe.readlines():
if line[:5] = 'total': continue
[perm,links,user,group,size,mon,day,YoT,name] = string.split(line)[:9]
print size, '\t' + name

The [:9] tacked to the end of the assignment does more or less what your
proposed =~ does. Note that "ls -l" on my system outputs both the
username and the group name, and outputs a first line starting with
'total', which makes this kind of scripts so dangerously non-portable.
Another way (oh no!) to do this in Python was to use posix.opendir()
and posix.stat(); I'll let that be an exercise for the reader (actually
there are examples of this in the demo subtree).

>The support for regular expressions is built in perl. This is
>very handy. Perhaps an equivalent capability can be added via a
>library module? Though that is likely to be very slow (just like
>the operations in string.py).

There's already a built-in module 'regexp', which does what you want.
Access is slightly clumsier than Perl (there's no special syntax to
handle regular expressions) and the expressions are simpler (just
Henry Spencer's regexp package), but what you want is there...

>Got to go.

Me too.

>-- Bakul

--Guido van Rossum, CWI, Amsterdam <guido@cwi.nl>
"All right, it's a fair cop, but society is to blame."