More random python observations from a perl programmer

Tom Christiansen tchrist at mox.perl.com
Thu Aug 19 20:38:25 CEST 1999


     [courtesy cc of this posting mailed to cited author]

In comp.lang.python, 
    Michael Hudson <mwh21 at 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




More information about the Python-list mailing list