Python's "only one way to do it" philosophy isn't good?
arkanes at gmail.com
Mon Jul 9 15:23:47 CEST 2007
On 7/6/07, Douglas Alan <doug at alum.mit.edu> wrote:
> "Chris Mellon" <arkanes at gmail.com> writes:
> > Sure, but thats part of the general refcounting vs GC argument -
> > refcounting gives (a certain level of) timeliness in resource
> > collection, GC often only runs under memory pressure. If you're
> > saying that we should keep refcounting because it provides better
> > handling of non-memory limited resources like file handles, I
> > probably wouldn't argue. But saying we should keep refcounting
> > because people like to and should write code that relies on implicit
> > scope level object destruction I very strongly argue against.
> And why would you do that? People rely very heavily in C++ on when
> destructors will be called, and they are in fact encouraged to do so.
> They are, in fact, encouraged to do so *so* much that constructs like
> "finally" and "with" have been rejected by the C++ BDFL. Instead, you
> are told to use smart pointers, or what have you, to clean up your
> allocated resources.
For the record, C++ doesn't have a BDFL. And yes, I know that it's
used all the time in C++ and is heavily encouraged. However, C++ has
totally different object semantics than Python, and there's no reason
to think that we should use it because a different language with
different rules does it. For one thing, Python doesn't have the
concept of stack objects that C++ does.
> I so no reason not to make Python at least as expressive a programming
> language as C++.
I have an overwhelming urge to say something vulgar here. I'm going to
restrain myself and point out that this isn't a discussion about
> >> > Relying on the specific semantics of refcounting to give
> >> > certain lifetimes is a logic error.
> >> >
> >> > For example:
> >> >
> >> > f = some_file() #maybe it's the file store for a database implementation
> >> > f.write('a bunch of stuff')
> >> > del f
> >> > #insert code that assumes f is closed.
> >> That's not a logic error if you are coding in CPython, though I agree
> >> that in this particular case the explicit use of "with" would be
> >> preferable due to its clarity.
> > I stand by my statement. I feel that writing code in this manner is
> > like writing C code that assumes uninitialized pointers are 0 -
> > regardless of whether it works, it's erroneous and bad practice at
> > best, and actively harmful at worst.
> That's a poor analogy. C doesn't guarantee that pointers will be
> initialized to 0, and in fact, they typically are not. CPython, on
> other other hand, guarantees that the refcounter behaves a certain
It's a perfect analogy, because the value of an uninitialized pointer
in C is *implementation dependent*. The standard gives you no guidance
one way or the other, and an implementation is free to assign any
value it wants. Including 0, and it's not uncommon for implementations
to do so, at least in certain configurations.
The Python language reference explicitly does *not* guarantee the
behavior of the refcounter. By relying on it, you are relying on an
implementation specific, non-specified behavior. Exactly like you'd be
doing if you rely on the value of uninitialized variables in C.
> There are languages other than C that guarantee that values are
> initialized in certain ways. Are you going to also assert that in
> those languages you should not rely on the initialization rules?
Of course not. Because they *do* guarantee and specify that. C
doesn't, and neither does Python.
More information about the Python-list