Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

More random python observations from a perl programmer

23 views
Skip to first unread message

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Per your collective requests, here is one of the documents
with my collective observations from learning Python.

This article was posted to the Perl newsgroup, but I have duplicated
the posting here without crossposting to avoid flame wars.

--tom

SIMILARITY:
When Python talks about tuples, lists, and dictionaries,
Perl people should think of lists, arrays, and hashes
respectively. Except that tuples in python are 1st-class
citizens. (Unclear whether this is good; see below.)

COOLNESS:
Python's print() function is more like the Perl debugger's
"x" command; that is, it's recursive and pretty-printed.

GOTCHA: (medium)
The whole mutability versus immutability thing causes many
confusions. For example:
t = ([1,2],3)
t[0][0] = "fred" # legal
t[1] = "fred" # ILLEGAL
I don't understand why tuples weren't just lists that weren't
somehow marked "read-only" or "constant". That way you
could do the same with dictionaries or any other data types.

GOTCHA: (low)
You can't use "in" on dicts. Instead, you must use
d = { "fred":"wilma", "barney":"betty" }
if d.has_key("fred"): # legal
if "fred" in d: # ILLEGAL
I don't understand why this was done.

SIMILARITY:
Both "and" and "or" return their last evaluated value
in both Python and Perl.

GOTCHA: (low)
I don't understand why we have so many C operators, such as "&" and
"|" and "~", but we don't have "&&" or "||" or "!" We also have "<<"
and ">>". It's bizarre that the relational and "?:" are missing.
Python uses so much from C to make people see what they expect to see,
but this is missing. Why?

GOTCHA: (high)
Local variables are never declared. They just *happen*. If a
variable is assigned to, then it belongs to that "scope". If it's
only looked at, it may be from the current global scope.

GOTCHA: (medium)
If you have a function that expects two arguments, such as:
def fn(x,y):
return x + y
and you have a tuple of the two elements:
t = (1,2)
You can't just call that function:
print fn(t)
Or you get a "TypeError: not enough arguments; expected 2, got 1"
error. You have to use this apply() function to get around this
issue:
print apply(fn,t)
3

SIMILARITY:
The number zero, the empty string, and the special value None
are all false. Non-zero numbers and non-empty strings are
all true. This is all like Perl. But here an empty tuple ()
is false, as is an empty list [] or an empty dictionary {}.
In Perl, the last two are true if you write them that way, because
they're references.

GOTCHA: (medium)
Assignment is a statement, not an operator. That means that
people are constantly writing loops that aren't really testing
the exit condition, as in:
while 1:
line = os.readline()
if not line: break
.....
Because they can't write:
while (line = os.readline()): # ILLEGAL
I feel that this hides the real test condition in a place
it doesn't belong.

GOTCHA: (low)
There are no compound assignment operators, like +=.

DISSIMILARITY:
There is no "test at the bottom" loop as in C's do{}while.

DISSIMILARITY:
There is no "three part for" loop from C.

GOTCHA: (low)
There are no loop labels, and therefore "break" and "continue" are
only through the next level. This encourages the proliferation of
spurious boolean condition variables. It was annoying when Pascal
made you do the same thing. There is no "goto", which is how C
works around it. As with many things in Python, here you force the
user to be tangled up with exceptions just to do very simple things.
That's not as clear a solution.

SIMILARITY:
Both Python and Perl are 0-based for indexing.

DISSIMILARITY:
Python uses [] to create a new empty list, which you
then reference with [] subscripts.
Perl uses [] to create a new empty array, which you
then reference with [] subscripts.
Python uses {} to create a new empty dictionary, which you
then reference with [] subscripts.
Perl uses {} to create a new empty hash, which you
then reference with {} subscripts.

GOTCHA: (high)
I had hoped that having *only* reference semantics would spare the beginner
from having to keep in mind the difference between a reference and its
referent as we have in C or Perl. Alas, it is not to be.
x = [1,2,3]
y = x
x[1] = "fred"
print y
[1,"fred",3]

COOLNESS:
You can "foreach" across multiple items.
a = [ [1,2], [3,4], [5,6] ]
for (i,j) in a:
print i+j
3
7
11

COOLNESS:
Python's "longs" are actually built-in, arbitrary precision
integers (i.e. BigInts)

COOLNESS: (?)
Named parameters are built into the language. So are
default paramters and variadic ones, although order matters
of course. It's quite elaborate.

COOLNESS:
Namespaces seem to be *the* thing in this language. You can always
get a listing of anything's names/attributes, even all the built-ins
(which you can't do in perl) or all the names in the local scope
(which you also can't do in perl).

DISSIMILARITY:
A class method call gets no class name as its implicit extra
argument the way an instance method would.

DISSIMILARITY:
In Python, there is no difference between single and double quotes:
both interpolate C-style escapes like \t, and neither
interpolates variables. In Perl, single quotes do neither escapes
nor variables, but double quotes do both.

GOTCHA: (low)
Single and double quoted strings can't cross line boundaries.
You need triple quotes for that!

SIMILARITY:
Python does a depth-first recursive search on class ancestors
looking for resolution of a method call. So does Perl.

DISSIMILARITY:
Python also does an inheritance search for data members that
are missing. This is probably cool, however. There is no
big difference between a functional and a data member.

DISSIMILARITY:
There are no private variables in a module or a class.
They can always be fully-qualified and accessed from
without. Perl can do this with file-scoped lexicals,
but still can't do so with data members (modulo obscure
tricks such as using a non-hash for an object).

GOTCHA: (medium)
Perl's hex() function is the opposite of Python's. Perl's hex
function converts 22 into 37. Python's hex function converts 37 into
0x22. Oh my! Like hex, Python has oct() completely backwards from
Perl. Python's oct(44) returns 054, but Perl's oct(44) return 36.

SIMILARITY:
Constructors and destructors (__init__ and __del__) aren't
automagically called in parent classes in Python. Neither
in Perl.

DISSIMILARITY:
Because there are no variable markers in Python, there are no
variable interpolation in strings. That makes something like
print "this $x is $y here\n"
become in python
print "this %d is %d here\n" % (x, y)
But since "stringification" is handy, Python usurps backticks
for that purpose:
print "this is", `x`, "here"
Is going to call the x object's stringification method (x.__str__)
to get a print value. In perl:
print "this is $x here"
also does so, although the stringification method is oddly named
in Perl.
use overload '""' => ....

GOTCHA: (medium)
Things that return lists can't be used where a tuple is expected.
A function that returns a list must be coerced into a tuple to
use this, though.
def fn: return [1,2]
print "this %d is %d here\n" % fn() # ILLEGAL
print "this %d is %d here\n" % tuple(fn())
The illegal part points out that this is an
TypeError: illegal argument type for built-in operation
Which isn't very helpful.

GOTCHA: (high)
Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
ENODOC

GOTCHA: (low)
Often Python's error messages leave something to be desired.
I don't know whether

GOTCHA: (medium)
All ranges are up to but *not including* that point. So range(3)
is the list [0,1,2]. This is also true in slices, which is the
real gotcha part. A slide t[2:5] does not include t[5] in it.

SIMILARITY:
Negative subscripts count back from the right. Same as in Perl.

COOLNESS:
Slices can omit either the starting point or the ending point.
t[2:5] # elts 2 through 4 (but not 5!)
t[:5] # elts up to 4 (but not 5!)
t[:-1] # all but the last element (up to but not to -1)

DISSIMILARITY:
Python doesn't convert between strings and numbers unless you tell
it to. And if you don't tell it to, you get an exception. Therefore
you have no idea what these
x = y + z
x = y - z
x = y * z
are really doing. The first would concat strings or lists, the last would
repeat them. Personally, I don't care for this, because I always
wonder what subtracting one string or list from another would be.

COOLNESS:
Python has a reduce() built-in that works somewhat like map().

COOLNESS:
Python's filter() [same-ish as Perl's grep()] and its map() operators
can operate on items from separate sequences in parallel.

GOTCHA: (high)
This is a big surprise: strings are not atomic (although they are
immutable). They are instead sequences of characters. This comes
up in strange places. For example:
>>> for c in ("weird", "bits"):
... print c
...
weird
bits
>>> for c in ("weird"):
... print c
...
w
e
i
r
d
The second case autosplit the characters! Here's another:
>>> print map(None, "stuff")
['s', 't', 'u', 'f', 'f']
>>> print map(None, "stuff", "here")
[('s', 'h'), ('t', 'e'), ('u', 'r'), ('f', 'e'), ('f', None)]
(Python's map None is like Perl's map $_.)

DISSIMILARITY:
This also means that instead of substr() in Perl, you slice a string
as in
s = "string"
print s[2:4]
ri
Yes, that's all you got. Strange, eh? See below on ranges.


GOTCHA: (high)
Because everything is a reference, and there's no way to dereference
that reference, it turns out that there is no trivial way to copy
a list! This fails:
x = [1,2]
y = x
Because you don't get a new list there, just a copy to an
old one. Suggested work-arounds include
y = x[0:]
y = x[:]
y = x + []
y = x * 1
This forces people to think about references, again.
So much for lists being first class citizens! Compare
this with Perl's
@x = (1,2);
@y = @x;
Or even with references:
$x = [1,2];
$y = [ @$x ];
or
@y = @$x;

GOTCHA: (medium)
Slices in Python must be contiguous ranges of a sequence.
In Perl, there's no such restriction.

GOTCHA: (medium)
You can't slice dictionaries at all in Python. In Perl, it's
easy to slice a hash, and just as sensible.

GOTCHA: (high)
As we saw with lists, because everything is a reference, and there's
no way to dereference that reference, this means that again there
is also no built-in, intuitive way to copy a dictionary. Instead,
the suggested work-around is to write a loop:
new = {}
for key in old.keys:
new[key] = old[key]
But this is guaranteed slower, because it's not at the C level.
It also shows that dictionaries aren't first class citizens in python
as they are in Perl:
%old = ( "fred" => "wilma", "barney" => "betty" );
%new = %old;
or even with references:
$old = { "fred" => "wilma", "barney" => "betty" };
$new = { %$old };
or
%new = %$old;

GOTCHA: (high)
Lists don't autoallocate the way dictionaries do. So while this works
on two dictionaries:
new = {}
for key in old.keys:
new[key] = old[key]
This fails on two lists:
new = []
for i in old:
new[i] = old[i]
Because Python refuses to grow the list as it did the dictionary. Perl
will grow both arrays and hashes just fine.

GOTCHA: (medium)
There's no way to set up a permitted exports list. The caller may have
anything they ask for.

COOLNESS:
DBM files seem (?) to automatically know about nested datatypes.

GOTCHA: (medium)
Importing a variable only gives you a local copy. In Perl, it makes
two names for the same object.

GOTCHA: (low)
Because you can't declare a local variable, you can't create variables
local to something other than a module (ie. file), class, or function.
There are no loop-local variables; they would persist through the end
of the function. You can't have a scope you can't name (well, almost;
see lambdas)

GOTCHA: (high)
Scopes don't nest in Python, but they they do in Pascal, Perl, or C.
This is supposedly "simpler", but it's very suprising in many ways:
x = 1 # global
def fn1():
x = 10 # implicit local
def fn2():
print x # whose?
fn2()
fn1()
The answer is that it prints 1, because fn2 has no x in its local
scope, so gets the global. The suggested work-around is
def fn2(x=x):
using default parameters.

GOTCHA: (medium)
You can't cut and paste these examples because of the issue
of white space significance. :-(

GOTCHA: (low)
List objects have built-in methods, like
l.append(x)
But string objects don't. You have to import
from the string module to get them, and then they're
functions, not methods.

GOTCHA: (low)
You have insert and append methods for lists, but only
a del function. Why is it a function not a method, and
why isn't it spelled out? Apprently the fashionable wayto do this is
now
a[2:3] = []
Which of course, deletes only one element. ARG.

DISSIMILARITY:
Where Python says "elif", Perl says "elsif".

SIMILARITY:
Neither Perl nor Python supports a case or switch statement, requiring
multiway if's or a lookup of a function dispatch table.

DISSIMILARITY:
Where Python says "break" and "continue", Perl says "last" and "next".

DISSIMILARITY:
Where Perl says "continue", Python uses "else" (for a loop block).

DISSIMILARITY:
Constrast Python:
import os
data = os.popen('grep %s %s' % (patstr, srcfile)).read()
with Perl:
$data = `grep $patstr $srcfile`;

GOTCHA: (high)
There doesn't seem to be away other than using low-level hand-rolling
of posix functions to supply things like os.popen and os.system
a list of shell-proof arguments. Looks like it always goes through the
shell. This has security ramifications.

GOTCHA: (high)
Because you can't use readline() to get a number, people seem to enjoy
calling eval() just to get a string turned into a number:
import sys
str = sys.stdin.readline()
num = eval(x)
This is scary. Even scarier is the propensity for calling input(),
which auto-eval()s its input to make sure it's the right "type".
(Funny that a soi-disant "typeless language" should be so danged
picky about this.) That means you see people write:
num = input("Pick a number? ")
But the person can supply as an answer 0x23 or 2+9 or pow(2,4)
or os.system("rm -rf *"). I am stunned.

GOTCHA: (medium)
The expression 3/4 is 0, which is false. In Perl, 3/4 is 0.75,
which is what you'd expect. You need to force the floatness.
Sometimes Python is just too tied to C, other time not enough.
This is one of the former.

GOTCHA: (low)
Regexes default to emacs style, not egrep style! Gads! This is
surprising to anyone except an emacs weenie. Sigh. And just *try*
to read the manpage on the differences based on passed in arguments
establishing the style. There aren't any manpages! Have a nice day.

GOTCHA: (low)
An out-of-bounds list reference raises an "IndexError: list index out
of range" exception, but not if you use a slice to get at it!
t = range(5)
print t[2:17]
[2, 3, 4]

COOLNESS:
Relationals stack:
x < y < z
means
x < y and y < z

COOLNESS:
There's no distinction between the mechanism used for operator
overloading and tying, as there is in Perl. Both use special
method names.

GOTCHA: (high)
Python's lambda's aren't really lambdas, because they are only
expressions, not full functions, and because they cannot see
their enclosing scope.

DISSIMILARITY:
What Perl calls eval(), Python calls exec().
What Perl calls exec(), Python calls os.execv().

GOTCHA: (low)
Python's eval() only works on expressions, not full code blocks full
of statements. You need exec() for the whole thing.

GOTCHA: (medium)
This is a tuple of two elements
(1,2)
But this is a tuple of one element:
(1,)
Whereas this is merely the expression 1:
(1)
Yes, the trailing comma counts.

GOTCHA: (low)
Normally, a print statement in python adds a newline. If you
don't want one, you need a trailing comma!

DISSIMILARITY:
Python uses a pow() function for Perl's ** operator.
Wait, no, they just added "**" later, with the same
semantics as in Perl, except that something like 2**3**4
in Perl gives you an answer, and in python, an exception.

GOTCHA: (low)
Python has a round() function, but it seems to ignore the
IEEE rules of rounding. However, its sprintf operator doesn't:
>>> print "int of %f is %.0f" % (1.5, 1.5)
int of 1.500000 is 2
>>> print round(1.5,0)
2.0
>>> print "int of %f is %.0f" % (2.5, 2.5)
int of 2.500000 is 2
>>> print round(2.5,0)
3.0
And I'd jolly well like to know why I wasn't allowed to use
print "int of %f is %.0f" % (2.5) * 2
or if needed,
print "int of %f is %.0f" % ( (2.5) * 2 )

GOTCHA: (medium)
Anything that python doesn't like, it raises an exception about.
There is no fail-soft. Even non-exception issues raise exceptions.
It's pervasive. K&P curse languages that force people who want
to open() a file to wrap everything in exception code, saying that
"failing to open a file is hardly exceptional".

GOTCHA: (medium)
You can't just interchange tuples and lists in python the way
you can lists and arrays in Perl. This is an error:
import sys # otherwise, no argv for you, buddy
print "First arg %s and second %s" % sys.argv[1:3]
because you need
print "First arg %s and second %s" % tuple(sys.argv[1:3])

GOTCHA: (low)
I can't figure out how to write a class destructor for at exit
handling the way I can with Perl's END{}

GOTCHA: (medium)
Python has no 2nd GC pass at thread shutdown time to find lost
objects and destruct them. This is a problem on embedded systems,
and breaks correctness issues.

SIMILARITY:
Like Perl, Python requires access to members through a self reference.
This gets rid of C++'s icky hidden scope. This is good.

COOLNESS:
I believe that Python checks the prototype signature on methods
as well as on functions. I wonder whether Tim Bunce's ideas run-time
evaluation of prototypes for Perl might be able to do this.

GOTCHA: (low)
sort and reverse are in-place. This leads to verbose code, such as:
old = [1,2,3]
new = old
new.reverse()
Likewise for sort.

GOTCHA: (low)
You have to compiled the definition for a function before you may
compile the call it. This is ok
def fn():
print "hi"
fn()
But putting the fn() call first:
fn()
def fn():
print "hi"
Produces the ever helpful:
NameError: fn
error message. So much for autoloading. Then again, this would
save me from the darned legnth() bug in Perl, that is, switching
characters. Maybe a "no autoload" pragma for perl? I always though
"use strict subs" shoud ldo this. But another python mystery is
why it's ok to compile code to methods that you don't know whether
will be legal, but not functions.
ob = some_fn()
ob.scattter()
That will compile, even though I used an extra 't'. It will die
on run-time, just as in Perl. But the fn() case at the start
of this looked like a compile-time death.
ADDENDA: It turns out that def() happens *AT RUN TIME* in python.
That's the root of this problem. In Perl, a sub{} is a compile-time
thing.

GOTCHA: (low)
When you need to make an empty copy of the same type, you write
x = y[:0]
So much for being typeless. Sigh.

SIMILARITY:
In theory, the Python rexec() module should be like Perl's Safe
module. I haven't tested to see whether they chroot the namespace,
or whether the evil method name leakages occur through the box.

COOLNESS:
Any function of class can have a significant string called a "doc
string" that can be accessed as whatever.__doc__

QUESTION:
What is and what is not thread safe?

SIMILARITY:
Python uses None in many places where Perl uses undef().
But not all. You can't over-subscript an array and get
away with it.

--
I know it's weird, but it does make it easier to write poetry in perl. :-)
--Larry Wall in <78...@jpl-devvax.JPL.NASA.GOV>

Christian Tismer

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

Tom Christiansen wrote:

[snipped a long list which I commented via private emails already]

> GOTCHA: (low)
> Python has a round() function, but it seems to ignore the
> IEEE rules of rounding. However, its sprintf operator doesn't:
> >>> print "int of %f is %.0f" % (1.5, 1.5)
> int of 1.500000 is 2
> >>> print round(1.5,0)
> 2.0
> >>> print "int of %f is %.0f" % (2.5, 2.5)
> int of 2.500000 is 2
> >>> print round(2.5,0)
> 3.0

I had a look at this again. Despite the fact that the text in
the above example is a bit misleading by "int of" where
a round() takes place, which version of Python/architecture
did you use? I get the expected result, see below.

>>> print "round of %f is %.0f" % (1.5, 1.5)
round of 1.500000 is 2
>>> print round(1.5,0)
2.0
>>> print "round of %f is %.0f" % (2.5, 2.5)
round of 2.500000 is 3
>>> print round(2.5,0)
3.0
>>>

> And I'd jolly well like to know why I wasn't allowed to use
> print "int of %f is %.0f" % (2.5) * 2
> or if needed,
> print "int of %f is %.0f" % ( (2.5) * 2 )

This is just a matter of commas needed for singleton tuples,
and operator precedence, yielding

>>> print "round of %f is %.0f" % ((2.5,) * 2)
round of 2.500000 is 3
>>>

ciao - chris

--
Christian Tismer :^) <mailto:tis...@appliedbiometrics.com>
Applied Biometrics GmbH : Have a break! Take a ride on Python's
Kaiserin-Augusta-Allee 101 : *Starship* http://starship.python.net
10553 Berlin : PGP key -> http://wwwkeys.pgp.net
PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF
we're tired of banana software - shipped green, ripens at home

Jeff Blaine

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
>GOTCHA: (low)
> You can't use "in" on dicts. Instead, you must use
> d = { "fred":"wilma", "barney":"betty" }
> if d.has_key("fred"): # legal
> if "fred" in d: # ILLEGAL
> I don't understand why this was done.

I'm very curious what would you think should be legal.

Would 'in' (when used on a dict) search the keys, values, or both?

Each one of those seem like a bad idea to me. You have 2 separate
areas containing data. Searching each of those individually
(has_key()...) seems right to me.

Thanks for the document. It was very interesting reading.

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

>I had a look at this again. Despite the fact that the text in
>the above example is a bit misleading by "int of" where
>a round() takes place, which version of Python/architecture
>did you use? I get the expected result, see below.

