Why "from __future__" stinks; a counter-offer

Tim Peters tim.one at home.com
Sun Mar 18 23:21:24 EST 2001


[Carlos Ribeiro]
> Have you ever seen this [deleting obsolete statements] happen in *any*
> sufficiently complex system? I'm afraid we'll be stuck with this
> solution" for a long, long time.

Because __future__.py contains reliable info about the state of various
incompatible changes, it will be easy to automate removing obsolete
future_statements; future_statements were deliberately designed so that
extraordinarily simple tools can be written to do this.  If you don't want
to, fine, but you can't sell me the idea that there will be anything other
than sloth preventing it.  This one was designed from the start to be easy to
get rid of.

[Tim]
>> ... in the absence of a competing PEP it's certain  to remain as
>> it is, and the last 2.1 beta release is scheduled for this coming
>> Friday (as>noted in PEP 226)

> So thats the matter? Forgive me, I'm pretty new on this list and I may be
> missing something. The lack of a PEP... this sound too much like
> design-by-comitee to me.

A PEP is "merely" a spec.  Without a spec, people don't really know what's
under discussion, and implementers don't know what to do.  You can rail
against the future_statement because nothing about is hidden:  there's a PEP
that describes it in detail.  The alternatives remain amorphous for lack of a
PEP, and into that lack of detail some people project the fulfillment of
their wishes.  Spell *anything* out in full and complaints zoom.

> I agree with the *intent* of the PEP - to keep  everything nice and
> documented, and to put some order into the process.  However I feel that
> in this case it sounds as a lazy excuse for not thinking about a better
> to solve the problem.

Sorry, but we don't have unbounded time.

> It's something like "the PEP is everything, lets follow the PEP as-is".

Yes indeed!  The spec *is* everything, and even Guido has to write PEPs.

> Why is it so difficult to write or change the existing PEP?

Don't look at me:  I gave up a night of sleep to write the future_statement
PEP, and I'm happy with it.  Since it's "good enough" in my eyes, I'm not
going to give up another night of sleep to dream up alternatives; the PEP I
wrote was already my best stab at solving the specific problem I wanted to
solve.  If somebody else wants to, great.

> ...
> You are right - the message is important, and this is one of the most
> compelling reason to abandon "import from __future__". It does send the
> wrong message - in fact it does not make any sense (if you were talking
> about "import quantum computing", that's in the future :-).

Then I suggest you either haven't read the PEP, or the PEP is unclear.  When
I do

    from __future__ import nested_scopes

at the top of a file today, what I'm saying in full is:

    I want to use nested scopes in this module, and I'm writing it
    using a compiler earlier than 2.2.  2.2 doesn't exist yet, and
    nested scopes do not become the rule until that (future) release.
    So now-- under 2.1 --I have to ask for it.  When 2.2 is released, I
    can get rid of this.

> And don't let me get started on the relativity aspects, because the
> "future" is not an  absolute, defined state - it's going to be
> differente for every release.

Of course.  What of it?  When 2.2 comes out, I'll run a cmdline tool to nuke
that subset of my future_statements that are no longer needed.  For people
who take copies of my code before that point and use them under pre-2.2
releases, the future_statements will correctly point out that they need a
future release of the *compiler*.  "future" here is wrt the version of the
language in use, not with respect to your birthdate <0.6 wink>.

> I think that some people got used to the proposed syntax, and as such
> they  dont see anything wrong with it.

I doubt that anyone has had time enough to "get used to" this syntax yet.
Because I wrote the PEP, you can be sure I've seen the most email about it.
Favorable comments outweighed negative about 2 to 1.  That makes it one of
the most popular changes in language history <0.9 wink>.

> ...
> And unfortunately I dont have the resources to grab the source and
> actually *do* something about it, this rant aside.

You don't need to be an implementer to write a PEP.

> Part of my rants are about the name of the module - __future__.py is
> a bad and misleading name in my opinion.

We disagree.

> One alternative would be to call this  module __compiler__.py. It's a
> better name because:
>
> - it is related to the *function* carried out by this module (it
> is handled at compile time, and carries compile-time information)

I agree __future__ doesn't say that, but __compiler__ misses the message that
an incompatible language change is being addressed (and, sorry, but
"incompatible language change" *is* about "before and after" -> time, wrt the
language definition).

> - it has nothing to do with the perception of time

A point against it; see above.

> - it could export other symbols and mappings useful for the script about
> the compile-time environment.

As I said in the msg to which you're replying, I actively want not to
conflate incompatible language changes with general directives.  A
future_statement signals a sea change, it's not just about minor fiddling.

> I dont think that this is a real solution to the problem, but it makes
> it look a little better.

Except for the first point, I think it's worse.

> It is also more consistent and has some prospect of being extensible.

I actively want future_statements not to be extensible.  This mechanism is
directed at a specific task, and one that's quite unlike any other in that it
addresses incompatibility across releases, a prospect so dreadful that it
deserves a unique mechanism.

> Also it's a easy change to make now without breaking any PEPs or the
> schedule.

Since the future_statement is already implemented, and the assorted people
who did the implementation have a full plate of work already lined up for
this week, there is no bandwidth to change it now unless somebody else
volunteers.  Such is life!  Hard as it may be to believe now, I predict
everyone will survive this.

> OTHER ISSUES & WEIRD IDEAS
>
> 1) A different way to handle the problem is to make the Python compiler
> itself scriptable. However, this is also dangerous, and poses a
> much bigger set of problems. The basic concept is to have a __compiler__
> symbol, pretty much like the __main__ symbol, except that this one is set
> only inside the  compiler. All code inside an if __compiler__: block
> would be executed immediately by the compiler.

