New statement proposal for Python

Alex Martelli aleaxit at yahoo.com
Sat Jun 16 04:08:31 EDT 2001


"David LeBlanc" <whisper at oz.nospamnet> wrote in message
news:9gelk3$324$2 at 216.39.170.247...
    ...[snipping lots of interesting asides]...

My last words on this thread -- I hope.  I've got a trip coming and too
many things to do in the too-short time before I leave, to waste more
hours flaming back and forth.  If you need to make sure I see some
specific question, observation or whatever, pls cc me, as I may skip
any future posts in this thread.

> >     if something:
> >         ...
> > and
> >     if not something:
> >         ...
> > and *NOT*
> >     if something is 1:
> >         ...
> > or
> >     if something is 0:
> >         ...
> > or any "aliases" of these flawed forms.
>
> If "naive newbie" makes a programming error he/she is going to make a
> programming error whether or not alias is present. This helps, it does
> not guarantee that you won't make mistakes.

In fact, one alias example you gave specifically ENCOURAGES this
likely beginner-without-C/C++-background mistake, by, as you said,
offering a seductively nice "is false"/"is true" anti-idiom (my coinage,
but similar to the use of "anti-pattern" to describe a recurring way
to design or code that damages program qualities or productivity).

Encouraging beginners to err does make it more likely they'll err.



> > "a newbie who seeks simplicity" consider:
> >
> >     const.magic = 23
> >
> > less simple than
> >
> >     alias magic : 23
>
> It's not less simple - nor is it more complex.

It's more complex because there is a new keyword "alias"
whose syntax is different from all others.  The colon in a
dictionary display takes an EXPRESSION on either side,
this one would take an expression on the right and an
IDENTIFIER on the left -- a terribly subtle distintion to
impart to a beginner.  The former usage relies on the
assignment-syntax which any beginner learns rapidly,
and makes absolutely no specialcase to be learned in ANY
sense, neither syntactically nor semantically.

Having less to learn is simpler.

> Your forgot the "import
> const" bit needed for your part unless one does what you suggest and
> manually add it to the default libraries (which then is loaded by every
> program - I don't know if Python does "lazy loading", so this might not
> be a valid arguement). What fun for a newbie!

import is 'lazy' per-module but not per-run (it does do a tiny amount
of work the FIRST time it's executed in a program's run).  But Python
does require import for extremely basic tasks such as accessing the
program's arguments or explicitly exiting from the program: in either
case one first does "import sys", before accessing sys.argv or calling
sys.exit.  Therefore, a beginner WILL already know that, before just
about *ANY* foo.bar is used, one does "import foo" -- nothing new to
learn.  So, if const were to be explicitly imported (probably wisest),
it would not add to Python's complexity in the least.


> The thing that an alias does address that your method does not is that if
> the newbie does "const.magic = 23" and then he/she imports some nice
> module, he/she is not going to be confused by the imported module's
> changing the value of magic...

sys.modules['const'].magic, in "my method", lets itself be bound ONCE
(globally).  Therefore your claim in this paragraph is counter-factual.  If
anything, you might critique the global nature of constants (although you
had hypothesized it as a possible enhancement, I believe).


> What "simple keword" syntax are you referring to? It does follow the idea
> of key : value in dictionaries and that many other statements have one
> part separated from another by a colon.

All compound statements in Python have uniform syntax:

    <keyword> [other optional stuff] :        # leading clause
        <suite>
    [maybe other clauses of similar form]

and 'alias' doesn't match this -- so it's not a compound statement and
has no business whatsoever with the way a compound statement uses
its colon[s].  Non-compound statements are called simple statements,
and except for assignment they're all uniform in syntax:

    <keyword> [other optional stuff *WITHOUT* magic colons]


The dictionary-display form, the other use of colon in Python apart from
compound statements, has the following characteristics:
    it is used within braces { }
    it is TOTALLY INDEPENDENT of what kind of statement it
        appears in -- it's an EXPRESSION
    on both sides of the colon you have EXPRESSIONS (so, if
        either is an identifier, it stands for whatever is already
        bound to that identifier, NOT "for itself"!!!)


Your desired use of colon satisfies NOT EVEN ONE of these three rules.

Its VAGUE SIMILARITY to an existing form accompanied with crucial
semantic distinctions becomes therefore a serious hindrance.  The
fact that the issue has subtlety makes it even worse.  Syntax sugar
is much like government: it can't really do all that much good when
it's good, but it sure CAN easily do HUGE harm when it's bad.  It's
hard to conceive of worse syntax sugar than one ACTIVELY MISLEADING,
similar but NOT equal to other spots in the language.

See for yourself:
    foo = 1
    bar = 2
    foo = bar