Both SunOS and Linux round every other 5s up and down. Somebody important
(IEEE I think) says you have to do this in order to regularize round-off
error. Perl, Python, and C all behave identically on this on both those
platforms. (I tested Perl and C on BSD, too, and they're the same.)
It's only Python's round() function that doesn't follow this.

1. C code

main() {
printf("Float %g rounds to %.0f\n", 1.5, 1.5);
printf("Float %g rounds to %.0f\n", 2.5, 2.5);
printf("Float %g rounds to %.0f\n", 3.5, 3.5);
printf("Float %g rounds to %.0f\n", 4.5, 4.5);
}

OUTPUT:

Float 1.5 rounds to 2
Float 2.5 rounds to 2
Float 3.5 rounds to 4
Float 4.5 rounds to 4

2. Perl code

main() {
printf("Float %g rounds to %.0f\n", 1.5, 1.5);
printf("Float %g rounds to %.0f\n", 2.5, 2.5);
printf("Float %g rounds to %.0f\n", 3.5, 3.5);
printf("Float %g rounds to %.0f\n", 4.5, 4.5);
}
main(); # not called by default

OUTPUT:

Float 1.5 rounds to 2
Float 2.5 rounds to 2
Float 3.5 rounds to 4
Float 4.5 rounds to 4

3. Python code: (did it really have to look so different? :-)

# remember to un-indent this or it won't run
print "Float %g rounds to %.0f" % (1.5, 1.5);
print "Float %g rounds to %.0f" % (2.5, 2.5);
print "Float %g rounds to %.0f" % (3.5, 3.5);
print "Float %g rounds to %.0f" % (4.5, 4.5);

OUTPUT:

Float 1.5 rounds to 2
Float 2.5 rounds to 2
Float 3.5 rounds to 4
Float 4.5 rounds to 4

You can see this in other situations, like working with pennies.
Imagine If you have extra half-pennies, like one and half cents,
two and half, there and half, etc:

>>> print "You have $%0.2f bucks" % (2.5/100)
You have $0.03 bucks
>>> print "You have $%0.2f bucks" % (3.5/100)
You have $0.04 bucks
>>> print "You have $%0.2f bucks" % (4.5/100)
You have $0.04 bucks

Strange but true. It's supposed to even out the error.
Ask a numbers guy. I'm just the messenger. :-)

As for the tuple thing, why can I say

print "You have $%0.2f bucks" % (4.5/100)

How is that a singleton tuple? Don't I have to use
a trailing comma? It won't let me! Why is

print "You have $%0.2f bucks" % (4.5/100,)

illegal, but

print "You have $%0.2f bucks" % ((4.5/100,) * 2)

mandatory? Was this (elt,) thing just an, er, unforeseen design
misfeature? Yes, I tripped me up again. :-(

--tom
--
I have a different view of the world. --Andrew Hume. Show&Tell '87

Thomas Wouters

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen
On Thu, Aug 19, 1999 at 08:22:49AM -0700, Tom Christiansen wrote:

> This article was posted to the Perl newsgroup, but I have duplicated
> the posting here without crossposting to avoid flame wars.

Sorry, i have to reply. I wont mention much, and i definately dont want to
start a flame war (i use perl about as often as python, but python fits my
soul, perl does not.)

> GOTCHA: (low)
> You can't use "in" on dicts. Instead, you must use
> d = { "fred":"wilma", "barney":"betty" }
> if d.has_key("fred"): # legal
> if "fred" in d: # ILLEGAL
> I don't understand why this was done.

It's an extension of Python's setup. Not everything is done to be immediately
obvious, but everything is done to be _consistent_, and instantly obvious if
you understand python. The 'in' statement works sort of like the pseudocode:

index = 0
try:
while 1:
if sequence[index] == findthis:
return index - 1
index = index + 1
except IndexError:
return 0

(same for the 'for' statement.)

You could of course write a dictionary wrapper that takes numeric arguments
to the __getitem__ to be index in a sorted list of keys, and other arguments
as normal key retrieval... but you'd lose the ability to index on numbers.

> GOTCHA: (low)
> I don't understand why we have so many C operators, such as "&" and
> "|" and "~", but we don't have "&&" or "||" or "!" We also have "<<"
> and ">>". It's bizarre that the relational and "?:" are missing.
> Python uses so much from C to make people see what they expect to see,
> but this is missing. Why?

&& and || are and and or.

> GOTCHA: (low)
> There are no loop labels, and therefore "break" and "continue" are
> only through the next level. This encourages the proliferation of
> spurious boolean condition variables. It was annoying when Pascal
> made you do the same thing. There is no "goto", which is how C
> works around it. As with many things in Python, here you force the
> user to be tangled up with exceptions just to do very simple things.
> That's not as clear a solution.

Only if you aren't used to exceptions. Exceptions are really very simple and
nice things. Especially back when they were just strings (before my time, but
still ;-)

> DISSIMILARITY:
> Python uses [] to create a new empty list, which you
> then reference with [] subscripts.
> Perl uses [] to create a new empty array, which you
> then reference with [] subscripts.
> Python uses {} to create a new empty dictionary, which you
> then reference with [] subscripts.
> Perl uses {} to create a new empty hash, which you
> then reference with {} subscripts.

You forget tuples, which you create with (), and subscript with [].
Subscripting is _always_ done with [], and it _always_ calls the
'__getitem__' member function (if any). There being no functional difference
is what makes it so nice :)

> DISSIMILARITY:
> A class method call gets no class name as its implicit extra
> argument the way an instance method would.

that's because it doesn't know what class it's going to be called with. You
can assign it to another class on the fly :)

> DISSIMILARITY:
> In Python, there is no difference between single and double quotes:
> both interpolate C-style escapes like \t, and neither
> interpolates variables. In Perl, single quotes do neither escapes
> nor variables, but double quotes do both.

There are 'raw' strings though, 'r"<string>"', that dont do backslashes.

> DISSIMILARITY:
> There are no private variables in a module or a class.
> They can always be fully-qualified and accessed from
> without. Perl can do this with file-scoped lexicals,
> but still can't do so with data members (modulo obscure
> tricks such as using a non-hash for an object).

There is some namemangling though, for datamembers/functions that start with
a single _, for hiding/overriding purposes. (those mmebers get the classname
encoded in, so it's dependant on the class it was called on.)

> GOTCHA: (high)
> Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
> ENODOC

Damn, i hadn't even noticed that. Can you imagine ? I guess the '__doc__'
attributes on objects are enough manpage for me. ;)

> DISSIMILARITY:
> Python doesn't convert between strings and numbers unless you tell
> it to. And if you don't tell it to, you get an exception. Therefore
> you have no idea what these
> x = y + z
> x = y - z
> x = y * z
> are really doing. The first would concat strings or lists, the last would
> repeat them. Personally, I don't care for this, because I always
> wonder what subtracting one string or list from another would be.

It's worse. _noone_ has any idea what you're doing until you're acutally
doing it. x, y and z can be any type of object, even a type of object that's
loaded in on demand or constructed on the fly.

> GOTCHA: (high)
> This is a big surprise: strings are not atomic (although they are
> immutable). They are instead sequences of characters. This comes
> up in strange places. For example:
> >>> for c in ("weird", "bits"):
> ... print c
> ...
> weird
> bits
> >>> for c in ("weird"):
> ... print c
> ...
> w
> e
> i
> r
> d
> The second case autosplit the characters! Here's another:
> >>> print map(None, "stuff")
> ['s', 't', 'u', 'f', 'f']
> >>> print map(None, "stuff", "here")
> [('s', 'h'), ('t', 'e'), ('u', 'r'), ('f', 'e'), ('f', None)]
> (Python's map None is like Perl's map $_.)

Wait, wait, you're doing two different things here. First off, you called
'for' with different types of arguments, the first time with a tuple of
strings, the second type with just a string. As a string is a sequence
object, it can be indexed, and the for loop wil 'iter' over the characters
in it. Perhaps you meant to do:

>>> for c in ("weird",):


... print c
...
weird

Or maybe

>>> for c in ("weird" + "bits"):
... print c
...

w
e
i
r
d

b
i
t
s

But they are definately not the same :)

As for the map(), almost the same. In the first instance you provide one
sequence, so map will pass 'None' a single argument, in the second 'None'
gets passed two items, and None returns it right back. If you want the
sequences turned into lists and concatenated, use + instead of ,

> GOTCHA: (high)
> Because everything is a reference, and there's no way to dereference
> that reference, it turns out that there is no trivial way to copy
> a list! This fails:
> x = [1,2]
> y = x
> Because you don't get a new list there, just a copy to an
> old one. Suggested work-arounds include
> y = x[0:]
> y = x[:]
> y = x + []
> y = x * 1
> This forces people to think about references, again.
> So much for lists being first class citizens! Compare
> this with Perl's
> @x = (1,2);
> @y = @x;
> Or even with references:
> $x = [1,2];
> $y = [ @$x ];
> or
> @y = @$x;

>>> import copy
>>> print copy.__doc__
Generic (shallow and deep) copying operations
=============================================
<etc>

> GOTCHA: (low)
> You have insert and append methods for lists, but only
> a del function. Why is it a function not a method, and
> why isn't it spelled out? Apprently the fashionable wayto do this is
> now
> a[2:3] = []
> Which of course, deletes only one element. ARG.

You can del a[3], or del a[3:5]

> GOTCHA: (high)
> Because you can't use readline() to get a number, people seem to enjoy
> calling eval() just to get a string turned into a number:
> import sys
> str = sys.stdin.readline()
> num = eval(x)
> This is scary. Even scarier is the propensity for calling input(),
> which auto-eval()s its input to make sure it's the right "type".
> (Funny that a soi-disant "typeless language" should be so danged
> picky about this.) That means you see people write:
> num = input("Pick a number? ")
> But the person can supply as an answer 0x23 or 2+9 or pow(2,4)
> or os.system("rm -rf *"). I am stunned.

Try eval(number, {}, {}). No sys or os module to call, no other variables
what so ever. Personally, i think being able to say, say, '4**5/3%2' in any
instance where the program asks you for a number is a coolness.

> GOTCHA: (low)
> Regexes default to emacs style, not egrep style! Gads! This is
> surprising to anyone except an emacs weenie. Sigh. And just *try*
> to read the manpage on the differences based on passed in arguments
> establishing the style. There aren't any manpages! Have a nice day.

Use re, perl regexps.

> And I'd jolly well like to know why I wasn't allowed to use
> print "int of %f is %.0f" % (2.5) * 2
> or if needed,
> print "int of %f is %.0f" % ( (2.5) * 2 )

Try print "int of %f is %.0f" % ((2.5,) * 2 )
"Yes, the trailing comma counts" :)

> QUESTION:
> What is and what is not thread safe?

Everything is thread safe. Or rather, there will at all times be only one
thread executing the Python interpreter.

Oh, damn, i erased the pow() thing. Well, anyway,

>>> 2**2**2
16
>>> 4**4**4
Traceback (innermost last):
File "<stdin>", line 1, in ?
OverflowError: integer pow()
>>> 4**4**4L
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096L

Is that what you meant ? You missed that gotcha... no automatic conversion
between int and longint. <wink>

The worst thing about python is what it does to your programming skills. gcc
is getting tired of warning me of syntax errors due to python syntax in my C
:-)

Pyton'ly y'rs,

--
Thomas Wouters <tho...@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
jbl...@shell2.shore.net (Jeff Blaine) writes:
:>GOTCHA: (low)


:> You can't use "in" on dicts. Instead, you must use
:> d = { "fred":"wilma", "barney":"betty" }
:> if d.has_key("fred"): # legal
:> if "fred" in d: # ILLEGAL
:> I don't understand why this was done.

:
:I'm very curious what would you think should be legal.


:
:Would 'in' (when used on a dict) search the keys, values, or both?
:
:Each one of those seem like a bad idea to me. You have 2 separate
:areas containing data. Searching each of those individually
:(has_key()...) seems right to me.

Well, it's the polymorphism thing. If "+" is supposed to work on anything
(which I don't agree with, but that's not my decision), I don't understand
why "in" shouldn't. I keep thinking that everything should work on
everything. For example, this surprises me:

x = {1:2, 3:4}
y = {10:20, 30:40}
z = x + y

The latter isn't legal. But in Perl, you can merge hashes easily.

%x = (1,2,3,4);
%y = (10,20,30,40);
%z = (%x, %y);

print $z{1}
2
print $z{30}
40

If you want to do it all with references, and use pretty => arrows,
it would look like this:

$x = {1 =>2, 3 =>4};
$y = {10 =>20, 30 =>40);
$z = { %$x, %$y };

print $z->{1}
2
print $z->{30}
40

Of course, that's not super efficient. And that overright duplicates,
rather than making lists of them. Still, that's not a bad behaviour.

I can't get used to not being able to do hash slices, as in

@revhash{values %hash} = keys %hash;

Or

print sort(@hash{@desired})


But I surely see your point about not knowing whether it's a key or
a value. The only sane thing would be the key, but that's what has_key
does. I say "sane" because otherwise you'd need to search all the values,
and as Larry Wall says, "Doing linear scans over an associative array is
like trying to club someone to death with a loaded Uzi." (Perl Cookbook,
Chapter 5, intro). :-)

I've always resisted adding "in" to Perl because I really want people
to get out of the habit of doing linear scans, because hashing it up
into a lookup mapping is almost always the right thing in the long
run, just not for one-offs.

:Thanks for the document. It was very interesting reading.

You're welcome. I got so fed up with the damned flames coming
from people who don't actually even know what they're talking about,
that I decided to make sure I wasn't one of them. :-)

--tom
--
Can you sum up plan 9 in layman's terms? It does everything
Unix does only less reliably --Ken Thompson

Andrew Csillag

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tom Christiansen wrote:
>
> As for the tuple thing, why can I say
>
> print "You have $%0.2f bucks" % (4.5/100)
>
> How is that a singleton tuple?
It's not. For format strings, if the item (here 4.5/100) is a single
thing, the items need not be a tuple. i.e.

"You have $%0.2f bucks" % 234.234

but if you want more than one item to be formatted, you have to use a
tuple

"you're name is %s and you have $%0.2f" % ("Tom", 234.234)

> Don't I have to use
> a trailing comma? It won't let me! Why is
>
> print "You have $%0.2f bucks" % (4.5/100,)
>
> illegal,

No, it's perfectly fine. Didn't try it, I guess.

>>> print "You have $%0.2f bucks" % (4.5/100,)

You have $0.04 bucks
>>>


but
>
> print "You have $%0.2f bucks" % ((4.5/100,) * 2)

This, on the other hand is wrong since ((4.5/100,) * 2) yields (0.045,
0.045) and you only have one formatting bit in the string (only 1
%0.2f). If you had
print "The New York Lotto jackpot is now $%0.2f bucks... $%0.2f" %
((4.5/100,) * 2)
That totally works.

>
> mandatory? Was this (elt,) thing just an, er, unforeseen design
> misfeature? Yes, I tripped me up again. :-(

Try reading the docs...
--
"Programmers are just machines that convert coffee to executable code"
-Unknown

"Drew Csillag" <drew_c...@geocities.com>

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
Thomas Wouters <tho...@xs4all.nl> writes:
:It's an extension of Python's setup. Not everything is done to be immediately


:obvious, but everything is done to be _consistent_, and instantly obvious if
:you understand python.

This is the goal. It is not always reached. There are plenty of
oddities sticking out.

:&& and || are and and or.

I know that. I asked why.

:Only if you aren't used to exceptions. Exceptions are really very simple and


:nice things. Especially back when they were just strings (before my time, but
:still ;-)

No, I'm sorry, the expressivity of "break LABEL" and "continue LABEL"
are much clearer than the cicumlocutions necessary for exceptions.
That's like saying you can get the same effect by adding a bunch of lines
of code. That's not the same as built-in support, nor half so clear,
nor half so convenient. Isn't python about rapid prototyping and all?
If it were about purity over convenience, I'm sure it would have been
a lot different -- and completely unused.

:There are 'raw' strings though, 'r"<string>"', that dont do backslashes.

Those aren't the book, and there are no manpages. Therefore,
in many ways, they don't really count. I know it hurts to hear
this, and you're all going to jump on me, but please please think
about it for a bit before you do so.

:> GOTCHA: (high)


:> Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
:> ENODOC
:
:Damn, i hadn't even noticed that. Can you imagine ? I guess the '__doc__'
:attributes on objects are enough manpage for me. ;)

It's unconscionable. Lack of tools and the tool-based
approach strikes again. See other postings.

:> >>> for c in ("weird", "bits"):
:> >>> for c in ("weird"):

:Wait, wait, you're doing two different things here. First off, you called


:'for' with different types of arguments, the first time with a tuple of
:strings, the second type with just a string.

Oh, come now, you're telling me I'm expected to count the items
in the parens to know whether a split will happen. Whatever.
It's not obvious, so it's a real gotcha. This is not consistent.

:But they are definately not the same :)

But they look the same, which is wicked.

:>>> import copy
:>>> print copy.__doc__

That's not a fricking manpage. How can I run "apropos copy"
on it? How do I do