Sorry, but I don't see how that addresses incompatible language changes.

> 2) There is something else bugging me. It is not clear what is the effect
> that "from __future__" has on the compiler.

Nor will it ever be:

    from __future__ import xyz

can have *any effect whatsoever* at compile time, depending on xyz.  It
could, for example, treat the rest of the module as Perl6 code, if Guido
decides that this Python experiment was a silly waste of time, and that
Python 3.0 should be identical to Perl6.  It's up to the PEP for xyz to spell
out xyz's compile-time semantics.

> PEP-236 states that this is handled at compile time.

The PEP says that it has both compile-time and runtime semantics.

> However the __future__.py module does exist and has some information in
> it.

Yes, and at runtime the future_statement imports the feature name from
__future__.py (this is explained in the PEP).

> For python applications that get distributed, this has a lot of potential
> side effects. Someone may have the right version of the interpreter, but
> the wrong version of the __future__ module.

Since __future__.py is distributed along with the compiler, you may as well
ask what will happen if someone screws up and gets a wrong version of any
library module.  However, the module __future__.py is a passive repository of
release information, so the worst that can happen in this case is that code
doing introspection on that info will get some wrong info.  That has no
effect on the compile-time semantics, though (they're hardwired into the
compiler).

> ...
> 3) In some time it may become be impossible to tell which subset of the
> language you are using - for instance, from a code snippet.

I expect you mean which *version* of the language is being used.  For
example,

    i = 3/4

*may* not return 0 in some future version of Python, and there is indeed no
way to tell which version is intended from looking at that line in isolation.

> This is *very* important to understand, because we are changing the
> semantics of the language, not the syntax, and it will not be obvious
> from the context of a snippet which "switch" has to be used.

Note that in the case of nested scopes, as soon as 2.2 comes out there is
*no* switch to restore 2.1 behavior.  This characteristic is common to all
uses of a future_statement.

> (We have to concede that this is going to be a problem whenever there
> is any semantic change - it is just impossible to avoid).

Sure, and it's just as true of changes to what assorted library modules do.
Not unique to incompatible language changes, or to Python, or to 2.1 or 2.2.

BTW, incompatible language changes are rare.

i-spent-more-time-on-this-reply-than-on-recovering-from-all-incompatible-
    python-changes-since-'91-ly y'rs  - tim





More information about the Python-list mailing list