A counter-proposal to __future__ in PEP 236

Tim Peters tim.one at home.com
Thu Mar 1 15:45:17 EST 2001


[Martin von Loewis]
> To selectively activate nested scopes in Python 2.1, PEP 236 proposes
> the "future" statement. That means that you have to write
>
> from __future__ import nested_scopes
>
> Even though this looks like an import statement, it is not:

Not so:  it is an import statement.  Read the PEP <0.9 wink>.

> instead, it changes the meaning of variable binding in the presence
> of nested functions.

Which (the compile-time meaning) is the more important part, but not the only
part (at run-time it's an ordinary import statement).

> I personally consider this a confusing notation,

I don't.  "__future__" screams "Deep Magic" because of the double
double-underscores; it *is* a perfectly vanilla import statement at runtime;
the word "future" helpfully suggests temporality; it works with all existing
tools today without change (so it's not confusing even the stupidest of them
<0.1 wink>); and the imported nested_scopes name gets bound to release data
that the importing code can examine; e.g.,

from __future__ import nested_scopes
assert nested_scopes[1] > sys.version_info, "don't need this anymore"

> and propose a different syntax, which would read
>
> directive nested_scopes

Which loses all of that.  Incompatible language changes are a serious special
case, and I don't want to see them swallowed up by some perfectly general
mechanism that makes them impossible to distinguish visually from some
innocuous request to, e.g., optimize for space instead of time.

> The directive statement currently only supports activating nested
> scopes,

I really dislike that

    directive nested_scopes

*looks* exactly the same as

    directive favor_space

or

    directive favor_time

or

    directive alabaster_weenoblobs

That will add to confusion over time, not reduce it.  Incompatible language
changes have to kick you in the teeth.

> but it may get further use later, e.g. to activate case-insensitivity
> or set the source file character set.
>
> A patch implementing the directive statement is at
>
> http://sourceforge.net/tracker/index.php?func=detail&aid=404997&gro
> up_id=5470&atid=305470
>
> In this implementation, directive is only considered as a keyword if
> it appears at the beginning of the module.

In that case it's too feeble for a pragma facility; e.g., perhaps I want to
optimize one method for space but another for time.  Or perhaps I want to
specify that one class in a module uses traditional dicts for its namespace,
but another freezes its attributes into integer-indexable vectors at
compile-time.  Etc.  A usefully general pragma facility can't be restricted
to the top of the module, because not all useful pragmatic choices apply to
an entire module.

> Therefore, code that happens to use directive as an identifier will
> not break (unless it assigns to directive as the first thing in the
> module).

Make it general enough to be useful, and it will get hairier than that.  Bite
the bullet:  if you want a new statement, make directive a reserved word.
Then we can introduce it via

    from __future__ import directive_is_reserved

in the release before it breaks code <0.7 wink>.

Note that it's also not enough to allow just one or two optional tokens
following "directive".  One of the primary reasons no pragma facility ever
got into Python is that in previous attempts nobody could agree on syntax
that *was* sufficiently general (as a hint of the horrors you're signing up
for, note that "optional static typing" fits-- because of the "optional"
part --into a pragma framework; and once people realize that, they're going
to hijack your proposal into an overly-generalized mess too).

> I'd appreciate any comments as to whether this directive statement is
> better or worse for the purpose of indicating that nested scopes are
> used in a module.

IMO it would be *much* better for everything *except* incompatible language
changes, for which latter purpose I dislike it.  The future_statement is
specifically aimed at the latter, and I believe will support it very well.
And I want not to confuse that purpose with other stuff.

> Please note that making nested scopes the default in a major release
> after 2.1 is an unrelated issue:

It is related:  the "__future__" in a future_statement helpfully implies that
a future_statement is temporary (lost via "directive"); the detailed release
info in __future__.py supplies a programatic means for automating tasks
related to when a future_statement becomes obsolete (lost via "directive");
and ditto for the feature name imported (lost via "directive").

> it can happen with either future statements or directives;

Except that directives lack all of the special support built into PEP 236 for
supporting incompatible language changes specifically.

> when it happens, both the future statement and the directive can continue
> to work (although they would be unnecessary); tools could automatically
> remove unnessary directives if desired.

But much more easily for future_statements, and especially if you generalize
the directive stmt enough to cover all the easily predictable uses for it,
and don't make "directive" a reserved word.

Note that I'm not opposed to a general pragma facility.  It could be a nice
hammer.  But that doesn't mean everything is a nail.

sell-it-on-its-real-merits-ly y'rs  - tim





More information about the Python-list mailing list