grep copy /usr/python/man/*/*.*

or

find /usr/python/man -print | xargs grep copy /dev/null

or

troff -man /usr/python/man/man3/copy.3py

etc etc. Tools, man. Man tools. Flexible interchangeable
parts.

:"Yes, the trailing comma counts" :)

Speaking of inconsistencies!

:
:> QUESTION:


:> What is and what is not thread safe?
:
:Everything is thread safe. Or rather, there will at all times be only one
:thread executing the Python interpreter.

Huh, no threads in python?

--tom
--
"The past is the only dead thing that smells sweet."
- Edward Thomas

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
>> How is that a singleton tuple?
>It's not. For format strings, if the item (here 4.5/100) is a single
>thing, the items need not be a tuple. i.e.

That's painfully inconsistent.

>> print "You have $%0.2f bucks" % (4.5/100,)
>> illegal,
>No, it's perfectly fine. Didn't try it, I guess.

No, I thought I had.

>> print "You have $%0.2f bucks" % ((4.5/100,) * 2)
>This, on the other hand is wrong since ((4.5/100,) * 2) yields (0.045,
>0.045) and you only have one formatting bit in the string (only 1
>%0.2f).

Typo.

>> mandatory? Was this (elt,) thing just an, er, unforeseen design
>> misfeature? Yes, I tripped me up again. :-(
>Try reading the docs...

Thanks for nothing: there are no manpages. I read the Lutz book.
You'll note that I even MENTIONED this issue in a gotcha.
It's just easy to get tripped up by the inconsistency.

You seem to be looking for a fight. Please say nothing
at all if that's all you want to do.

--tom

Michael Hudson

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
I'm going to be quite picky in some of what follows.

Tom Christiansen <tch...@mox.perl.com> writes:

> COOLNESS:
> Python's print() function is more like the Perl debugger's
> "x" command; that is, it's recursive and pretty-printed.

Python doesn't have a print() function. It has a `print' statement.


> GOTCHA: (high)
> Local variables are never declared.

*Nothing* is ever delcared in Python.

> GOTCHA: (medium)
> If you have a function that expects two arguments, such as:
> def fn(x,y):
> return x + y
> and you have a tuple of the two elements:
> t = (1,2)
> You can't just call that function:
> print fn(t)
> Or you get a "TypeError: not enough arguments; expected 2, got 1"
> error. You have to use this apply() function to get around this
> issue:
> print apply(fn,t)
> 3

Well, no. How would you like to pass a tuple to a function?



> GOTCHA: (medium)
> Perl's hex() function is the opposite of Python's. Perl's hex
> function converts 22 into 37. Python's hex function converts 37 into
> 0x22. Oh my! Like hex, Python has oct() completely backwards from
> Perl. Python's oct(44) returns 054, but Perl's oct(44) return 36.

This would have to do with strings not being automatically coerced
into numbers, methinks.



> SIMILARITY:
> Constructors and destructors (__init__ and __del__) aren't
> automagically called in parent classes in Python. Neither
> in Perl.

This sucks, IMHO.

> GOTCHA: (medium)
> Things that return lists can't be used where a tuple is expected.
> A function that returns a list must be coerced into a tuple to
> use this, though.
> def fn: return [1,2]
> print "this %d is %d here\n" % fn() # ILLEGAL
> print "this %d is %d here\n" % tuple(fn())
> The illegal part points out that this is an
> TypeError: illegal argument type for built-in operation
> Which isn't very helpful.

I think this may have changed in the CVS sources. <quick check>, Oh
no, it hasn't. It should.



> GOTCHA: (high)
> Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
> ENODOC

There's info format if you look for it and you have to have a CLI.

> GOTCHA: (low)
> Often Python's error messages leave something to be desired.
> I don't know whether

Is this a joke? This is improving.

> GOTCHA: (medium)
> All ranges are up to but *not including* that point. So range(3)
> is the list [0,1,2]. This is also true in slices, which is the
> real gotcha part. A slide t[2:5] does not include t[5] in it.

This does mean that range(a,b) or t[a:b] has b-a elements in it.

> DISSIMILARITY:
> This also means that instead of substr() in Perl, you slice a string
> as in
> s = "string"
> print s[2:4]
> ri
> Yes, that's all you got. Strange, eh? See below on ranges.

What were you expecting?

> GOTCHA: (medium)
> Slices in Python must be contiguous ranges of a sequence.
> In Perl, there's no such restriction.

At some point Python will probably support `extended slice syntax'
like so:

range(0,10)[1:4:2] => [1,3]

Numerical Python already does this.



> GOTCHA: (medium)
> You can't slice dictionaries at all in Python. In Perl, it's
> easy to slice a hash, and just as sensible.

Huh? What would that mean? There's no reason to suspect that the keys
of a dictionary are ordered.

> GOTCHA: (high)
> As we saw with lists, because everything is a reference, and there's
> no way to dereference that reference, this means that again there
> is also no built-in, intuitive way to copy a dictionary. Instead,
> the suggested work-around is to write a loop:
> new = {}
> for key in old.keys:
> new[key] = old[key]
> But this is guaranteed slower, because it's not at the C level.

new = old.copy()



> GOTCHA: (medium)
> There's no way to set up a permitted exports list. The caller may have
> anything they ask for.

This is a general Python convention; you *can* shoot yourself in the
foot if you try hard enough. Means the debugger can be written in
Python, for one thing.



> COOLNESS:
> DBM files seem (?) to automatically know about nested datatypes.

Ah, that's pickle. pickle is cool.

> GOTCHA: (high)
> Scopes don't nest in Python, but they they do in Pascal, Perl, or C.
> This is supposedly "simpler", but it's very suprising in many ways:
> x = 1 # global
> def fn1():
> x = 10 # implicit local
> def fn2():
> print x # whose?
> fn2()
> fn1()
> The answer is that it prints 1, because fn2 has no x in its local
> scope, so gets the global. The suggested work-around is
> def fn2(x=x):
> using default parameters.

Yes this is a bit annoying. The Right Way to attach state to a
function is a class, of course. Not that that helps much.



> GOTCHA: (low)
> List objects have built-in methods, like
> l.append(x)
> But string objects don't. You have to import
> from the string module to get them, and then they're
> functions, not methods.

This will change in 1.6.



> GOTCHA: (low)
> You have insert and append methods for lists, but only
> a del function.

del statement.

> GOTCHA: (high)
> Because you can't use readline() to get a number, people seem to enjoy
> calling eval() just to get a string turned into a number:
> import sys
> str = sys.stdin.readline()
> num = eval(x)
> This is scary.

Do people really do that? I don't. It can be made safe:

num = eval(string,{'__builtins__':{}})

but that's a bit hairy. Use float instead.

> Even scarier is the propensity for calling input(),
> which auto-eval()s its input to make sure it's the right "type".
> (Funny that a soi-disant "typeless language" should be so danged
> picky about this.)

Python is more "dynamically typed" than "typeless", I'd say.

> GOTCHA: (low)
> Regexes default to emacs style, not egrep style!

Not any more. import re.

> GOTCHA: (low)
> Python's eval() only works on expressions, not full code blocks full
> of statements. You need exec() for the whole thing.

Writing exec() suggests it's a function; it isn't, it's a statement.

> GOTCHA: (medium)
> Anything that python doesn't like, it raises an exception about.
> There is no fail-soft. Even non-exception issues raise exceptions.
> It's pervasive. K&P curse languages that force people who want
> to open() a file to wrap everything in exception code, saying that
> "failing to open a file is hardly exceptional".

This is a bit of a flaw, IMHO. Mind you, it forces you to pay
attention.

> GOTCHA: (medium)
> You can't just interchange tuples and lists in python the way
> you can lists and arrays in Perl. This is an error:
> import sys # otherwise, no argv for you, buddy
> print "First arg %s and second %s" % sys.argv[1:3]
> because you need
> print "First arg %s and second %s" % tuple(sys.argv[1:3])

This has been changing over the last year or so. I expect the trend
will continue.

> COOLNESS:
> I believe that Python checks the prototype signature on methods
> as well as on functions. I wonder whether Tim Bunce's ideas run-time
> evaluation of prototypes for Perl might be able to do this.

You mean perl doesn't? Ouch.

> QUESTION:
> What is and what is not thread safe?

Everything is, but in a crude way. There's a global interpreter
lock. This isn't the best of situations.

I hope this post has raised the signal-to-noise ratio in the
perl/Python debate (it could hardly lower it).

Michael

Jeremy Hylton

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen
[Tom Christiansen <tch...@mox.perl.com> writes:]

>Well, it's the polymorphism thing. If "+" is supposed to work on anything
>(which I don't agree with, but that's not my decision), I don't understand
>why "in" shouldn't. I keep thinking that everything should work on

I kind of agree with you. I often use in with a dictionary without
thinking about it and then go back to fix it. (I'm quite happy that +
works on many types BTW.)

It is interesting to note that early version of JPython implemented in
for dictionaries, based on exactly the reasoning you describe. It
ended up leading to some puzzling behavior when used in a for loop.
I'm hazy on the detail, but I think the exact behavior was: JPython
would treat a dictionary as a sequence within a loop context provided
that there was a 0 key (plus zero or more successive integers). I
passed a dictionary without a 0 key; JPython caught an exception and
treated the dictionary as an empty sequence. I hadn't intended to use
a dictionary in the for loop, rather a function had mistakenly
returned a dictionary rather than the dictionary's keys.

I'm not sure what the moral of the story is, except that JPython
doesn't implement in for dictionaries anymore and I'm mostly happy
about that.

>everything. For example, this surprises me:
>
> x = {1:2, 3:4}
> y = {10:20, 30:40}
> z = x + y
>
>The latter isn't legal. But in Perl, you can merge hashes easily.
>
> %x = (1,2,3,4);
> %y = (10,20,30,40);
> %z = (%x, %y);
>
> print $z{1}
> 2
> print $z{30}
> 40
>

You can do almost exactly this in Python using the update method on
dictionaries.

x = {1:2, 3:4}
y = {10:20, 30:40}

z = {}
z.update(x)
z.update(y)
print z
{30: 40, 3: 4, 10: 20, 1: 2}

As you noted with the [].sort operation, you need to explicitly create
the new object that call some methods on it. In my book it is at
worst a minor annoyance.

>:Thanks for the document. It was very interesting reading.
>
>You're welcome. I got so fed up with the damned flames coming
>from people who don't actually even know what they're talking about,
>that I decided to make sure I wasn't one of them. :-)
>

Indeed, I enjoyed reading both your posts this morning. While I don't
agree with all of your criticisms, I think you make many good points.
I did notice that some of your criticisms were out-of-date, perhaps
reflecting Python previous to 1.5.2. (And some of your criticisms are
already being addressed, such as the string methods that are in the
current CVS tree but not yet release.
x = 'asdbasdas'
x.split('s')
['a', 'dba', 'da', '']
# instead of:
# import string
# string.split(x, 's')
)

Jeremy

Andrew Csillag

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tom Christiansen wrote:
>
> >> How is that a singleton tuple?
> >It's not. For format strings, if the item (here 4.5/100) is a single
> >thing, the items need not be a tuple. i.e.
>
> That's painfully inconsistent.

No, just extremely convienent. Why have to have a single item tuple for
a single item? It's not that inconsistant, there are two options for
it: either a single item, or a tuple of items (which may be one item).
The only time I get tripped up by this is when I do things like:
foo = "some format string %s" % b
and b turns out to be a tuple, but for me, at least, it happens
infrequently and is easily fixed by using a 1 item tuple instead:
foo = "some format string %s" % (b,)
or since I'm using %s anyway,
foo = "some format string %s" % str(b)

>
> >> print "You have $%0.2f bucks" % (4.5/100,)
> >> illegal,
> >No, it's perfectly fine. Didn't try it, I guess.

Not an attack, just a clarification.

>
> No, I thought I had.
>
> >> print "You have $%0.2f bucks" % ((4.5/100,) * 2)
> >This, on the other hand is wrong since ((4.5/100,) * 2) yields (0.045,
> >0.045) and you only have one formatting bit in the string (only 1
> >%0.2f).
>
> Typo.
>
> >> mandatory? Was this (elt,) thing just an, er, unforeseen design
> >> misfeature? Yes, I tripped me up again. :-(
> >Try reading the docs...
>
> Thanks for nothing: there are no manpages.

Manpages don't work very well if you're stuck on a Windows box :(. If
only the world were Unix... <sigh>

There are the python manuals which are excellent, available at:
http://www.python.org/doc/ (linked to from the homepage)
available in your choice of HTML, PostSript, PDF, Info, LaTeX and
windows help.

Not to mention that they're searchable via:
http://www.python.org/search/

But for the most part, I usually don't need the search portal since the
indexes are really good. But if you want a greppable form, there's Info
(although I don't like info in general, but info (both standalone and
emacs versions) does have the document search key 's'), HTML, and the
LaTeX versions grep quite well.

> I read the Lutz book.

I personally think that the Lutz book (the big thick one) isn't all that
great (sorry Mark). Not an offence to you, I bought it also. The
online tutorial:
http://www.python.org/doc/current/tut/tut.html
last I looked is quite good. The Learning Python book seems to be quite
a bit better. The pocket reference is also quite handy.

> You'll note that I even MENTIONED this issue in a gotcha.
> It's just easy to get tripped up by the inconsistency.
>
> You seem to be looking for a fight. Please say nothing
> at all if that's all you want to do.

No, actually, just trying to help you out, so chill out alright? I've
got better things to do then get in a flame war with you over nothing.

Jees, try to be nice and have to go and buy asbestos clothing!

Ivan Van Laningham

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Hi All--

Tom Christiansen wrote:
>

[bobbit]

> :Thanks for the document. It was very interesting reading.
>
> You're welcome. I got so fed up with the damned flames coming
> from people who don't actually even know what they're talking about,
> that I decided to make sure I wasn't one of them. :-)
>

> --tom
>

If that's what you believe, why are posting stuff like this (from a
different, but nearly simultaneous, posting)?

> You seem to be looking for a fight. Please say nothing
> at all if that's all you want to do.

In response to someone else's quite reasonable suggestion to read the
documentation.

You also say in the same message

> Thanks for nothing: there are no manpages. I read the Lutz book.

It's true that there are no manpages. Linux comes with manpages, but
every single manpage says (paraphrased): ``Don't trust this page; we
don't. See the info help system for the real scoop.'' When you do,
it's harder to use and usually doesn't have any more to say than the
manpage. I'm not sure that the choice of two mostly wrong options is a
choice with any value.

Python doesn't have manpages, true. It does have perfectly adequate
documentation available at

http://www.python.org/doc

You can download that documentation and install it on your own computer
if you wish to avoid the net. Like all documentation, it leaves
something to be desired (decent search facilities, for one, but manpages
don't have those either); but, like Kernighan & Ritchie's _The C
Programming Language_, it's all there.

Your complaint that Python doesn't have manpages is like complaining
that Buddhism doesn't have a Bible. Perfectly true, and perfectly
false.

<a-difference-that-doesn't-make-a-difference-isn't-information>-ly y'rs,
Ivan
----------------------------------------------
Ivan Van Laningham
Callware Technologies, Inc.
iva...@callware.com
iva...@home.com
http://www.pauahtun.org
See also:
http://www.foretec.com/python/workshops/1998-11/proceedings.html
Army Signal Corps: Cu Chi, Class of '70
----------------------------------------------

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Jeremy Hylton
>Indeed, I enjoyed reading both your posts this morning. While I don't
>agree with all of your criticisms, I think you make many good points.
>I did notice that some of your criticisms were out-of-date, perhaps
>reflecting Python previous to 1.5.2.

I only have the Lutz book. I don't have manpages. :-(

--tom

William Tanksley

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
On Thu, 19 Aug 1999 16:34:12 GMT, Tom Christiansen wrote:

[talking about a Python feature]
>That's painfully inconsistent.

Your messages are interesting and enlightening and so on... But coming
from a Perl guru this statement is... interesting.

>--tom

--
-William "Billy" Tanksley

aaron_...@my-deja.com

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to tch...@mox.perl.com
Greetings tchrist. Hope to shake hands at the ORA conference
soon.

In article <37bc...@cs.colorado.edu>,


tch...@mox.perl.com (Tom Christiansen) wrote:
> I keep thinking that everything should work on

> everything. For example, this surprises me:
>
> x = {1:2, 3:4}
> y = {10:20, 30:40}
> z = x + y
>
> The latter isn't legal. But in Perl, you can merge hashes easily.
>
> %x = (1,2,3,4);
> %y = (10,20,30,40);
> %z = (%x, %y);

To get exactly what you want you need my kjbuckets extension
( http://www.chordate.com/kjbuckets/index.html ),
but Python has D.update, viz:

>>> x = {1:2, 3:4}
>>> y = {10:20, 30:40}

>>> sum = {}
>>> sum.update(x); sum.update(y)
>>> sum


{30: 40, 3: 4, 10: 20, 1: 2}

But for my purposes this is not too useful since I normally
need to know after a dict union whether the union was ambiguous
(that is, caused key collisions)
or not -- hence the notion of a "dirty" or "clean" kjbuckets
structure. I suspect the Perl version doesn't flag
ambiguities either, no?

Also, you might find some of the fancier kjbuckets
features (intersect, diff, composition, transitive closure,
reachability, etc) of use as well.
-- Aaron Watters http://www.chordate.com

===

All generalizations are wrong.

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Robb Shecter

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Jeremy Hylton wrote:

>
> You can do almost exactly this in Python using the update method on
> dictionaries.
>

> x = {1:2, 3:4}
> y = {10:20, 30:40}

> z = {}
> z.update(x)
> z.update(y)
> print z


> {30: 40, 3: 4, 10: 20, 1: 2}
>

> As you noted with the [].sort operation, you need to explicitly create
> the new object that call some methods on it. In my book it is at
> worst a minor annoyance.

In my book it's the right way to do things. My book, by the way, is
"Object Oriented Software Construction", by Bertrand Meyer. He makes
the great point for developing classes that work in a consistent
style:

1) You instantiate an object
2) You set some options
3) You tell it to do its thing

This pays off big in clarity of code. Related to this are his other
commandments, such as banning functions with side effects.

Perl's version:

%z = (%x, %y);

is ambiguous. It looks more like it creates a nested structure than a
flat one.

- Robb

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
>> You're welcome. I got so fed up with the damned flames coming
>> from people who don't actually even know what they're talking about,
>> that I decided to make sure I wasn't one of them. :-)
>>

>If that's what you believe, why are posting stuff like this (from a


>different, but nearly simultaneous, posting)?

Stuff like what?

>> You seem to be looking for a fight. Please say nothing
>> at all if that's all you want to do.

>In response to someone else's quite reasonable suggestion to read the
>documentation.


>You also say in the same message

>> Thanks for nothing: there are no manpages. I read the Lutz book.
>
>It's true that there are no manpages. Linux comes with manpages, but
>every single manpage says (paraphrased): ``Don't trust this page; we
>don't. See the info help system for the real scoop.''

And they're full of crap, too. Don't get me started. Use BSD.

>Python doesn't have manpages, true. It does have perfectly adequate
>documentation available at
> http://www.python.org/doc

>You can download that documentation and install it on your own computer
>if you wish to avoid the net. Like all documentation, it leaves
>something to be desired (decent search facilities, for one, but manpages
>don't have those either);

Yes, you can. Well, I can. I can show you how if you want.

I guess you'd better drop the manpage issue, because I don't
intend to stop considering its absence a nasty, glaring hole.

--tom

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
Michael Hudson <mw...@cam.ac.uk> writes:
:> GOTCHA: (high)


:> Local variables are never declared.
:
:*Nothing* is ever delcared in Python.

This is hardly a happiness. :-(

I've been finding out how much more that Perl's compiler does with symbols
than Python's does. For example, in Perl, a sub fn(){} is compiled when
the compiler sees it, and goes in the symbol table then. In Python,
it appears that def fn(): is a run-time event, and executable statement.
Hence the need to get all your defs in first. Perl's declarations are
sub, format, package, and my.

Another difference is that because the Perl compiler does the symbol table
lookup at compile time for both globals and locals, including
functions. Indirect run-time lookups that happen at run-time are
slower.

:Well, no. How would you like to pass a tuple to a function?

I'd like using

fn(t)

and then the function deciding whether it got enoguh arguments.

:
:> GOTCHA: (medium)


:> Perl's hex() function is the opposite of Python's. Perl's hex
:> function converts 22 into 37. Python's hex function converts 37 into
:> 0x22. Oh my! Like hex, Python has oct() completely backwards from
:> Perl. Python's oct(44) returns 054, but Perl's oct(44) return 36.
:
:This would have to do with strings not being automatically coerced
:into numbers, methinks.

No, that's not it. Perl's hex takes a hex number and returns
a decimal one; same with oct. Python's is the reverse. Very weird.

echo 'print oct(12)' | python
14

echo 'print oct(12)' | perl -l
10

See what I mean?

:There's info format if you look for it and you have to have a CLI.

At the very least, python needs a top-level python(1) manpage that gives
calling conventions, options, envariables etc, and an explanation of how
to locate the rest of the documentation (even if it's in non-man form).
That's a POSIX.2 requirement.

And info sucks. Please don't emacs me. I hurt enough already.

:
:> GOTCHA: (low)


:> Often Python's error messages leave something to be desired.
:> I don't know whether
:
:Is this a joke? This is improving.

No, it isn't a joke. The error messages are often mysterious.
Contrast:

% perl -e 'fn()'
Undefined subroutine &main::fn called at -e line 1.

% echo 'fn()' | python


Traceback (innermost last):
File "<stdin>", line 1, in ?

NameError: fn

:> print s[2:4]


:> ri
:> Yes, that's all you got. Strange, eh? See below on ranges.
:
:What were you expecting?

Charcters 2 through 4, of course. Hey, does python do Unicode
yet?

:> GOTCHA: (medium)


:> You can't slice dictionaries at all in Python. In Perl, it's
:> easy to slice a hash, and just as sensible.
:
:Huh? What would that mean? There's no reason to suspect that the keys
:of a dictionary are ordered.

Order is irrelevant. You seem to be equating slicing with ranges.

@a = ("this", "and", "that", "are", "all", "ready")
print "@a[-1, 2, 4, 2, 0, -2]\n"

Which prints:

ready that ready that this are

Likewise, with a hash. For example:

print "@ENV{HOME,TERM,USER}\n";

Which prints:

/home/tchrist xterm tchrist

So slicing is just selecting multiple values at once. I can assign
to a hash that way, too:

@wife_of{"fred", "barney"} = ("wilma", "betty");

:new = old.copy()

I wonder how many times I'll have to explain that I read the
Lutz book, wasn't on the Internet at the time, and found no manpages
installed with python on my laptop.

:> There's no way to set up a permitted exports list. The caller may have


:> anything they ask for.
:
:This is a general Python convention; you *can* shoot yourself in the
:foot if you try hard enough. Means the debugger can be written in
:Python, for one thing.

We did that in Perl, too, nevertheless.

:Yes this is a bit annoying. The Right Way to attach state to a


:function is a class, of course. Not that that helps much.

That sounds like religion. And aren't bound methods inherent
memory leaks?

fn = obj.method;

:> GOTCHA: (low)


:> Python's eval() only works on expressions, not full code blocks full
:> of statements. You need exec() for the whole thing.
:
:Writing exec() suggests it's a function; it isn't, it's a statement.

Funny that you guys are all flustered about this statement/function thing.
I think of if and def as statements. I'm not saying print and exec
aren't, but they sure look just like it.
:
:> COOLNESS:


:> I believe that Python checks the prototype signature on methods
:> as well as on functions. I wonder whether Tim Bunce's ideas run-time
:> evaluation of prototypes for Perl might be able to do this.
:
:You mean perl doesn't? Ouch.

Method calls go through the symbol table at run-time. Function calls
are resolve at compile time, and need no symbol table stuff. That means
you get prototype errors at compile time, before you start, if you get
them at all. But because we don't know what type is going to be in
the object, the compiler can't know, and the interpreter doesn't care.
Well, it cares and will hurl an exception if it can't find the method
by that name, but it does no proto checks. This may change.

Technically, there are the new optional lexical declarations to help
the compiler and the backend C code-generator, but those still leave a
lot to be desired.

--tom
--
To stay young requires unceasing cultivation of the ability to unlearn
old falsehoods. -- Lazarus Long

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
drew_c...@geocities.com writes:
:> Thanks for nothing: there are no manpages.
:Manpages don't work very well if you're stuck on a Windows box :(. If


:only the world were Unix... <sigh>

So what? man is a trivial program to write, if all you have
to do is display preformatted text info.

:There are the python manuals which are excellent, available at:


:http://www.python.org/doc/ (linked to from the homepage)
:available in your choice of HTML, PostSript, PDF, Info, LaTeX and
:windows help.

None of those is text. I can't use not only man(1), apropos(1),
or whatis(1), I also can't use text-processing tools like grep(1) or
directory processing ones like find(1).

:Not to mention that they're searchable via:
:http://www.python.org/search/

I wasn't on the Internet when I learnt python. Please don't shoot me.

:But for the most part, I usually don't need the search portal since the


:indexes are really good. But if you want a greppable form, there's Info
:(although I don't like info in general, but info (both standalone and
:emacs versions) does have the document search key 's'), HTML, and the
:LaTeX versions grep quite well.

You think HTML greps sell? I don't think so. Now, you can argue
that troff doesn't grep well either, and you'd be right. But
I grep the catpages or podpages.

:No, actually, just trying to help you out, so chill out alright?

Fine. I just hate being told to read the fucking manual when there
ISN'T one. I despite Linux and GNU and the FSF and all that crap
because of this.

--tom
--
"VAX. For those who care enough to steal the very best."
-- A microscopic message on the silicon chip inside
one of Digital Equipment's often stolen computer designs.

Ben Gertzfield

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
>>>>> "Tom" == Tom Christiansen <tch...@mox.perl.com> writes:

Tom> At the very least, python needs a top-level python(1) manpage
Tom> that gives calling conventions, options, envariables etc, and
Tom> an explanation of how to locate the rest of the documentation
Tom> (even if it's in non-man form). That's a POSIX.2
Tom> requirement.

I don't know about your system, but on Debian Linux 2.1, I have a
python(1) manpage, along with an entire set of HTML docs in
/usr/doc/python . The manpage includes an explanation on how to get
the Tutorial and Library Reference. Here's the first page:

PYTHON(10 April, 1998) PYTHON(10 April, 1998)


NAME
python - an interpreted, interactive, object-oriented pro-
gramming language

SYNOPSIS
python [ -d ] [ -i ] [ -O ] [ -S ] [ -t ] [ -u ] [ -v ] [
-x ] [ -X ]
[ -c command | script | - ] [ arguments ]

DESCRIPTION
Python is an interpreted, interactive, object-oriented
programming language that combines remarkable power with
very clear syntax. For an introduction to programming in
Python you are referred to the Python Tutorial. The
Python Library Reference documents built-in and standard
types, constants, functions and modules. Finally, the
Python Reference Manual describes the syntax and semantics
of the core language in (perhaps too) much detail.

Ben

--
Brought to you by the letters P and M and the number 6.
"What's green and sits in the corner? ... A naughty frog!"
Debian GNU/Linux maintainer of Gimp and GTK+ -- http://www.debian.org/

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
drew_c...@geocities.com writes:
:There are the python manuals which are excellent, available at:
:http://www.python.org/doc/ (linked to from the homepage)
:available in your choice of HTML, PostSript, PDF, Info, LaTeX and
:windows help.

The fact that they did icky windows help and not man pages says
something significant.

--tom
--
"Have the appropriate amount of fun." --Larry Wall

Skip Montanaro

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen

: There are 'raw' strings though, 'r"<string>"', that dont do
: backslashes.

Tom> Those aren't the book, and there are no manpages. Therefore, in
Tom> many ways, they don't really count. I know it hurts to hear this,
Tom> and you're all going to jump on me, but please please think about
Tom> it for a bit before you do so.

Tom,

You assume the only two proper places to put documentation are in man pages
or in Mark Lutz's book. Mark's a fine person and wrote a great book, but it
was written when Python 1.4 was the current version. Raw strings are new
with 1.5. Was the Camel book always in sync with Perl? If it was, then
more power to ya. Perhaps you can share your synchronization secrets with
Mark and Guido. The Camel book I have documents Perl 4 (so I guess Perl 5
doesn't count).

As for man pages, they aren't the only valid way to document reference
material. Most Windows and Mac people wouldn't even know what you were
talking about. From what I can tell by traffic on c.l.p, the bulk of the
Python user base uses Windows these days anyway, so man pages are probably
not a good first choice of documentation format, being largely unavailable
to the unwashed masses. HTML seems to be pretty ubiquitous these days,
however.

As others have pointed out, the library and language reference manuals (and
the tutorial and a fairly good collection of demo scripts) are available as
part of Python's distribution. If you have a web browser, a dvi viewer or
PostScript previewer and the appropriate tools to build them, you can browse
them. If you haven't got the build tools (unlike Perl Python requires a few
non-Python tools - like TeX and latex2html - to build the docs), you can
view them online or download pre-built copies from the Python website.

Is everything in Python's documentation space as complete as the equivalent
Perl docs? No, and for the forseeable future that will probably be the
case. I suppose that might make Python less attractive in some people's
eyes. I view it simply that Python isn't as far along the path to
completion as Perl.

Skip Montanaro | http://www.mojam.com/
sk...@mojam.com | http://www.musi-cal.com/~skip/
847-971-7098

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Skip Montanaro
>As for man pages, they aren't the only valid way to document reference
>material. Most Windows and Mac people wouldn't even know what you were
>talking about. From what I can tell by traffic on c.l.p, the bulk of the
>Python user base uses Windows these days anyway, so man pages are probably
>not a good first choice of documentation format, being largely unavailable
>to the unwashed masses. HTML seems to be pretty ubiquitous these days,
>however.

Sigh. And you wonder why folks say that alienating Unix programmers
has never been something Python has tried to avoid? :-(

--tom

Duncan Booth

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
tch...@mox.perl.com (Tom Christiansen) wrote in
<37bc...@cs.colorado.edu>:

>GOTCHA: (medium)
> The whole mutability versus immutability thing causes many
> confusions.
Yup, powerful but confusing at first.


>GOTCHA: (medium)
> If you have a function that expects two arguments, such as:
> def fn(x,y):
> return x + y
> and you have a tuple of the two elements:
> t = (1,2)
> You can't just call that function:
> print fn(t)
> Or you get a "TypeError: not enough arguments; expected 2, got 1"
> error. You have to use this apply() function to get around this
> issue:
> print apply(fn,t)
> 3

Or if you know you are going to have a tuple, you could declare the
function to take a tuple as its argument:
def fn((x,y)): ...

>GOTCHA: (low)
> There are no compound assignment operators, like +=.

We would have to reach agreement first on what += actually meant, and that
doesn't seem to be happening for all the number of times it has been
discussed.


>GOTCHA: (low)
> Single and double quoted strings can't cross line boundaries.
> You need triple quotes for that!

I would put this one under COOLNESS.

>DISSIMILARITY:
> Because there are no variable markers in Python, there are no
> variable interpolation in strings. That makes something like
> print "this $x is $y here\n"
> become in python
> print "this %d is %d here\n" % (x, y)

You didn't mention the alternative way of writing this which is possibly
nearer the Perl version:
print "this %(x)s is %(y)s here\n" % {'x': x, 'y': y}

>GOTCHA: (high)
> Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
> ENODOC

Python has loads and loads of documentation.

>GOTCHA: (medium)
> All ranges are up to but *not including* that point. So range(3)
> is the list [0,1,2]. This is also true in slices, which is the
> real gotcha part. A slide t[2:5] does not include t[5] in it.

I think this is necessary to allow all of the variations on slicing. For
example to insert between elements of a list.
x = [1, 2, 3]
x[1:1] = [5]
print x
[1, 5, 2, 3]

>GOTCHA: (high)
> This is a big surprise: strings are not atomic (although they are
> immutable).

> >>> for c in ("weird", "bits"):

> >>> for c in ("weird"):
For consistency with the first example you need
>>> for c in ("weird",)

However I agree it can be confusing that when you subscript a string you
get another object of type string.

>GOTCHA: (high)
> As we saw with lists, because everything is a reference, and there's
> no way to dereference that reference, this means that again there
> is also no built-in, intuitive way to copy a dictionary. Instead,
> the suggested work-around is to write a loop:
> new = {}
> for key in old.keys:
> new[key] = old[key]

My suggested way to copy a dictionary is:
new = old.copy()
Or, if you want to copy all the elements as well:
from copy import deepcopy
new = deepcopy(old)

> But this is guaranteed slower, because it's not at the C level.

The copy method and functions are at the C level.

> It also shows that dictionaries aren't first class citizens in python
> as they are in Perl:

I think there is a fundamental misunderstanding here. Variables in python
are always references. They never copy the value they point to when
assigned. You could equally say that this means that integers are not first
class citizens because:
x = 1
y = x
leaves x and y pointing at the same object (x is y) is true.



>
>GOTCHA: (high)
> Lists don't autoallocate the way dictionaries do. So while this works
> on two dictionaries:
> new = {}
> for key in old.keys:
> new[key] = old[key]
> This fails on two lists:
> new = []
> for i in old:
> new[i] = old[i]

This is meaningless and nothing to do with autoallocating. i is iterating
over values not indexes. you get the effect you want here by writing
for i in old:
new.append(i)

>GOTCHA: (medium)
> Importing a variable only gives you a local copy. In Perl, it makes
> two names for the same object.

No, importing just gives you two names for the same object just as
assignment only ever gives you two names for the same object. Of course if
you later reassign one of the names to point to a different object the two
variables no longer have the same value.

>GOTCHA: (high)
> Because you can't use readline() to get a number, people seem to enjoy
> calling eval() just to get a string turned into a number:
> import sys
> str = sys.stdin.readline()
> num = eval(x)
> This is scary. Even scarier is the propensity for calling input(),
> which auto-eval()s its input to make sure it's the right "type".
> (Funny that a soi-disant "typeless language" should be so danged
> picky about this.) That means you see people write:
> num = input("Pick a number? ")
> But the person can supply as an answer 0x23 or 2+9 or pow(2,4)
> or os.system("rm -rf *"). I am stunned.

People may enjoy this but personally I would just do
num = int(sys.stdin.readline())
BTW, I am not commenting on the comparisons with Perl since I don't claim
to know that language, but I seem to remember hearing that Perl would
silently convert the string "42x" into the number 42 without throwing an
error, now there is scary.

>GOTCHA: (low)
> Regexes default to emacs style, not egrep style! Gads! This is
> surprising to anyone except an emacs weenie. Sigh. And just *try*
> to read the manpage on the differences based on passed in arguments
> establishing the style. There aren't any manpages! Have a nice day.

Try reading the manual page doc/lib/re-syntax.html in your python
distribution.


>GOTCHA: (low)
> Normally, a print statement in python adds a newline. If you
> don't want one, you need a trailing comma!

Or use the write method of the file which doesn't do any of the print
prettifying.

>GOTCHA: (medium)
> Anything that python doesn't like, it raises an exception about.
> There is no fail-soft. Even non-exception issues raise exceptions.
> It's pervasive. K&P curse languages that force people who want
> to open() a file to wrap everything in exception code, saying that
> "failing to open a file is hardly exceptional".

I love this. But thats just me.

>
>GOTCHA: (medium)
> You can't just interchange tuples and lists in python the way
> you can lists and arrays in Perl.

Or the way you can interchange strings and numbers in Perl.
They are different types. (Why we need two list types is another question
though).

>GOTCHA: (low)
> You have to compiled the definition for a function before you may
> compile the call it.

Not true, you have to compile the definition for a function before you may
execute the call to it. You may compile the call before the function if you
wish.

> ADDENDA: It turns out that def() happens *AT RUN TIME* in python.
> That's the root of this problem. In Perl, a sub{} is a compile-time
> thing.

Dont forget that in Python you can stick your def in a for loop to define a
whole host of functions with different default arguments.

Thanks for the article though, it made good reading.
(BTW if anyone flames me for getting bits of this wrong don't expect a
reply soon because I'm away for two weeks).


Jeremy Hylton

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen
>>>>> "TC" == Tom Christiansen <tch...@mox.perl.com> writes:

TC> :There are 'raw' strings though, 'r"<string>"', that dont do
TC> backslashes.

TC> Those aren't the book, and there are no manpages. Therefore, in
TC> many ways, they don't really count. I know it hurts to hear
TC> this, and you're all going to jump on me, but please please
TC> think about it for a bit before you do so.

[I know I said I wasn't going to get into this, but...] I think this
statement is just plain silly. I use lots of tools, languages,
libraries, etc. that have non-existent or bad manpages. The raw
string exist regardless of whether there is a manpage that describes
them. Which is not to say that I'm opposed to manpages; it would
probably be helpful to provide them.

I did think about this before I jumped, but it still seems fair to
jump. As a possible counterexample to the "if it don't have manpages
it don't exist" argument, I would suggest the C programming language.
I don't believe there are manpages that describe the language itself,
yet I found it (relatively) easy to learn. The K&R C book is mighty
fine.

It's also worth noting that the old Lutz book is a little like the
pre-ANSI K&R C book. You're not going to find ANSI changes in the old
K&R, and you're not going to find Python 1.5 info in the old Lutz
book. In neither case does that mean the improvements don't exist.

Jeremy


Barry A. Warsaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to pytho...@python.org

>>>>> "TW" == Thomas Wouters <tho...@xs4all.nl> writes:

TW> There is some namemangling though, for datamembers/functions
TW> that start with a single _, for hiding/overriding
TW> purposes. (those mmebers get the classname encoded in, so it's
TW> dependant on the class it was called on.)

The name manging rule in Python is actually "starts with double
underscore with no trailing underscores". E.g. __mangled()

I like to call these `private' attributes, but they really aren't in
the C++/Java sense of privateness. Because their names get mangled in
a predicatable way, it's quite easy to get at them directly:

>>> class Shy:
... def __handsoff(self): print "please don't touch"
...
>>> me = Shy()
>>> me.__handsoff()


Traceback (innermost last):
File "<stdin>", line 1, in ?

AttributeError: __handsoff
>>> me._Shy__handsoff()
please don't touch

If you want true privateness, you'll probably want to look at the
Bastion module, ExtensionClass, or some such.

Name mangling still serves an important purpose though. It allows a
class to be designed for inheritance, with only the public and
`protected' interfaces needing documentation. If I inherit from class
Shy above, my DerivedShy doesn't need to know that it's base class has
a private method called __handsoff() because my similarly named method
can't collide with it.

>>> class DerivedShy(Shy):
... def __handsoff(self): print "touch all you want"
..
>>> you = DerivedShy()
>>> you.__handsoff()


Traceback (innermost last):
File "<stdin>", line 1, in ?

AttributeError: __handsoff
>>> you._DerivedShy__handsoff()
touch all you want
>>> you._Shy__handsoff()
please don't touch

My personal coding convention has long been to use "starts with a
single underscore with no trailing underscores" to mean a `protected'
attribute; i.e. one that is intended to be used or overridden by
derived classes. But there is no language support for this.

-Barry

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
dun...@rcp.co.uk (Duncan Booth) writes:
:However I agree it can be confusing that when you subscript a string you

:get another object of type string.

*Tell me* about it!

>>> s = "fred"
>>> print s[0]
f
>>> print s[0][0]
f
>>> print s[0][0][0]
f
>>> print s[0][0][0][0]
f
>>> print s[0][0][0][0][0]
f
>>> print s[0][0][0][0][0][0]
f

--tom
--
"... my dear old friend. I wish to God there were more automata in the world
like you." - Charles Darwin to T H Huxley, letter, 1882.

Jeremy Hylton

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen
>>>>> "TC" == Tom Christiansen <tch...@mox.perl.com> writes:

TC> [courtesy cc of this posting mailed to cited author] In
TC> comp.lang.python, drew_c...@geocities.com writes: :There are
TC> the python manuals which are excellent, available at:
TC> :http://www.python.org/doc/ (linked to from the homepage)
TC> :available in your choice of HTML, PostSript, PDF, Info, LaTeX
TC> and :windows help.

TC> The fact that they did icky windows help and not man pages says
TC> something significant.

Yup. It says that Windows help is useful for more people than icky
manpages.

(And who are these mysterious "they" people who did this?)

Jeremy

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Jeremy Hylton
>Yup. It says that Windows help is useful for more people than icky
>manpages.

No, it means that it's considered ok to alienate people who expect manpages.

--tom

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
dun...@rcp.co.uk (Duncan Booth) writes:
:>GOTCHA: (high)


:> Lists don't autoallocate the way dictionaries do. So while this works
:> on two dictionaries:
:> new = {}
:> for key in old.keys:
:> new[key] = old[key]
:> This fails on two lists:
:> new = []
:> for i in old:
:> new[i] = old[i]
:This is meaningless and nothing to do with autoallocating. i is iterating
:over values not indexes. you get the effect you want here by writing
: for i in old:
: new.append(i)

You're right. I should have written

new = []
for i in range(0,len(old)):


new[i] = old[i]

And that certainly is parallel to the dictionary case. Dictionary
auto-allocate. Lists don't. It's a gotcha to a Perl programmer,
because he's using to having both hashes and arrays autoallocate.
Not, of course, that we need to copy things that way, since arrays and
hashes are firstclassy. :-) But you know what I mean.

--tom
--
"... an initial underscore already conveys strong feelings of
magicalness to a C programmer."
--Larry Wall in <1992Nov9.1...@netlabs.com>

Andrew Csillag

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tom Christiansen wrote:
>
> [courtesy cc of this posting mailed to cited author]
>
> In comp.lang.python,
> drew_c...@geocities.com writes:
> :There are the python manuals which are excellent, available at:

> :http://www.python.org/doc/ (linked to from the homepage)
> :available in your choice of HTML, PostSript, PDF, Info, LaTeX and
> :windows help.

>
> The fact that they did icky windows help and not man pages says
> something significant.

Yes, that python has a decent sized population of windows users. I'm no
windows guy but PythonWin is way cool from what I've seen (IDE, cool COM
support, etc.).

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
dun...@rcp.co.uk (Duncan Booth) writes:
:People may enjoy this but personally I would just do


: num = int(sys.stdin.readline())
:BTW, I am not commenting on the comparisons with Perl since I don't claim
:to know that language, but I seem to remember hearing that Perl would
:silently convert the string "42x" into the number 42 without throwing an
:error, now there is scary.

Sorry, I was doing to do just one or two, but your reply
merits more.

% perl -le 'print int("42x")'
42
(Exit 0)

Add warnings:

% perl -wle 'print int("42x")'
Argument "42x" isn't numeric in int at -e line 1.
42
(Exit 0)

Promote numeric-class warnigns to exceptions:

% perl -wle "use warning FATAL => 'numeric'; print int('42x')"
Argument "42x" isn't numeric in int at -e line 1.
(Exit 255)

In short, Perl doesn't normally hurl. But you can ask it to,
at least in newer, undocumented releases. :-)

% perl -v
This is perl, version 5.005_60 built for OpenBSD.i386-openbsd
Copyright 1987-1998, Larry Wall

:Try reading the manual page doc/lib/re-syntax.html in your python
:distribution.

% man doc/lib/re-syntax.html
man: no entry for doc/lib/re-syntax.html in the manual.
(Exit 1)

Just kidding. :-)

:Or use the write method of the file which doesn't do any of the print
:prettifying.

Good point.

:> You can't just interchange tuples and lists in python the way


:> you can lists and arrays in Perl.
:Or the way you can interchange strings and numbers in Perl.
:They are different types. (Why we need two list types is another question
:though).

They're only two types if you think of them that way. But they're not if
you don't. :-) It's like saying chars and short ints and ints and long
ints and long long ints and floats and doubles (which are long floats)
and long doubles (which are long long floats) are different types.
Or you can just call them numbers.

Now, complex, *those* are different. :-)

:>GOTCHA: (low)


:> You have to compiled the definition for a function before you may
:> compile the call it.
:Not true, you have to compile the definition for a function before you may
:execute the call to it. You may compile the call before the function if you
:wish.

Python deems def an executable statement. Perl doesn't. Therefore,
it's a gotcha for a Perl programmer, who doesn't understand why the
silly compiler did that. Apparently, it's just at run-time interring
a function that was compiled at compile-time in the current symbol table.
I've done that in Perl, expecially for local functions, but people
glare at me when I do. :-)

:> ADDENDA: It turns out that def() happens *AT RUN TIME* in python.


:> That's the root of this problem. In Perl, a sub{} is a compile-time
:> thing.
:Dont forget that in Python you can stick your def in a for loop to define a
:whole host of functions with different default arguments.

Ah, like this, using lexical closures (you're expected to "ooh" and
"aah" now :-) and direct symbol table diddling:

my @colors = ('red', 'blue', 'green', 'yellow', 'orange', 'purple');
for my $name (@colors) {
*$name = sub { "<FONT COLOR='$name'>@_</FONT>" };
}

That's what gets me talked about. :-)

BTW, the @colors assignment is more legibly written using the qw//
syntactic sugar:

@colors = qw(red blue green yellow orange purple);

--tom
--
Perl itself is usually pretty good about telling you what you shouldn't do. :-)
--Larry Wall in <11...@jpl-devvax.JPL.NASA.GOV>

tim...@email.msn.com

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[dun...@rcp.co.uk (Duncan Booth)]
> :However I agree it can be confusing that when you

> subscript a string you get another object of type string.

[tch...@mox.perl.com (Tom Christiansen) wrote:]


> *Tell me* about it!
>
> >>> s = "fred"
> >>> print s[0]
> f
> >>> print s[0][0]
> f
> >>> print s[0][0][0]
> f
> >>> print s[0][0][0][0]
> f
> >>> print s[0][0][0][0][0]
> f
> >>> print s[0][0][0][0][0][0]
> f

Hmm. I don't see how this differs from the Perl:

$x = "fred";
print substr($x, 0, 1), "\n";
print substr(substr($x, 0, 1), 0, 1), "\n";
print substr(substr(substr($x, 0, 1), 0, 1), 0, 1), "\n";
etc

except-that-python-isn't-so-verbose<wink>-ly y'rs - tim

Jeremy Hylton

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen
Heck, in the postmodern world of programming languages it probably
means neither and both.

Jeremy

Aahz Maruch

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[please don't cc me if you follow up]

In article <37bc...@cs.colorado.edu>,
Tom Christiansen <tch...@mox.perl.com> wrote:
>In comp.lang.python,
> Thomas Wouters <tho...@xs4all.nl> writes:
>:
>:Only if you aren't used to exceptions. Exceptions are really very simple and
>:nice things. Especially back when they were just strings (before my time, but
>:still ;-)
>
>No, I'm sorry, the expressivity of "break LABEL" and "continue LABEL"
>are much clearer than the cicumlocutions necessary for exceptions.
>That's like saying you can get the same effect by adding a bunch of lines
>of code. That's not the same as built-in support, nor half so clear,
>nor half so convenient. Isn't python about rapid prototyping and all?
>If it were about purity over convenience, I'm sure it would have been
>a lot different -- and completely unused.

OTOH, you can raise an exception and an arbitrary bit of code higher up
in the chain can catch it. Which has good points and bad points; I
certainly won't claim that it discourages obscure code.

As a former perler, I would not say that Python is "about" rapid
prototyping; for me, even a "quick hack" in Python takes more planning
than the equivalent bit in Perl. However, I do believe that Python
overall is *much* better suited for software engineering; I simply can't
imagine doing a multi-person project in Perl.

You neglected to mention IDLE and the command-line interpreter as a
Coolness, BTW.

>:> GOTCHA: (high)


>:> Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
>:> ENODOC

>:
>:Damn, i hadn't even noticed that. Can you imagine ? I guess the '__doc__'
>:attributes on objects are enough manpage for me. ;)
>
>It's unconscionable. Lack of tools and the tool-based
>approach strikes again. See other postings.

That's one approach. HTML, OTOH, leads to a navigation-based approach.
With Lynx as my primary browser, I feel that I get the best of both
worlds.

>:> QUESTION:
>:> What is and what is not thread safe?
>:
>:Everything is thread safe. Or rather, there will at all times be only one
>:thread executing the Python interpreter.

This is incorrect. See the docs for whrandom.

>Huh, no threads in python?

Yes, there are threads, but there is a global interpreter lock.
Anything that executes C code releases the lock (in general), so you get
significant parallelism if you're I/O heavy (for example), but not so
much if you're computationally intensive (in Python-only code).
--
--- Aahz (@netcom.com)

Androgynous poly kinky vanilla queer het <*> http://www.rahul.net/aahz/
Hugs and backrubs -- I break Rule 6 (if you want to know, do some research)

Skip Montanaro

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen

Tom> BTW, the @colors assignment is more legibly written using the qw//
Tom> syntactic sugar:

Tom> @colors = qw(red blue green yellow orange purple);

In Python an occasional idiom you see is to use string.split to save typing
so many quotes:

colors = string.split("red blue green yellow orange purple")

Barry A. Warsaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to pytho...@python.org

>>>>> "TC" == Tom Christiansen <tch...@mox.perl.com> writes:

TC> No, I'm sorry, the expressivity of "break LABEL" and "continue
TC> LABEL" are much clearer than the cicumlocutions necessary for
TC> exceptions.

Plus, they'd probably be faster. This is a good point: being able to
label breaks and continues a la Java would be useful. I sometimes
miss them in Python but the workarounds are easy enough.

-Barry

Barry A. Warsaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to pytho...@python.org

>>>>> "TC" == Tom Christiansen <tch...@jhereg.perl.com> writes:

TC> Thanks for nothing: there are no manpages.

You're right. Is that a fatal lossage? For some people, definitely
not for everybody, or even most Python programmers it seems (although
I do not follow the doc-sig, I haven't seen a tidal wave hue and cry
for manpages).

Is Python adequately documented? Absolutely, because the latex source
is easily printed or viewed by a web browser (and you don't even need
to be on-line). The current suite of documentation formats seems to
give poor overworked Fred the most bang for the buck. Info format
used to be supported, but I don't think that was used by enough people
to justify the work involved in keeping it going. Manpage format just
doesn't seem to be that popular either. I know that sucks for you
Tom, but I'm sure Fred would gladly take a contribution that generated
manpage format from the latex source. You might even be surprised at
the languages he'd accept such a contribution in! :)

It's really a simple matter of resources and the 80/20 rule.

-Barry

Guido van Rossum

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tom Christiansen <tch...@jhereg.perl.com> writes:

> I only have the Lutz book. I don't have manpages. :-(

Tom, I've skimmed this thread and I think you have expressed your
desire for Python documentation formatted as man pages a more than
sufficient number of times.

The argument that there is no online documentation has been amply
refuted -- your only remaining complaint must be that they aren't
there in your preferred format. Tough.

Please let the issue go. As we say, you are welcome to fix it
yourself. We'd even accept a Perl script that turns our latex (soon
to be SGML or XML) into man page format.

Since you're an O'Reilly author, I'm surprised you didn't base your
(otherwise excellent) Perl/Python guide on the much more recent (April
99) Learning Python by Mark Lutz and David Ascher. It would have
saved you a whole bunch of pitfalls.

--Guido van Rossum (home page: http://www.python.org/~guido/)

Barry A. Warsaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to pytho...@python.org

MH> At some point Python will probably support `extended slice
MH> syntax' like so:

MH> range(0,10)[1:4:2] => [1,3]

MH> Numerical Python already does this.

As does JPython:

JPython 1.0.3 on java1.2
Copyright 1997-1998 Corporation for National Research Initiatives
>>> range(0,10)[1:4:2]
[1, 3]

Not surprising given the author of NumPy and JPython :)

-Barry

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
Guido van Rossum <gu...@cnri.reston.va.us> writes:
:Please let the issue go. As we say, you are welcome to fix it


:yourself. We'd even accept a Perl script that turns our latex (soon
:to be SGML or XML) into man page format.

I tend to answer every criticism instead of letting it settle
in and saying one answer once. This is sub-optimal.

Your wishes shall be granted--if I can; I'll certainly try.

:Since you're an O'Reilly author, I'm surprised you didn't base your


:(otherwise excellent) Perl/Python guide on the much more recent (April
:99) Learning Python by Mark Lutz and David Ascher. It would have
:saved you a whole bunch of pitfalls.

I couldn't find it when I was looking on the way to the desert. I could
only find the first one, so that's the one I took with me! I'm not sure
whether I have the other one still, or whether one of my random visitors
absconded with it.

--tom
--
"All mainstream science was once heresy."
- Gould

Barry A. Warsaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to pytho...@python.org

>>>>> "TC" == Tom Christiansen <tch...@jhereg.perl.com> writes:

TC> I only have the Lutz book. I don't have manpages. :-(

That's okay, I only have the first edition Programming Perl book :)

-Barry

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python, bwa...@cnri.reston.va.us (Barry A. Warsaw) writes:


:>>>>> "TC" == Tom Christiansen <tch...@jhereg.perl.com> writes:
: TC> I only have the Lutz book. I don't have manpages. :-(
:
:That's okay, I only have the first edition Programming Perl book :)

No biggie: It's nearly all there as manpages. :-)

The Perl Cookbook, on the other hand, is not, although you can ftp all
its code examples and programs, just not its prose. However, I do have
a policy of giving away Perl books to visitors who show up in Boulder.
I'm sure I could fix that then. :-) (I don't bring a stash to the Open
Source Conference, or I would then.)

--tom
--
Those who do not fight the demons within themselves are destined to fight them
outside themselves...

Barry A. Warsaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to pytho...@python.org

>>>>> "TC" == Tom Christiansen <tch...@mox.perl.com> writes:

TC> The fact that they did icky windows help and not man pages
TC> says something significant.

It says that Windows users were more motivated to provide platform
specific documentation than any Unix user so far.

-Barry

Fred L. Drake, Jr.

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

Barry A. Warsaw writes:
> give poor overworked Fred the most bang for the buck. Info format
> used to be supported, but I don't think that was used by enough people

Bucks? I'm supposed to be getting bucks for this?
Check the FTP site, Barry; GNU info is there thanks to the active
Python community.

> to justify the work involved in keeping it going. Manpage format just
> doesn't seem to be that popular either. I know that sucks for you

Manpages have never been requested, unless you consider Tom's
complaint a request. I've received nothing at
pytho...@python.org. Certainly not a contributed conversion
script.

> Tom, but I'm sure Fred would gladly take a contribution that generated
> manpage format from the latex source. You might even be surprised at
> the languages he'd accept such a contribution in! :)

Hey, you're making me look bad! ;-)


-Fred

--
Fred L. Drake, Jr. <fdr...@acm.org>

John Landahl

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen, pytho...@python.org
On Thu, Aug 19, 1999 at 11:48:02AM -0700, Tom Christiansen wrote:
> In comp.lang.python,
> drew_c...@geocities.com writes:
> :There are the python manuals which are excellent, available at:
> :http://www.python.org/doc/ (linked to from the homepage)
> :available in your choice of HTML, PostSript, PDF, Info, LaTeX and
> :windows help.
>
> The fact that they did icky windows help and not man pages says
> something significant.

What's all this about no Python manpages?

$ man python
Reformatting page. Wait... done

Misc. Reference Manual Pages PYTHON(10 April, 1998)

NAME
python - an interpreted, interactive, object-oriented pro-
gramming language

Did this change relatively recently? I'm running v1.5.2.

- John Landahl / j...@digex.net

Bernhard Herzog

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Thomas Wouters <tho...@xs4all.nl> writes:

> On Thu, Aug 19, 1999 at 08:22:49AM -0700, Tom Christiansen wrote:

> > DISSIMILARITY:
> > There are no private variables in a module or a class.
> > They can always be fully-qualified and accessed from
> > without. Perl can do this with file-scoped lexicals,
> > but still can't do so with data members (modulo obscure
> > tricks such as using a non-hash for an object).
>
> There is some namemangling though, for datamembers/functions that start with
> a single _, for hiding/overriding purposes. (those mmebers get the classname
> encoded in, so it's dependant on the class it was called on.)

For class members it's a leading double underscore.

The single leading underscore only affects module globals in that they
are *not* imported by 'from module import *'


> > GOTCHA: (low)
> > You have insert and append methods for lists, but only
> > a del function. Why is it a function not a method, and

del is a statement, not a function.

> > GOTCHA: (high)
> > Because you can't use readline() to get a number, people seem to enjoy
> > calling eval() just to get a string turned into a number:
> > import sys
> > str = sys.stdin.readline()
> > num = eval(x)
> > This is scary. Even scarier is the propensity for calling input(),
> > which auto-eval()s its input to make sure it's the right "type".
> > (Funny that a soi-disant "typeless language" should be so danged
> > picky about this.) That means you see people write:
> > num = input("Pick a number? ")
> > But the person can supply as an answer 0x23 or 2+9 or pow(2,4)
> > or os.system("rm -rf *"). I am stunned.
>

> Try eval(number, {}, {}). No sys or os module to call, no other variables
> what so ever.

Passing empty dicts is not enough. You still have access to all builtin
functions:

>>> s = '''eval(compile("import os; os.system('pwd')", "", "exec"))'''
>>> eval(s, {}, {})
/home/herzog

You can disable the builtins by defining a '__builtins__' item in the
globals dict:

>>> eval(s, {'__builtins__':{}}, {})


Traceback (innermost last):
File "<stdin>", line 1, in ?

File "<string>", line 0, in ?
NameError: eval
>>>

See the rexec module.


The safest way to read a number interactively is probably to use
raw_input and to convert the string explicitly to an int or float with
int() or float() respectively. You loose the automatic recognition of
ints and floats and syntaxes for octal or hexadecimal numbers, though.

A standard function eval_literal() that works like eval() but only
accepts literals would be convenient for this. E.g.

eval_literal('1.0') -> float 1.0
eval_literal('0x10') -> int 16
eval_literal('(10, "hallo")') -> tuple with int a string
eval_literal('sin(0.5)') -> raise exception


--
Bernhard Herzog | Sketch, a drawing program for Unix
her...@online.de | http://www.online.de/home/sketch/

Evan Simpson

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
First off, thanks for taking so much time and effort on this, and sharing it
with us. I'll respond point-by-point, after noting some philosophical
differences.

Python programmers appear to prefer hyperlinked over man-style
documentation, but unlike the GNU Project, we don't have any old manpages to
deprecate <wink>. Others have pointed out that a great deal of
documentation is available in several formats, but you don't seem to place
any value on any format other than manpages. I can slightly grok your point
for quick reference purposes, but do you *really* find *any other* format
unusable for exploration and learning of the language? Enough about that.

Tim Peters once half-joking tripped off a list of principles which describe
the "Python Way". They go a long way toward explaining the design choices
of Python. Here are some of them:
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
Namespaces are one honking great idea -- let's do more of those!

Tom Christiansen <tch...@mox.perl.com> wrote everything quoted, in message
news:37bc...@cs.colorado.edu


> GOTCHA: (medium)
> The whole mutability versus immutability thing causes many
> confusions

It needs to be internalized to avoid confusion, yes, but once grasped it's
not troublesome. Mutability issues and namespaces/dictionaries are closely
related; A major reason that tuples exist is for use as dictionary keys,
since keys require an unchanging hash value, and that means immutability
(pace weird classes). All namespaces, including those of modules, classes,
and instances, are based on dictionaries. Lists are actually the only other
mutable (built-in) objects in Python! It's true that there are several
cases where Python requires a tuple when a list or other sequence should
work just fine, but that is expected to change.

> GOTCHA: (low)
> I don't understand why we have so many C operators, such as "&" and
> "|" and "~", but we don't have "&&" or "||" or "!" We also have "<<"
> and ">>". It's bizarre that the relational and "?:" are missing.

Python took all (and only) the bitwise operators from C. Words are
preferred to symbols unless they're well-established from mathematics, IMHO.
It makes sense to Pascal programmers too <wink>.

> GOTCHA: (high)
> Local variables are never declared. They just *happen*. If a
> variable is assigned to, then it belongs to that "scope". If it's
> only looked at, it may be from the current global scope.

Think of it this way: Locals are declared *by* an assignment statement (or
param list), unless overridden by an explicit global declaration. If it's
only looked at, it *must* be from the global namespace.

> GOTCHA: (medium)
> If you have a function that expects two arguments [...]
> and you have a tuple of the two elements [...]
> You can't just call that function [with the tuple as argument]

You want automatic implicit tuple unpacking on function calls. Python
prefers explicit to implicit. A syntax for expressing explicit tuple
unpacking has been proposed (fn(*t)), and it remains to be seen whether it
will enter the language.

> GOTCHA: (medium)
> Assignment is a statement, not an operator.
[...]


> There are no compound assignment operators, like +=.

This is often, and heavily, discussed. Again, a syntax has been proposed
for Python 2.0 which should garner most of the benefits (set & test in
loops) while avoiding drawbacks (typos, obfuscation). There are no compound
assignment operators since there are no assignment operators, period.

> GOTCHA: (low)
> There are no loop labels, and therefore "break" and "continue" are
> only through the next level.

Agreed that this would be nice, although it's never been much of a problem
for me.

> GOTCHA: (high)
> I had hoped that having *only* reference semantics would spare the
beginner
> from having to keep in mind the difference between a reference and its
> referent as we have in C or Perl. Alas, it is not to be.
[...]
> GOTCHA: (high)
> Because everything is a reference, and there's no way to dereference
> that reference, it turns out that there is no trivial way to copy a
list! [later: or dictionary]
[...]
> This forces people to think about references, again.
> So much for lists being first class citizens!

This is the whole mutability/namespace issue again. Since all you *ever* do
is bind names to references, copying *must* be explicit, and dereferencing
is meaningless. Copying immutable objects is also meaningless, so this is
only an issue for mutable objects. There's more than one desirable way to
copy complex nested objects, so the copy module is provided. For lists,
"x=list(y)" or "x=y[:]" suffice for shallow copying, while dicts require the
more verbose "y={}; y.update(x)". If you wanted to be consistent, you could
use "y=[]; y.extend(x)" for lists. These are not "workarounds", just
different explicit copy methods. What does any of this have to do with
first-class citizenship?

> GOTCHA: (low)
> Single and double quoted strings can't cross line boundaries.
> You need triple quotes for that!

Once again, explicit wins over implicit. If you accidentally leave the
closing quote off of a string, it's caught at the end-of-line. You can break
single-quote strings over multiple lines by '\'-escaping the newline, and
you can embed newlines with '\n'. Triple-quoted strings are a convenience.

> GOTCHA: (medium)
> All ranges are up to but *not including* that point. So range(3)
> is the list [0,1,2]. This is also true in slices, which is the
> real gotcha part. A slide t[2:5] does not include t[5] in it.

That's because slices specify 'gaps', not elements. '0' is the gap at the
start of a sequence, 'n' is the gap before element 'n', and '-n' is the gap
before the nth element from the end. Gaps are defined past the end of the
sequence, so s[:n] takes the first n elements of s, or all of s if it is too
short. This also allows "s[3:3] = x" to express inserting into the gap
before the third element. The size of a slice (or range) a:b is b-a.

> GOTCHA: (high)
> This is a big surprise: strings are not atomic (although they are

> immutable). They are instead sequences of characters.

Immutability and atomicity are unrelated, except that atomic things tend to
be immutable. Strings are *not* sequences of characters, technically; They
are sequences of length-1 strings <grin>. This may surprise you, but it
comes in very handy, because it means we can apply all of the sequence
concepts, such as slicing.

> GOTCHA: (medium)
> Slices in Python must be contiguous ranges of a sequence.
> In Perl, there's no such restriction.

I don't see the difficulty. If I want to extract a set of ranges, I can
write "s[1:5] + s[10:20] + s[100:120]". Notational inconvenience? Or are
you talking about taking every nth element or something?

> GOTCHA: (medium)
> You can't slice dictionaries at all in Python. In Perl, it's
> easy to slice a hash, and just as sensible.

Dictionary keys are conceptually unordered, so they don't act like
sequences, so they don't slice. It would probably be uncontroversial to
define an operation like Perl's that uses the slicing notation, though.

> GOTCHA: (high)
> Lists don't autoallocate the way dictionaries do.

Explicit wins, here. A list element is required to exist before you can
re-bind it. Class wrappers do exist to provide Perl-like behavior.

> GOTCHA: (medium)
> There's no way to set up a permitted exports list. The caller may
have
> anything they ask for.

Python assumes trust. You can indicate (with a leading '_') that a name
isn't meant for external consumption, but there's no automatic protection
mechanism for determined users to have to find an obscure way around <wink>.
Double leading '_' mangles attribute names to prevent name clashes, but
doesn't render them inaccessible.

> GOTCHA: (medium)
> Importing a variable only gives you a local copy. In Perl, it makes
> two names for the same object.

Mnh? Importing an object binds it to a local name, it doesn't copy it. If
what you wanted was a way to re-bind the name *in the original namespace*,
you have to do that explicitly.

> GOTCHA: (high)
> Scopes don't nest in Python, but they they do in Pascal, Perl, or C.
> This is supposedly "simpler", but it's very suprising in many ways.

Lexical scoping is being seriously considered. In Pascal and C (and Perl?),
though, a nested function can only execute within the scope of a single call
to the containing scope. A Python function definition is a runtime
operation which produces a new object, which can then be passed back to the
caller and executed at any time, well after the factory function is dead and
gone.

> GOTCHA: (medium)
> You can't cut and paste these examples because of the issue
> of white space significance. :-(

That's indentation significance, buster <wink>. You need to use an editor
with block indent/dedent.

> GOTCHA: (low)
> List objects have built-in methods, like l.append(x)
> But string objects don't. You have to import
> from the string module to get them, and then they're
> functions, not methods.

This is a recognized inconsistency, and *will* change.

> GOTCHA: (low)
> You have insert and append methods for lists, but only
> a del function. Why is it a function not a method, and

> why isn't it spelled out? Apprently the fashionable way
> to do this is now a[2:3] = []
> Which of course, deletes only one element. ARG.

"del" isn't a function, it's a statement, and a very general one. I've
never seen the spelling you cite, but always "del a[2]".

> GOTCHA: (high)
> Because you can't use readline() to get a number, people seem to enjoy
> calling eval() just to get a string turned into a number

[...]


> This is scary. Even scarier is the propensity for calling input(),
> which auto-eval()s its input to make sure it's the right "type".

People enjoy being able to type expressions as input, and these methods
should only be used in a trusted context. If you have a string containing a
literal string, 'int(s)' and 'long(s)' work just fine. 'raw_input("Yes? ")'
should be used to fetch raw strings.

> GOTCHA: (medium)
> The expression 3/4 is 0, which is false. In Perl, 3/4 is 0.75,
> which is what you'd expect. You need to force the floatness.

It's what you would expect if you assume floating point arithmetic at all
times. If you're operating on integers, it's quite wrong. Explicitness
wins, in Python.

> GOTCHA: (low)
> An out-of-bounds list reference raises an "IndexError: list index out
> of range" exception, but not if you use a slice to get at it!

Slicing returns a sequence, which may be empty. Element indexing must
address a valid element. If element access out of range returned None, for
example, how could we tell the difference from a valid access of an element
containing None? Should an out of range access extend the list?

> GOTCHA: (high)
> Python's lambda's aren't really lambdas, because they are only
> expressions, not full functions, and because they cannot see
> their enclosing scope.

Python's lambdas are crippled little sops to functional programmers and
one-line-coders. Guido is sorry he added them :-)

> GOTCHA: (medium)
[...]
> Yes, the trailing comma counts [in tuples]

A trailing comma is *always* allowed, in any comma separated list. Thus
"(1,2)" equals "(1,2,)" and "f(2)" is the same as "f(2,)". The only time it
makes a difference is at the end of a print statement, or when leaving the
comma off would give you something indistinguishable from a parenthesized
expression.

> GOTCHA: (low)
> sort and reverse are in-place. This leads to verbose code

Only if what you wanted was a sorted or reversed *copy*. Writing a
"sorted()" or "reversed()" function is trivial, if the copying becomes
bothersome.

Barry A. Warsaw

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

Fred> Bucks? I'm supposed to be getting bucks for this?

Oops, sorry. Don't tell Fred we're all getting rich here.

Fred> Check the FTP site, Barry; GNU info is there thanks to the
Fred> active Python community.

Ah, that'll teach me to underestimate the Pythoneers!

Barry> Tom, but I'm sure Fred would gladly take a contribution
Barry> that generated manpage format from the latex source. You
Barry> might even be surprised at the languages he'd accept such a
Barry> contribution in! :)

Fred> Hey, you're making me look bad! ;-)

Just trying to fire up the masses. Look what it did for mailing list
managers :)

-Barry

Robb Shecter

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Evan Simpson wrote:
> ...Python programmers appear to prefer hyperlinked over man-style
> documentation...

Well, I don't think we should base assumptions on the posts of one
vocal advocate, but -

I'd say it has to do with the language itself:

Perl is "old school", along with awk, and sed: The complexity of the
system is in the language definition itself. Pure OO/Component-like
libraries are a secondary source for features. In this environment,
having docs that read linearly, more like a book, may be the best
solution.

Python is "new school", along with Java and Smalltalk (years ahead of
its time). The language is intended to be simple, and the complexity
is in the libraries. In this case, having highly structured,
hyperlinked refs may be the best way to go.

- Robb

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to John Landahl
>What's all this about no Python manpages?

$ man python
No manual entry for python
[Exit 1]

$ locate python.1
[Exit 1]

That there appears to be running a 1.5.1 version on a Redhat
Linux system. I haven't tried a from-scratch build. I'm
happy to blame RH. Their doc situation is nasty.

--tom

Bernhard Herzog

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tom Christiansen <tch...@mox.perl.com> writes:

> [courtesy cc of this posting mailed to cited author]
>
> In comp.lang.python,

> Thomas Wouters <tho...@xs4all.nl> writes:

> :> >>> for c in ("weird", "bits"):
> :> >>> for c in ("weird"):
>
> :Wait, wait, you're doing two different things here. First off, you called
> :'for' with different types of arguments, the first time with a tuple of
> :strings, the second type with just a string.
>
> Oh, come now, you're telling me I'm expected to count the items
> in the parens to know whether a split will happen. Whatever.
> It's not obvious, so it's a real gotcha. This is not consistent.
>
> :But they are definately not the same :)
>
> But they look the same, which is wicked.
>
[snip]
>
> :"Yes, the trailing comma counts" :)
>
> Speaking of inconsistencies!

The thing to note about tuples is that in a way it's not the parens that
make a tuple, it's the comma:

>>> t = 1, 2
>>> t
(1, 2)

The inconsistency is that () is an empty tuple, not that (1,) is a
one-element tuple. The parens are often needed because commas are also
used in list and dictionary literals and function calls and definitions,
among other places.

This is also why you can't slice dictionaries (if I understood what you
meant by slicing dicts in perl correctly). d[1,2] is equivalent to
d[(1,2)], i.e. it refers to the item with (1,2) as the key:

>>> d = {}
>>> d[1,2] = 'xyzzy'
>>> d
{(1, 2): 'xyzzy'}

Robert Kern

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

Not really. I have never seen anyone express a desire for manpages
before today. There was a large discussion some time back on Python's
documentation. While I didn't read every post of that discussion, I
don't recall anyone requesting manpages. Many people were requesting
something like pod, though. :-)

The reason we have Windows help files for Python's documentation is
because someone in the Python community (not Fred Drake, the official
documentation maintainer) wanted them and did the necessary work to
provide them. The reason we don't have UNIX manpages is because not
enough people (if any besides you) have asked for them or done the
work. Fred is always willing to accept volunteers, though.

In the meantime, python(1), which should be installed automatically by
the Makefile (if it didn't, the file "python.man" is in the Misc/
subdirectory of the source package), will refer you to the Python
Tutorial, the Python Library Reference, and the Python Reference
Manual. Unfortunately, what it doesn't mention is the URL for getting
this documentation. This is a holdover from the time before the
source and documentation were split into separate distributions. If
nothing else is done about manpages, this oversight should be fixed.
Fred?

>--tom

Robert Kern |
----------------------|"In the fields of Hell where the grass grows high
This space | Are the graves of dreams allowed to die."
intentionally | - Richard Harter
left blank. |

John Landahl

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to Tom Christiansen

Ahhhhhhhhhh, that seems to be the problem. I just tried it on a recently
built (RedHat)SparcLinux box and got the same thing.

Having followed the manpage discussion a bit, I see two arguments that might
have gotten confused by this new info:

1) There should at least be a python(1) manpage that tells you command
line args, some basic information about the interpreter, etc.

2) There should be manpages documenting all aspects of the language.

If your problem was mostly with 1) then I concur, and so would most Unix
types, I think. The rest of this debate seems centered around issue 2), and
I'm not sure that was your main point. I agree that 1) should be the
minimum, but I would tend to look for web-based cross-referenced
hypertextified documentation for more detailed information. Though I've
definitely found "man perlfunc" to be extremely useful when I want to get at
something quick, so I agree that Python manpages would be a nice addition.

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
ke...@mail.ncifcrf.gov (Robert Kern) writes:
:This is a holdover from the time before the


:source and documentation were split into separate distributions.

Why was this done? Is this a good thing? You can't do that with Perl
modules' documentation because all the module doc is embedded. We did
this to avoid a sync problem, and so people could never not have the docs.
In fact, they can even be links to the same file, e.g. File::stat.3
linked to and File/stat.pm. Or do you just mean core docs, not
module docs were split?

--tom
--
"IMHO, CAPS LOCK should be somewhere more
convenient; e.g., in another building." --jgreely

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to John Landahl
>If your problem was mostly with 1) then I concur, and so would most Unix
>types, I think. The rest of this debate seems centered around issue 2), and
>I'm not sure that was your main point. I agree that 1) should be the
>minimum, but I would tend to look for web-based cross-referenced
>hypertextified documentation for more detailed information. Though I've
>definitely found "man perlfunc" to be extremely useful when I want to get at
>something quick, so I agree that Python manpages would be a nice addition.

% (echo 'import os' ; echo 'print os.execv.__doc__' ) | python
Execute an executable path with arguments, replacing current process.

path: path of executable file
args: tuple or list of strings

Well, that's better than nothing.

% (echo 'import os' ; echo 'print os.__doc__' ) | python
None

But that isn't. :-)

I'd guess for a module, you should traverse its members and
print docs for all that have them.

I'm still getting ideas for autogenerating manpages. :-)

But I haven't looked at the HTML or latex docs yet. Probably
won't till after the conference or so.

--tom

Robert Kern

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
On 19 Aug 1999 15:57:54 -0700, Tom Christiansen <tch...@mox.perl.com>
wrote:

> [courtesy cc of this posting mailed to cited author]
>
>In comp.lang.python,
> ke...@mail.ncifcrf.gov (Robert Kern) writes:
>:This is a holdover from the time before the
>:source and documentation were split into separate distributions.
>
>Why was this done? Is this a good thing? You can't do that with Perl
>modules' documentation because all the module doc is embedded. We did
>this to avoid a sync problem, and so people could never not have the docs.
>In fact, they can even be links to the same file, e.g. File::stat.3
>linked to and File/stat.pm. Or do you just mean core docs, not
>module docs were split?

The core docs (Tutorial, Ref. Manual, Ext. and Emb., etc.) plus the
Library Reference, which, I guess, *is* the module docs (except for
doc strings, which are embedded). I think that the reasoning behind
the split was to allow Fred to update the documentation between
releases. For the most part, this is A-Good-Thing, since the
documentation is still incomplete in some regards (probably not enough
to justify a split if we were considering the docs now, but back then
the docs were).

The issue was more of getting the documentation into sync than keeping
it there. And, generally speaking, there aren't enough sync problems
to justify losing the flexibility of separate distributions (IMO).

>--tom
>--
>"IMHO, CAPS LOCK should be somewhere more
>convenient; e.g., in another building." --jgreely

Robert Kern |

Robert Kern

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
On Thu, 19 Aug 1999 15:55:47 -0600, Tom Christiansen
<tch...@jhereg.perl.com> wrote:

[snip]

>% (echo 'import os' ; echo 'print os.execv.__doc__' ) | python

You can simplify that to
% python -c 'import os; print os.execv.__doc__'
:-)

>Execute an executable path with arguments, replacing current process.
>
> path: path of executable file
> args: tuple or list of strings
>
>Well, that's better than nothing.
>
>% (echo 'import os' ; echo 'print os.__doc__' ) | python
>None
>
>But that isn't. :-)

True. Missing doc-strings has been the perennial biggest problem with
Python's documentation.

>I'd guess for a module, you should traverse its members and
>print docs for all that have them.
>
>I'm still getting ideas for autogenerating manpages. :-)

We've probably thought of them, too (well, the autogeneration part at
least). The biggest problem with using them on third-party modules is
that there is no consistent standard for them like pod. We have
Guido's recommendations from his style guide, and we have things like
Structured Text, but we also have have a zillion other styles for
docstrings. We could probably enforce a standard for the standard
library, though. Use Deja.com to read a thread named "Pod" we had
here back in October and November of 1998 where we talked about most
of these things. But ...

>But I haven't looked at the HTML or latex docs yet. Probably
>won't till after the conference or so.

... more of the information you would want in a manpage is probably in
the latex sources (and, by extension, HTML) than in the docstrings.

Things will get even easier when the conversion to XML or SGML is made
(RSN).

>--tom

Michael Hudson

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
I sooo want to keep out of this; just a couple of points.

Tom Christiansen <tch...@mox.perl.com> writes:
> :> GOTCHA: (medium)
> :> Perl's hex() function is the opposite of Python's. Perl's hex
> :> function converts 22 into 37. Python's hex function converts 37 into
> :> 0x22. Oh my! Like hex, Python has oct() completely backwards from
> :> Perl. Python's oct(44) returns 054, but Perl's oct(44) return 36.
> :
> :This would have to do with strings not being automatically coerced
> :into numbers, methinks.
>
> No, that's not it. Perl's hex takes a hex number and returns
> a decimal one; same with oct. Python's is the reverse. Very weird.
>
> echo 'print oct(12)' | python
> 14
>
> echo 'print oct(12)' | perl -l
> 10
>
> See what I mean?

Well, in Python an integer's an integer. It has no property of being
hex or decimal or octal. So by the time the hex/oct function sees it,
it's just an integer irrespective of the way it was typed.

It would seem to me that perl's

oct(12)

is like Python's

012

A difference.

> :There's info format if you look for it and you have to have a CLI.
>
> At the very least, python needs a top-level python(1) manpage that gives
> calling conventions, options, envariables etc, and an explanation of how
> to locate the rest of the documentation (even if it's in non-man form).
> That's a POSIX.2 requirement.

On this subject I'll just say: If people before you had cared as much
about the existence of a python(1) manpage, it would have one.

> :> GOTCHA: (low)
> :> Often Python's error messages leave something to be desired.
> :> I don't know whether
> :
> :Is this a joke? This is improving.
>
> No, it isn't a joke.

I was referring to the unfinished "I don't know whether" line.

[explanantion of slicing dicts elided]

Oh, I see.

> :new = old.copy()
>
> I wonder how many times I'll have to explain that I read the
> Lutz book, wasn't on the Internet at the time, and found no manpages
> installed with python on my laptop.

Ah, have you discovered rlcompleter yet? Put this in your ~/.pythonrc:

import rlcompleter
readline.parse_and_bind('tab: complete')

set PYTHONSTARTUP=~/.pythonrc and then in python type:

d={}
d.

and whack tab a couple of times. This should definitely be better
advertised; I use it all the time.

> :Yes this is a bit annoying. The Right Way to attach state to a
> :function is a class, of course. Not that that helps much.
>
> That sounds like religion.

I suppose, but not Python's particularly.

> And aren't bound methods inherent
> memory leaks?
>
> fn = obj.method;

No.

> :> GOTCHA: (low)
> :> Python's eval() only works on expressions, not full code blocks full
> :> of statements. You need exec() for the whole thing.
> :
> :Writing exec() suggests it's a function; it isn't, it's a statement.
>
> Funny that you guys are all flustered about this statement/function thing.
> I think of if and def as statements. I'm not saying print and exec
> aren't, but they sure look just like it.

I was just being accurate.

Cheers,
Michael

Tom Christiansen

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
Michael Hudson <mw...@cam.ac.uk> writes:
:Ah, have you discovered rlcompleter yet? Put this in your ~/.pythonrc:


:
:import rlcompleter
:readline.parse_and_bind('tab: complete')
:
:set PYTHONSTARTUP=~/.pythonrc and then in python type:
:
:d={}
:d.
:
:and whack tab a couple of times. This should definitely be better
:advertised; I use it all the time.

That just triggers:

% python
Python 1.5.1 (#1, Sep 3 1998, 22:51:17) [GCC 2.7.2.3] on linux-i386
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
Traceback (innermost last):
File "/home/tchrist/.pythonrc", line 2, in ?
readline.parse_and_bind('tab: complete')
NameError: readline

Time to do a real install. Hate redHate.

--tom
--
I think I'm likely to be certified before Perl is... :-)
--Larry Wall in <1995Feb12....@netlabs.com>

Michael Hudson

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tom Christiansen <tch...@mox.perl.com> writes:

> [courtesy cc of this posting mailed to cited author]
>
> In comp.lang.python,
> Michael Hudson <mw...@cam.ac.uk> writes:
> :Ah, have you discovered rlcompleter yet? Put this in your ~/.pythonrc:
> :
> :import rlcompleter

Agh! Duh!

Try making that

import rlcompleter, readline

(sound of forehead being smacked)

> :readline.parse_and_bind('tab: complete')
> :
> :set PYTHONSTARTUP=~/.pythonrc and then in python type:
> :
> :d={}
> :d.
> :
> :and whack tab a couple of times. This should definitely be better
> :advertised; I use it all the time.
>
> That just triggers:
>
> % python
> Python 1.5.1 (#1, Sep 3 1998, 22:51:17) [GCC 2.7.2.3] on linux-i386
> Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
> Traceback (innermost last):
> File "/home/tchrist/.pythonrc", line 2, in ?
> readline.parse_and_bind('tab: complete')
> NameError: readline
>
> Time to do a real install. Hate redHate.

You might need to do that too.

HTH
Michael

Fred L. Drake, Jr.

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

Robert Kern writes:
> Manual. Unfortunately, what it doesn't mention is the URL for getting
> this documentation. This is a holdover from the time before the
> source and documentation were split into separate distributions. If
> nothing else is done about manpages, this oversight should be fixed.

Robert,
Thanks for pointing this out; I'll certainly add the missing
information to the man page.

Richard Jones

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to

[Tom Christiansen]

> That just triggers:
>
> % python
> Python 1.5.1 (#1, Sep 3 1998, 22:51:17) [GCC 2.7.2.3] on linux-i386
> Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
> Traceback (innermost last):
> File "/home/tchrist/.pythonrc", line 2, in ?
> readline.parse_and_bind('tab: complete')
> NameError: readline
>
> Time to do a real install. Hate redHate.

Mmmm. Step 1 for me on a new RedHat system is almost always to replace the
Python install with something usable like Oliver Andrich's RPMs from
http://www.andrich.net/

It annoys me that they ship such a minimalist version :(


Richard

Mark Jackson

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Jeremy Hylton <jer...@cnri.reston.va.us> writes:
> >>>>> "TC" == Tom Christiansen <tch...@mox.perl.com> writes:
>
> TC> :There are 'raw' strings though, 'r"<string>"', that dont do
> TC> backslashes.
>
> TC> Those aren't the book, and there are no manpages. Therefore, in
> TC> many ways, they don't really count. I know it hurts to hear
> TC> this, and you're all going to jump on me, but please please
> TC> think about it for a bit before you do so.
>
> [I know I said I wasn't going to get into this, but...] I think this
> statement is just plain silly. I use lots of tools, languages,
> libraries, etc. that have non-existent or bad manpages. The raw
> string exist regardless of whether there is a manpage that describes
> them. Which is not to say that I'm opposed to manpages; it would
> probably be helpful to provide them.
>
> I did think about this before I jumped, but it still seems fair to
> jump. As a possible counterexample to the "if it don't have manpages
> it don't exist" argument, I would suggest the C programming language.
> I don't believe there are manpages that describe the language itself,
> yet I found it (relatively) easy to learn. The K&R C book is mighty
> fine.

On my Solaris box:

"man c" returns nothing.

"man cc," "man gcc," even "man f77" return varying amounts of
information about the *compilers*, at best a mention of where to go to
learn about the *language*.

You know, I have never read c.l.perl.misc, but I have developed a
strong theory about why it is widely reputed to be a rude and
unpleasant place.

--
Mark Jackson - http://www.alumni.caltech.edu/~mjackson
The entrepreneurial spirit is not rare in humankind. The problem
is most people who have it, apply it to lunatic enterprises.
- Mike O'Brien

Brad Howes

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
dun...@rcp.co.uk (Duncan Booth) writes:

> Or if you know you are going to have a tuple, you could declare the
> function to take a tuple as its argument:
> def fn((x,y)): ...

Get out! You can do that?! Wow -- learn something new every day. Thanks!

Brad

--
Brad Howes br...@mediaone.net

bowman

unread,
Aug 19, 1999, 3:00:00 AM8/19/99
to
Tom Christiansen wrote:
>
> That there appears to be running a 1.5.1 version on a Redhat
> Linux system. I haven't tried a from-scratch build. I'm
> happy to blame RH. Their doc situation is nasty.

Would that be the same RH5.2 that caused me a day's frustration because
their
Perl is so broken it can't handle PerlTk? You want to be careful
building Python 1.5.2, also, as a little misstep will break RH's
'glint', 'linuxconfig' and other Python based oddities.

--
Bear Technology Making Montana safe for Grizzlies

http://people.montana.com/~bowman/

Moritz Moeller-Herrmann

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
On 19 Aug 1999 10:30:51 -0700, Tom Christiansen <tch...@mox.perl.com> wrote:

[...]


>>There are 'raw' strings though, 'r"<string>"', that dont do backslashes.

>Those aren't the book, and there are no manpages. Therefore,

>in many ways, they don't really count. I know it hurts to hear
>this, and you're all going to jump on me, but please please think


>about it for a bit before you do so.

>>> GOTCHA: (high)
>>> Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
>>> ENODOC
>>
>>Damn, i hadn't even noticed that. Can you imagine ? I guess the '__doc__'
>>attributes on objects are enough manpage for me. ;)

>It's unconscionable. Lack of tools and the tool-based
>approach strikes again. See other postings.


[...]

>That's not a fricking manpage. How can I run "apropos copy"
>on it? How do I do
> grep copy /usrpython/man/*/*.*
>or
> find /usrpython/man -print | xargs grep copy /dev/null
>or
> troff -man /usrpython/man/man3/copy.3py