this is an assignment: the LEFT-HAND identifier "STANDS FOR ITSELF"
and gets bound or (as in this case) rebound, without *ANY EFFECT AT
ALL* on whatever (if anything) it was previously bound to (except of
course that an object becomes eligible for recycling when all references
to it disappear).  The '=' separator says exactly this: "my LHS identifier
is NOT being used as an expression".  The RIGHT-HAND identifier, otoh,
IS being used as an expression -- it matters not a whit what the
identifier itself is, it DOES matter (it's the *only* thing that matters)
what OBJECT it is bound to.  The other (non-assignment) case in
which '=' signals the same thing: keyword-style (named-style) for
parameters to a function.  Again the LHS identifier STANDS FOR ITSELF
(it gets bound *in the namespace of the CALLED function*).
Vs:
    xx={foo:bar}
BOTH identifiers here are used as expressions.  They are not and can
NEVER be rebound by such usage.

You're proposing to use a colon *EXACTLY* like an equals-character
is always uniformly used in Python: to have its LHS identifier stand
for itself (and be bound or rebound) WITHOUT reference to or effect
on on whatever (if any) it was previously bound to.

Now try to write a couple of paragraphs explaining this anomaly, as
we would have to explain it to all Python newbies forevermore.  "All
cases where an LHS identifier stands for itself are denoted with an
'=' separator *EXCEPT*... the colon always terminates the leading
clause of a compound statement, *EXCEPT*... the x:y form is an
expression when used in dictionary display, and in that case it of
course follows ordinary expression rules (each subexpression is
evaluated), *BUT* in the magical alias statement x:y is not an
expression and follows completely different rules, to wit... all statements
except assignment begin with a reserved keyword and are either
simple keyword statements, or compound statements, OR alias
which is completely and utterly different from ALL other statements
because...".  Ohmygod.  I have a hard enough time explaining the
*PERFECTLY SIMPLE, REGULAR AND SENSIBLE* underlying rules of
Python syntax and semantics, in ways that are (all at once:-) full,
precise, readable, concise, and memorable -- even a TINY durned
irregularity such as the use of parentheses in 'class' vs 'def' when
no bases (resp formal arguments) are present already rankles (let's
not get into "print>>", *PLEASE*)... your "alias" would throw a huge
spanner into the works.

"nor is it more complex" *INDEED*...!!!


> > lines?  In a script using "module const" there may or may not be a
> > single line
> >     import const
> > for explicitness (the alternative is having it performed implicitly
> > at startup, e.g. by sitecustomize.py &c &c, placing const in the
> > __builtin__ module, of course).  That's up to the "experienced
> > developer" who decides constants are necessary at his/her site.
>
> Heaven forefend the newbie using what is generally considered good
> programming experience from the start. Let them develop the bad habbit of
> using magic numbers and other obscurities and then, once the bad habbit
> is ingrained, introduce the idea of consts with meaningful names... Wow,
> wish i'd thought of that!. Maybe it was my mistake, but I was under the
> impression that one of Python's objectives was to be a teaching language.
> Better to teach good practice from the start isn't it?

Sure, and good practice is to NOT rebind what should not be rebound
rather than do it with abandon and rely on a compiler to rap your
knuckles for it, because the compiler will NOT be able to catch ALL
of your wanton rebindings anyway.  Good practice is also to be fully
explicit about what you're doing, whence the "import const" is a
move FOR good practice.  A bare identifier without indication of where
it's coming from -- is it rebindable or not?  You can't tell -- there is
NO localized indication in the identifier itself.  What advantage do you
purport for having rebindable and non-rebindable identifiers look
exactly the same?  const.something clearly and locally indicates "hey
guy, I'm not rebindable".  Now *THAT* is good practice.

And please don't imply I like "magic numbers or other obscurities"
just because I loathe, detest, abhor and reject your "alias" proposal
(the specific killer is the use of ":" -- with an equal sign it would just
be an ordinary bad proposal, the colon makes it truly horrid).  I like
things being NAMED more often than not -- well chosen names are
a big help.  But Python's existing naming mechanisms are good and
fully sufficient to teach beginners good practices, including that of
"just don't do it" as opposed as "the language is your nanny and will
spank you whenever you do something naughty".  Adding a "const"
module, for non-rebindable constants which need global scope, is
not necessarily a bad idea -- such needs do arise, and if one must
have globals it IS better to make them non-rebindable when that
is at all feasible.  But it's very far from needing to add a new kind
of statements -- much less one ripe with strangeness wrt all of
the rest of the language...!


> (Sorry, the word is "extraneous" - i'm a prgammer not a dictionary :). I
> actually do spend considerable time on longer posts proofing.)

Wasn't meant to be a spelling flame -- just a doublecheck in case you
were trying to say something different and I had misunderstood.


> > > with more lines of code, not to mention the antics needed to do
something
> > > that should be as simple as possible (imho).
> >
> > What "antics"?  If you want 'const' to be activated by default
> > in every Python installation (e.g. in site.py), write a PEP
> > proposing just that.  You DO realize, of course, that no matter
> > what little chance such a PEP may have, it IS going to be at
> > least a thousand times more likely to be adopted than anything
> > that will introduce a new keyword and thereby break perfectly
> > working code -- that's something that can *possibly* happen
> > only for really momentous developments (such as the new proposed
> > "yield" keyword-statement for generators) which DESPERATELY NEED
> > a new statement (can't POSSIBLY work halfway-decently without).
>
> Why? Is there something you know about how well new ideas are viewed by
> the core python team that I don't? I guess we'll never see the

Apparently, there is... "first, do no harm" is close to a prime directive
(*RARE* blotches such as print>>blah notwithstanding).

> introduction of another Python keyword like... hmm... "do" since it might
> break perfectly working code? I'd be clever here and point out in Latin
> that languages that don't grow die... but I don't know Latin since it's
> dead!

Oh, do you know all non-dead languages?  Wow -- must be many
thousands of them right?  Funny enough, Latin (and to a lesser
extent Greek and Sanskrit) are known far more widely than all but
a handful of "living" languages.  Check, just for an example,
http://www.yle.fi/fbc/latini/index.html -- "Bush Europam circumit",
"Novum Regimen Britanniae", and other news of the day in the
sweetly artificial and elegant tongue of Caesar and Cicero (which
never really was Latin as people *spoke* it, of course).

Sigh, it seems we're both ramblers at heart, whence all of the
asides.  Back to our muttons -- a language can grow in many and
important ways WITHOUT breaking working code.  Python only
introduces incompatible changes *MOST CAREFULLY* -- either
when a previously tolerated practice was anyway bad and it was
deprecated in the docs (which can hardly apply to any use of a
perfectly ordinary word which is slated to become reserved!),
or in *TRULY MAJOR* circumstances where there is really no
way new functionality can be supplied well WITHOUT the use of
a new keyword.  I think the proposed 'yield' is the first new
keyword that stands a chance of making it into Python in MANY
years -- it does meet both key criteria (truly major, no real
semi-decent alternative).  'alias', IMHO, has _less_ chance than
a snowball in hell (the latter *might* happen to end up in one
of the _frozen_ circles, after all!).  But note that channeling
Guido is NOT my specialty -- gotta ask the timbot for that.


> Frankly, while it might not be as DRAMATIC as GENERATORS, in it's own
> quiet way, *I* think it's just as momentuous.

You think the differences in functionality offered between const.foo=bar
and alias foo:bar are as momentous as generators?!  Oh my.

> (As for "yield" - whatever
> does a generator need yield for? My understanding of generators is that
> they produce a new value based on retained state, not actually generate a
> huge sequence - oops, there I go digressing again.)

Yes, and?  Every yield "suspends" or "freezes" the state, ready for
the _next_ "new value" when it will be requested.


> I don't see this as anything as earthshaking as introducing nested scope
> which is going to cause far more problems in changing program structure
> (when it becomes the default) then changing the name of an identifier.
> Nor do I think that this is the first new keyword that was introduced
> since the inception of Python - of course, not having done the research
> to find 1.3 or earlier if they're publically available, I won't make such
> a bald statement.

I said "years", not "decades".  Python's inception dates back to 1990,
after all.


> > > One can certainly argue that this is syntactical sugar. It does
however
> > > serve a multitude of good purposes among which are: maintainability;
> > > clarity;  consistancy; correctness; good programming habbits; - a not
> > > inconsiderable set of advantages for a little sugar.
> >
> > I fail to see ANY of these advantages when comparing your "alias"
> > with a "const" module installed by site.py.  How is
> >     alias magic : 23
> > more maintainable, clearer, more consistent, more correct, or
> > a better programming habit than
> >     const.magic = 23
> > ?!?!  Please bring SOME kind of argument for such extraordinary
> > assertions... your bald statements are not "support" for them!
>
> I suggest you read an introductory book on good programming practice. If
> you fail to see any of these advantages, then I shudder to think about
> your code quality. Seriously, please bring SOME kind of argument for
> saying that such notions are NOT a better programming habbit then... etc.

*WHAT* "such notions" are you blabbering about?  We're comparing
your proposed horror, "alias magic:23", versus the sane alternative of
"const.magic=23".  What *NOTIONS* are involved in "favour" of your
absurdity?  And if you want to go into flames and ad hominem attacks,
dear fellow, I think you've met your match.  I *shouldn't* waste my
time flaming total unredeemable idiots, and it will make Steve Holden
cry, but hey, there IS a limit to the amount of idiocy and insults one
can tolerate, isn't there?  I DO fail to see ANY advantage at all for your
proposal, which I consider a serious contender for the title of worst
language-modification-change suggestion of the year (among many
other worthy contenders of course), compared to the obvious low-key
alternative of having site.py (or sitecustomize.py) "install" a const
module in sys.modules (and optionally in __builtin__ -- I'm neutral
about that last part).  I believe the syntax you propose is despicable,
the semantics inferior, the invasiveness on the language an obvious
problem that even an average opium addict would not have failed to
notice (suggesting that your awareness is below that of said average
opium addict:-), AND your shudders about the quality of the code I
write (with or without const.blah:-) insulting, idiotic, and uncalled for.

There -- so much for diplomacy.


> How is your suggestion that a new user:
> 1. Figure out how to import a feature that's inherantly available
> in many other programming languages.

Learn to read, jerk -- you just QUOTED it, ferchrissakes!

> > with a "const" module installed by site.py.  How is
                                       ^^^^^^^^^^^^

If it's installed by site.py, ***WHY*** would a new user have
to "figure out how to import" it?!  CHEEZ...

> 2. Make sure to not ever change any variable meant to be constant.

Did you MAJOR in this kind of behavior, or does it come natural to
you?  If you ever *TRY* to rebind an attribute in const, an exception
is raised, just as if you ever try to divide by zero, or use a variable
that doesn't exist.  Have you READ the const.py code I posted?!

Have you *UNDERSTOOD* it, or is it your normal behavior to
go around proposing changes to a language you understand so
well as to be unable to understand what a few lines of elementary
code in the language *DO*, when such lines are served to you on
a plate (since apparently you were unable to come up with
them yourself)?  I spell it out AGAIN, just in case endless repetition
can finally penetrate your apparent drunken stupor: if site.py
installs const, a new user will have to 'make sure' he or she never
rebinds const attributes in exactly the same sense in which he or
she makes sure that he or she never divides by zero nor uses a
non-existent variable -- if the errant behavior happens, Python
raises an exception.  This is how all errors are diagnosed in Python.

> 3. Figure out why the program won't work when const.magic magically
> changes because they imported a module that changed it without notice or
> warning.

See point 2.  If the module they import tries to rebind an attribute
of const that is already bound, there will be an exception.

> 4. How are you going to ensure that developers are going to
> indentify every "meant to be constant so don't use this identifier as a
> constant" constant that they create? Heck, you can't even get programmers
> to do comments reliably and that's built in now! Forstalling the obvious
> argument, of course there is nothing that ensures that any developer is
> going to practice safe programming and use an alias... this isn't meant
> to legislate against stupidity (who was that king that decreed that the
> tide not come in?) but rather to facilitate doing things more correctly.
> any better then what i've proposed?

You claim *ADVANTAGES* for your 'alias' horror versus the obvious
"const installed by site.py" solution, bubba.  *ADVANTAGES*, get it?

You want to break working code (see below), *SHOW* me the huge
pluses your proposal gives, that make it worth breaking good code (ha).

Now you're arguing that your wretched "alias" has no DISADVANTAGES
on this specific point wrt "const" -- neither can in any way force any
developer to use it.  Let's say they're even on this score -- how does
this justify your extraordinary claim of *advantages* for your horrid
proposal wrt const?!  And more, your SHUDDERS at my code's quality?
Do you think that to write good code one must be just as confused
as you are and claim a "lack of disadvantages" as an *ADVANTAGE*?!


> > > Finally, this wouldn't break any code,
> >
> > Puh-LEEZE.  *ANY* use of 'alias' in existing code would be
> > broken.  Let's not make such obviously-false assertions...
>
> Yeah, that was my error - of course anyone can use "alias" as an
> identifier. I refer you to my previous remarks with respect to changes in
> Python since the first version, above. At least, unlike the recent furor
> over changing the semantics of "print", this is new.

Nihil sub sole novi.  Just about every stupid change to Python is
requested over and over and over again on this newsgroup (hardly
ever with the needed Python Enhancement Proposal followup, to
be sure) -- often there is a quirk (here, specifically, that crazy use
of ':'), but the substance is just about always the same.  People
who don't fully understand a language, yet, instead of striving for
comprehension (which is NOT all that hard in Python's case),
start blabbering to CHANGE it!


> > Alex
>
> Fred
>
> P.S If you're confused by "Fred", I changed my identifier - oops, did I
> forget to mention that in the docs?

I think this was one of your smartest moves -- if you can manage to
change your name, maybe you can live down the shame of this
"alias" proposal.  Shudder at my code's quality, will you...?


Alex






More information about the Python-list mailing list