Newest release issues (was: Nested Scopes)

thelazydogsback at my-deja.com thelazydogsback at my-deja.com
Mon Feb 5 23:56:15 EST 2001


In article <p6qbsskrng5.fsf at informatik.hu-berlin.de>,
  Martin von Loewis <loewis at informatik.hu-berlin.de> wrote:
> thelazydogsback at my-deja.com writes:
>
> > I've seen Py described as both a "scripting language" and
> > "programming language" - I think one could equally read the universe
> > or nothing into these adjectives, but one qualification that comes
> > to mind that may grant a language status in the latter camp is
> > run-time efficiency.
>
> Yes, certainly. However, run-time efficiency does not mean "as fast as
> possible".

Agreed. (Notice I haven't asked about producing native code...)

>
> > In evaluating Py I was surprised that apparently the compiler
> > creates code such that in "f(x)" the binding for "f" is looked up in
> > a dictionary every time "f" is executed. (E.g, even in
> > "for...for...f(x)") This seems very slow
>
> That conclusion is incorrect - dictionary lookups are very fast in
> Python. By the same token, you might argue that virtual functions in
> C++ and Java are very slow, because an access to the virtual function
> table is necessary.

Actually, I wouldn't argue that. :) As I  understand it, a C++ compiler
analyses namespaces and the class hierarchy at compile-time, so a
virtual method call is a simple indirection with a known offset into
the vtable. (I.e, virtual foo(x,y) is always ((obj->vtable)[36])(x,y) )
A dynamic dictionary lookup (string hash + dealing w/collisions, or the
dict algol of your choice) will be a lot slower. (Again, if I'm wrong
here, I'd like to know.) (I guess if you're using an interned symbol
rather than a plain string, the hash fn would not be necessary, but
you'd still have to do the lookup.)

> > and allows the (dubious, IHMO) flexibility of allowing "f" to be
> > re-bound at will, even given the "static" nature of the syntax. I
> > would think that "f(x)" (calling a function that you assume to be
> > bound to a single fn object for the duration) is such a common
> > metaphor that the defualt would be to do all one could to optimize
> > for this case.
>
> Be assured - all that can be done has been :-)

I don't necessarily beleive that - but then again, I don't expect it
either. Certainly a lot of rocket science (at compile-time and run-
time) could produce global and local optimizations that have not been
applied yet - but this stuff is really hard to do and may not be worth
it.

> > If the user really wants the flexibily of "f" to be re-bound, (s)he
> > should be forced to lookup the reference and call apply() (or
> > similar) explicitly - this usage is also far more descriptive of the
> > actual effect.
>
> That would be a change in the language. Another aspect to qualify as a
> programming language is that programs that use it should not break
> with new releases - atleast the majority should not. Your proposed
> change likely breaks more programs than acceptable.

Really? I'd expect that most programs (and programmers) expect names
representing functions in a particular scope to remain bound to the
same fn obj for the duration of the scope's activation. Is there a
prevailing Python coding paradigm that goes against this princpal?

> > Anyway... I was wondering if the new "nested scope" (2 pass?)
> > compiler did anything differently as far as late vs. earlier binding
> > of the fn obj.
>
> No, it still works the same way: accessing a global means a dictionary
> lookup.

Hmm... Maybe that's a good reason to use functions defined in a nested
scope when possible - if they are treated as (faster) locals. (Then
again, I think that the new scoping w/o decls is potentially confusing -
 I'd
love to see optional decl's in Python. (Whether they're typed is
another question.) The rule could be as simple as
(?): if you want simple module/fn level scoping, do what you do now,
and if you want to use nested lexical scoping, use decls.)

> > On a related note, on "weak references" w.r.t. gc(), I thought
> > cycles have been collected correctly for a few versions now?
>
> Sure, since 2.0. However, there are cases where objects are still kept
> alive by the application when they really should go away. The typical
> case is a cache: to speed-up access to some object, you cache it in a
> dictionary. That makes the cached object life, even if the cache holds
> the last reference. With weak references, the object will go away if
> the only reference to it is from the cache.
>
> In addition, if you produce cycles, the objects participating in the
> cycle will go away only when the collector runs. If you want to clear
> them as soon as the last "external" reference to the structure is
> released, you should use weak references. E.g. in a tree, you could
> make parent link weak. That way, the tree will go away once the
> reference to the root is released, as the tree does not contain cycles
> anymore.

Thanks - good explanation. I figured most of that out, but the article
I read mislead me into beleiving that cycles would *never* get
collected w/o the weak refs.

thanks for the reply,
mike

ps -
One interesting idea (?) would be for a dev tool to observe scoping
rules
during coding and add "shadow decls" in the form of comments at the
level appropiate, so the use of a var that creates new scope would
create/update the comments in real-time.

> Regards,
> Martin
>


Sent via Deja.com
http://www.deja.com/



More information about the Python-list mailing list