>etc etc. Tools, man. Man tools. Flexible interchangeable
>parts.

[...]

Actually, there are excellent html docs. And I found raw strings easily.

grep -3 "raw strings" python-doc/html/*/*.html

python-doc/html/lib/node66.html-subsequent character are included in the resulting string. However,
python-doc/html/lib/node66.html-if Python would recognize the resulting sequence, the backslash should
python-doc/html/lib/node66.html-be repeated twice. This is complicated and hard to understand, so
python-doc/html/lib/node66.html:it's highly recommended that you use raw strings for all but the
python-doc/html/lib/node66.html-simplest expressions.
python-doc/html/lib/node66.html-<DT><tt>[]</tt>
python-doc/html/lib/node66.html-<DD>Used to indicate a set of characters. Characters can

python-doc/html/ref/ref-4.html-longstringchar: &lt;any ASCII character except
&quot;\&quot;&gt;
python-doc/html/ref/ref-4.html-escapeseq: &quot;\&quot; &lt;any ASCII
character&gt;
python-doc/html/ref/ref-4.html-</PRE>
python-doc/html/ref/ref-4.html: In plain English: String literals can
be enclosed in single <A NAME=MARKER-2-51></A>quotes (') or double quotes
(&quot;). They can also be enclosed in groups of three single or double quotes
(these are generally referred to as <I><A NAME=MARKER-2-52></A>triple-quoted
strings</I>). The <A NAME=MARKER-2-53></A>backslash (\) character is used to
escape characters that otherwise have a special meaning, such as newline,
backslash itself, or the quote character. String literals may optionally be
prefixed with a letter 'r' or 'R'; such strings are called <I>raw strings</I>
and use different rules for backslash escape sequences.<P>
python-doc/html/ref/ref-4.html- In "long strings" (strings surrounded by sets
of three quotes), unescaped newlines and quotes are allowed (and are
retained), except that three unescaped quotes in a row terminate the string.
(A "quote" is the character used to open the string, i.e. either ' or
&quot;.)<P>
python-doc/html/ref/ref-4.html- <A NAME=MARKER-2-54></A>Unless an 'r' or 'R'
prefix is present, escape sequences in strings are interpreted according to
rules similar to those used by Standard <A NAME=MARKER-2-55></A>C. The
recognized escape sequences are:
python-doc/html/ref/ref-4.html-<TABLE BORDER="1">


I fail to see why lynx and grep don't work :-)


--
Moritz Moeller-Herrmann m...@gmx.net ICQ# 3585990 # Not only
Get my public pgp / gpg key from # Open Source(TM)
http://webrum.uni-mannheim.de/jura/moritzpubkeymoritz # but also
KDE forever! Use Linux to impress your friends! # Open Minded!


Chad Netzer

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Tom Christiansen wrote:

> You're right. I should have written
>
> new = []
> for i in range(0,len(old)):
> new[i] = old[i]
>
> And that certainly is parallel to the dictionary case. Dictionary
> auto-allocate. Lists don't.

Again, why not just use new.append(old[i])? If you REALLY want to
write it with an equals sign or start the indexing at other than zero, then
declare new as a dictionary (integers are valid keys since they are non
mutable)

old = [1,2,3,4,5,6,7,8,9]
new={}
for i in range(4, len(old)):
new[i] = old[i]

Autoallocating arrays, or arrays with holes, are simply Python dicts.
Of course, having something like new.sortedprint() might be nice,
but it is easy to define a function.

def sortedprint(dict):
spam = dict.keys()
spam.sort() # What, you've never heard of the amazing spamsort?
for i in spam:
print dict[i],
print


Chad Netzer
ch...@vision.arc.nasa.gov

Per Kistler

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Tom Christiansen wrote:

> The fact that they did icky windows help and not man pages says
> something significant.

Why not create something like perldoc for python?
There must be others missing it...
Per.
--
Per Kistler kis...@fnmail.com / kis...@gmx.net
------------------------------------------------------------

Per Kistler

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
John Landahl wrote:

> What's all this about no Python manpages?
>
> $ man python

> Reformatting page. Wait... done
>
> Misc. Reference Manual Pages PYTHON(10 April, 1998)

It's there, but I think "perldoc perl" still has more
to say. Why not offer all possible resources?
Even tcl has more...

-Per.

Robert Kern

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
On Fri, 20 Aug 1999 02:57:24 +0200, Per Kistler <kis...@fnmail.com>
wrote:

>John Landahl wrote:
>
>> What's all this about no Python manpages?
>>
>> $ man python
>> Reformatting page. Wait... done
>>
>> Misc. Reference Manual Pages PYTHON(10 April, 1998)
>
>It's there, but I think "perldoc perl" still has more
>to say. Why not offer all possible resources?

Lack of man-hours. Fred's the only person (AFAIK) who is officially
working on the docs. Doing the rest takes volunteers (hint, hint).
:-)

>Even tcl has more...
>
>-Per.

Robert Kern |

Skip Montanaro

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to bowman

bowman> You want to be careful building Python 1.5.2, also, as a little
bowman> misstep will break RH's 'glint', 'linuxconfig' and other Python
bowman> based oddities.

There are two or three scripts that need to have their function def's fixed
to not have default args after non-default args. If anyone needs them I can
build a context diff. Just let me know.

Skip Montanaro | http://www.mojam.com/
sk...@mojam.com | http://www.musi-cal.com/~skip/
847-971-7098

Tim Peters

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to pytho...@python.org
[Tom Christiansen]
> Python has a round() function, but it seems to ignore the
> IEEE rules of rounding. However, its sprintf operator doesn't:
> >>> print "int of %f is %.0f" % (1.5, 1.5)
> int of 1.500000 is 2
> >>> print round(1.5,0)
> 2.0
> >>> print "int of %f is %.0f" % (2.5, 2.5)
> int of 2.500000 is 2
> >>> print round(2.5,0)
> 3.0

Python's sprintf rounding is inherited from the platform libc's. Virtually
all systems will round 1.5 up to 2.0, but there's wide variation (even among
Unices) in what %f.0 does to 2.5. The "round" function is Python's own.

[while Christian Tismer gets ...]
> I had a look at this again. Despite the fact that the text in
> the above example is a bit misleading by "int of" where
> a round() takes place, which version of Python/architecture
> did you use? I get the expected result, see below.
>
> >>> print "round of %f is %.0f" % (1.5, 1.5)
> round of 1.500000 is 2
> >>> print round(1.5,0)
> 2.0
> >>> print "round of %f is %.0f" % (2.5, 2.5)
> round of 2.500000 is 3
> >>> print round(2.5,0)
> 3.0
> >>>

My guess is you're running on Windows. MS rounds all halfway cases up;
Tom's complaint is that under IEEE-754 to-nearest/even rules, 1.5 and 2.5
should both round to 2. Luckily, Python's will do that the instant MS's
does <wink>.

not-sure-there's-a-winner-in-arguing-over-which-language-has-the-
lamest-754-support-ly y'rs - tim

Tim Peters

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to Tom Christiansen, pytho...@python.org
[posted & mailed]

[Tom Christiansen]
> ...
>
> 2. Perl code
>
> main() {
> printf("Float %g rounds to %.0f\n", 1.5, 1.5);
> printf("Float %g rounds to %.0f\n", 2.5, 2.5);
> printf("Float %g rounds to %.0f\n", 3.5, 3.5);
> printf("Float %g rounds to %.0f\n", 4.5, 4.5);
> }
> main(); # not called by default
>
> OUTPUT:
>
> Float 1.5 rounds to 2
> Float 2.5 rounds to 2
> Float 3.5 rounds to 4
> Float 4.5 rounds to 4


I know Python (and expect Perl) both inherit their sprintf behavior from the
platform libc. Here's what Perl does under Windows (& Python does too):

C:\temp>perl temp.pl
Float 1.5 rounds to 2
Float 2.5 rounds to 3
Float 3.5 rounds to 4
Float 4.5 rounds to 5

>>>

Unices also vary widely in what they do to 2.5 and 3.5; I don't know of any
platform that doesn't round 1.5 to 2 and 3.5 to 4, though.

add-a-half-&-chop-is-even-older-than-us<wink>-ly y'rs - tim

Tim Peters

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to pytho...@python.org
[tchrist]
>> GOTCHA: (medium)
>> Slices in Python must be contiguous ranges of a sequence.
>> In Perl, there's no such restriction.

[Michael Hudson]
> At some point Python will probably support `extended slice syntax'
> like so:
>
> range(0,10)[1:4:2] => [1,3]
>
> Numerical Python already does this.

[tchrist]
>> GOTCHA: (medium)
>> You can't slice dictionaries at all in Python. In Perl, it's
>> easy to slice a hash, and just as sensible.

[Michael Hudson]
> Huh? What would that mean? There's no reason to suspect that the keys
> of a dictionary are ordered.

What Tom calls "slicing" here the NumPy folk would call gather/scatter
subscripting. A list can be used as an index, e.g.

thing[[7,2,3]] == [thing[7], thing[2], thing[3]]

Perl has something like that; Python does not.

can't-tell-the-subscripting-modes-without-a-scorecard-ly y'rs - tim

Chad Netzer

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Skip Montanaro wrote:

> bowman> You want to be careful building Python 1.5.2, also, as a little
> bowman> misstep will break RH's 'glint', 'linuxconfig' and other Python
> bowman> based oddities.
>
> There are two or three scripts that need to have their function def's fixed
> to not have default args after non-default args. If anyone needs them I can
> build a context diff. Just let me know.
>

Those of us on the Python4Linux issues are ironing these issues out.
Hopefully,
we will submit an SRPM that the major distributions will accept in order to
upgrade their next supported releases to 1.5.2 (Debian seems to have 1.5.2
available in their unstable release already).

Those wanting to know more can subscribe or see the archives:

http://starship.python.net/mailman/listinfo/python4linux

Look at my posting titled "Evaluation packages now online", which will lead
you to packages for Redhat that will work for Python 1.5.2 (well, not glint
actually)

Chad Netzer
ch...@vision.arc.nasa.gov

Tim Peters

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to Tom Christiansen, pytho...@python.org
[posted & mailed]

[tchrist]
> ...
> Python deems def an executable statement. Perl doesn't. Therefore,
> it's a gotcha for a Perl programmer, who doesn't understand why the
> silly compiler did that.

That cuts both ways, of course, as does any difference. That is, I once got
miffed at Perl because my named, nested functions weren't working. "man
pages" or not <wink>, it wasn't until I studied the source that I figured
out Perl effectively moves all named functions to the top level, and if you
have two nested functions in a package that happen to have the same name,
the first gets tossed into the bit bucket:

$x = 5;

sub outer1 {
my $x = 50;
sub inner {
print "in the first inner, and here's x: $x\n";
}
&inner();
}

sub outer2 {
my $x = 500;
sub inner {
print "in the second inner, and here's x: $x\n";
}
&inner();
}

&outer1();

Which prints:

in the second inner, and here's x:

(the first inner vanished, and $x in the second inner is undefined).

It's curious that Python & Perl both *allow* lexical nesting of named
functions, and both do wildly-- yet different! --unexpected things with
them. Python may not have lexical closures in Perl's sense, but Perl
doesn't have nesting in Python's sense <wink>.

> Apparently, it's just at run-time interring a function that was
> compiled at compile-time in the current symbol table.

Yes, "def" acts exactly like an assignment statement, binding the function
name to the code object in the current local namespace (which happens to be
the module namespace if the function is at top-level, the current function's
local namespace if the "def" is contained in a function, or the class's
namespace if the function is contained in a class).

One cute consequence is stuff like:

if __debug__:
def f():
# slow but careful implementation
else:
def f():
# fast but caressless implementation

more-powerful-than-a-speeding-#ifdef-ly y'rs - tim

Tom Christiansen

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to Tim Peters
>That cuts both ways, of course, as does any difference. That is, I once got
>miffed at Perl because my named, nested functions weren't working. "man
>pages" or not <wink>, it wasn't until I studied the source that I figured
>out Perl effectively moves all named functions to the top level, and if you
>have two nested functions in a package that happen to have the same name,
>the first gets tossed into the bit bucket:

You didn't localize your function! Remember, in Perl things
are only local if you say they are.

>$x = 5;

>sub outer1 {
> my $x = 50;
> sub inner {
> print "in the first inner, and here's x: $x\n";
> }
> &inner();
>}

>sub outer2 {
> my $x = 500;
> sub inner {
> print "in the second inner, and here's x: $x\n";
> }
> &inner();
>}

>&outer1();

That could have been like this:

sub outer1 {
my $x = 50;

local *inner = sub {


print "in the first inner, and here's x: $x\n";
};
&inner();
}

sub outer2 {
my $x = 500;

local *inner = sub {


print "in the second inner, and here's x: $x\n";
};
&inner();
}

&outer1();

And run just fine. BTW, you should have gotten a bucket of frightened
warnings out of the compiler about that. Syntax checking the compile,
with warnings (somewhat like gcc -Wall -pedantic, but without *.o
generation):

% perl -wc /tmp/timstuff
Variable "$x" will not stay shared at /tmp/timstuff line 6.
Variable "$x" will not stay shared at /tmp/timstuff line 14.
Subroutine inner redefined at /tmp/timstuff line 13.
Name "main::x" used only once: possible typo at /tmp/timstuff line 1.
/tmp/timstuff syntax OK

If that is mysterious, bump up the verbosity:

% perl -Mdiagnostics -wc /tmp/timstuff

Variable "$x" will not stay shared at /tmp/timstuff line 6 (#1)

(W) An inner (nested) named subroutine is referencing a lexical
variable defined in an outer subroutine.

When the inner subroutine is called, it will probably see the
value of the outer subroutine's variable as it was before and
during the *first* call to the outer subroutine; in this case,
after the first call to the outer subroutine is complete, the
inner and outer subroutines will no longer share a common value
for the variable. In other words, the variable will no longer
be shared.

Furthermore, if the outer subroutine is anonymous and references
a lexical variable outside itself, then the outer and inner
subroutines will never share the given variable.

This problem can usually be solved by making the inner subroutine
anonymous, using the sub {} syntax. When inner anonymous subs
that reference variables in outer subroutines are called or
referenced, they are automatically rebound to the current values
of such variables.

Variable "$x" will not stay shared at /tmp/timstuff line 14 (#1)

Subroutine inner redefined at /tmp/timstuff line 13 (#2)

(W) You redefined a subroutine. To suppress this warning, say

{
local $^W = 0;
eval "sub name { ... }";
}

Name "main::x" used only once: possible typo at /tmp/timstuff line 1 (#3)

(W) Typographical errors often show up as unique variable names.
If you had a good reason for having a unique name, then just
mention it again somehow to suppress the message. The use vars
pragma is provided for just this purpose.

/tmp/timstuff syntax OK

Yes, this local function thing is in the Perl Cookbook in the subroutines
chapter. Larry said that the next release of Perl *shall support

sub outer1 {
my $x = 50;

my sub inner {


print "in the first inner, and here's x: $x\n";
}
&inner();
}

sub outer2 {
my $x = 500;

my sub inner {


print "in the second inner, and here's x: $x\n";
}
&inner();
}

&outer1();

But this is lexical scoping, not dynamic scoping. With the local
sub inner, inner could call fred, and then fred could still
see inner to call it again in indirect recursion. That couldn't
happen with my sub inner, which is lexically scoped.

BTW, see what I mean about the importance of good error messages?
I'm used to something more than Ken Thompson's "?" retort. Everytime I
get NameError from Python, I just want to kick it.

And yes, those were compile-time warnigns. In the developer
release of Perl, you can promote some or all of those into
fatals if you want, which will make Guido carp less.

use warnings qw/FATAL uninitialized numeric/;

is more in the "python" style. And you can always say

use warnings qw/FATAL all/;

if you feel all warnings should kill you. Note that that pragma, like use
strict, is lexically scoped to the surrounding nested scope. That way
one block can selectively enable classes of warnings. Warning classes
are:

all ambiguous closed closure default deprecated exec io misc newline
numeric octal once parenthesis pipe precedence printf recursion
redefine reserved semicolon signal substr syntax taint uninitialized
unopened unsafe untie utf8 void

And you can do

use warnings;
no warnings qw/once exec ambiguous/;

or whatever.

You know, it occurs to me that it might be nice to be able to selectively
promote only compile-time warnings to fatals. Perl does a lot of
compile-time stuff (including constant expression folding, inlining of
some subroutines, and folding of those results!).

What does Python do at compile-time?

--tom

Alexander Williams

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
On Thu, 19 Aug 1999 15:31:17 -0400 (EDT), Barry A. Warsaw
<bwa...@cnri.reston.va.us> wrote:

>It says that Windows users were more motivated to provide platform
>specific documentation than any Unix user so far.

More specifically, it says we Real Unix Men(tm) don't mind using the
HTML indices to the module docs on the Python site since Lynx works
just fine from our Wyse or VT100 character terminals ... Why reinvent
the wheel?

Besides, language internals shouldn't be documented in seperate man
pages, that way lies madness in any language with any kind of complex
syntax. Why reinvent the wheel?

--
Alexander Williams (tha...@gw.total-web.net)
"In the end ... Oblivion Always Wins."

Fredrik Lundh

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
as so often before, Tom ran out of positive energy and
started posting stuff like:

> You seem to be looking for a fight. Please say nothing
> at all if that's all you want to do.

> Fine. I just hate being told to read the fucking manual when there
> ISN'T one. I despite Linux and GNU and the FSF and all that crap
> because of this.

> The fact that they did icky windows help and not man pages says
> something significant.

> --tom

some days, this guy really works hard to live up
to his first name:

Svenskt uppslagsord:
tom tomt tomma (adj.)

without content (also fig. "lacking substance,
meaning, or value")

English translation:

empty

> Is your newsreader broken, or haven't you ever bothered to
> read news.announce.newusers to learn how to use Usenet?

comp.lang.python is not your ordinary usenet. please read
the comp.lang.python posting guidelines before you post more
crap like this. this is not comp.lang.perl.misc.

</F>


Fredrik Lundh

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
(posted and mailed)

just some random comments on tom's
random comments:

Tom Christiansen <tch...@mox.perl.com> wrote:
> GOTCHA: (low)
> You can't use "in" on dicts. Instead, you must use
> d = { "fred":"wilma", "barney":"betty" }
> if d.has_key("fred"): # legal
> if "fred" in d: # ILLEGAL
> I don't understand why this was done.

"in" is a sequence operator; it's supposed to loop over
a sequence object (an ordered collection). dictionaries
are mappingss, not ordered collections. some extension
types provide collections that are both sequences and
mappings. the archives have more info on this.

> GOTCHA: (medium)
> If you have a function that expects two arguments, such as:
> def fn(x,y):
> return x + y
> and you have a tuple of the two elements:
> t = (1,2)
> You can't just call that function:
> print fn(t)
> Or you get a "TypeError: not enough arguments; expected 2, got 1"
> error. You have to use this apply() function to get around this
> issue:
> print apply(fn,t)
> 3

and praise Guido for that one...

> GOTCHA: (medium)
> Assignment is a statement, not an operator. That means that
> people are constantly writing loops that aren't really testing
> the exit condition, as in:
> while 1:
> line = os.readline()
> if not line: break
> .....

except that experienced Python programmers
write that as:

while 1:
line = os.readline()
if not line:
break

and use advanced pattern matching mechanisms to
read that as single construct. see the archives for
more info.

(contrary to popular belief, few lines doesn't always
mean better code...)

> GOTCHA: (low)
> Single and double quoted strings can't cross line boundaries.
> You need triple quotes for that!

strings (single and double quoted strings are fully equivalent)
obey the same rule as all other python code: they won't go
over multiple lines, unless you add a backslash to the end of
the line.

print "spam"\
"egg"

works, in other words.

btw, note that Python automatically concatenates string
literals:

print (
"spam"
"egg"
)

> DISSIMILARITY:
> There are no private variables in a module or a class.
> They can always be fully-qualified and accessed from
> without.

unless you use things like Bastion, mxProxy, et al.

and the "__" prefix can be used to get private scoping,
of course.

> GOTCHA: (medium)
> Things that return lists can't be used where a tuple is expected.
> A function that returns a list must be coerced into a tuple to
> use this, though.
> def fn: return [1,2]
> print "this %d is %d here\n" % fn() # ILLEGAL
> print "this %d is %d here\n" % tuple(fn())
> The illegal part points out that this is an
> TypeError: illegal argument type for built-in operation
> Which isn't very helpful.

>
> GOTCHA: (high)
> Python has no manpages! The horror!!!!!!!!!!!!!!!!!!!!!!
> ENODOC

well, since I've hardly ever heard anyone else asking for them.
maybe you could help us out -- I doubt it would be a major
effort to write an "esis2man" converter (look under
Doc/tools/sgmlconv).

> GOTCHA: (low)
> Often Python's error messages leave something to be desired.
> I don't know whether

agreed. they often expose too much technical stuff (how
many python programmers know what a read-only buffer is,
for example). but this is a quite complex issue...

> GOTCHA: (high)
> Because everything is a reference, and there's no way to dereference
> that reference, it turns out that there is no trivial way to copy
> a list! This fails:
> x = [1,2]
> y = x
> Because you don't get a new list there, just a copy to an
> old one. Suggested work-arounds include

it's not a copy. it's just another reference, under a
new name. the target object doesn't know anything
about this...

> y = x[0:]
> y = x[:]
> y = x + []
> y = x * 1
> This forces people to think about references, again.
> So much for lists being first class citizens!

I don't really understand the second sentence here,
but never mind...

> GOTCHA: (medium)
> You can't slice dictionaries at all in Python. In Perl, it's
> easy to slice a hash, and just as sensible.

sensible? what are the semantics?

>
> GOTCHA: (high)
> As we saw with lists, because everything is a reference, and there's
> no way to dereference that reference, this means that again there
> is also no built-in, intuitive way to copy a dictionary.

maybe not intuitive, but:

x = y.copy()

is pretty clear when you see it. as are:

from copy import copy, deepcopy

x = copy(y)

note that all the above return shallow copies. if
that's not what you want, use deepcopy instead.

> Instead,
> the suggested work-around is to write a loop:
> new = {}
> for key in old.keys:
> new[key] = old[key]
> But this is guaranteed slower, because it's not at the C level.
> It also shows that dictionaries aren't first class citizens in python
> as they are in Perl:

now he does that again. what's your definition of "first
class citizen"? is Python objects disqualified just because
the (virtual) common class ancestor doesn't implement a
standard "copy" method?

> GOTCHA: (medium)
> Importing a variable only gives you a local copy. In Perl, it makes
> two names for the same object.

as in Python.

it's the assignment statement that doesn't work as you think.
look again...

> GOTCHA: (low)
> List objects have built-in methods, like
> l.append(x)
> But string objects don't. You have to import
> from the string module to get them, and then they're
> functions, not methods.

this will most likely change in 1.6 (which introduces
Unicode strings, among other things).

> GOTCHA: (low)
> You have insert and append methods for lists, but only
> a del function. Why is it a function not a method, and
> why isn't it spelled out? Apprently the fashionable way
> to do this is now
> a[2:3] = []
> Which of course, deletes only one element. ARG.

del a[2]

(del can affect the active namespace, which is
why it's a statement and not a function).

there's also a remove method, of course, but that's
a slightly different thing.

> GOTCHA: (medium)
> The expression 3/4 is 0, which is false. In Perl, 3/4 is 0.75,
> which is what you'd expect.

depends on who you are, as earlier threads on this topic have
shown. on the other hand, I'm pretty sure Guido won't make
this mistake the next time he creates a new language ;-)

fwiw, my copy of perl refuses to answer, though. maybe
it's broken?

[fredrik@brain tools]$ perl
3/4


^D
[fredrik@brain tools]$

> GOTCHA: (low)
> Regexes default to emacs style, not egrep style! Gads! This is
> surprising to anyone except an emacs weenie. Sigh. And just *try*
> to read the manpage on the differences based on passed in arguments
> establishing the style. There aren't any manpages! Have a nice day.

$ lynx www.python.org/doc/current/lib/module-re.html

obviously, there are more perl weenies out there than
posix weenies...

> GOTCHA: (low)
> An out-of-bounds list reference raises an "IndexError: list index out
> of range" exception, but not if you use a slice to get at it!
> t = range(5)
> print t[2:17]
> [2, 3, 4]

yup. a slice is not a given set of elements. quoting
the language reference:

a[i:j] selects all items with index k such that i <=k < j.

which is exactly what's going on here...

> GOTCHA: (medium)
> Anything that python doesn't like, it raises an exception about.
> There is no fail-soft. Even non-exception issues raise exceptions.
> It's pervasive. K&P curse languages that force people who want
> to open() a file to wrap everything in exception code, saying that
> "failing to open a file is hardly exceptional".

and accordingly, the world if full of programs
that does something like:

fh = open(backupfile, O_APPEND|...)
write(fh, data)
close(fh)

remove(originalfile)

btw, if you don't want open to raise an exception, use
os.path.exists to test for the existence (better test be-
fore than after, as we all know).

if you do this, you'll still get an exception sometimes, but
only under exceptional circumstances!

(Who's K&P? Kuchling and Peters?)

> GOTCHA: (medium)
> You can't just interchange tuples and lists in python the way
> you can lists and arrays in Perl. This is an error:
> import sys # otherwise, no argv for you, buddy
> print "First arg %s and second %s" % sys.argv[1:3]
> because you need
> print "First arg %s and second %s" % tuple(sys.argv[1:3])

this is changing, as more code is starting to use the
abstract API.

on the other hand, there's a reason why the string
formatting operator is picky about this. consider this:

> print "Arguments are %s" % sys.argv[1:3]

and then think a while about how things would work
if you'd replace sys.argv[1:3] with a user defined object,
and changed the string formatting operator to accept
any sequence object.

> GOTCHA: (low)
> sort and reverse are in-place. This leads to verbose code, such as:
> old = [1,2,3]
> new = old
> new.reverse()
> Likewise for sort.

http://www.python.org/doc/FAQ.html#6.20

> GOTCHA: (low)
> You have to compiled the definition for a function before you may
> compile the call it. This is ok
>
> def fn():
> print "hi"
> fn()

this places something called "fn" in the current namespace (the
global one, if you run that code as is), and then refers to it.

> But putting the fn() call first:
> fn()
> def fn():
> print "hi"
> Produces the ever helpful:
> NameError: fn
> error message.

and this attempts to refer to something called "fn" in the current
namespace, which doesn't exist.

> So much for autoloading.

what's autoloading gotta do with it?

here's how things really work:

1) Python compiles the *entire* module into byte codes.
2) Python *executes* that byte code in the module's name space

when you execute "fn()", Python looks for something
called "fn" and calls it (where fn could be a function,
a class, a bound method, a lambda expression, or a
callable object instance).

when you execute "def fn", Python sets "fn" to point
to a function object.

(yes, def's a statement, looking a lot like if and while et. al.,
and behaving a lot like assignment and import).

> ADDENDA: It turns out that def() happens *AT RUN TIME* in python.
> That's the root of this problem. In Perl, a sub{} is a compile-time
> thing.

python's a dynamic language, you know ;-)

> GOTCHA: (low)
> When you need to make an empty copy of the same type, you write
> x = y[:0]
> So much for being typeless. Sigh.

sorry, I don't understand that comment...

(maybe because Python's not a typeless language. objects
are strongly typed, but name don't imply types; a name can
refer to different kinds of things at different times...)

> SIMILARITY:
> Python uses None in many places where Perl uses undef().
> But not all. You can't over-subscript an array and get
> away with it.

and unfortunately,

None, spam = 1, 2

doesn't really do what you would expect...

</F>


Fredrik Lundh

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Jeremy Hylton <jer...@cnri.reston.va.us> wrote:
> I did think about this before I jumped, but it still seems fair to
> jump. As a possible counterexample to the "if it don't have manpages
> it don't exist" argument, I would suggest the C programming language.
> I don't believe there are manpages that describe the language itself,
> yet I found it (relatively) easy to learn. The K&R C book is mighty
> fine.
>
> It's also worth noting that the old Lutz book is a little like the
> pre-ANSI K&R C book. You're not going to find ANSI changes in the old
> K&R, and you're not going to find Python 1.5 info in the old Lutz
> book. In neither case does that mean the improvements don't exist.

as an aside, it's a bit sad that Tom didn't read the book's
preface, where Mark says, among other things:

"... It's Not a Reference Manual ... This book is more like
a tutorial than a reference manual. ... this book doesn't
replace Python's reference manuals. If you want an ex-
haustive list of language rules, the manuals do the job ...
the manuals can be used to supplement the material
here, if needed ..."

on the other hand, Webster says a "manual" is "a book that
is conveniently handled," so maybe Mark should have used
the word "handbook" to be on the safe side ;-)

</F>


Ian Clarke

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to

> Ah, have you discovered rlcompleter yet? Put this in your ~/.pythonrc:
>
> import rlcompleter
> readline.parse_and_bind('tab: complete')
>
> set PYTHONSTARTUP=~/.pythonrc and then in python type:
>
> d={}

Is there any way to get this working on Windoze?

Ian.

Patrick Bogaart

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Jeff Blaine wrote:
>
> >GOTCHA: (low)
> > You can't use "in" on dicts. Instead, you must use
> > d = { "fred":"wilma", "barney":"betty" }
> > if d.has_key("fred"): # legal
> > if "fred" in d: # ILLEGAL
> > I don't understand why this was done.
>
> I'm very curious what would you think should be legal.
>
> Would 'in' (when used on a dict) search the keys, values, or both?
>
> Each one of those seem like a bad idea to me. You have 2 separate
> areas containing data. Searching each of those individually
> (has_key()...) seems right to me.

If you need to search *both* data areas,
why not do it the obvious way, then?:

d = { "fred":"wilma", "barney":"betty" }

if "fred" in dict.keys(): # legal, and true
if "wilma" in dict.values(): # also legal, also true

logic: dictionaries do have a "has_key()" methods, but no "has_value()"
method
drawback: keys() and values() create copies of the dict's list of keys,
values,
so has_key() is much faster..

--
Patrick W. Bogaart
Department of Geomorphology and Quaternary Geology
Faculty of Earth Sciences, Vrije Universiteit Amsterdam
bo...@geo.vu.nl http://www.geo.vu.nl/users/bogw

Michael Hudson

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to

Not that I know of; there is a port of readline to Windows (or at least I
found a reference to one last time I looked) but I don't know how much
work would be involved in getting Python to play nice with it.

Or Pythonwin could be modified to include such a feature. Now idea how
much work that would be either.

(Tab completion (nad I guess readline editing features in general) is the
main reason I still use the interpreter over idle.)

HTH,
Michael


Tim Peters

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to Tom Christiansen
[posted & mailed]

[tchrist, discovers that Python "def" is executable, and notes that
this is a gotcha for Perl programmers]

[Tim, notes that Perl's "sub" is equally a gotcha for Python programmers]

[back to tchrist]


> You didn't localize your function! Remember, in Perl things
> are only local if you say they are.

But it doesn't matter, Tom <0.5 wink>: the "gotchas" you identified in
Python are things that would throw a Perl programmer if they hadn't read and
understood the Python docs first. Perl is at least equally as surprising to
the Python programmer who hasn't read and understood the Perl docs first (as
the self-proclaimed Pythoneers who flame on c.l.p.m. prove more than often
enough).

[and where I had
sub inner sub { ... },
do instead]
> ...


> That could have been like this:
>
> sub outer1 {
> my $x = 50;
> local *inner = sub {
> print "in the first inner, and here's x: $x\n";
> };
> &inner();
> }

No problem, but that's (symbol table globbing) a *real* stretch for someone
just learning the language. There are real barriers for native speakers of
either language in picking up the other.

I ended up doing something like this instead:

sub makefac {
my $fac;
$fac = sub {
my $n = shift;
return 1 if $n < 2;
return $n * &$fac($n - 1);
};
return $fac;
}

my $i;
for ($i = 0; $i < 1000000; ++$i) {
my $fac = makefac;
my $n = &$fac(3);
print "$n ";
}

This one is more interesting than it looks <wink>: in the last version of
Perl I tried it on, it leaked memory at a prodigious rate. The reason it's
interesting is because it's faking pretty much what Python would have to do
to support lexical closures, given that a nested "def" acts exactly like an
assignment statement binding a name local to its containing function (and
here an anonymous sub is assigned to a lexical local of *its* containing
function).

In Python and in Perl (at least in the Perl I last tried that under) that
creates cyclic garbage: makefac's lexicals have to contain a binding for
fac, and fac has to point back to makefac's lexicals in order to resolve
up-level references. And that's (unrecoverable trash) the reason Python
doesn't have lexical closures today. If a nested def were-- as my original
nested "sub inner" is in Perl --treated as global, that problem would go
away, and for the same reason it does in Perl. But it wouldn't be Python
anymore either <wink>.

> ...


> BTW, you should have gotten a bucket of frightened warnings out of
> the compiler about that.

I got strong indications of trouble with -w, yes.

[examples of great msgs produced by
perl -wc
and
perl -Mdiagnostics -wc
]

> ...


> BTW, see what I mean about the importance of good error messages?

No argument from me that Perl's msgs are often very helpful, much more often
pinpointing a problem than Python's (the "runaway multi-line string starting
at line nnn" is one Python should steal!). On the other hand, I've written
a few Klines of production Perl too, and my experience is that Perl has so
many more syntactic and semantic gotchas than Python that the language would
be nearly unusable without great msgs. Python's NameError may drive you
nuts, but it's the same as Perl's runtime "use of uninitialized value" --
and Perl is no more help in tracking down the *cause* of those than is
Python in cracking a NameError. At least Perl's -w warns about names that
appear only once! You have to grab a copy of PyLint for that (but then you
are a fan of separate tools, right <wink>?).

[various ways to promote warning into errors, "if you feel all
warnings should kill you"]

Whereas Python has no warnings of any kind -- it it's irked enough at me to
complain at all, it's irked enough to kill me. In that it's a faithful
reflection of Guido's personality <wink>. Seriously, I do prefer that.

> ...


> You know, it occurs to me that it might be nice to be able to
> selectively promote only compile-time warnings to fatals.

As a native speaker of Python, -w and "use strict" decorate all my Perl, and
in the few Official Perl projects I've been on "NO WARNINGS!" was an
absolute rule. The more fatals the better.

> Perl does a lot of compile-time stuff (including constant
> expression folding, inlining of some subroutines, and folding
> of those results!).
>
> What does Python do at compile-time?

It's too busy desperately scrounging for excuses to kill your program with a
bogus SyntaxError to do anything useful <wink>. About the only compile-time
optimization is that function locals (in the absence of "exec" and "import
*" statements) are mapped to consecutive indices into a contiguous runtime
vector.

"exec" and "import *" can alter the *set* of local names, so their presence
inhibits that optimization. That's why "exec" is a stmt rather than a
function: since no builtin names are resolved at compile-time, and any name
may be bound to any object at runtime, if exec were a function Python
couldn't know that

exec(s)

does refer to the builtin "exec", or that

f(s)

*doesn't*, so the local-var optimization would be crippled almost always.
So "exec" is a keyword, the only kind of word whose meaning is known for
sure at compile-time.

Python's default arguments are sometimes used to fake lexical closures, but
they're also used to fake the effect of compile-time binding; e.g., because
def *is* executable, when Python (at runtime) gets to

def somefunc(x, int=int):
... = int(...)

the local name "int" gets bound to whatever-the-heck the global name "int"
is bound to at the time the def is executed. Of course it *is* bound to the
builtin int function, but Python can't know that at compile-time. This
trick lets the programmer force the issue, and within somefunc the "int"
lookup is very fast (just a C indexed array ref); without this trick each
dynamic instance of "int" in somefunc does a failing lookup in the global
dict first, and then a successful lookup in the builtin dict.

So, no matter what anyone here tells you, Perl doesn't have a monopoly on
being cute & repulsive at the same time <0.8 wink>.

takes-one-to-know-one-ly y'rs - tim


Alex Maranda

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
> > So much for being typeless. Sigh.
Tom, you might have done reasonably well the rest of your Python
homework, but that is a very dumb statement. Tcl is typeless. Python is
rather strongly typed and proud with that. The fact that the type
checking is done at run-time might admittedly screw the minds of C/C++
guys. And optional static typing (ala Dylan) is planned for Python 2.0.

Regards,
Alex

Florian Weimer

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Tom Christiansen <tch...@jhereg.perl.com> writes:

> >Try reading the docs...
>
> Thanks for nothing: there are no manpages.

Manpages are most useful for languages which do not support namespaces
(so you can hit `K' or `M-x man RET RET', and you get the right page).
Perl fits into this more than Python (which heavily uses methods on
builtin objects). Unfortunately, `man exists' (or `perldoc exists')
doesn't work with my Perl installation either, so I don't see why it
makes that much sense to have any manpages.

In addition, it's a PITA to search for a specific function in the
`perlfunc' manpage because the entries aren't marked at all. You have
to prepend a few spaces to the function name and search for that,
otherwise you might get too many references in the descriptions of other
functions. I must admit that personally, I like Python's structured
Info documentation much better.

Tom Christiansen

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
"Tim Peters" <tim...@email.msn.com> writes:
:There are real barriers for native speakers of


:either language in picking up the other.

What do you think falls into this category? What thing
about Python makes it hard for a native speaker thereof
to learn Perl, and vice versa?

[massive closure generator deleted]

:This one is more interesting than it looks <wink>: in the last version of


:Perl I tried it on, it leaked memory at a prodigious rate.

Absolutely. You've a circular reference there.

:The reason it's


:interesting is because it's faking pretty much what Python would have to do
:to support lexical closures,

I'm not sure why you say "faking".

:In Python and in Perl (at least in the Perl I last tried that under) that


:creates cyclic garbage: makefac's lexicals have to contain a binding for
:fac, and fac has to point back to makefac's lexicals in order to resolve
:up-level references. And that's (unrecoverable trash) the reason Python
:doesn't have lexical closures today.

That's quite right. Doesn't python have some similar issue related
to the use of bound methods?

:Whereas Python has no warnings of any kind -- it it's irked enough at me to


:complain at all, it's irked enough to kill me. In that it's a faithful
:reflection of Guido's personality <wink>. Seriously, I do prefer that.

perl -w is "pardon me, but are you really sure you know what you're
doing there?", it's not "die die die, you ignorant script kiddie!".

:As a native speaker of Python, -w and "use strict" decorate all my Perl, and


:in the few Official Perl projects I've been on "NO WARNINGS!" was an
:absolute rule. The more fatals the better.

That's how I virtually always programmed it. Sometimes I don't bother
on little one-liners that turn Perl into Super Sed, like

perl -i.orig -pe 's/^(\d+)/$1 + $./e' file1 file2 file3
# add current line number to each number that occurs at
# the front of a line, and put changes back in place,
# backups into file.orig

But real programs get -w and use strict always. After all,
just as with /* Lint Happiness */ of days of old, I know
how to temporarily rescind them if I really am convinced
that I really do know what I'm doing.

:> What does Python do at compile-time?


:It's too busy desperately scrounging for excuses to kill your program with a
:bogus SyntaxError to do anything useful <wink>. About the only compile-time
:optimization is that function locals (in the absence of "exec" and "import
:*" statements) are mapped to consecutive indices into a contiguous runtime
:vector.

You, Tim, might someday look at the interesting tricks that the Perl
compiler and interpreter go through about storage, speed, and tacit reuse
of my() variables (lexically scoped locals). Remember that my() in Perl
is one of Perl's four declarations, something then that the *compiler*
knows about, and can take suitable actions based up static analysis.

(And I nearly never mean the (C or byte)-code-generating backends when
I say "compiler" in a Perl context. I just the guy who does the parsing
in the previous paragraph.)

I remember my frutration as a flaming C advocate (you didn't really
think I started with Perl, did you? :-) getting a job at a company
that made US$75k Fortran compilers being told that Fortran would always
be faster than C because the fc compiler could know more things about
your code than the cc compiler could, and thus make better compile-time
optimization to speed run-time. I wonder whether Python simply hasn't
matured as far as Perl has along those lines, or whether in fact there
are inherent barriers, as there are between Fortran and C. What do you
think? I also notice that Python is bereft of compiler pragmata.

:"exec" and "import *" can alter the *set* of local names, so their presence
:inhibits that optimization.

Aren't you glad you don't have Tcl's "upscope" naughtiness?
People sometimes ask for this in Perl, to be able pop up a level
into your dynamic caller's private lexical scope? I'd rather have
pass-by-name. :-)

:So, no matter what anyone here tells you, Perl doesn't have a monopoly on


:being cute & repulsive at the same time <0.8 wink>.

Oh, I know. It's the new converts who are scariest. The adage that
one should "beware the man of one book" becomes "beware the programmer
of one language" in our world, or should that really be "the zeal of
fresh converts burns annoyingly"? :-)

--tom
--
Timesharing: the use of several people by the computer

Tom Christiansen

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
"Fredrik Lundh" <fre...@pythonware.com> writes:
:as so often before, Tom ran out of positive energy and


:started posting stuff like:
:> You seem to be looking for a fight. Please say nothing
:> at all if that's all you want to do.

Thank you for your constructive encouragement and enthusiasm.

Like most people, I do not take kindly to digs. Would that
I were so patient as thou.

--tom
--
"A young man who is not a radical about something is a pretty poor risk
for education."
- Jacques Barzun

Tom Christiansen

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
Florian Weimer <f...@s.netic.de> writes:
:Manpages are most useful for languages which do not support namespaces


:(so you can hit `K' or `M-x man RET RET', and you get the right page).
:Perl fits into this more than Python (which heavily uses methods on
:builtin objects). Unfortunately, `man exists' (or `perldoc exists')
:doesn't work with my Perl installation either,

I really hate that. You're right about perlfunc being insanely long.
I've always argued against it, and there's a script in the distribution
kid that *will* create things like /usr/local/perl/man/man3/exists.3,
but I haven't managed to get my lobbying power worked up enough to push
through to make that the default.

--tom
--
"If you don't know where you are going, any road will take you there."
Lewis Carroll, "Alice in Wonderland".

Florian Weimer

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Tom Christiansen <tch...@mox.perl.com> writes:

> GOTCHA: (low)
> Regexes default to emacs style, not egrep style! Gads! This is
> surprising to anyone except an emacs weenie. Sigh. And just *try*
> to read the manpage on the differences based on passed in arguments
> establishing the style. There aren't any manpages! Have a nice day.

That's no longer true. There's now a regular expression module
in the standard distribution based on the PCRE library which uses
Perl-compatible regular expressions (with some very helpful extensions,
like named groups).

Tom Christiansen

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
"Fredrik Lundh" <fre...@pythonware.com> writes:
:as an aside, it's a bit sad that Tom didn't read the book's


:preface, where Mark says, among other things:

It's a shame that so many of you should be so unbelievably harsh on me
when *I'm* the one who with malice toward none and full of revulsion
at the flames causes by *YOUR* community's ignorant attacks on mine,
that *I* made the honest effort to learn *YOUR* language, and that I
furthermore for your benefit not my own then took the additonal trouble
to write-up my experiences and observations gleaned while five hundred
miles away from the nearest tree or internet link.

And for that, I am abused for my candor and effort in trying to convey
to you what that process was like for me.

Shame on you!

Don't you understand your gain? How dare you punch a gifthorse in the
mouth--repeatedly? If these petty slams and disdainful arrogances are the
kind of response typical of your community, this bodes not well for you.

But no, that's not it. It's just Usenet, the place where condescension,
conceit, and cruelty all come far too easily. The more the pissier,
you know. I'll try to keep that in mind as I continue to attempt to
sift through this dreck to find the gems.

--tom
--
"I will always write it the second way, so if you're optimizing for
contrariness, it's obviously better to do it the second way."
--Larry Wall

Tom Christiansen

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
[courtesy cc of this posting mailed to cited author]

In comp.lang.python,
Alex Maranda <amar...@spider.com> writes:
:> > So much for being typeless. Sigh.
:Tom, you might have done reasonably well the rest of your Python


:homework, but that is a very dumb statement. Tcl is typeless. Python is
:rather strongly typed and proud with that.

I'm just reporting what I've read. I wasn't aware that Mark Lutz was
considered a spreader of fictions. I'd swear his book used that phrase
a lot. I agree that dynamically typed is more sensible a term.

--tom
--
Perle, plesaunte to prynces paye/ To clanly clos in golde so clere,
Oute of oryent, I hardyly saye/ Ne proued I neuer her precios pere.

Michael Hudson

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
On 20 Aug 1999, Tom Christiansen wrote:
> In comp.lang.python,
> "Tim Peters" <tim...@email.msn.com> writes:
> :In Python and in Perl (at least in the Perl I last tried that under) that

> :creates cyclic garbage: makefac's lexicals have to contain a binding for
> :fac, and fac has to point back to makefac's lexicals in order to resolve
> :up-level references. And that's (unrecoverable trash) the reason Python
> :doesn't have lexical closures today.
>
> That's quite right. Doesn't python have some similar issue related
> to the use of bound methods?

Not in the simple case, no.

I take it you're thinking a bound method has a reference to the instance
which has a reference to the method? That's not the case, for, if you have
a class like this:

class Account:
def __init__(self,amount):
self.amount = amount
def withdraw(self,amount):
self.amount = self.amount - amount

then executing

W=Account(50).withdraw

gets you a bound method which has a im_self member which refers to an
Account object which has a __class__ member which refers to the Account
class which has a __dict__ member which contains a function "withdraw" (as
in plain Python function).

(with apologies to the authors of sicp for using that example yet again,
and to all concerned for the length of that previous sentence).

>>> Account(50).withdraw.im_self.__class__.__dict__["withdraw"]
<function withdraw at 87cd30>

No cycles, see?

internally-y'rs
Michael


aaron_...@my-deja.com

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
In article <001301beeacf$9819a560$712d2399@tim>,

"Tim Peters" <tim...@email.msn.com> wrote:
> [tchrist]
> >> GOTCHA: (medium)
> >> Slices in Python must be contiguous ranges of a sequence.
> >> In Perl, there's no such restriction.
>
> [Michael Hudson]
> > At some point Python will probably support `extended slice syntax'
> > like so:
> >
> > range(0,10)[1:4:2] => [1,3]
> >
> > Numerical Python already does this.
>
> [tchrist]
> >> GOTCHA: (medium)
> >> You can't slice dictionaries at all in Python. In Perl, it's
> >> easy to slice a hash, and just as sensible.
>
> [Michael Hudson]
> > Huh? What would that mean? There's no reason to suspect that the
keys
> > of a dictionary are ordered.
>
> What Tom calls "slicing" here the NumPy folk would call gather/scatter
> subscripting. A list can be used as an index, e.g.
>
> thing[[7,2,3]] == [thing[7], thing[2], thing[3]]
>
> Perl has something like that; Python does not.

All of these things of course can be implemented using the
various python meta-hooks either at the Python or the C level.
They aren't intrinsic limitations of the Python interpreter,
just limitations of the standard dictionary/list/tuple
implementations.

BTW, kjbuckets.kjDict's have a method called "dump" (with a dual
kjUndump function) where

D.dump((x,)) --> D[x]
D.dump((x,y,z)) --> (D[x], D[y], D[z])

Gadfly uses these features to quickly pack/unpack data in/out
of dictionary format either for indexing or archiving.

I really think you should get kjbuckets, Tom, it sounds like it's just
what you need for the Python app you are apparently working on. :)

Aaron Watters http://www.chordate.com

===

I forgot my mantra.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Fredrik Lundh

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Tom Christiansen <tch...@mox.perl.com> wrote:
> Don't you understand your gain? How dare you punch a gifthorse in the
> mouth--repeatedly? If these petty slams and disdainful arrogances are the
> kind of response typical of your community, this bodes not well for you.

as one of the more prolific posters on this list/group, and
one who reads lots of other python lists, and speaks to many
python newbies both via mail and in person, I can assure you
that you are not behaving like the typical Python newcomer
in any fashion whatsoever. it's okay to be different, but the
"I'm better, and you folks are not really worthy" stuff won't
get you nowhere. face it: you're not, and we are. calming
down a little may help you realise that.

on the other hand, since I don't know you in person, and
since the followups I quoted in an earlier post (as well as
the mails I recently found in my mailbox) didn't match the
positive tone and the content of your original post, I can
only hope that it's someone else who has hijacked your
computer.

> The more the pissier, you know. I'll try to keep that in mind as I continue
> to attempt to sift through this dreck to find the gems.

good luck!

</F>


Per Kistler

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Robert Kern wrote:

> Lack of man-hours. Fred's the only person (AFAIK) who is officially
> working on the docs. Doing the rest takes volunteers (hint, hint).
> :-)

If I'll ever proceed to a presentable state, I might do some docs,
but now it's much too early.

-Per.
--
Per Kistler kis...@fnmail.com / kis...@gmx.net
------------------------------------------------------------

Per Kistler

unread,
Aug 20, 1999, 3:00:00 AM8/20/99
to
Fredrik Lundh wrote:

> comp.lang.python is not your ordinary usenet. please read
> the comp.lang.python posting guidelines before you post more
> crap like this. this is not comp.lang.perl.misc.

In a way it's pleasing, that Tom invests his time in Python
usnet. It revealed to me a lot about the state of the scripting
community, which could be a motivator for a change in some parts,
and it also showed some real technical stuff.

It is a fact in real life, that programmers of some kind are
extremely occupied with their ideas. These ideas are mostly
very good. For me it was always natural to use different tools
for reaching a goal. Only if one knows about the ideas of
others, one can incorporate them.

A clash at first, is quite normal, because many experienced
pains, when they were forced to use a differnt language against
their will, or were even compelled to read someone elses
code in an alien language.

What I personally would like now, is a usnet discussion
between Larry Wall and Guido van Rossum, and they would swear,
not to use any flames. If that would produce enough good and
copious pages, one could even publish it as a book, make many
people happy, and finally make some money:-)

Regards, Per.

It is loading more messages.
0 new messages