Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Am I the only one who would love these extentions? - Python 3.0 proposals (long)

30 views
Skip to first unread message

Georgy Pruss

unread,
Nov 10, 2003, 5:21:29 AM11/10/03
to
Hi all,

I would like to propose some extentions to the language, probably
for the version 3.0. They are mainly lexical or syntactical and the
language will stay compatible with 2.X (even although it was
declared somewhere that it's not the main concern in the Python
community) but some of them are a bit more "radical." Yes, I know
that some of the proposals were discussed here before, but I don't
think it means that the language is frozen in its development
forever and that everybody's absolutely happy with what it is
today. Anyway, this is my wish list :)

The features I'd like to see in Python are: underscores in numbers,
binary integers, hex strings, true boolean and none constants,
enum type, optional colon, built-in regex and RE match, slices,
for-as loop, until loop, unconditional loop, one line if-else, etc.


1) Underscores in numbers. It will help to read long numbers.
E.g.
12_345_678
3.14159_26535_89793_23846


2) Binary constants. Not in great demand, just nice to have,
half an hour to implement.
E.g.
0b01110011
0b1110_0101_1100_0111


3) Hex strings. Very useful when you want to initialize long
binary data, like inline pictures.
E.g.
x'48656C6C6F 21 0D0A'
ux'0021 000D 000A'
They can be combined with other strings: 'Hello!' x'0d0a'
Now you can use hexadecimal values, but with two times
longer sequences like '\x..\x..\x..\x..', or do the translation
during run-time using '....'.decode('hex').


4) Keywords 'none', 'false', 'true'. They should be keywords,
and they should be lowercase, like all the rest keywords.
True, False and None can stay for some time as predefined
identifiers, exactly like they are now.


5) Enum type. Introduces global (module-level) constants of
number or string values. The numeric values can be assigned
automatically like in the C language. If the enum declaration
has a name, this name defines "a namespace" and it must be
specified for referring to the values.

# defines constants AXIS.X=0, AXIS.Y=1, AXIS.Z=2
enum AXIS: X, Y, Z

# defines color.red, color.green, color.blue
enum color
red = '#FF0000', green = '#00FF00', blue = '#0000FF'

# defines consts A=0, B=1, C=2, D=10, E=11, F=12
enum
A, B, C
D = 10, E
F

# the same as above
enum: A; B, C, D=10; E, F # ';' and ',' are the same here.


6) The colon is optional after for,if,try,enum etc. if it is
followed by a new line. Although it's mandatory if there are
statements on the same line. So it's like ';' -- you MUST
use it when it's needed. You CAN still use it if you like it,
like now you can put a semicolon after each statement
as well.

def abs(x)
if x < 0
return -x
else
return x


7) Built-in regex'es. It would be nice to have built-in regular
expressions. Probably, some RE functionality can be shared
with the built-in string class, like presently we can write
'x'.encode('y'). For example $str can produce a regex object
and then s==re can return true if s matches re. This would be
very good for the switch construction (see below).
E.g.
id = $ "[A-Za-z_][A-Za-z0-9_]*"
if token == id: return token


8) Slices. They can have two external forms and they are
used in three contexts: a) in [index], b) in the 'case' clause,
c) in the 'for-as' statement. The have these forms:
a:b means a <= x < b (a:b:c -- with step c)
a..b means a <= x <= b (a..b:c -- with step c)
E.g.
1:100 == 1,2,3,...,99
1..100 == 1,2,3,...,100


9) For-as loop. Actually, 'as' is chosen because it is already
used as a keyword, and it fits here quite well. Another possible
spelling can be 'from' (as somebody proposed in 1999).

for <var> as <sequence>:
<stmts>

The sequence (it also occurs in the case clause, see below)
is composed of one or more expressions or slices. This form
is very short and visual. It will permit a better optimization
comparing to the old "in range(x,y)" form.
E.g.
for n as 1:10,10:50:2,50:100:5
for item as 1..100, 201..300

The ambiguity of constructions like "for v as a():b():c()" can be
solved with additional parenthesis:
for v as a():b():c() # from a() till b() with step c(); stmts start
stmts() # on the next line
for v as (a():b()): c() # from a() till b() with step 1; do c()
for v as [a():b()]: c() # maybe this form looks better


10) Until loop -- repeat the loop body at least one time
until the condition is true.

until <postcond>
<stmts>

It's the same as:

<stmts>
while not <postcond>
<stmts>


11) Unconditional loop. Yes, I'm from the camp that
finds 'while 1' ugly. Besides, sometimes we don't need
a loop variable, just a repetition.

loop [<expr_times_to_repeat>]
<stmts>

E.g.
loop 10
print_the_form()

loop
line = file.readline()
if not line
break
process_line( line )


12) Selection statement. The sequence (it can also
occur in the for-as statement, see above) is composed
of one or more expressions or slices.

switch <expr>
case <sequence>
<stmts>
case <sequence>
<stmts>
else
<stmts>

The sequence can contain RE-patterns.

case $pattern,$pattern2 # if expr matches patterns
...


13) One line if-else.

if <cond>: <stmt>; else: <stmt>


14) Conditional expression. Yes, I'd love it.

cond ? yes : no


15) Better formatting for repr()

repr(1.1) == '1.1'

If the parser recognizes 1.1 as a certain number, I can't see
any reason why it should print it as 1.1000000000000001 for
the next parser run.


16) Depreciated/obsolete items:

-- No `...` as short form of repr();
-- No '\' for continuation lines -- you can always use parenthesis;
-- No else for while,for,try etc -- they sound very unnatural;
-- Ellipsis -- it looks like an alien in the language.


I do believe that these changes follow the spirit of the language
and help Python to become an even better language.

And I'm ready to implement them, if they pass the PEP vote :)
If not... I love Python anyway!


--
Georgy Pruss
E^mail: 'ZDAwMTEyMHQwMzMwQGhvdG1haWwuY29t\n'.decode('base64')


Alex Martelli

unread,
Nov 10, 2003, 5:50:18 AM11/10/03
to
Georgy Pruss wrote:
...

> I would like to propose some extentions to the language, probably
> for the version 3.0. They are mainly lexical or syntactical and the
> language will stay compatible with 2.X (even although it was

Not at all -- these changes would break the vast majority of significant,
well-coded existing Python programs, for example by removing the 'else'
clause on 'try' for no other reason that it "sounds very unnatural" to you.
(I'm not sure how extensive your Python experience is, but this remark
suggests "not very").

3.0 will not guarantee 100% backwards compatibility (that is what will
make it a 3.0 rather than a 2.something), but the main way Guido will
use that extra degree of freedom is by removing some redundancies and
complications that have crept in the language and built-ins over the
years due to the need to keep compatible with past versions even while
better ways to perform many tasks were developed. I believe it is
totally out of the question that something as crucial to good Python
coding as try/except/else will be removed. I also strongly doubt the
changes will go in the direction of _introducing_ many "more than one
way to do it"'s, given that Guido's on record as advocating exactly the
reverse direction for 3.0 -- simplification, _removal_ of MTOWTDI's.

> declared somewhere that it's not the main concern in the Python
> community) but some of them are a bit more "radical." Yes, I know
> that some of the proposals were discussed here before, but I don't
> think it means that the language is frozen in its development

Of course not, but the direction of that development appears likely,
in most important ways, to go exactly the _other_ way round from
what you would want (introducing many more looping constructs, etc).

This suggests to me that, if you're truly keen on all items on your
wish list, you might want to consider _forking_ Python (or perhaps
some other language that is already closer than Python to many of
your wishes, such as Ruby). Sure, a decision to fork is considered
very extreme in the open-source world, but then, so is your list of
60 or more items grouped under 16 headings. If you can get some
substantial number of people agreeing to a majority of your desires,
and more importantly to your overall stance and philosophy on
language design, then starting your own language with Python as its
base might be more productive for y'all than wasting your efforts
lobbying for changes most of which are unlikely to ever be accepted.

E.g., you might center your new language's development on a
drastically different principle from Python's (which is that Guido,
the language architect with the consistent vision and a proven track
record of making good design trade-offs, gets absolute veto rights);
for example, "any change with 50% or more of votes that can in fact
be implemented gets in", or something like that. I'm a pessimist and
my prediction is that such an effort would rapidly degenerate into an
inconsistent mess, but, hey, I might be wrong -- here's your chance
to prove that Eric Raymond's theorizations about cathedrals and
bazaars are well-founded, by making a much more bazaar-like and less
cathedral-like language-design environment than Python's.


Alex

Georgy Pruss

unread,
Nov 10, 2003, 6:10:04 AM11/10/03
to

"Alex Martelli" <al...@aleax.it> wrote in message news:K3Krb.446059$R32.14...@news2.tin.it...

| Georgy Pruss wrote:
| ...
| > I would like to propose some extentions to the language, probably
| > for the version 3.0. They are mainly lexical or syntactical and the
| > language will stay compatible with 2.X (even although it was
|
| Not at all -- these changes would break the vast majority of significant,
| well-coded existing Python programs, for example by removing the 'else'
| clause on 'try' for no other reason that it "sounds very unnatural" to you.
| (I'm not sure how extensive your Python experience is, but this remark
| suggests "not very").

That particular item, 'else' for 'try' and 'for' has the lowest priority for me,
if I dare to say so. Of course I understand that it would break many many
existing programs. My main suggestions were the first ones, dealing mainly
with the lexer and the parser of Python.

I have rather little experience with Python, but very big programming
experience. I remember PL/I and IBM/360 assembler :) And I like Python a lot.

| 3.0 will not guarantee 100% backwards compatibility (that is what will
| make it a 3.0 rather than a 2.something), but the main way Guido will
| use that extra degree of freedom is by removing some redundancies and
| complications that have crept in the language and built-ins over the
| years due to the need to keep compatible with past versions even while
| better ways to perform many tasks were developed. I believe it is
| totally out of the question that something as crucial to good Python
| coding as try/except/else will be removed. I also strongly doubt the
| changes will go in the direction of _introducing_ many "more than one
| way to do it"'s, given that Guido's on record as advocating exactly the
| reverse direction for 3.0 -- simplification, _removal_ of MTOWTDI's.

I see.

| <...>


| This suggests to me that, if you're truly keen on all items on your
| wish list, you might want to consider _forking_ Python (or perhaps
| some other language that is already closer than Python to many of
| your wishes, such as Ruby). Sure, a decision to fork is considered
| very extreme in the open-source world, but then, so is your list of
| 60 or more items grouped under 16 headings. If you can get some
| substantial number of people agreeing to a majority of your desires,
| and more importantly to your overall stance and philosophy on
| language design, then starting your own language with Python as its
| base might be more productive for y'all than wasting your efforts
| lobbying for changes most of which are unlikely to ever be accepted.

No, no. I don't think that it's a good idea to fork Python. Again, I'm
quite happy with what it is now. I don't insist on introducing the switch
statement and conditional expression in 3.0. But I forget a colon for
each 'else' and I feel that I'm not the only one.

| E.g., you might center your new language's development on a
| drastically different principle from Python's (which is that Guido,

| <...>
|
|
| Alex
|

Thank you for the answer Alex.
Georgy


KefX

unread,
Nov 10, 2003, 6:59:15 AM11/10/03
to
>But I forget a colon for
>each 'else' and I feel that I'm not the only one.

Funny...I always remember it on the 'else' statement and forget it on the 'if'
statement. ;)

Yet, I'm in favor of leaving the colon there. All you have to do to make sure
that your module is syntactically correct, in case you're worried about it, is
try to import it (it doesn't have to be in the context of your program). The
colon also helps programs such as text editors, code processing tools, and such
figure out where blocks begin: all blocks begin with a colon. Think of it as an
opening brace, or a 'begin' statement, and nobody has to argue over where it
belongs. ;) You'll get used to it in time and I don't think it really hurts
anything. And I do think it makes code a little more readable, by saying "Hey!
A block begins here!", which is why the colon was put into the language in the
first place.

As for the rest of your suggestions, well, from what I've heard, half of the
issues have been beaten to death, and some of the rest seem silly. Why make
"True" a keyword when it's fine as it is?

There's no ?: operator because nobody can agree on its syntax, and most of the
people who commented on the matter said that if they couldn't have their way,
they wouldn't have it at all, so nobody has it. When the primary idea in a PEP
is rejected, it has almost zero chance of ever resurfacing.

regexps aren't built into the language because, for one thing, they really
aren't pretty. Most Python code, assuming a competent programmer, is pretty.
You wouldn't want to ruin that prettiness by making a non-pretty feature too
tempting, would you? ;) Of course, you still have regexps when you need them,
so what does it cost you?

And so on. I don't think your ideas are the worst things I've ever heard or
anything, but I have to say that you might be better served in trying to figure
out why it is the way it is, rather than thinking "I don't like this, what can
I do to change it?"...and if you can't figure it out for yourself, you can
always ask here. :)

- Kef

Alex Martelli

unread,
Nov 10, 2003, 7:25:14 AM11/10/03
to
Georgy Pruss wrote:

> "Alex Martelli" <al...@aleax.it> wrote in message
> news:K3Krb.446059$R32.14...@news2.tin.it...
> | Georgy Pruss wrote:
> | ...
> | > I would like to propose some extentions to the language, probably
> | > for the version 3.0. They are mainly lexical or syntactical and the
> | > language will stay compatible with 2.X (even although it was
> |
> | Not at all -- these changes would break the vast majority of
> | significant, well-coded existing Python programs, for example by
> | removing the 'else' clause on 'try' for no other reason that it "sounds
> | very unnatural" to you. (I'm not sure how extensive your Python
> | experience is, but this remark suggests "not very").
>
> That particular item, 'else' for 'try' and 'for' has the lowest priority
> for me, if I dare to say so. Of course I understand that it would break
> many many existing programs.

It's not just that: it would break *well-coded* programs, programs that
are coded using the _BEST, MOST APPROPRIATE_ constructs, and not give any
really good alternative way to recode them. It's not so much the 'else'
on _for_ -- removing _that_ would break a zillion good programs, but the
alternatives are almost decent, at least in most cases. But the 'else' on
_try_?!?! How would you code around _THAT_ lack?

One sign that somebody has moved from "Python newbie" to "good Python
programmer" is exactly the moment they realize why it's wrong to code:

try:
x = could_raise_an_exception(23)
process(x)
except Exception, err:
deal_with_exception(err)
proceed_here()

and why the one obvious way is, instead:

try:
x = could_raise_an_exception(23)
except Exception, err:
deal_with_exception(err)
else:
process(x)
proceed_here()

What WOULD sound natural to you in order to express the crucial pattern:
1. first, try doing "this and that"
2. if "this and that" raises such an exception, do something
3. else (i.e. if it doesn't raise exceptions) do s/thing else instead
4. and then in either case proceed from here
...???

Trying to kludge it around with "status-flag" variables isn't very
satisfactory, of course -- it can only complicate things and add
error-prone needs for setting and resetting "status flags". To me,
removing 'else' from 'try' and proposing to use status-flags instead
is about as sensible as making the same proposal regarding 'if' --
i.e., not very.

> My main suggestions were the first ones,
> dealing mainly with the lexer and the parser of Python.

Ah, I see -- you probably weakened the effectiveness of your post
by mixing in it things you cared little about and at the same time
were such as to ensure alarm among experienced Pythonistas.

Each of your proposals requires very detailed analysis to become a
PEP. For example, consider one I do like a bit: the ability to insert
underscores in literal numbers. If we enrich the lexer to allow
that, I would _also_ want at the very least a warning to be raised
if the underscores are not inserted at "regular" intervals -- this
would, I think, enhance the usefulness, by making the lexer able to
help diagnose at least _some_ typos in number literals. However,
there seem to be arguments for at least two approaches: one, just
force the number of digits allowed between underscores to exactly
three -- probably the most common usage; or, two, allow any number
of digits between underscores as long as the usage is "consistent"
(within a single number? or in a larger lexical unit, and, if so,
which one -- a module?). In either case, the issue of number of
digits allowed before the first underscore and after the last one
should be tackled -- perhaps differently for sequences of digits
that come before a decimal point (or without any at all) or after
a decimal point.

Further, if we're able to _input_, say, 1_000_000 to indicate "a
million" to the lexer -- surely we'll want that same ability when
the same string is otherwise recovered (e.g. read from a file)
and then transformed into an integer by calling int(s). Should
int(s) just accept underscores in string s, or be more selective?
Should underscores perhaps only be accepted in int(...) [and other
type constructors such as long(...), float(...), ...) if explicitly
enabled by an optional argument?

And what about the _output_ side of things? Surely if 1_000_000
becomes an acceptable syntax for "one million" there should be a
simple way to make the number 1000000 _print out_ that way. Should
that be through some optional argument to str() and/or repr()? Or
a new function (and/or method), and where located? How would we
get that effect with the %-formatting operator?

A PEP on this single change to the language would stand no chance
of acceptance -- it would probably, and quite correctly, just get
rejected outright by the PEP-editor, as clearly under-researched --
unless each and every one of these points (and probably more yet
that I haven't thought of -- all of the above is the result of just
a couple minutes' worth of thought, after all!) was identified and
clearly addressed, indicating what design choices were considered
and why they were accepted or rejected. Considerations about how
such things are dealt with in other languages and why adopting their
solutions would be appropriate or inappropriate in Python would be
very helpful here, too.

And this one is probably the simplest out of all of your wishes,
right? Plus, as I said, is one I might well like, so I'm definitely
not "looking for excuses" against it -- on the contrary, I'm trying to
pin down enough details so it stands a _chance_ (and it might, even
in Python 2.4, since changes that are useful and backwards-compatible
ARE under consideration for that, the next release).

> I have rather little experience with Python, but very big programming
> experience. I remember PL/I and IBM/360 assembler :) And I like Python a
> lot.

Yep, I also recall PL/I (not very fondly...) and BAL (very fondly indeed,
though I admit it was on a /370 that I was using it -- I don't think there
were any /360's left by that time, at least not in IBM Research).


> No, no. I don't think that it's a good idea to fork Python. Again, I'm

Probably not -- forking rarely _is_ a good idea, except perhaps under
extreme provocation. However, Python's conservatism might feel like
such (extreme provocation) to somebody who's truly gung-ho for change.

> quite happy with what it is now. I don't insist on introducing the switch
> statement and conditional expression in 3.0. But I forget a colon for
> each 'else' and I feel that I'm not the only one.

Yep -- as for me, I kept doing that continuously for the first (roughly)
three months of intense Python use, still a lot (just a bit less) over the
_next_ three months, and even though the frequency's been going down it's
mainly thanks to smart-editors which immediately show, typically by not
auto-formatting things as I expect, that I have _again_ forgotten.

However, I do like the colons there when I _read_ Python code, which, all
in all, I do far more often than writing it; so, the slight inconvenience
in writing is (for me, and by now) balanced out by the convenience in
reading. You may want to investigate "smart editors" to see if the balance
can be made similarly acceptable to you.


Alex

Alex Martelli

unread,
Nov 10, 2003, 8:41:59 AM11/10/03
to
KefX wrote:
...

> As for the rest of your suggestions, well, from what I've heard, half of
> the issues have been beaten to death, and some of the rest seem silly. Why
> make "True" a keyword when it's fine as it is?

True, False and None may well become keywords in the future, because that
might make things "even finer" in some respects. E.g., right now,
while True:
...
has to look-up 'True' at EACH step just in case the ... code rebinds
that name. This _is_ a bit silly, when there is no real use-case for
"letting True be re-bound". Nothing major, but...:

[alex@lancelot test]$ timeit.py -c -s'import itertools as it' 'c=it.count()'
'while True:' ' if c.next()>99: break'
10000 loops, best of 3: 91 usec per loop

[alex@lancelot test]$ timeit.py -c -s'import itertools as it' 'c=it.count()'
'while 1:' ' if c.next()>99: break'
10000 loops, best of 3: 76 usec per loop

...it still seems silly to slow things down by 20% w/o good reason...

(people who wonder why suddenly some Pythonistas are _so_ interested in
efficiency might want to review
http://www.artima.com/weblogs/viewpost.jsp?thread=7589
for a possible hint...).

OTOH, the chance that the spelling of True, False and None will change
is close to that of a snowball in the _upper_ reaches of Hell (the
_lower_ ones are in fact frozen, as any reader of Alighieri well knows,
so the common idiom just doesn't apply...:-).


Alex

Paul Rubin

unread,
Nov 10, 2003, 11:49:40 AM11/10/03
to al...@aleax.it
Alex Martelli <al...@aleax.it> writes:
> This suggests to me that, if you're truly keen on all items on your
> wish list, you might want to consider _forking_ Python (or perhaps
> some other language that is already closer than Python to many of
> your wishes, such as Ruby). Sure, a decision to fork is considered
> very extreme in the open-source world, but then, so is your list of
> 60 or more items grouped under 16 headings.

I've been thinking for a while that Python could benefit from a fork,
that's not intended to replace Python for production use for any group
of users, but rather to be a testbed for improvements and extensions
that would allow more concrete experiments than can be done through
pure thought and the PEP process. Most proposals for Python
improvements could then be implemented and tried out in the
experimental platform before being folded back into the regular
implementation.

Alex Martelli

unread,
Nov 10, 2003, 12:00:20 PM11/10/03
to
Paul Rubin wrote:

> I've been thinking for a while that Python could benefit from a fork,
> that's not intended to replace Python for production use for any group
> of users, but rather to be a testbed for improvements and extensions
> that would allow more concrete experiments than can be done through
> pure thought and the PEP process. Most proposals for Python
> improvements could then be implemented and tried out in the
> experimental platform before being folded back into the regular
> implementation.

That's one of the benefits that the pypy project is intended to
provide: a "reference implementation" that's easiest to play with
for exactly such purposes as the experiments you mention. And --
we do hope to release pypy 1.0 before Christmas...!


Alex

Paul Rubin

unread,
Nov 10, 2003, 12:03:01 PM11/10/03
to al...@aleax.it
Alex Martelli <al...@aleax.it> writes:
> That's one of the benefits that the pypy project is intended to
> provide: a "reference implementation" that's easiest to play with
> for exactly such purposes as the experiments you mention. And --
> we do hope to release pypy 1.0 before Christmas...!

Interesting and cool. During the early discussion of Pypy it sounded
as if Pypy was specifically *not* intended for such purposes. It'll
be great to see what comes out.

Peter Otten

unread,
Nov 10, 2003, 12:56:30 PM11/10/03
to
Georgy Pruss wrote:

> I would like to propose some extentions to the language, probably

...

> 5) Enum type. Introduces global (module-level) constants of
> number or string values. The numeric values can be assigned
> automatically like in the C language. If the enum declaration
> has a name, this name defines "a namespace" and it must be
> specified for referring to the values.
>
> # defines constants AXIS.X=0, AXIS.Y=1, AXIS.Z=2
> enum AXIS: X, Y, Z
>
> # defines color.red, color.green, color.blue
> enum color
> red = '#FF0000', green = '#00FF00', blue = '#0000FF'
>
> # defines consts A=0, B=1, C=2, D=10, E=11, F=12
> enum
> A, B, C
> D = 10, E
> F
>
> # the same as above
> enum: A; B, C, D=10; E, F # ';' and ',' are the same here.

enum WhosAfraidOf:
red
yellow
blue

for color in WhosAfraidOf:
barnetPaintsItIn(color)
>>> len(WhosAfraidOf)
3

I would like something along these lines. I think you omitted the most
important benefit, getting the names rather than the values, which I'm
looking forward to, so I will shamelessly copy from a recent conversation
on Python-Dev:

[quote]
> > I would love it if what happened really was something like:
> >
> >>>> from socket import *
> >>>> print AF_UNIX
> > socket.AF_UNIX
> >>>> from errno import *
> >>>> print EEXIST
> > errno.EEXIST
>
> I've had this idea too. I like it, I think. The signal module could
> use it too...

Yes, that would be cool for many enums.
[end quote]

(I do not follow the list closely, but I think there was no talking of a new
syntax for enums, though)

> 6) The colon is optional after for,if,try,enum etc. if it is
> followed by a new line. Although it's mandatory if there are
> statements on the same line. So it's like ';' -- you MUST
> use it when it's needed. You CAN still use it if you like it,
> like now you can put a semicolon after each statement
> as well.
>
> def abs(x)
> if x < 0
> return -x
> else
> return x

While I forget the colon more often than I'd like to, this is mostly a
non-issue as it is caught by the compiler and does no runtime harm. Also,
the colon would make the above example slightly more readable.

> 11) Unconditional loop. Yes, I'm from the camp that
> finds 'while 1' ugly. Besides, sometimes we don't need
> a loop variable, just a repetition.
>
> loop [<expr_times_to_repeat>]
> <stmts>

Not sure. Maybe

while:
repeatThisForever()

> 16) Depreciated/obsolete items:
>
> -- No `...` as short form of repr();
> -- No '\' for continuation lines -- you can always use parenthesis;

Yes, away with these!

> -- No else for while,for,try etc -- they sound very unnatural;

I'm just starting to use else in try ... except, so my resistance to the
extra else clauses is not as strong as it used to be...

> -- Ellipsis -- it looks like an alien in the language.

What the heck is this? The Nutshell index does not have it, and I couldn't
make any sense of the section in the language reference.


Peter


Thomas Bellman

unread,
Nov 10, 2003, 2:31:52 PM11/10/03
to
Alex Martelli <al...@aleax.it> wrote:

> True, False and None may well become keywords in the future, because that
> might make things "even finer" in some respects. E.g., right now,
> while True:
> ...
> has to look-up 'True' at EACH step just in case the ... code rebinds
> that name. This _is_ a bit silly, when there is no real use-case for
> "letting True be re-bound". Nothing major, but...:

That's a silly reason to make them keywords. A much better way
to achieve the same goal would be to make the optimizer recognize
that True isn't re-bound within the loop. Making the optimizer
better would improve the performance of much more code than just
'while True' loops.


--
Thomas Bellman, Lysator Computer Club, Linköping University, Sweden
"You cannot achieve the impossible without ! bellman @ lysator.liu.se
attempting the absurd." ! Make Love -- Nicht Wahr!

Alex Martelli

unread,
Nov 10, 2003, 2:40:14 PM11/10/03
to
Peter Otten wrote:
...
>> -- Ellipsis -- it looks like an alien in the language.
>
> What the heck is this? The Nutshell index does not have it, and I couldn't
> make any sense of the section in the language reference.

Ooops, sorry -- I guess I shouldn't have skipped it in the Nutshell.

Ellipsis is the singleton object that represents ... (three dots) used
in an indexing. Check this out:

>>> class showindex(object):
... def __getitem__(self, index): return index
...
>>> si = showindex()
>>> si[1, ..., 7]
(1, Ellipsis, 7)
>>>

see? in this case, the index is a 3-tuple, and Ellipsis is its middle
item. As far as I know, the only USE of this notation is in package
Numeric (p. 307-308 in the Nutshell), to indicate that some indices or
slices apply to the rightmost axes of a multi-dimensional array.

Few Pythonistas outside of the ranks of numeric-array mavens may have
any interest in multi-dimensional arrays and the like. However, such
numeric-array mavens are an important part of the Python community (thanks
to such wonderful add-ons as Numeric, its future successor numarray, and
the many splendid packages built on top), so you can judge for yourself
what the chance may be that Guido would want to take away from under them
the "..." syntax that is so useful and habitual for them.


Alex

Alex Martelli

unread,
Nov 10, 2003, 3:09:24 PM11/10/03
to
Paul Rubin wrote:

At http://codespeak.net/pypy/index.cgi?doc you can already see a
lot of what comes out...!-)

In particular, re a "reference implementation", at:
http://codespeak.net/pypy/index.cgi?doc/funding/B3.impact.html

you can read...:

"""
Guido van Rossum has expressed interest in giving PyPy the status of
'implementation standard' (executable specification) of the Python
programming language.
"""

and the quotation from Guido:

"""
It is even possible that PyPy will eventually serve as an "executable
specification" for the language, and the behavior of one of PyPy's object
spaces will be deemed the correct one.
"""

Whether or not one of pypy's object spaces is ever officially blessed
as the "executable specification", aka "implementation standard", you
can see that many of the work-packages under B6.7 have to do exactly
with the "easiest to play with ... for such purposes as experiments"
nature of pypy. Of course, we'll be able to develop the project's
ambitious objectives only if we obtain the EU funding we have requested
under "IST-2002-2.3.2.3 - Open development platforms for software and
services" (indeed, all the general and detailed plans & projections
you'll see on the webpage were developed mostly to submit to the EU a
good proposal -- it IS, however, a nice side effect that our plans and
ambitions are now spelled out with such extreme precision:-).

Still, we _have_ gone farther than most would have expected without yet a
scrap of funding from anybody -- each participant covering his or her own
travel & accomodation expenses to the Sprints... -- and we'll keep trying
to do our best come what may, in typical open-source spirit!


Alex

Alex Martelli

unread,
Nov 10, 2003, 3:45:03 PM11/10/03
to
Thomas Bellman wrote:

> Alex Martelli <al...@aleax.it> wrote:
>
>> True, False and None may well become keywords in the future, because that
>> might make things "even finer" in some respects. E.g., right now,
>> while True:
>> ...
>> has to look-up 'True' at EACH step just in case the ... code rebinds
>> that name. This _is_ a bit silly, when there is no real use-case for
>> "letting True be re-bound". Nothing major, but...:
>
> That's a silly reason to make them keywords. A much better way
> to achieve the same goal would be to make the optimizer recognize
> that True isn't re-bound within the loop. Making the optimizer
> better would improve the performance of much more code than just
> 'while True' loops.

You are heartily welcome to perform the dynamic whole-code analysis
needed to prove whether True (or any other built-in identifier) may
or not be re-bound as a side effect of functions called within the
loop -- including the calls to methods that can be performed by just
about every operation in the language. It seems a very worthy
research project, which might take good advantage of the results
of the pypy project (there is plenty of such advanced research that
is scheduled to take place as part of pypy, but there is also surely
space for a lot of other such projects; few are going to bear fruit,
after all, so, the more are started, the merrier).

Meanwhile, during the years in which this advanced research project
of yours matures and (with luck) produces usable results, Python's
mainstream implementation will stick to the general strategy that has
served it so well and for so long: _simplicity_ first and foremost,
optimization (and thus complication) only where it has provable great
benefit/cost ratios (e.g., dictionary access and list-sorting).

As there is really no good use case for letting user code rebind the
built-in names None, True, and False, making them keywords has almost
only pluses (the "almost" being related to backwards compatibility
issues), as does "nailing down" many other popular built-in names (by
techniques different from making them into keywords, most likely, as
the tradeoffs are quite different in those cases).

The process has already begun in Python 2.3, mind you...:

[alex@lancelot bo]$ python2.3 -c 'None=23'
<string>:1: SyntaxWarning: assignment to None

(True and False will take more time, because a program may try to
assign them [if not already known] in order to be compatible with
relatively recent Python releases which did not have them as
built-in names).


Alex


John Roth

unread,
Nov 10, 2003, 3:49:52 PM11/10/03
to

"Thomas Bellman" <bel...@lysator.liu.se> wrote in message
news:boop38$c2l$1...@news.island.liu.se...

> Alex Martelli <al...@aleax.it> wrote:
>
> > True, False and None may well become keywords in the future, because
that
> > might make things "even finer" in some respects. E.g., right now,
> > while True:
> > ...
> > has to look-up 'True' at EACH step just in case the ... code rebinds
> > that name. This _is_ a bit silly, when there is no real use-case for
> > "letting True be re-bound". Nothing major, but...:
>
> That's a silly reason to make them keywords. A much better way
> to achieve the same goal would be to make the optimizer recognize
> that True isn't re-bound within the loop. Making the optimizer
> better would improve the performance of much more code than just
> 'while True' loops.

Making them keywords isn't exactly correct. There's a movement
to make just about everything in the built-in scope immutable and
not rebindable at any lower scope for performance reasons. The
usual example is the len() built-in function. All this function does is
call the __len__() method on the object; the extra function call
is a complete waste of time, and could be eliminated if the
compiler could depend on len() never being modified or
rebound at any level.

John Roth

Mel Wilson

unread,
Nov 10, 2003, 3:51:32 PM11/10/03
to
In article <boop38$c2l$1...@news.island.liu.se>,

Thomas Bellman <bel...@lysator.liu.se> wrote:
>Alex Martelli <al...@aleax.it> wrote:
>
>> True, False and None may well become keywords in the future, because that
>> might make things "even finer" in some respects. E.g., right now,
>> while True:
>> ...
>> has to look-up 'True' at EACH step just in case the ... code rebinds
>> that name. This _is_ a bit silly, when there is no real use-case for
>> "letting True be re-bound". Nothing major, but...:
>
>That's a silly reason to make them keywords. A much better way
>to achieve the same goal would be to make the optimizer recognize
>that True isn't re-bound within the loop.

Often you can't tell. Any loop that includes a function
call could do anything, determined by events that occur long
after the optimizer terminates. And many things can invoke
function calls.. __add__, anyone?

Regards. Mel.

David Eppstein

unread,
Nov 10, 2003, 4:34:49 PM11/10/03
to
In article <vqvuih9...@news.supernews.com>,
"John Roth" <newsg...@jhrothjr.com> wrote:

> Making them keywords isn't exactly correct. There's a movement
> to make just about everything in the built-in scope immutable and
> not rebindable at any lower scope for performance reasons. The
> usual example is the len() built-in function. All this function does is
> call the __len__() method on the object; the extra function call
> is a complete waste of time, and could be eliminated if the
> compiler could depend on len() never being modified or
> rebound at any level.

This would also have the advantage of more quickly catching certain
common programming errors:

idSequence = 0
def makeUniqueID(str):
global idSequence
n = str(idSequence)
idSequence += 1
return str + n

Here of course the argument "str" should be named differently than the
built in type "str"... if it's a syntax error, you'd find out about it
at compile time instead of run time.

Of course such explicit shadowing is easy for the compiler to detect,
the harder part is when some module changes e.g. the "cmp" global of
some other module. (I did this intentionally recently but later thought
better of it...)

--
David Eppstein http://www.ics.uci.edu/~eppstein/
Univ. of California, Irvine, School of Information & Computer Science

Ron Adam

unread,
Nov 10, 2003, 4:39:55 PM11/10/03
to
On Mon, 10 Nov 2003 13:41:59 GMT, Alex Martelli <al...@aleax.it>
wrote:

>
>[alex@lancelot test]$ timeit.py -c -s'import itertools as it' 'c=it.count()'
>'while True:' ' if c.next()>99: break'
>10000 loops, best of 3: 91 usec per loop
>
>[alex@lancelot test]$ timeit.py -c -s'import itertools as it' 'c=it.count()'
>'while 1:' ' if c.next()>99: break'
>10000 loops, best of 3: 76 usec per loop
>
>...it still seems silly to slow things down by 20% w/o good reason...
>

Is it possible to make the argument optional for while? That may
allow for an even faster time?

while:
<instructions>

It would be the equivalent as making the default argument for while
equal to 1 or True. Could it optimize to single cpu instruction when
that format is used? No checks or look ups at all?

_Ron Adam

Alex Martelli

unread,
Nov 10, 2003, 5:11:53 PM11/10/03
to
Ron Adam wrote:
...
> Is it possible to make the argument optional for while? That may

Yes, it is technically possible -- you'd need to play around with the
Dreaded Grammar File, but as Python grammar tasks go this one seems
simple.

> allow for an even faster time?

No, there is no reason why "while 1:", "while True:" once True is
a keyword, and "while:" were the syntax extended to accept it, could
or should compile down to code that is at all different.

> while:
> <instructions>
>
> It would be the equivalent as making the default argument for while
> equal to 1 or True. Could it optimize to single cpu instruction when
> that format is used? No checks or look ups at all?

"while 1:" is _already_ compiled to a single (bytecode, of course)
instruction with "no checks or look ups at all". Easy to check:

>>> x=compile('while 1: foop()', '<str>', 'exec')
>>> dis.dis(x)
1 0 SETUP_LOOP 19 (to 22)
3 JUMP_FORWARD 4 (to 10)
6 JUMP_IF_FALSE 11 (to 20)
9 POP_TOP
>> 10 LOAD_NAME 0 (foop)
13 CALL_FUNCTION 0
16 POP_TOP
17 JUMP_ABSOLUTE 10
>> 20 POP_TOP
21 POP_BLOCK
>> 22 LOAD_CONST 1 (None)
25 RETURN_VALUE

the four bytecodes from 10 to 17 are the loop: name 'foop'
is loaded, it's called with no argument, its result is
discarded, and an unconditional jump back to the first of
these steps is taken (this loop, of course, will only get
out when function foop [or the lookup for its name] cause
an exception). (The 2 opcodes at 6 and 9 never execute,
and the opcode at 3 could be eliminated if those two were,
but that's the typical kind of job for a peephole optimizer,
an easy but low-returns project).

Note the subtle difference when we use True rather than 1:

>>> x=compile('while True: foop()', '<str>', 'exec')
>>> dis.dis(x)
1 0 SETUP_LOOP 19 (to 22)
>> 3 LOAD_NAME 0 (True)
6 JUMP_IF_FALSE 11 (to 20)
9 POP_TOP
10 LOAD_NAME 1 (foop)
13 CALL_FUNCTION 0
16 POP_TOP
17 JUMP_ABSOLUTE 3
>> 20 POP_TOP
21 POP_BLOCK
>> 22 LOAD_CONST 0 (None)
25 RETURN_VALUE

_Now_, the loop runs all the way through the bytecodes
from 3 to 20 included (the opcodes at 0 and 21 surround
it just like they surrounded the unconditional loop we
just examined). Before we can get to the "real job" of
bytecodes 10 to 17, each time around the loop, we need
to load the value of name True (implying a lookup), do
a conditional jump on it, otherwise discard its value.

If True was a keyword, the compiler could recognize it and
generate just the same code as it does for "while 1:" --
or as it could do for "while:", were that extension of
the syntax accepted into the language.


As to the chances that a patch, implementing "while:" as
equivalent to "while 1:", might be accepted, I wouldn't
be particularly optimistic. Still, one never knows!


Alex

Andrew Dalke

unread,
Nov 10, 2003, 6:51:13 PM11/10/03
to
Georgy Pruss:

> 1) Underscores in numbers. It will help to read long numbers.
> E.g.
> 12_345_678
> 3.14159_26535_89793_23846

Perl has this. How often do long numbers occur in your code?

When is the workaround of
int("12_345_678".replace("_", ""))
float("3.14159_26535_89793_23846".replace("_",""))
inappropriate? Note also that this allows the more readable
(to some)
float("3.14159 26535 89793 23846".replace(" ",""))

> 2) Binary constants. Not in great demand, just nice to have,
> half an hour to implement.
> E.g.
> 0b01110011
> 0b1110_0101_1100_0111

Why is it nice enough to make it be a syntax addition,
as compared to

>>> int("01110011", 2)
115
>>> int("1110_0101_1100_0111".replace("_", ""), 2)
58823
>>>

?

> 3) Hex strings. Very useful when you want to initialize long
> binary data, like inline pictures.
> E.g.
> x'48656C6C6F 21 0D0A'
> ux'0021 000D 000A'
> They can be combined with other strings: 'Hello!' x'0d0a'

> Now you can use hexadecimal values, but with two times
> longer sequences like '\x..\x..\x..\x..', or do the translation
> during run-time using '....'.decode('hex').

I very rarely include encode binary data in my data files.
Images should usually be external resources since it's hard
to point an image viewer/editor at a chunk of Python code.

A counter example is some of the PyQt examples, which
have pbm (I think) encoded images, which are easy to see
in ASCII. In that case, there's a deliberate choice to use
a highly uncompressed format (one byte per pixel).

The run-time conversion you don't is only done once.
In addition, another solution is to have the Python spec
require that a few encodings (like 'hex') cannot be changed,
and allow the implementation to preprocess those cases.

So why is it useful enough to warrant a new special-case
syntax?

> 4) Keywords 'none', 'false', 'true'. They should be keywords,
> and they should be lowercase, like all the rest keywords.
> True, False and None can stay for some time as predefined
> identifiers, exactly like they are now.

Why *should* they be lower case? There was a big dicussion
when True/False came out, which resulted in that "casing".

You argue consistancy to other keywords. What other
keywords refer to objects?

>>> keyword.kwlist
['and', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif',
'else',
'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in',
'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try',
'while', 'yield']
>>>

None that I can see.

> 5) Enum type.

There are approximations to this, as in
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/67107

> # defines constants AXIS.X=0, AXIS.Y=1, AXIS.Z=2
> enum AXIS: X, Y, Z

For that case, I would prefer the following

class AXIS:
X, Y, Z = range(3)

If there are more terms then here's an alternative. I've not
seen it before so I think it's a novel one

class Keywords:
AND, ASSERT, BREAK, CLASS, CONTINUE, DEF, \
DEL, ELIF, YIELD, ... = itertools.count()

That is, the ellipsis at the end of a sequence assignment means
to ignore RHS terms at that point and beyond.

> # defines color.red, color.green, color.blue
> enum color
> red = '#FF0000', green = '#00FF00', blue = '#0000FF'

This can be done already as

class color:
red = '#FF0000'
green = '#00FF00'
blue = '#0000FF'

> # defines consts A=0, B=1, C=2, D=10, E=11, F=12
> enum
> A, B, C
> D = 10, E
> F

While I know C allows this, I've found it more confusing
than useful. What about

class consts:
A, B, C, ... = itertools.count()
D, E, F, ... = itertools.count(10)


> 6) The colon is optional after for,if,try,enum etc. if it is
> followed by a new line. Although it's mandatory if there are
> statements on the same line. So it's like ';' -- you MUST
> use it when it's needed. You CAN still use it if you like it,
> like now you can put a semicolon after each statement
> as well.
>
> def abs(x)
> if x < 0
> return -x
> else
> return x

The reason for the ":" is to make the block more visible. This
came out during human factors testing in ABC (as I recall). It
also simplifies tool development since software can assume
that if the previous line ends in a : then there should be an indent.

BTW, what advantage is there in having an optional syntax
for this?

> 7) Built-in regex'es. It would be nice to have built-in regular
> expressions. Probably, some RE functionality can be shared
> with the built-in string class, like presently we can write
> 'x'.encode('y'). For example $str can produce a regex object
> and then s==re can return true if s matches re. This would be
> very good for the switch construction (see below).
> E.g.
> id = $ "[A-Za-z_][A-Za-z0-9_]*"
> if token == id: return token

Regexps play much less a role than in languages like Perl and
Ruby. Why for Python should this be a syntax-level feature.
Eg, your example can already be done as

id = re.compile("[A-Za-z_][A-Za-z0-9_]*")
if id.match(token): return token

Note that you likely want the id pattern to end in a $.

A downside of the == is that it isn't obvious that ==
maps to 'match' as compared to 'search'.

Suppose in 5 years we decide that Larry Wall is right
and we should be using Perl6 regexp language. (Just
like we did years ago with the transition from the regex
module to the re module.) What's the viable migration
path?

Does your new regexp builtin allow addition

$"[A-Za-z_]" + $"[A-Za-z0-9_]*"

or string joining, like

$"[A-Za-z_]" $"[A-Za-z0-9_]*"

or addition with strings, as in

$"[A-Za-z_]" + "[A-Za-z0-9_]*"

What about string interpolation?

$"[%s]" % "ABCDEF"


> 8) Slices. They can have two external forms and they are
> used in three contexts: a) in [index], b) in the 'case' clause,
> c) in the 'for-as' statement. The have these forms:
> a:b means a <= x < b (a:b:c -- with step c)
> a..b means a <= x <= b (a..b:c -- with step c)
> E.g.
> 1:100 == 1,2,3,...,99
> 1..100 == 1,2,3,...,100

See http://python.org/peps/pep-0204.html . Proposed and
rejected.

> 9) For-as loop.

See also http://python.org/peps/pep-0284.html which is for
integer loops. Since your 8) is rejected your 9) syntax
won't be valid.

> 10) Until loop -- repeat the loop body at least one time
> until the condition is true.
>
> until <postcond>
> <stmts>
>
> It's the same as:
>
> <stmts>
> while not <postcond>
> <stmts>

Actually, it's the same as

while True:
<stmts>
if postcond:
break

Why is this new loop construct of yours useful enough
to warrant a new keyword?

> 11) Unconditional loop. Yes, I'm from the camp that
> finds 'while 1' ugly. Besides, sometimes we don't need
> a loop variable, just a repetition.
>
> loop [<expr_times_to_repeat>]
> <stmts>
>
> E.g.
> loop 10
> print_the_form()
>
> loop
> line = file.readline()
> if not line
> break
> process_line( line )

Do you find 'while True' to be ugly?

How much code will you break which uses the
word "loop" as a variable? I know you expect it
for Python 3 which can be backwards incompatible,
but is this really worthwhile? How many times do
you loop where you don't need the loop variable?
Is this enough to warrant a special case construct?

I don't think so.

Note that the case you gave is no longer appropriate.
The modern form is

for line in file:
process_line(line)

> 12) Selection statement. The sequence (it can also
> occur in the for-as statement, see above) is composed
> of one or more expressions or slices.
>
> switch <expr>
> case <sequence>
> <stmts>
> case <sequence>
> <stmts>
> else
> <stmts>
>
> The sequence can contain RE-patterns.
>
> case $pattern,$pattern2 # if expr matches patterns
> ...

See http://python.org/peps/pep-0275.html which has
not yet been decided


> 13) One line if-else.
>
> if <cond>: <stmt>; else: <stmt>

Why? What's the advantage to cramming things on a line
compared to using two lines?

if a: print "Andrew"
else: print "Dalke"

Even this is almost always too compact for readability.

> 14) Conditional expression. Yes, I'd love it.
>
> cond ? yes : no

rejected. See
http://python.org/peps/pep-0308.html

> 15) Better formatting for repr()
>
> repr(1.1) == '1.1'
>
> If the parser recognizes 1.1 as a certain number, I can't see
> any reason why it should print it as 1.1000000000000001 for
> the next parser run.

Then use 'str', or "%2.1f" % 1.1

What you want (a parser level change) makes
a = 1.1
repr(a)

different from
repr(1.1)

That's not good.

Note that 1.1 cannot be represented exactly in IEEE 754
math. Following IEEE 754 is a good thing. What is your
alternative math proposal?

> 16) Depreciated/obsolete items:
>
> -- No `...` as short form of repr();

I agree. I believe this is one of the things to be removed
for Python 3.

> -- No '\' for continuation lines -- you can always use parenthesis;

I agree. I believe this is one of the things to be removed
for Python 3.

> -- No else for while,for,try etc -- they sound very unnatural;

I've found 'else' very useful for a few cases which once required
ugly flags.

> -- Ellipsis -- it looks like an alien in the language.

As you can see, I proposed a new way to use ellipsis. In real
life I almost never use the ....

> I do believe that these changes follow the spirit of the language
> and help Python to become an even better language.

Given how many new looping constructs you want, I disagree
with your understanding of the spirit of the language.

Andrew
da...@dalkescientific.com


David M. Wilson

unread,
Nov 10, 2003, 6:52:20 PM11/10/03
to
"Georgy Pruss" <SEE_AT_...@hotmail.com> wrote in message news:<JEJrb.76675$v82.4...@twister.southeast.rr.com>...


> -- No `...` as short form of repr();

I have to agree here, the backtick syntax makes no sense to me at all.
Distinguishing between backticks and single quotes can be hard,
especially at 4am. On top of that, the syntax does not hint at what it
does, unless the reader is a unix type who has used backward shells
and languages all his life. :)

Even then, why repr()? Why not eval() or <insert crazy os.popen
shortcut>?


> -- No '\' for continuation lines -- you can always use parenthesis;

When reading complex expressions at speed, I have found that bumping
into a '\' in the absence of another continuation indicator (eg.
indentation) improves my ability to comprehend what I am reading. Once
again, this is one of those "4am'ers":

a = x/y+(1^2+(3+u(b(4**5)))//3
...

Quickly now! Without counting the parens, is the expression complete?
Time's up. Now:

a = x/y+(1^2+(3+u(b(4**5)))//3 \
...


David.

Ron Adam

unread,
Nov 10, 2003, 7:10:13 PM11/10/03
to
On Mon, 10 Nov 2003 22:11:53 GMT, Alex Martelli <al...@aleax.it>
wrote:

>Ron Adam wrote:


Thanks for the detailed explanation. I would only suggest 'while:' if
there was a performance advantage. Since there is none, the only
plus is it save two keystrokes. That isn't reason enough to change
something that isn't broken.

Thanks for showing me how to use compile() and dis().

>>> x=compile('while 1: pass','<str>','exec')
>>> dis.dis(x)
1 0 SETUP_LOOP 12 (to 15)


3 JUMP_FORWARD 4 (to 10)

6 JUMP_IF_FALSE 4 (to 13)
9 POP_TOP
>> 10 JUMP_ABSOLUTE 10
>> 13 POP_TOP
14 POP_BLOCK
>> 15 LOAD_CONST 1 (None)
18 RETURN_VALUE

Yes, this is as short as it gets. :-)

In the case of using 'while 1:' it seems to me you end up loosing
what you gain because you have to test inside the loop which is more
expensive than testing at the 'while' statement.

>>> x=compile('a=1\nwhile a:\n a=0','<str>','exec')
>>> dis.dis(x)
1 0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (a)

2 6 SETUP_LOOP 18 (to 27)
>> 9 LOAD_NAME 0 (a)
12 JUMP_IF_FALSE 10 (to 25)
15 POP_TOP

3 16 LOAD_CONST 1 (0)
19 STORE_NAME 0 (a)
22 JUMP_ABSOLUTE 9
>> 25 POP_TOP
26 POP_BLOCK
>> 27 LOAD_CONST 2 (None)
30 RETURN_VALUE


>>> x=compile('a=1\nwhile 1:\n a=0\n if a==0:\n break','<str>','exec')
>>> dis.dis(x)
1 0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (a)

2 6 SETUP_LOOP 36 (to 45)
>> 9 JUMP_FORWARD 4 (to 16)
12 JUMP_IF_FALSE 28 (to 43)
15 POP_TOP

3 >> 16 LOAD_CONST 1 (0)
19 STORE_NAME 0 (a)

4 22 LOAD_NAME 0 (a)
25 LOAD_CONST 1 (0)
28 COMPARE_OP 2 (==)
31 JUMP_IF_FALSE 5 (to 39)
34 POP_TOP

5 35 BREAK_LOOP
36 JUMP_ABSOLUTE 9
>> 39 POP_TOP
40 JUMP_ABSOLUTE 16
>> 43 POP_TOP
44 POP_BLOCK
>> 45 LOAD_CONST 2 (None)
48 RETURN_VALUE
>>>

This requires twice as many instructions, 12 vs 6. So it's probably
better to avoid 'while 1:' or 'while True': if possible. But it is
nice to know 'while 1:' is 20% faster than 'while True:' in those
situations where you need to use it.

_Ron Adam


Georgy Pruss

unread,
Nov 10, 2003, 9:57:25 PM11/10/03
to
Thank you all for the comments.

Dave Benjamin

unread,
Nov 11, 2003, 1:59:19 AM11/11/03
to
In article <eppstein-8D1264...@news.service.uci.edu>, David Eppstein wrote:
> In article <vqvuih9...@news.supernews.com>,
> "John Roth" <newsg...@jhrothjr.com> wrote:
>
>> Making them keywords isn't exactly correct. There's a movement
>> to make just about everything in the built-in scope immutable and
>> not rebindable at any lower scope for performance reasons. The
>> usual example is the len() built-in function. All this function does is
>> call the __len__() method on the object; the extra function call
>> is a complete waste of time, and could be eliminated if the
>> compiler could depend on len() never being modified or
>> rebound at any level.
>
> This would also have the advantage of more quickly catching certain
> common programming errors....

This would break backward compatibility, especially with some of the more
popular variable names like "file" and "list" (most of us know not to do
that these days, but they're such tasty words, I'm sure there's enough code
out there to make the restriction painful).

I seem to remember Guido being opposed to command-line arguments that change
the language, but it seems like this could be a good opportunity for an
argument that locks down built-ins.

--
.:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :

Michele Simionato

unread,
Nov 11, 2003, 3:03:02 AM11/11/03
to
"John Roth" <newsg...@jhrothjr.com> wrote in message news:

> There's a movement
> to make just about everything in the built-in scope immutable and
> not rebindable at any lower scope for performance reasons.

I am a bit worried by this movement. While I have found no reason to twick
the builtins in production code, I have found specific situations where
the ability of tinkering with the builtins is extremely convenient.
Typically this happens in the debugging phase. For instance I have used
tricks such as modifying the `object` class to induce tracing capabilities
on all my classes, withouth touching my source code.

So, I would be happy with the following:

1. by default builtins cannot be changed, resulting in a performance
benefit;

2. nevertheless, it is possible to use a command line switch to revert
to the current behavior.

If the project is to kill option 2, then I would be unhappy :-(


Michele

Andrew Dalke

unread,
Nov 11, 2003, 4:01:09 AM11/11/03
to
Just to highlight a new suggestion I made that I hadn't seen before,
use eillipsis ("...") at the end of a list assignment to mean "ignore the
rest of
the RHS." This would allow a style of enum definition like

class Keywords:
AND, ASSERT, BREAK, CLASS, CONTINUE, DEF, \
DEL, ELIF, YIELD, ... = itertools.count()

class consts:


A, B, C, ... = itertools.count()

D, E, F, G, H, ... = itertools.count(10)

This could also be used in

calendar.py has
year, month, day, hour, minute, second = tuple[:6]
which would become
year, month, day, hour, minute, second, ... = tuple

and of course for
(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
in that same file.

HOWEVER, those are effectively the only two places in the top-level
Python lib which would use this construct correctly. There are places
where it can be used incorrectly, because I think changing
OK, BOOM, FAIL = range(3)
into
OK, BOOM, FAIL, ... = itertools.count()
is overkill -- there should be at least 5 elements before this ... is
useful.

and I think changing
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
into
FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT, ... = x*x for x in
itertools.count(1)
is just plain stupid.

Therefore I withdraw this proposal, leaving it for contemplation and
posterity's.

Plus, if accepted then should the following be allowed?

..., x, y, z = itertools.count(100) # get the last three elements
a, b, c, ..., x, y, z = itertools.count(100) # get the first three and
last three elements
?

Andrew
da...@dalkescientific.com


Alexander Schmolck

unread,
Nov 11, 2003, 4:30:00 AM11/11/03
to
"Andrew Dalke" <ada...@mindspring.com> writes:

> Just to highlight a new suggestion I made that I hadn't seen before,
> use eillipsis ("...") at the end of a list assignment to mean "ignore the
> rest of
> the RHS." This would allow a style of enum definition like
>
> class Keywords:
> AND, ASSERT, BREAK, CLASS, CONTINUE, DEF, \
> DEL, ELIF, YIELD, ... = itertools.count()

IMHO, this is a not such a good way to define enums. Why not do

AND, ASSERT, BREAK, CLASS, etc == "AND, ASSERT, BREAK, CLASS, etc".split(", ")

This is almost as easy to type (or rather paste) and you shouldn't loose
comparison efficiency as long as you compare with 'is':

``if thingy is CLASS: blah``

and you've got the significant advantage that screw-ups are less likely and
you automatically get sensible print values. If you need equality comparisons
often maybe ``map(intern,...`` would help, but I don't know about that.

Nonetheless I think would really like see something along those lines because
I think there a plenty other good uses (especially, as you suggest in
combination with iterators).I'd also like to have the apply-* work in
assignments, e.g. ``first, second, *rest = someList``. This would also make
python's list destructuring facilities much more powerful.

'as

Alex Martelli

unread,
Nov 11, 2003, 5:39:32 AM11/11/03
to
Alexander Schmolck wrote:
...

> IMHO, this is a not such a good way to define enums. Why not do
>
> AND, ASSERT, BREAK, CLASS, etc == "AND, ASSERT, BREAK, CLASS,
> etc".split(", ")

Unfortunately, this breaks the "once, and only once" principle: you
have to ensure the sequence of words is the same on both sides -- any
error in that respect during maintenance will cause small or big
headaches.

> and you've got the significant advantage that screw-ups are less likely

I disagree with you on this point. Any time two parts of a program
have to be and remain coordinated during maintenance, screw-ups'
likelihood unfortunately increases.

Keeping enum values in their own namespace (a class or instance) is
also generally preferable to injecting them in global namespace,
IMHO. If you want each constant's value to be a string, that's easy:

class myenum(Enum):
AND = ASSERT = BREAK = CLASS = 1

with:

class Enum: __metaclass__ = metaEnum

and:

class metaEnum(type):
def __new__(mcl, clasname, clasbases, clasdict):
for k in clasdict:
clasdict[k] = k
return type.__new__(mcl, clasname, clasbases, clasdict)

The problem with this is that the attributes' _order_ in the
classbody is lost by the time the metaclass's __new__ runs, as
the class attributes are presented as a dictionary. But if the
values you want are strings equal to the attributes' names, the
order is not important, so this works fine.

But many applications of enums DO care about order, sigh.


> in combination with iterators).I'd also like to have the apply-* work in
> assignments, e.g. ``first, second, *rest = someList``. This would also
> make python's list destructuring facilities much more powerful.

Yes, I agree on this one. Further, if the "*rest" was allowed to
receive _any remaining iterable_ (not just necessarily a list, but
rather often an iterator) you'd be able to use itertools.count()
and other unbounded-iterators on the RHS.


Alex

Alex Martelli

unread,
Nov 11, 2003, 5:47:46 AM11/11/03
to
Andrew Dalke wrote:
...

> and I think changing
> FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
> into
> FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT, ... = x*x for x in
> itertools.count(1)
> is just plain stupid.

Not necessarily stupid, but it sure IS semantics-altering (as well
as syntactically incorrect in the proposed 2.4 syntax for genexps --
you'll need parentheses around a genexp) -- a sequence of squares
rather than one of powers of two.
(2**x for x in itertools.count()), however, would be fine:-).


> Therefore I withdraw this proposal, leaving it for contemplation and
> posterity's.

I think you just grabbed the record for shortest-lived proposal
in Python's history. Applause, applause!-).


Alex

Alex Martelli

unread,
Nov 11, 2003, 6:17:21 AM11/11/03
to
Michele Simionato wrote:

Sounds reasonable to me. If nailing down built-ins is seen as good
_only_ for performance, then perhaps the same -O switch that already
exists could be used. Personally, I think nailing down built-ins may
also be good for clarity in most cases, so I would prefer a more
explicit way to request [2]. However, we would then need a third
file-extension besides .pyc and .pyo -- clearly you would not want
the same bytecode for the "builtins nailed down" and "builtins can
be modified" modes; and that might pose some problems -- so perhaps
sticking to -O would be better overall.

I think that discussing the possibilities here is productive only up
to a point, so you might want to come to python-dev for the purpose,
at least when some clarification of possibilities has been reached.


Alex

Alexander Schmolck

unread,
Nov 11, 2003, 7:12:34 AM11/11/03
to al...@aleax.it
Alex Martelli <al...@aleax.it> writes:

> Alexander Schmolck wrote:
> ...
> > IMHO, this is a not such a good way to define enums. Why not do
> >
> > AND, ASSERT, BREAK, CLASS, etc == "AND, ASSERT, BREAK, CLASS,
> > etc".split(", ")
>
> Unfortunately, this breaks the "once, and only once" principle: you
> have to ensure the sequence of words is the same on both sides -- any
> error in that respect during maintenance will cause small or big
> headaches.

True, but I'd still prefer this one (+ editor macro) in most cases to
(ab)using numbers as symbols (this was my main point; I'm sure I could also
think of various hacks to avoid the duplication and do the the stuffing in the
global namespace implicitly/separately -- if it must go there at all costs).
The main advantage the above has over custom enum types is that it's
immediately obvious. Maybe the standard library should grow a canonical enum
module that adresses most needs.


> Keeping enum values in their own namespace (a class or instance) is
> also generally preferable to injecting them in global namespace,
> IMHO.

Yep, this would also be my preference. I'd presumably use something like

DAYS = enum('MON TUE WED [...]'.split())

maybe even without the split.


> If you want each constant's value to be a string, that's easy:

Doesn't have to be, strings are just the simplest choice for something with a
sensible 'repr' (since you might want some total order of your enums a class
might be better -- if one goes through the trouble of creating one's own enum
mechanism).

>
> class myenum(Enum):
> AND = ASSERT = BREAK = CLASS = 1
>
> with:
>
> class Enum: __metaclass__ = metaEnum
>
> and:
>
> class metaEnum(type):
> def __new__(mcl, clasname, clasbases, clasdict):
> for k in clasdict:
> clasdict[k] = k
> return type.__new__(mcl, clasname, clasbases, clasdict)

Yuck! A nice metaclass demo but far too "clever" and misleading for such a
simple task, IMO.

>
> The problem with this is that the attributes' _order_ in the
> classbody is lost by the time the metaclass's __new__ runs, as
> the class attributes are presented as a dictionary. But if the
> values you want are strings equal to the attributes' names, the
> order is not important, so this works fine.
>
> But many applications of enums DO care about order, sigh.

If that prevents people from using the above, I'd consider it a good thing ;)

>
>
> > in combination with iterators).I'd also like to have the apply-* work in
> > assignments, e.g. ``first, second, *rest = someList``. This would also
> > make python's list destructuring facilities much more powerful.
>
> Yes, I agree on this one. Further, if the "*rest" was allowed to
> receive _any remaining iterable_ (not just necessarily a list, but
> rather often an iterator) you'd be able to use itertools.count()
> and other unbounded-iterators on the RHS.

Indeed, as I noted in my previous post, iterators and such extensions would go
very well together.

'as

Peter Hansen

unread,
Nov 11, 2003, 9:59:13 AM11/11/03
to
Michele Simionato wrote:
>
> "John Roth" <newsg...@jhrothjr.com> wrote in message news:
> > There's a movement
> > to make just about everything in the built-in scope immutable and
> > not rebindable at any lower scope for performance reasons.
>
> I am a bit worried by this movement. While I have found no reason to twick
> the builtins in production code, I have found specific situations where
> the ability of tinkering with the builtins is extremely convenient.
> Typically this happens in the debugging phase. For instance I have used
> tricks such as modifying the `object` class to induce tracing capabilities
> on all my classes, withouth touching my source code.

Another use case I've raised in the past, and I believe it is accepted
that it is a valid one, is in automated unit testing or acceptance testing
where it is often extremely beneficial to be able to "mock" a builtin by
replacing it with a custom test method.

For us, the most common use of this is to change open() to return a
special mock file object which doesn't actually cause any disk access.

Removing the ability to do this would cripple our ability to properly
test some code.

Alex' suggestion of using -O to switch to a mode where builtins are
static is okay as far as it goes, but it would prevent proper testing
of code that relies on the aforementioned technique when one wishes
to verify that the standard -O improvements still work. I'd vote for
decoupling this behaviour from the rest of -O, as Michele suggests.

-Peter

Alex Martelli

unread,
Nov 11, 2003, 10:07:46 AM11/11/03
to
Alexander Schmolck wrote:
...

>> > AND, ASSERT, BREAK, CLASS, etc == "AND, ASSERT, BREAK, CLASS,
>> > etc".split(", ")
>>
>> Unfortunately, this breaks the "once, and only once" principle: you
>> have to ensure the sequence of words is the same on both sides -- any
>> error in that respect during maintenance will cause small or big
>> headaches.
>
> True, but I'd still prefer this one (+ editor macro) in most cases to
> (ab)using numbers as symbols (this was my main point; I'm sure I could

I'm used to take bus 20 to go downtown. And perhaps some of my ancestors
fought in the VII Legio (also known by nicknames such as Gemina and Felix,
and not to be confused with the _other_ VII Legio, also known as Claudia
and Pia). If using numbers just as arbitrary tags used to distinguish
items is "abuse", then there's been enough of that over the last few
millennia -- and there's by far enough of it in everyday life today --
that to keep considering it "abuse" is, IMHO, pedantry.

All the more so, when we also want our "tags" to have _some_ of the
properties of numbers (such as order) though not all (I'm not going
to "add" buses number 20 and 17 to get bus number 37, for sure).

> also think of various hacks to avoid the duplication and do the the
> stuffing in the global namespace implicitly/separately -- if it must go
> there at all costs). The main advantage the above has over custom enum
> types is that it's immediately obvious. Maybe the standard library should
> grow a canonical enum module that adresses most needs.

"A canonical enum module" would be great, but the probability that a
design could be fashioned in such a way as to make _most_ prospective
users happy is, I fear, very low. Anybody's welcome to try their hand
at a pre-PEP and then a PEP, of course, but I suspect that enough
consensus on what features should get in will be hard to come by.


>> Keeping enum values in their own namespace (a class or instance) is
>> also generally preferable to injecting them in global namespace,
>> IMHO.
>
> Yep, this would also be my preference. I'd presumably use something like
>
> DAYS = enum('MON TUE WED [...]'.split())
>
> maybe even without the split.

Sure, if you have an 'enum' factory function or type you may choose
to have it do its own splitting. But if DAYS.MON and DAYS.WED are
just strings, so you cannot _reliably_ test e.g. "x > DAYS.WED" in
the enumeration order, get "the next value after x", and so on, then
I fear your enum will satisfy even fewer typical, widespread
requirements than most other proposals I've seen floating around
over the years.


>> If you want each constant's value to be a string, that's easy:
>
> Doesn't have to be, strings are just the simplest choice for something
> with a sensible 'repr' (since you might want some total order of your
> enums a class might be better -- if one goes through the trouble of
> creating one's own enum mechanism).

I don't think a repr of e.g. 'TUE' is actually optimal, anyway --
"DAYS.TUE" might be better (this of course would require the enum
builder to intrinsically know the name of the object it's building --
which again points to a metaclass as likely to be best).

But representation has not proven to be the crucial issue for enums in
C, and this makes me doubt that it would prove essential in Python; the
ability to get "the next value", "a range of values", and so on, appear
to meet more needs of typical applications, if one has to choose. Sure,
having both (via a type representing "value within an enumeration")
might be worth engineering (be that in a roll-your-own, or standardized
PEP, for enum).

I _think_ the rocks on which such a PEP would founder are:
-- some people will want to use enums as just handy collections of
integer values, with the ability, like in C, to set FOO=23 in the
middle of the enum's definition; the ability to perform bitwise
operations on such values (using them as binary masks) will likely
be a part of such requests;
-- other people will want "purer" enums -- not explicitly settable to
any value nor usable as such, but e.g. iterable, compact over
predecessor and successor operations, comparable only within the
compass of a single enum;
-- (many will pop in with specific requests, such as "any enum must
subclass int just like bool does", demands on str and/or repr,
the ability to convert to/from int or between different enums,
and so on, and so forth -- there will be many such "nonnegotiable
demands", each with about 1 to 3 proponents);
-- enough of a constituency will be found for each different vision
of enums to make enough noise and flames to kill the others, but
not enough to impose a single vision.

This may change if and when Python gets some kind of "optional
interface declarations", since then the constraints of having enums
fit within that scheme will reduce the too-vast space of design
possibilities. But, that's years away.


>> class myenum(Enum):
>> AND = ASSERT = BREAK = CLASS = 1
>>
>> with:
>>
>> class Enum: __metaclass__ = metaEnum
>>
>> and:
>>
>> class metaEnum(type):
>> def __new__(mcl, clasname, clasbases, clasdict):
>> for k in clasdict:
>> clasdict[k] = k
>> return type.__new__(mcl, clasname, clasbases, clasdict)
>
> Yuck! A nice metaclass demo but far too "clever" and misleading for such a
> simple task, IMO.

I disagree that defining an Enum as a class is "clever" or "misleading"
in any way -- and if each Enum is a class it makes a lot of sense to use
a metaclass to group them (with more functionality than the above, of
course). Of course, values such as 'myenum.ASSERT' should be instances
of myenum (that is not shown above, where I made them strings because
that's what you were doing -- the only point shown here is that there
should be no duplication).


>> The problem with this is that the attributes' _order_ in the
>> classbody is lost by the time the metaclass's __new__ runs, as
>> the class attributes are presented as a dictionary. But if the
>> values you want are strings equal to the attributes' names, the
>> order is not important, so this works fine.
>>
>> But many applications of enums DO care about order, sigh.
>
> If that prevents people from using the above, I'd consider it a good thing
> ;)

Oh, it's not hard to substitute that with e.g.

class myenum(Enum):
__values__ = 'AND ASSERT BREAK CLASS'.split()

(or, ditto w/o the splitting) so that order is preserved. But then
we have to check explicitly at class creation time that all the values
are valid identifiers, which is a little bit of a bother -- being able
to _use_ identifiers in the first place would let us catch such errors
automatically and as _syntax_ errors. Unfortunately, we can't do it
without counting, or having an alas very hypothetical construct to mean
"and all the rest goes here", as below.


>> > in combination with iterators).I'd also like to have the apply-* work
>> > in assignments, e.g. ``first, second, *rest = someList``. This would
>> > also make python's list destructuring facilities much more powerful.
>>
>> Yes, I agree on this one. Further, if the "*rest" was allowed to
>> receive _any remaining iterable_ (not just necessarily a list, but
>> rather often an iterator) you'd be able to use itertools.count()
>> and other unbounded-iterators on the RHS.
>
> Indeed, as I noted in my previous post, iterators and such extensions
> would go very well together.

Now _that_ is a PEPworthy idea that might well garner reasonably vast
consensus here. Of course, getting it past python-dev's another issue:-).


Alex

Terry Reedy

unread,
Nov 11, 2003, 12:48:20 PM11/11/03
to

"Paul Rubin" <http://phr...@NOSPAM.invalid> wrote in message
news:7xznf4j...@ruckus.brouhaha.com...
> I've been thinking for a while that Python could benefit from a
fork,
> that's not intended to replace Python for production use for any
group
> of users, but rather to be a testbed for improvements and extensions
> that would allow more concrete experiments than can be done through
> pure thought and the PEP process. Most proposals for Python
> improvements could then be implemented and tried out in the
> experimental platform before being folded back into the regular
> implementation.

This is such a good idea that some of the developers, including Guido,
actually do this for some things in a non-distribution sandbox branch
of the CVS tree. However, PyPy should make such experimentation
practically possible for more of us and much easier for almost
everyone.

TJR


Thomas Bellman

unread,
Nov 11, 2003, 12:52:48 PM11/11/03
to
Alex Martelli <al...@aleax.it> wrote:

> You are heartily welcome to perform the dynamic whole-code analysis
> needed to prove whether True (or any other built-in identifier) may
> or not be re-bound as a side effect of functions called within the
> loop -- including the calls to methods that can be performed by just
> about every operation in the language.

There are other ways. Ways that do change the semantics of the
language somewhat, making it somewhat less dynamic, but my
understanding is that Guido is actually positive to doing so.

It is quite easy to determine whether some code modifies a
specific binding in its own local or global scope. (The use of
'exec' would of course make the analyzer assume that the binding
*is* changed.) You could then add the restriction that a module
may not change the bindings in another modules global or builtin
namespace.


> It seems a very worthy
> research project, which might take good advantage of the results
> of the pypy project (there is plenty of such advanced research that
> is scheduled to take place as part of pypy, but there is also surely
> space for a lot of other such projects; few are going to bear fruit,
> after all, so, the more are started, the merrier).

It almost sounds as if you are implying that doing analysis of
the entire program is something that is almost unheard of. I
don't think you are actually meaning that, but for the benefit of
others, it might be worth noting that there have been compilers
that *do* data flow analysis on entire programs available for
several years now. The MIPS C compiler, or rather the linker,
did global register allocation more than a decade ago, and since
then other compilers have done even more ambitious analysis of
entire programs. I am under the impression that some LISP
compilers have done this too.

(But, yes, I do realize that it is more difficult to do this in a
dynamic language like Python than in a statically typed language
like C.)

If you, as I suspect, really mean that to implement this kind of
code analysis in Python is lots of hard work and involves lots of
trial-and-error testing to determine what is worth-while, then I
heartily agree.


> As there is really no good use case for letting user code rebind the
> built-in names None, True, and False, making them keywords has almost
> only pluses (the "almost" being related to backwards compatibility
> issues),

Note that I have no quibbles with this reasoning.

Skip Montanaro

unread,
Nov 11, 2003, 3:22:52 PM11/11/03
to Thomas Bellman, pytho...@python.org

Thomas> A much better way to achieve the same goal would be to make the
Thomas> optimizer recognize that True isn't re-bound within the loop.

Easier said than done. Given:

while True:
foo()

how do you know that foo() doesn't twiddle Python's builtins?

Thomas> Making the optimizer better would improve the performance of
Thomas> much more code than just 'while True' loops.

What optimizer? ;-)

Skip

Alex Martelli

unread,
Nov 11, 2003, 5:06:13 PM11/11/03
to
Thomas Bellman wrote:

> Alex Martelli <al...@aleax.it> wrote:
>
>> You are heartily welcome to perform the dynamic whole-code analysis
>> needed to prove whether True (or any other built-in identifier) may
>> or not be re-bound as a side effect of functions called within the
>> loop -- including the calls to methods that can be performed by just
>> about every operation in the language.
>
> There are other ways. Ways that do change the semantics of the
> language somewhat, making it somewhat less dynamic, but my
> understanding is that Guido is actually positive to doing so.

Yes, for other built-ins. Not for these -- try assigning to None in Python
2.3 and see the warning. There's just NO use case for supporting None
being assigned to, thus, that was put in immediately; True and False need
to remain syntactically assignable for a while to support code that
_conditionally_ assigns them if they're not already defined, but while it's
therefore unacceptable to have such assignments give _syntax_ errors or
warnings, for the moment, they can nevertheless be blocked (and warned
against) at runtime whenever Guido thinks that's opportune.


> It almost sounds as if you are implying that doing analysis of
> the entire program is something that is almost unheard of. I

Oh, no, I do remember when it was a brand-new novelty in a
production compiler (exactly the MIPS one, on DEC workstations
I believe). Absolutely unusable for any program above toy-level,
of course -- and when we got shiny new workstations twice as
fast as the previous ones, it barely made a dent in the size of
programs it could deal with, since apparently the resources it
consumed went up exponentially with program size. We gritted
our teeth and let it run for some humungous time on the smallest
of the applications we sold, thinking that we'd measure the real
effects and see if it was worth restructuring all of our production
environment around such times.

We never found out what benefits whole-program analysis might
have given, because the resulting program was so bug-ridden it
couldn't perform ANY user-level task in our field (mechanical CAD).
Shutting off the whole-program optimizations gave us a perfectly
usable program, of course, just as we had on every other platform
we supported (a dozen at that time); they were _all_ "whole-program
analysis" bugs. That was basically the end of my interest in the issue
(that was supposed to be a _production_ compiler, it had been years
in research and beta stages already, as I recall...!)

The concept of turning Python's super-lightweight, lightning-fast,
"i don't even _peephole_ optimize" compiler into any semblance of
such a monster, in order to let people code "None=23" rather than
making None a keyword (etc), is _truly_ a hoot. (I realize that's
not what you're advocating, thanks to your clarification at the end,
but the incongruity of the image is still worth at least a smile).


> (But, yes, I do realize that it is more difficult to do this in a
> dynamic language like Python than in a statically typed language
> like C.)

It's a nightmare to do it right for C, and I don't think any production
compiler currently claims to do it (MIPS went up in flames -- pity for
their chips, but their whole-program-analyzer is one thing I _don't_
miss:-). Languages such as Haskell, with a much cleaner and rigid
design, maybe.


> If you, as I suspect, really mean that to implement this kind of
> code analysis in Python is lots of hard work and involves lots of
> trial-and-error testing to determine what is worth-while, then I
> heartily agree.

I don't have to spend lots of hard work to determine that _any_
substantial complication of the compiler for the purpose of letting
somebody code "None=23" is _not_ worthwhile. As for the various
possibilities regarding _optimization_ (which have nothing to do with
wanting to allow assignments to None etc), one of pypy's motivations
is exactly to make such experimentation much easier. But I don't
expect such research to turn into production-use technology in the
bat of an eye.


>> As there is really no good use case for letting user code rebind the
>> built-in names None, True, and False, making them keywords has almost
>> only pluses (the "almost" being related to backwards compatibility
>> issues),
>
> Note that I have no quibbles with this reasoning.

Oh good. "We'll design the language any which way and incredibly
smart optimizers will take care of the rest" has never been Python's
philosophy, and I think its emphasis of simplicity _including simplicity
of implementation_ has served it very well and it would be foolhardy
to chuck it away.


Alex

Andrew Dalke

unread,
Nov 11, 2003, 6:02:38 PM11/11/03
to
Me:

> > and I think changing
> > FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16
> > into
> > FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT, ... = x*x for x in
> > itertools.count(1)
> > is just plain stupid.

Alex:


> Not necessarily stupid, but it sure IS semantics-altering (as well
> as syntactically incorrect in the proposed 2.4 syntax for genexps --
> you'll need parentheses around a genexp) -- a sequence of squares
> rather than one of powers of two.
> (2**x for x in itertools.count()), however, would be fine:-).

Oops! :)

What I considered 'stupid' was changing something that was easy
to verify by eye (1, 2, 4, 8, 16) into something which used a generator
(or list comprehensions; I was experimenting with the new idea) and
is harder to verify by eye.

The generator form has the advantage of allowing new terms to be
added without additional modifications, but given how unchanging
that code is, it's a false savings.

> I think you just grabbed the record for shortest-lived proposal
> in Python's history. Applause, applause!-).

I can do better than that ;)

I propose a requirement that all Python code include the
author's PSU name before the first exectuable statement
in the file. It must be of the form '#PSU: ....' as in

#PSU: Parrot Funny-Walker of Wensleydale

This would let ... err, just a mo', someone's at the


Douglas Alan

unread,
Nov 11, 2003, 7:12:54 PM11/11/03
to al...@aleax.it
Alex Martelli <al...@aleax.it> writes:

> OTOH, the chance that the spelling of True, False and None will change
> is close to that of a snowball in the _upper_ reaches of Hell (the
> _lower_ ones are in fact frozen, as any reader of Alighieri well knows,
> so the common idiom just doesn't apply...:-).

Can someone remind me as to why these are capitalized? They clash
annoyingly with the common coding convention that capitalizes only
classes.

|>oug

Andrew Dalke

unread,
Nov 11, 2003, 7:42:18 PM11/11/03
to
Douglas Alan:
> Can someone remind me as to why [None, True, False] are

> capitalized? They clash annoyingly with the common coding
> convention that capitalizes only classes.

Here's a conjecture -- those are singletons, and note that classes
are singletons too.

Andrew
da...@dalkescientific.com


Dave Benjamin

unread,
Nov 11, 2003, 8:12:15 PM11/11/03
to
In article <Klfsb.7716$nz....@newsread2.news.pas.earthlink.net>, Andrew Dalke wrote:
> Douglas Alan:
>> Can someone remind me as to why [None, True, False] are
>> capitalized? They clash annoyingly with the common coding
>> convention that capitalizes only classes.
>
> Here's a conjecture -- those are singletons, and note that classes
> are singletons too.

And so are modules... ;)

Andrew Dalke

unread,
Nov 11, 2003, 11:48:40 PM11/11/03
to
Dave Benjamin:

> And so are modules... ;)

True. But there's only rough consistancy on how those are
capitalized.

Andrew
da...@dalkescientific.com


Patrick Maupin

unread,
Nov 12, 2003, 12:15:44 AM11/12/03
to
Alexander Schmolck wrote:

> True, but I'd still prefer this one (+ editor macro) in most cases to
> (ab)using numbers as symbols (this was my main point;

I think comp.lang.lisp is the group for language features which
mortals cannot cope with absent the aid of editor machinery :)

Pat

Dave Benjamin

unread,
Nov 12, 2003, 1:32:15 AM11/12/03
to
In article <IYisb.7991$nz....@newsread2.news.pas.earthlink.net>, Andrew Dalke wrote:
> Dave Benjamin:
>> And so are modules... ;)
>
> True. But there's only rough consistancy on how those are
> capitalized.

I thought the old rule of thumb was that if its main purpose was to expose a
class, name it after that class (and capitalize), otherwise, name it after
the concept it represents, in lower case.

If you were to use a module as a singleton value or namespace, would you
capitalize it?

Just curious,
Dave

Michele Simionato

unread,
Nov 12, 2003, 2:19:33 AM11/12/03
to
"Andrew Dalke" <ada...@mindspring.com> wrote in message news:<Klfsb.7716$nz....@newsread2.news.pas.earthlink.net>...

Better to say: singletons are classes. But True and False are not
classes (no '__base__' attribute, for instance) so they are not
singletons.

I think using smallcaps would have been more consistent.
BTW, I would have been favorable to "Staticmethod", "Classmethod", "Super",
etc. since they are all classes. But it is useless to protest now :-(

Michele Simionato

Andrew Dalke

unread,
Nov 12, 2003, 3:12:40 AM11/12/03
to
Dave Benjamin:

> I thought the old rule of thumb was that if its main purpose was to expose
a
> class, name it after that class (and capitalize), otherwise, name it after
> the concept it represents, in lower case.

For the most part, yes. But consider 'cStringIO'. And why is
'gzip' not named GzipFile? (Or both named 'Gzip'?)

> If you were to use a module as a singleton value or namespace, would you
> capitalize it?
>
> Just curious,

I'm trying to think of a time when I've used a module as anything
other than a module, that is, where the normal module naming
guidelines applied. I can't think of one.

I have used a class as a singleton, eg, if I really need
to know if one argument was passed in or two. (This
is rarely needed and should almost never be used in
real code.)

class _default:
pass

def f(a, b = _default):
if b is _default:
print "One parameter"
else:
print "Two parameters"

Here I used lower-case. I think that's what I normally do.
However, I'm one who would have had that 'True' and
'False' be in lower-case. My comment about how the
singleton nature affects the capitalization was conjecture.

I've not seen that conjecture presented before. I'm now
wondering if it doesn't actually make some decent sense,
so that my own singletons -- where there is a fundamental
expectation for singleton-ness in the object model and
not just an aspect of the implementation -- will get a
leading capitalization.

To make things even more complicated, it wasn't until
the MOP that it was possible to have a true user-defined
singleton instance.

(Hmm. If I have an Atom class with a reference to
an Element then the Element should be a singleton and
will be named Tungston or Scandium or Helium ... or
maybe W, Sc, He. In any case, leading upper case.)

Andrew
da...@dalkescientific.com


Andrew Dalke

unread,
Nov 12, 2003, 3:32:36 AM11/12/03
to
Michele Simionato

> Better to say: singletons are classes. But True and False are not
> classes (no '__base__' attribute, for instance) so they are not
> singletons.

I don't follow your statement.

Not all singletons are classes. Imported modules are
singletons, yes? And as an implementation choice the
numbers -1 to 100 are singletons as are the single character
byte strings. (Implementation choice since the spec requires
that None references a singleton but not that 1 and 3-2
always reference the same object.)

>>> import sys
>>> sys.__base__
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
AttributeError: 'module' object has no attribute '__base__'
>>> (1).__base__
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
AttributeError: 'int' object has no attribute '__base__'
>>>

> I think using smallcaps would have been more consistent.

Well, I do too. Just conjecturing.

Andrew
da...@dalkescientific.com


Alex Martelli

unread,
Nov 12, 2003, 4:12:42 AM11/12/03
to
Michele Simionato wrote:
...

> BTW, I would have been favorable to "Staticmethod", "Classmethod",
> "Super", etc. since they are all classes. But it is useless to protest now
> :-(

Well, understanding is never useless. So could you please clarify why
you think of (e.g.) staticmethos as needing a different capitalization
from (e.g.) int?

>>> type(staticmethod)
<type 'type'>

>>> type(int)
<type 'type'>

Why is staticmethod "a class" to you while int presumably isn't?

To me, personally, all of this debates only underscores yet again the
one serious "ergonomic" defect in Python's syntax -- case sensitivity.

The desire to distinguish between uppercased "classes" and lowercased
"types" when they're becoming undistinguishable by design in the
language is (in my warped worldview) due to having case sensitivity
in the language at all. Ah well, I've basically lost that debate in
the past, already!


Alex

Michele Simionato

unread,
Nov 12, 2003, 9:06:00 AM11/12/03
to
"Andrew Dalke" <ada...@mindspring.com> wrote in message news:<Eemsb.8193$nz....@newsread2.news.pas.earthlink.net>...

> Michele Simionato
> > Better to say: singletons are classes. But True and False are not
> > classes (no '__base__' attribute, for instance) so they are not
> > singletons.
>
> I don't follow your statement.
>
> Not all singletons are classes. Imported modules are
> singletons, yes? And as an implementation choice the
> numbers -1 to 100 are singletons as are the single character
> byte strings. (Implementation choice since the spec requires
> that None references a singleton but not that 1 and 3-2
> always reference the same object.)

It is solely a matter of conventions. I am used to the definition
"a singleton is a class with only one instance". According to this
definition a singleton is a class. But it is true that a lot of
people extend the meaning to modules or numbers, so you are also
right. It is unfortunate that many concept in CS are not very well
defined (or, even if well defined, the right definition is not
universally known).

Michele

Michele Simionato

unread,
Nov 12, 2003, 9:20:00 AM11/12/03
to
Alex Martelli <al...@aleax.it> wrote in message news:<eQmsb.9095$9_.3...@news1.tin.it>...

> Michele Simionato wrote:
> ...
> > BTW, I would have been favorable to "Staticmethod", "Classmethod",
> > "Super", etc. since they are all classes. But it is useless to protest now
> > :-(
>
> Well, understanding is never useless. So could you please clarify why
> you think of (e.g.) staticmethos as needing a different capitalization
> from (e.g.) int?
>
> >>> type(staticmethod)
> <type 'type'>
>
> >>> type(int)
> <type 'type'>
>
> Why is staticmethod "a class" to you while int presumably isn't?

Actually, I would prefer "Int" over ""int" ;)
I am not sure I would like to impose the capitalization (the way Ruby
does) but I would be happier with a strict standard code convention
saying "classes are capitalized". Of course, I am not proposing to
change anything. It is a very minor annoyance I can very well live
with.

> To me, personally, all of this debates only underscores yet again the
> one serious "ergonomic" defect in Python's syntax -- case sensitivity.
>
> The desire to distinguish between uppercased "classes" and lowercased
> "types" when they're becoming undistinguishable by design in the
> language is (in my warped worldview) due to having case sensitivity
> in the language at all. Ah well, I've basically lost that debate in
> the past, already!

I never understood why you advocate case insensitivity. I would expect
case insensitivity to be a source of bugs: for instance, identifiers
with similar names could be confused (es. myfunction vs. myFunction):
one would expect them to be different (at least people coming from
case insensitive languages) whereas they would be the same.
Also, now I can write

ONE=1

and

def one(): return 1

and it is clear that the first name (ONE) refers to a constant
whereas the second name (one) refers to something which is not a constant.
In a case insensitive language I am sure I would risk to override constants
with functions. When I learned C (coming from Basic and Pascal) I
thought case sensitivity was a good idea, why you don't think so?
(you are free to point me to old posts if this, as I suspect, has
been debated to death already ;)

Michele

JCM

unread,
Nov 12, 2003, 10:30:27 AM11/12/03
to
Alex Martelli <al...@aleax.it> wrote:
...

> To me, personally, all of this debates only underscores yet again the
> one serious "ergonomic" defect in Python's syntax -- case sensitivity.

You know this has been discussed repeatedly with opinions expressed on
both sides. Calling it a defect is just incitive.

Hallvard B Furuseth

unread,
Nov 12, 2003, 10:44:45 AM11/12/03
to
David M. Wilson wrote:

>> -- No '\' for continuation lines -- you can always use parenthesis;
>
> When reading complex expressions at speed, I have found that bumping
> into a '\' in the absence of another continuation indicator (eg.
> indentation) improves my ability to comprehend what I am reading.

So use indentation.

> Once again, this is one of those "4am'ers":
>
> a = x/y+(1^2+(3+u(b(4**5)))//3
+ 4)

--
Hallvard

Alex Martelli

unread,
Nov 12, 2003, 11:03:42 AM11/12/03
to
Michele Simionato wrote:
...

>> Why is staticmethod "a class" to you while int presumably isn't?
>
> Actually, I would prefer "Int" over ""int" ;)

A consistent preference -- which will never be satisfied, of course.

So, when I used to have a factory function (as 'int' was), and change
it into a type (or class, same thing), I should rename it and break all
existing programs that would otherwise keep working just fine? Or
would you prefer to bloat the built-in namespace (or module namespace
where such refactoring is going on) by having both 'int' _and 'Int'?

I consider such a desire to distinguish callables that are for the
most part quite polymorphic, such as types/classes on one hand and
factory functions on the other, quite misplaced. Python is all about
signature-based polymorphism: why should we sacrifice the wonders of
this on the altar of "Capitalization"?!

> saying "classes are capitalized". Of course, I am not proposing to
> change anything. It is a very minor annoyance I can very well live
> with.

To me, case sensitivity is somewhat more than a minor annoyance,
though I still live with it because the case-insensitive languages
I know of (such as Lisp) have many more things I don't really like.


> I never understood why you advocate case insensitivity. I would expect
> case insensitivity to be a source of bugs: for instance, identifiers
> with similar names could be confused (es. myfunction vs. myFunction):
> one would expect them to be different (at least people coming from
> case insensitive languages) whereas they would be the same.

People coming from (an exclusive diet of) case _sensitive_ (not, as you
say, INsensitive!) languages would surely expect these identifiers to
be separate, but there are enough people coming from case INsensitive
languages (Pascal, Fortran, Basic, Lisp, ...) to basically even this
factor out. One factor that makes me prefer insensitivity is that
people who meet Python as their _first_ programming language quite
rightly see case-sensitivity as just one more hassle being thrown at
them, since in real life people aren't really case-sensitive. E.g.,
intel's trademark is all-lowercase, but on the website they keep
referring to themselves as uppercase-I Intel and nobody's confused;
hostnames and protocols in URL's are case-insensitive, too, so people
don't particularly have a connection of computers with case-sensitivity;
so are filenames in Windows, the most widespread OS, and MacOS, widely
considered the most user-friendly one (in the default filesystem,
although since it has Unix underneath you can use a case-insensitive
FS on it if you deliberately go for it); etc, etc, ad nauseam.

But people's expectations when they first meet Python are only a
part of it. More relevant is, how usable are the two possibilities?
Case sensitivity means you must basically memorize several more bits
to go with each name -- for no good reason whatsoever. You must
remember that module FCNTL has an all-uppercase name, htmllib all-lower,
cStringIO weirdly mixed, mimetypes lower, MimeWriter mixed, etc, etc --
totally wasted mnemonic effort. Then you get into the single modules
for more of the same -- unless you can know what is conceptualized as
"a class" vs "a type" vs "a function" memorization's your only hope,
and if you DO know it's still learning by rote, incessantly (ah yes,
class dispatcher in module asyncore, that's LOWER-case, ah yes, the
'error' exception class, that's lowercase in sunaudiodev, it's
lowercase in socket, and in anydbm, and thread -- it's uppercase Error
in sunau, and also in shutil, and multifile, and binhex ... and
functions are supposed to start lowercase? Yeah right, look at
imaplib and weep. or stat. or token... And you think your troubles
are over once you've got the casing of the FIRST letter right? HA!
E.g., would the letter 'f' in the word 'file' be uppercased or not
when it occurs within a composite word? Take your pick...
shelve.DbfilenameShelf, zipfile.BadZipfile, zipfile.ZipFile,
mimify.HeaderFile, ...

Basically, you end up looking all of these things up -- again and
again and again -- for no good reason. Case-sensitivity inevitably
causes that, because people sometimes think of e.g. "zipfile" as ONE
word, sometimes as two, so they uppercase the 'f' or not "wantonly".

Some will inevitably say that's just the fault of the human beings
who choose each of these many names -- case sensitivity as an abstract
ideal is pristine and perfect. To which, my witty repartee is "Yeah,
right". When you present me a language whose entire libraries have
been written by superhumanly perfect beings my attitude to case
sensitivity may change. Until you do, I'll surmise that _most_ such
languages and libraries ARE going to be written by humans, and there
really is no added value in me having to memorize or constantly look
up the capitalization of all of these names -- misspellings are bad
enough (and fortunately are generally acknowledged as mistakes, and
fixed, when found, which isn't the case for capitalization issues).

Moreover, many of the distinctions you're supposed to be drawing
with this precious capitalization, allegedly worth making me and a
zillion learners suffer under silly gratuitous mnemonic load, are
distinctions I'd much rather *NOT* see, such as ones between types
and classes (traditionally), or types/classes and factory functions.
Some factory functions get capitalized, like threading.RLock, cause
it's "sorta like a class", some don't, because, hey, it's a function.
More useless distinction and more memorization.

But at least constants, I hear some claim? THOSE are invariably
ALWAYS spelled in all-uppercase...?

"Sure", say I, "just like math.pi"...


> Also, now I can write
>
> ONE=1
>
> and
>
> def one(): return 1
>
> and it is clear that the first name (ONE) refers to a constant
> whereas the second name (one) refers to something which is not a constant.

Except that it is, unless your design intention (unlikely though
possible) is that the user will rebind name 'one' in your module
to indicate some other function object. Unless such is your meaning,
names 'one' and 'ONE' are "constants" in exactly the same sense: you
do not intend those names to be re-bound to different objects. One
of the objects is callable, the other is not, but that's quite another
issue. One is technically immutable -- the other one isn't (you can
set arbitrary attributes on it) but it IS hashable (the attributes
don't enter into the hash(one) computation) which is more often than
not the key issue we care about when discussing mutability. So,
what IS "a constant" in Python? If you wanted to bind a name (asking
implicitly that it never be re-bound) to a "indisputably mutable" (not
hashable) object, how would you capitalize that? Python itself does
not seem to care particularly. E.g.:

>>> def f(): pass
...
>>> f.func_name = 'feep'


Traceback (most recent call last):

File "<stdin>", line 1, in ?
TypeError: readonly attribute
>>> f.func_defaults = ()

I can rebind f.func_defaults, NOT f.func_name -- but they have exactly
the same capitalization. So, no guidance here...


> In a case insensitive language I am sure I would risk to override
> constants with functions.

Why is that any more likely than 'overriding' (e.g.) types (in the old
convention which makes them lowercase) or "variables" (names _meant_
to be re-bound, but not necessarily to functions)? And if you ever use
one-letter names, is G a class/type, or is it a constant?

I consider the desire to draw all of these distinctions by lexical
conventions quite close to the concepts of "hungarian notation", and
exactly as misguided as those.

> When I learned C (coming from Basic and Pascal)
> I thought case sensitivity was a good idea, why you don't think so?

When I learned C (coming from a lot of languages, mostly case
insensitive) I thought case sensitivity was a ghastly idea, and I
still do. Much later I met the concept of "case _preservation_" --
an identifier is to be spelled with the same case throughout, and
using a different casing for it is either impossible or causes an
error -- and THAT one is a concept I might well accept if tools did
support it well (but I suspect it's more suitable for languages
where there are declarations, or other ways to single out ONE
spelling/capitalization of each identifier as the "canonical, mandated"
one -- I'm not sure how I'd apply that to Python, for example).
As long as I could input, e.g., simplexmlrpcserver and have the
editor (or whatever tool) change it to SimpleXMLRPCServer (or
whatever other SpelLing they've chOseN) I wouldn't mind as much.

> (you are free to point me to old posts if this, as I suspect, has
> been debated to death already ;)

Oh, this isn't the first round, but it isn't the second one, either.
It's essentially a discussion on how languages should be designed,
rather than anything that could ever concretely change in Python:
the very existence of "indistinguishable except for spelling" names
such as fileinput and FileInput, random and Random, etc, etc, makes
it certain that this characteristic can never be changed.

Perhaps it's exactly because the discussion is totally moot, that
it keeps getting hot each time it's vented (wanna bet...?-).


Alex

Alex Martelli

unread,
Nov 12, 2003, 11:22:51 AM11/12/03
to
JCM wrote:

Nice word (I admit I had to look it up, but don't feel too bad about
that, because American Heritage didn't know it either:-). But, so
what? Particularly when carefully starting a sentence with "To me,
personally", I _DO_ get to express my opinions, you know, even though
you consider them "[adj] arousing to action or rebellion" (and I
disagree with your opinion of them: I am convinced that no action nor
rebellion can ever remove from Python the wart of case-sensitivity).

If and when people design their own little languages they're quite
likely to model some of their aspects on languages they do know. I
_do_ hope to "arouse to action" some would-be designer of some such
specialized language, enough that they'll consider making said future
minilanguage case-insensitive; if they do, I think the overall amount
of happiness in the world will be (albeit minutely) increased.


Alex

Jay O'Connor

unread,
Nov 12, 2003, 11:35:20 AM11/12/03
to
On Wed, 12 Nov 2003 09:12:42 GMT, Alex Martelli <al...@aleax.it>
wrote:

>To me, personally, all of this debates only underscores yet again the
>one serious "ergonomic" defect in Python's syntax -- case sensitivity.

Prior to Python I was using Smalltalk, which is case sensitive. Like
'case statements' it's something that even after using Python quite
some time I never really even thought about whether the language had
it or not.

Hallvard B Furuseth

unread,
Nov 12, 2003, 12:19:14 PM11/12/03
to
I like some of your suggestions, like enum. Some
particular dislikes:

Georgy Pruss wrote:

> 6) The colon is optional after for,if,try,enum etc. if it is
> followed by a new line.

Sounds to me like this would just make code harder to read, for very
little gain. And harder to parse for editors.

> 7) Built-in regex'es. It would be nice to have built-in regular
> expressions. Probably, some RE functionality can be shared
> with the built-in string class, like presently we can write
> 'x'.encode('y'). For example $str can produce a regex object
> and then s==re can return true if s matches re. This would be
> very good for the switch construction (see below).
> E.g.
> id = $ "[A-Za-z_][A-Za-z0-9_]*"
> if token == id: return token

'token == id' should test if token is the same regexp, not if it
matches. I prefer id.match(token). OTOH, it would be an advantage if
one could write something like $"...".match(token) and have this
automatically perform re.compile, so one didn't have to put regexps one
wanted to be compiled in a variable outside the loop using them.

I don't really care much, though - beacuse I don't use python regexps
much. I use Perl for regexpy code. Decide for yourself if that's an
argument for or against such a change to Python:-)

> 10) Until loop -- repeat the loop body at least one time
> until the condition is true.
>
> until <postcond>
> <stmts>
>
> It's the same as:
>
> <stmts>
> while not <postcond>
> <stmts>

Very surprising semantics. I'd expect that to be the same as:

while not <postcond>
<stmts>

If the while should be executed at the end, put it at the end:

while 1:
<stmts>
until <postcond #1>
<more stmts>
until <postcond #1>

> 12) Selection statement.

Yes!

> 14) Conditional expression. Yes, I'd love it.
>
> cond ? yes : no

Yes! But too late, the vote was lost.

> 16) Depreciated/obsolete items:
> -- No else for while,for,try etc -- they sound very unnatural;

Thanks for bringing this up. I've been wishing there was a way to say
what 'try: ... except: ... else: ...' says, and I didn't know that there
already was one.

--
Hallvard

Douglas Alan

unread,
Nov 12, 2003, 12:35:04 PM11/12/03
to al...@aleax.it
I agree with Alex. Case sensitivity is evil! When color monitors
started becoming common, I began to worry that programming languages
would come to allow you to have blue variable names, and red and green
variables names, and they would all be different. Or maybe even
variable names in mixed color! Then in mixed color and font. I
better be quiet now, lest I give anyone ideas.

|>oug

JCM

unread,
Nov 12, 2003, 12:44:53 PM11/12/03
to
Alex Martelli <al...@aleax.it> wrote:
> JCM wrote:

>> Alex Martelli <al...@aleax.it> wrote:
>> ...
>>> To me, personally, all of this debates only underscores yet again the
>>> one serious "ergonomic" defect in Python's syntax -- case sensitivity.
>>
>> You know this has been discussed repeatedly with opinions expressed on
>> both sides. Calling it a defect is just incitive.

> Nice word (I admit I had to look it up, but don't feel too bad about
> that, because American Heritage didn't know it either:-). But, so
> what? Particularly when carefully starting a sentence with "To me,
> personally", I _DO_ get to express my opinions, you know, even though
> you consider them "[adj] arousing to action or rebellion" (and I
> disagree with your opinion of them: I am convinced that no action nor
> rebellion can ever remove from Python the wart of case-sensitivity).

I took your "To me, personally" to refer to your opinion about what
the debate underscores, not about whether case-sensitivity is a wart.
In any case, not an interesting enough tangent to continue (in my
opinion...).

Peter Hansen

unread,
Nov 12, 2003, 12:53:18 PM11/12/03
to

Not a bad idea... although the implementation would probably require
something like using a special suffix to represent the colour, so the
file could still be saved as ASCII. The editor would of course have
to be smart enough to translate this suffix into the appropriate colour,
and then suppress the suffix. I'm sure vi and that other editor,
whatever it's called, could do that.

Of course, we could also specify the colour separately with new
keywords. We could have different keywords for different things,
such as integers, floats, strings, etc. That way you could reuse
the same variable name for different types of data, without worrying
about conflict. You could see at a glance which was which!

You could also allow custom defined types... let's call them
"type defs" for short. Then you could customize the colouring
for just about any type of variables.

With a large enough palette, you could just reuse the same variable
name for everything, needing only to respect the proper colour for
correct behaviour. Imagine never having to think up variable names
more complicated than "foo".

def foo(foo, foo):
foo = foo + foo.foo()
return [foo for foo in foo(foo.foo) if foo != foo]

(I can't show the proper colourization of the above in the primitive
Usenet medium, so you'll just have to trust me that it works...)

Yes, definitely not a bad idea... ;-)

-Peter

Dave Brueck

unread,
Nov 12, 2003, 12:37:40 PM11/12/03
to python-list
> I like some of your suggestions, like enum.

I wouldn't mind having a standard module include something like this:

class Enumerate(object):
def __init__(self, names):
for number, name in enumerate(names.split()):
setattr(self, name, number)

WORK = Enumerate('NONE WRITE READ SENDFILE CONNECT ACCEPT')

I like it better than C-style enums because it's clear that the element
comes from a particular enumeration, e.g.:

workFlags = WORK.WRITE

-Dave


Jay O'Connor

unread,
Nov 12, 2003, 1:04:54 PM11/12/03
to
On Wed, 12 Nov 2003 12:53:18 -0500, Peter Hansen <pe...@engcorp.com>
wrote:

>Douglas Alan wrote:
>>
>> I agree with Alex. Case sensitivity is evil! When color monitors
>> started becoming common, I began to worry that programming languages
>> would come to allow you to have blue variable names, and red and green
>> variables names, and they would all be different. Or maybe even
>> variable names in mixed color! Then in mixed color and font. I
>> better be quiet now, lest I give anyone ideas.
>
>Not a bad idea... although the implementation would probably require
>something like using a special suffix to represent the colour, so the
>file could still be saved as ASCII. The editor would of course have
>to be smart enough to translate this suffix into the appropriate colour,
>and then suppress the suffix. I'm sure vi and that other editor,
>whatever it's called, could do that.

There's a guy named Roedy Green, I believe, who hangs out in
comp.lang.somethingorother who has been advocating something pretty
close to this for a while. Except that he advocates using a database
based code management so you could store more meta information about
the code in the DB along with the text. This shows up onc.l.smalltalk
occasionally because most Smalltalk implementations do not use
text-file based code management so it fits in well with Smalltalk
schemes already

Peter Otten

unread,
Nov 12, 2003, 1:50:02 PM11/12/03
to
Peter Hansen wrote:

> With a large enough palette, you could just reuse the same variable
> name for everything, needing only to respect the proper colour for
> correct behaviour. Imagine never having to think up variable names
> more complicated than "foo".
>
> def foo(foo, foo):
> foo = foo + foo.foo()
> return [foo for foo in foo(foo.foo) if foo != foo]
>
> (I can't show the proper colourization of the above in the primitive
> Usenet medium, so you'll just have to trust me that it works...)
>
> Yes, definitely not a bad idea... ;-)

See http://www.cnn.com/2000/TECH/computing/09/07/smell.digiscents.reut/
about the now overdue "click-and-sniff" computers.
So, with technology fast advancing, you'd probably better start training
your dog to track down bugs and, ahem... code smells. On the internet,
everybody will know you're coding without a dog soon :-)

Peter


Kristian Ovaska

unread,
Nov 12, 2003, 2:02:10 PM11/12/03
to
Skip Montanaro <sk...@pobox.com>:
> while True:
> foo()
>how do you know that foo() doesn't twiddle Python's builtins?

If could also happen in the loop, right in front of the compiler's
observing eye:

def fun():
import __builtin__
return (setattr, __builtin__, 'True', 0)

while True:
f, builtins, name, value = fun()
f(builtins, name, value)

I recall from theory courses that determining any nontrivial semantic
feature of a program is, in the general case, impossible. Maybe
static-binding languages give enough hints in the syntax that some
analyzis could be done, but Python is very dynamic...

--
Kristian Ovaska - http://www.cs.helsinki.fi/u/hkovaska/

Michael Geary

unread,
Nov 12, 2003, 2:03:26 PM11/12/03
to
Douglas Alan:

Too late.

http://www.colorforth.com/

-Mike


Nick Vargish

unread,
Nov 12, 2003, 2:26:17 PM11/12/03
to
Douglas Alan <nes...@mit.edu> writes:

> I better be quiet now, lest I give anyone ideas.

Too late... have you seen this?

http://www.colorforth.com/

Chuck Moore, a wild and crazy guy... (I mean that in a good way.)

Nick

--
# sigmask || 0.2 || 20030107 || public domain || feed this to a python
print reduce(lambda x,y:x+chr(ord(y)-1),' Ojdl!Wbshjti!=obwAcboefstobudi/psh?')

Douglas Alan

unread,
Nov 12, 2003, 2:37:57 PM11/12/03
to
Nick Vargish <nav+...@bandersnatch.org> writes:

> Douglas Alan <nes...@mit.edu> writes:

>> I better be quiet now, lest I give anyone ideas.

> Too late... have you seen this?

> http://www.colorforth.com/

See? I'm not paranoid -- they really are out to get me!

|>oug

Ron Adam

unread,
Nov 12, 2003, 4:00:46 PM11/12/03
to


Sounds a bit like the windows registry. Since it's there, why not
put a bunch of other stuff in it. <sarcastically> Wouldn't that
just be fantastic. <and even more sarcastically> Then we could have
everything in one convenient place!

I hope nobody is thinking of that approach seriously. It may work
well in places where the use is naturally limited in both scope and
degree, but it becomes unmanageable when the size and content are
allowed to grow with no limits on them.

_Ron Adam

Dave Benjamin

unread,
Nov 12, 2003, 4:05:26 PM11/12/03
to

Hah! With luck, we can reduce the entire discipline of refactoring to merely
applying a perfume bottle to our monitors. We can start a business around
aromatherapy-oriented programming! I can almost smell it now... =)

Jay O'Connor

unread,
Nov 12, 2003, 4:08:11 PM11/12/03
to

>I hope nobody is thinking of that approach seriously. It may work
>well in places where the use is naturally limited in both scope and
>degree, but it becomes unmanageable when the size and content are
>allowed to grow with no limits on them.


If you mean color-coded code with meaning, I don't know.

but if you mean using databases for source-code management, it works
very well and I much prefer it to text file based approaches.

Tim Jarman

unread,
Nov 12, 2003, 4:51:51 PM11/12/03
to python-list
On Wednesday 12 Nov 2003 5:37 pm, Dave Brueck wrote:
> > I like some of your suggestions, like enum.
>

I knocked this up when I was after something similar:

<code linewrap_alert="on">
# Utility class to manage a set of named integer constants within a namespace.

class Enum(object):
"""Class to manage a set of named integer constants within a namespace.

Examples:

Enum("RED", "GREEN", "BLUE") creates constants RED=1, GREEN=2, BLUE=3.
Enum(RED=1, GREEN=2, BLUE=4) creates constants RED=1, GREEN=2, BLUE=4.
Enum("RED", "GREEN", "BLUE", BLACK=0) creates BLACK=0, RED=1, GREEN=2,
BLUE=3.

These values are created as attributes of the Enum instance, thus:

constants = Enum("RED", "GREEN", "BLUE")
constants.RED # -> 1
"""
def __init__(self, *names, **pairs):
"""Create an attribute for each name.

Positional arguments are assigned a sequential integer value
starting from 1.
Named arguments are assigned the supplied value.
"""
self._lookup = {}
value = 1
for name in names:
setattr(self, name, value)
self._lookup[value] = name
value += 1

for name, value in pairs.items():
if hasattr(self, name):
raise ValueError("Name %s specified more than once." %
name)
setattr(self, name, value)
self._lookup[value] = name
value += 1


def lookup(self, value):
"""Return the name corresponding to a given value.

Example:

constants = Enum("RED", "GREEN", "BLUE")
constants.lookup(1) # returns "RED"
"""
return self._lookup[value]

def isValid(self, value):
"""Return True if value is a valid constant, False otherwise.

Example:

constants = Enum("RED", "GREEN", "BLUE")
constants.isValid(1) # returns True
constants.isValid(42) # returns False
"""
return self._lookup.has_key(value)

def __repr__(self):
"""Make a nice description of enum contents."""
desc = ["<enum object at %x: " % id(self)]
bits = []
for value, name in self._lookup.items():
bits.append("%s: %d" % (name, value))
desc.append(", ".join(bits))
desc.append(">")
return "".join(desc)

</code>

I don't claim that this is the One True Answer but it works for me. It has the
advantage of going both ways - it can be handy for debugging if you can map
the value 42 to the name SPAM.

regards,

Tim J (an ex-Delphi programmer :)

Ron Adam

unread,
Nov 12, 2003, 5:09:35 PM11/12/03
to
On Wed, 12 Nov 2003 12:35:04 -0500, Douglas Alan <nes...@mit.edu>
wrote:


I also agree with you and Alex. Although I may differ on the
reasoning.

Since python tends to go the way of user practicality in many cases,
this seems to me to be counter to that. The only reason to use case
sensitivity is as a way to differentiate names. In my opinion its
not needed in python because there are other better ways to
differentiate names.

This is one of the items that consistently caused me errors as I
learned python. It is nearly opposite of some other languages which
used case to emphasize syntax and language specific keywords but
were in them selves non-case sensitive.

For example if a variable was a built in constant, the editor would
capitalize it for me. By doing that it helps to increase readability
and reduce programming errors in the same way that editors use colors.
At the same time it is much easier to type in lowercase and not have
to worry about putting the caps in the right place. That has both
benefits of easy to type lower case and the improved readability of
using mixed case.

Since python is an objective language, many of the names are
properties of objects and follow the form of <object>.<name>. This
feature of python is in my opinion more than enough to keep names from
interfering with each other in most cases. Thus 'foo.True' can be
different from the built in 'True'. And entering 'true' can and
should work in place of 'True' so that both forms are acceptable.
Personally I like 'True' to be capitalized but I don't want to have to
remember to type it in that way.

I think case is a useful tool and adds readability to programs when
used, but I don't think requiring it is necessary. If I have so
many variables that I run out of meaningful names, (I have yet to
write a program that does that), then I probably need to make better
use of lists and tuples.

_Ron Adam

Georgy Pruss

unread,
Nov 12, 2003, 6:13:02 PM11/12/03
to
I like it. Thanks!
G-:

"Dave Brueck" <da...@pythonapocrypha.com> wrote in message news:mailman.673.1068658...@python.org...

Ron Adam

unread,
Nov 12, 2003, 6:18:24 PM11/12/03
to

Both.

But as for using databases for source-code management, I don't think
it should be necessary. The source code itself should contain all the
information required to construct an application. Thus, makefiles
and/or database oriented sorce-code management tools shouldn't be
needed.

My reference to the windows registry was an example of how a seemingly
good idea can become a problem. The registry contains so much
information now it's difficult to manage and is a security risk. The
reference earlier to using a database for keeping all sorts of meta
information is a very similar situation in my opinion.

I'm definitely not against using databases. It's the separation of
related content in such a way that the source code is incomplete
without the other, that I don't like.

_Ron Adam

Rainer Deyke

unread,
Nov 12, 2003, 6:49:57 PM11/12/03
to
Ron Adam wrote:
> The only reason to use case
> sensitivity is as a way to differentiate names.

No. The only reason to use case sensitivity is to let the programmer
recognize names immediately without mentally translating them into a common
case. A language which allows 'sWord' as an alias for 'Sword' is
unnecessarily difficult to read.

Differentiating names is an undesired side effect of case sensitivity.


--
Rainer Deyke - rai...@eldwood.com - http://eldwood.com


Georgy Pruss

unread,
Nov 12, 2003, 7:12:07 PM11/12/03
to

"Alex Martelli" <al...@aleax.it> wrote in message news:yRssb.11182$9_.4...@news1.tin.it...
| <...>

| languages and libraries ARE going to be written by humans, and there
| <...>

| distinctions I'd much rather *NOT* see, such as ones between types
| <...>

| But at least constants, I hear some claim? THOSE are invariably
| ALWAYS spelled in all-uppercase...?
| <...>

Alex, you ARE case-sensitive! And even *MORE* than that. <g>

G-:

--
s='s=;print s[:2]+chr(39)+s+chr(39)+s[2:]';print s[:2]+chr(39)+s+chr(39)+s[2:]


Ron Adam

unread,
Nov 12, 2003, 8:32:51 PM11/12/03
to
On Wed, 12 Nov 2003 23:49:57 GMT, "Rainer Deyke" <rai...@eldwood.com>
wrote:


Once side of this is from the programmers point of view and the other
is from the machine interpreter point of view.

From the interpreters view, case sensitivity is used to differentiate
names in name space.

From the programmers view, it helps us to recognize names.

I don't believe they are mutually exclusive. You can still have caps
and identifiable variables without requiring case sensitivity.

A smart editor can implement case insensitivity without changing
Python. This isn't true case insensitive but it has the same effect
from a programmers point of view. It would need to correct case at
some point to do it. So call it case correcting instead of case
insensitive.


Which would you choose from the following?

As I type in a program:

1: I get an error for using the wrong case at compile time. Then
have to find the problem and correct it. Then try to recompile.

2: I'm very careful to make sure and look up all the proper names
which takes quite a bit of additional time. The program compiles and
runs normally if I didn't have any typos. If I did, then the result
is the same as #1.

3. The editor doesn't do anything special and the compiler ignores
case differences and it compiles and runs normally. I only have to
remember the correct spellings. I can use any editor I choose or have
available with the same result.

4: The editor or IDE matches what I enter to the names and then
substitutes the proper case of the name at some definitive point.
This ensures that the case is correct and the program compiles and
runs normally. If I choose a different editor then see #1 or #2.

5. The editor or IDE matches corrects the case as in #4, and the
compiler which is case insensitive compiles and runs normally. I can
choose any editor. If it doesn't support case correcting then see #3.

My preferences would be in order:

#5, #3, #4, #1, #2

Numbers 1 and 2 are really the same, but #1 is what I'm most likely to
do. Numbers 5 and 3 are basically the same, but #5 uses case
correcting while editing. Number 4 is possible to do now, but I
don't know of any editors that currently do it. It would be a nice
option to include in one I think.

_Ron Adam


Rainer Deyke

unread,
Nov 12, 2003, 9:12:38 PM11/12/03
to
Ron Adam wrote:
> Which would you choose from the following?

Here are the options I see, in order of preference:

1. The compiler enforces a consistent capitalization scheme, preferably
all_lower_case. Note that MixedCase is only consistent if PsychoTheRapist
is a different identifier than Psychotherapist. Different syntactical
elements (identifiers vs keywords) are allowed to use different schemes.

2. Traditional case sensitivity: Bob and bOb are different identifiers.

3. Case insensitity.

What your editor does is an orthogonal issue and irrelevant to me; what my
editor does is let me type what I want without correcting me.

Michele Simionato

unread,
Nov 13, 2003, 12:35:14 AM11/13/03
to
Alex Martelli <al...@aleax.it> wrote in message news:<yRssb.11182$9_.4...@news1.tin.it>...
> So, when I used to have a factory function (as 'int' was), and change
> it into a type (or class, same thing), I should rename it and break all
> existing programs that would otherwise keep working just fine? Or
> would you prefer to bloat the built-in namespace (or module namespace
> where such refactoring is going on) by having both 'int' _and 'Int'?

This is one of the reasons why I said "I am not sure if I want to
enforce the capitalization or if I want a code convention".
A code convention would be better for the situation you are talking
about; the situation I had in mind was a class with an (abused)
__new__ method, such that it works as a function (i.e. does not
return instances of the class). Using a lowercase would document
the fact that the class is intended to be used as a function.
But these are very rare cases, so probably I could live with an
enforced capitalization too.

> > I never understood why you advocate case insensitivity. I would expect
> > case insensitivity to be a source of bugs: for instance, identifiers
> > with similar names could be confused (es. myfunction vs. myFunction):
> > one would expect them to be different (at least people coming from
> > case insensitive languages) whereas they would be the same.
>
> People coming from (an exclusive diet of) case _sensitive_ (not, as you
> say, INsensitive!)

Oops! You understood, it was a misprint ;)

> But people's expectations when they first meet Python are only a
> part of it. More relevant is, how usable are the two possibilities?
> Case sensitivity means you must basically memorize several more bits
> to go with each name -- for no good reason whatsoever. You must
> remember that module FCNTL has an all-uppercase name, htmllib all-lower,
> cStringIO weirdly mixed, mimetypes lower, MimeWriter mixed, etc, etc --
> totally wasted mnemonic effort.

This is more a problem of inconsistent conventions. It is true that
it will disappear with case insensitivity enforced, but somewhat I
don't feel it a reason strong enough.

> Then you get into the single modules
> for more of the same -- unless you can know what is conceptualized as
> "a class" vs "a type" vs "a function" memorization's your only hope,
> and if you DO know it's still learning by rote, incessantly (ah yes,
> class dispatcher in module asyncore, that's LOWER-case, ah yes, the
> 'error' exception class, that's lowercase in sunaudiodev, it's
> lowercase in socket, and in anydbm, and thread -- it's uppercase Error
> in sunau, and also in shutil, and multifile, and binhex ... and
> functions are supposed to start lowercase? Yeah right, look at
> imaplib and weep. or stat. or token... And you think your troubles
> are over once you've got the casing of the FIRST letter right? HA!
> E.g., would the letter 'f' in the word 'file' be uppercased or not
> when it occurs within a composite word? Take your pick...
> shelve.DbfilenameShelf, zipfile.BadZipfile, zipfile.ZipFile,
> mimify.HeaderFile, ...

You are exaggerating a bit. Yes, you are right in your complaints,
but in my experience I never had headaches due to case sensitivity.

>
> > Also, now I can write
> >
> > ONE=1
> >
> > and
> >
> > def one(): return 1
> >
> > and it is clear that the first name (ONE) refers to a constant
> > whereas the second name (one) refers to something which is not a constant.
>
> Except that it is, unless your design intention (unlikely though
> possible) is that the user will rebind name 'one' in your module
> to indicate some other function object. Unless such is your meaning,
> names 'one' and 'ONE' are "constants" in exactly the same sense: you
> do not intend those names to be re-bound to different objects. One
> of the objects is callable, the other is not, but that's quite another
> issue. One is technically immutable -- the other one isn't (you can
> set arbitrary attributes on it) but it IS hashable (the attributes
> don't enter into the hash(one) computation) which is more often than
> not the key issue we care about when discussing mutability.

You are still exaggerating. 99% of times uppercase constants denote
numbers or strings. I don't remember having ever seen an all uppercase
function, even if I am sure you do ;)

> So,
> what IS "a constant" in Python? If you wanted to bind a name (asking
> implicitly that it never be re-bound) to a "indisputably mutable" (not
> hashable) object, how would you capitalize that? Python itself does
> not seem to care particularly. E.g.:
>
> >>> def f(): pass
> ...
> >>> f.func_name = 'feep'
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: readonly attribute
> >>> f.func_defaults = ()
>
> I can rebind f.func_defaults, NOT f.func_name -- but they have exactly
> the same capitalization. So, no guidance here...

Yeah, having read-only attributes distinguished by some code convention
(underscores or capitalization) would be a possibility, but what if in
a future version of Python the read-only attribute becomes writable? I
am use you had this are argument in the back of you mind. Nevertheless,
notice that this is an argument against a too strict code convention,
not against case insensitivity.



> > In a case insensitive language I am sure I would risk to override
> > constants with functions.
>
> Why is that any more likely than 'overriding' (e.g.) types (in the old

oops again, I meant "shadowing" instead of 'overriding' but you understood

> convention which makes them lowercase) or "variables" (names _meant_
> to be re-bound, but not necessarily to functions)? And if you ever use
> one-letter names, is G a class/type, or is it a constant?

I often use lowercase for constants, for instance in mathematical formulas:

a=1
b=2
y=a*x+b

Readability counts more than foolish consistency. Please, remember that
I am not advocating *enforcing* capitalization, even if I would welcome
a more consistent usage of capitalization in the standard library.
What I say is that case sensitivity is convenient, it gives me more
indentifiers for free.

For instance, I can define a matrix type, overload "*" and write the
multiplication of a matrix "A" times a vector "a" as

b=A*a

Much more readable to me, that something like

b=a_matrix*a

or even

b=c*a # c is a matrix

Mathematical formulas are the first reason why I like case sensitivity.



> I consider the desire to draw all of these distinctions by lexical
> conventions quite close to the concepts of "hungarian notation", and
> exactly as misguided as those.

<horrified> Hungarian notation is an abomination you cannot put on
the same foot with case sensitivity! </horrified>

> Much later I met the concept of "case _preservation_" --
> an identifier is to be spelled with the same case throughout, and
> using a different casing for it is either impossible or causes an
> error -- and THAT one is a concept I might well accept if tools did
> support it well (but I suspect it's more suitable for languages
> where there are declarations, or other ways to single out ONE
> spelling/capitalization of each identifier as the "canonical, mandated"
> one -- I'm not sure how I'd apply that to Python, for example).
> As long as I could input, e.g., simplexmlrpcserver and have the
> editor (or whatever tool) change it to SimpleXMLRPCServer (or
> whatever other SpelLing they've chOseN) I wouldn't mind as much.

Case preservation is an interesting concept which would solve some
of my objections against case insensitivity, but not all of them. We would
need more letters!

For example, Scheme and Lisp are case insensitive, but they are richer
than Python in the character set of their identifiers: so they can
distinguish a class from an instance writing something like "c"
for the instance and "c*" or "c#" or "c-" etc. for the class. How would
you do that in Python? "c" for the class and "ac" for the instance? Not
readable at all, IMHO. And think again to mathematical formulae, they
would really suffer from case insensitivity.

> Perhaps it's exactly because the discussion is totally moot, that
> it keeps getting hot each time it's vented (wanna bet...?-).
>

You won ;)

> Alex

Michele

Ron Adam

unread,
Nov 13, 2003, 12:53:32 AM11/13/03
to
On Thu, 13 Nov 2003 02:12:38 GMT, "Rainer Deyke" <rai...@eldwood.com>
wrote:

>Ron Adam wrote:


>> Which would you choose from the following?
>
>Here are the options I see, in order of preference:
>
>1. The compiler enforces a consistent capitalization scheme, preferably
>all_lower_case. Note that MixedCase is only consistent if PsychoTheRapist
>is a different identifier than Psychotherapist. Different syntactical
>elements (identifiers vs keywords) are allowed to use different schemes.

So to you, it is an advantage to be able to use names with the same
spelling and different case combinations for different things. And
you prefer to let the compiler catch your errors when you try and run
your programs in a traditional code, compile, debug, repeat sequence.
Is that correct?

To me, I find the use of names spelled the same with caps in different
places, that are used for different things, to be ambiguous. I would
also prefer as little repetitive debugging as possible.

Not to mention my memory for spelling, including differing case
arrangements, is definitely not one of my strong points as you would
see if I didn't use a spelling checker. So my preferences differ from
yours in this manner for personal reasons. I don't think either of us
is alone in our views.


>2. Traditional case sensitivity: Bob and bOb are different identifiers.

So what is the difference between 'Bob' and 'bOb'? I have no idea.
Even though they are supposedly following some consistent scheme, the
caps don't really help me that much.

Since the bulk of python code is in the form of modules, many of
which are written by different people at different times, and by
third parties, it would be very difficult (if even possible) to
rename and enforce everything to follow a consistent naming scheme.


>3. Case insensitity.

Then 'Bob and 'bOb' would be the same thing. Even though they look a
little different, I can understand this. Simple, easy to remember,
easy to use.


>What your editor does is an orthogonal issue and irrelevant to me; what my
>editor does is let me type what I want without correcting me.

And I believe that's the way it should be for you if that's what you
want. That was options #1,#2, and #3 in my list.

If an option for case insensitivity were implemented it would just be
a matter of doing a lower() function on all source code as a first
step in the compile process. Then case in the source code need not
matter, or you could choose to have it matter if that's what you want.
It probably isn't that simple. I haven't looked into the source code
far enough yet. Doing so would probably cause errors in existing
programs where names do use same spelling/different case for different
things. And it may also break calls to .dll's and .pyd files. There
would also need to be a switch to turn it one way or the other for
compatibility purposes.

Using a case correcting editor is one way of doing it that doesn't
change pythons core and lets the programmer choose the behavior they
want.

_Ron Adam

Terry Reedy

unread,
Nov 13, 2003, 8:46:28 AM11/13/03
to

"Tim Jarman" <tim.j...@lineone.net> wrote in message
news:mailman.682.1068673...@python.org...

> Enum("RED", "GREEN", "BLUE") creates constants RED=1, GREEN=2,
BLUE=3.
> Enum(RED=1, GREEN=2, BLUE=4) creates constants RED=1, GREEN=2,
BLUE=4.
> Enum("RED", "GREEN", "BLUE", BLACK=0) creates BLACK=0, RED=1,
GREEN=2,
> BLUE=3.
...

> I don't claim that this is the One True Answer but it works for me.

The apparent lack of there being One True Answer or even a close
approximation seems to be one of the barriers to a standard lib
module. Other people would rather that Enum("RED", "GREEN", "BLUE")
create constants RED='RED', GREEN='GREEN', BLUE='BLUE'. There have
been serious proposals on Python-Dev that the standard lib use
self-identifying constants that would at least print something more
meaningful than a number. On the other hand, some constants
(weekdays, months) do need to be ordered other than alphabetically.

Terry J. Reedy

Alex Martelli

unread,
Nov 13, 2003, 9:26:42 AM11/13/03
to
Ron Adam wrote:
...

> If an option for case insensitivity were implemented it would just be
> a matter of doing a lower() function on all source code as a first
> step in the compile process. Then case in the source code need not
> matter, or you could choose to have it matter if that's what you want.
> It probably isn't that simple. I haven't looked into the source code
> far enough yet. Doing so would probably cause errors in existing
> programs where names do use same spelling/different case for different

And all uses of standard Python modules such as random and fileinput,
which do exactly that sort of thing systematically.

> Using a case correcting editor is one way of doing it that doesn't
> change pythons core and lets the programmer choose the behavior they
> want.

Nope, can't do. Consider:

>>> import random
>>> x=random.Random()
>>> y=random.random()

now x and y are two VERY different things:

>>> x
<random.Random object at 0x81aa9d4>
>>> y
0.93572104869999828

...but how would a poor "case correcting editor" distinguish them...?

Such a smart editor might HELP a little by SUGGESTING a case-correction
when it appears unambiguous, even just for standard modules and the
functions therein. Maybe a menu-command for "suggest case corrections
if any" WOULD be helpful in IDLE, and offer good cost/benefit ratio as
a fun, not-too-terribly-hard project reducing human misery a bit...:-).


Alex

Alex Martelli

unread,
Nov 13, 2003, 10:17:19 AM11/13/03
to
Michele Simionato wrote:

> Alex Martelli <al...@aleax.it> wrote in message
> news:<yRssb.11182$9_.4...@news1.tin.it>...
>> So, when I used to have a factory function (as 'int' was), and change
>> it into a type (or class, same thing), I should rename it and break all

...


> But these are very rare cases, so probably I could live with an
> enforced capitalization too.

You think it's rare, during refactoring, to change between types and
factory functions?! I suspect you may not have been maintaining and
enhancing code (in languages allowing interchange of the two things)
for long enough. Consider that *ALL* types in Python's builtins started
life as factory functions -- that's 100%... "very rare"?!-)


>> remember that module FCNTL has an all-uppercase name, htmllib all-lower,
>> cStringIO weirdly mixed, mimetypes lower, MimeWriter mixed, etc, etc --
>> totally wasted mnemonic effort.
>
> This is more a problem of inconsistent conventions. It is true that
> it will disappear with case insensitivity enforced, but somewhat I

[[ probably mean "case sensivity enforced" ? ]]

> don't feel it a reason strong enough.

Ruby seems to survive with warnings for capitalization inconsistent
with its favourite conventions, but then it doesn't let you "just call
the class" to instantiate it -- you have to call Theclass.new(23) or
the like. Ooops, was that TheClass.new(23) ...? How is the assumed
"enforcement" going to deal with THESE issues?-)


>> E.g., would the letter 'f' in the word 'file' be uppercased or not
>> when it occurs within a composite word? Take your pick...
>> shelve.DbfilenameShelf, zipfile.BadZipfile, zipfile.ZipFile,
>> mimify.HeaderFile, ...
>
> You are exaggerating a bit. Yes, you are right in your complaints,
> but in my experience I never had headaches due to case sensitivity.

How am I "exaggerating" in claiming that the SAME module, zipfile,
spells "zipfile" differently in the module name itself, in class
zipfile.ZipFile, and in class zipfile.BadZipfile? Maybe you have a
photographic memory so that having seen each of these ONCE you are
never going to forget which ones uppercase exactly which letters, but
even back when my memory was outstanding (when I was younger) it was
always more "auditory" than "visual": I could easily recite by heart
long quotes from books I had read once, but never could recall the
details of punctuation (or capitalization, when non-systematic, as
it often was e.g. in 17th/18th century english) without painstaking
and painful explicit memorization effort.

Should a language cater mostly to the "crowd" (?) of people with
photographic memories, or shouldn't it rather help the productivity
of people whose memories aren't _quite_ that good and/or visual...?


> You are still exaggerating. 99% of times uppercase constants denote
> numbers or strings. I don't remember having ever seen an all uppercase
> function, even if I am sure you do ;)

Maybe my defect is knowing the Python standard library too well? It's
got SEVERAL all-uppercase functions, Michele! Check out modules
difflib (functions IS_LINE_JUNK and IS_CHARACTER_JUNK), gzip
(functions U32 and LOWU32), stat (all the S_IMODE etc functions),
token (functions ISTERMINAL and ISNONTERMINAL)...!

Maybe the sum total IS 1% or so of the functions in the library, but
that's _STILL_ a silly, arbitrary memorization chore which I shouldn't
have had to undergo in the first place -- and I'm not even sure I
have in fact remembered all of them...


>> I can rebind f.func_defaults, NOT f.func_name -- but they have exactly
>> the same capitalization. So, no guidance here...
>
> Yeah, having read-only attributes distinguished by some code convention
> (underscores or capitalization) would be a possibility, but what if in
> a future version of Python the read-only attribute becomes writable? I

Exactly: a silly distinction. So, let's NOT draw it in the first place.

> am use you had this are argument in the back of you mind. Nevertheless,
> notice that this is an argument against a too strict code convention,
> not against case insensitivity.

You seem to argue that case sensitivity is good because it lets you
draw a distinction that, you've just shown, should NOT be drawn. It
seems to me that this is rather one of the reasons that make it BAD:-).


>> > In a case insensitive language I am sure I would risk to override
>> > constants with functions.
>>
>> Why is that any more likely than 'overriding' (e.g.) types (in the old
>
> oops again, I meant "shadowing" instead of 'overriding' but you understood
>
>> convention which makes them lowercase) or "variables" (names _meant_
>> to be re-bound, but not necessarily to functions)? And if you ever use
>> one-letter names, is G a class/type, or is it a constant?
>
> I often use lowercase for constants, for instance in mathematical
> formulas:
>
> a=1
> b=2
> y=a*x+b
>
> Readability counts more than foolish consistency. Please, remember that
> I am not advocating *enforcing* capitalization, even if I would welcome
> a more consistent usage of capitalization in the standard library.
> What I say is that case sensitivity is convenient, it gives me more
> indentifiers for free.

It's anything BUT "for free", as I've been arguing: we pay quite a
price for it. Adding ONE character (a letter, assumed case-insensitive,
digit or underscore) gives you 37 times more identifiers; for identifiers
of length 6, drawing them from an alphabet of 63 rather than 37 chars
gives you just 24.37 times more identifiers -- and you aren't going to
use most of those extra possibilities unless you're TRYING to drive
readers of your code crazy, anyway.


> For instance, I can define a matrix type, overload "*" and write the
> multiplication of a matrix "A" times a vector "a" as
>
> b=A*a
>
> Much more readable to me, that something like

Please note that here you are suddenly and undocumentedly _switching
conventions on the fly_ regarding capitalization. One moment ago,
leading cap had to mean "type" and all caps had to mean "numeric
constant" (which in turn made a single-caracter capital identifier
ambiguous already...) -- now suddenly neither of these conventions
exists any more, since that uppercase A means 'matrix' instead of
'vector' (and a _number_, i.e. even lower dimensionality, would be
indicated *HOW*? Don't you EVER multiply your matrices by scalars?!
Or is it so crucial to distinguish matrices from vectors but totally
irrelevant to distinguish either from scalars?!).

> b=a_matrix*a
>
> or even
>
> b=c*a # c is a matrix
>
> Mathematical formulas are the first reason why I like case sensitivity.

My opinion is that, while _habit_ in mathematical formulas may surely
make one hanker for such case-sensitivity, the preference just does not
stand up to critical analysis, as above. You're trying to overload WAY
too many different and conflicting "conventions" onto a meager "one bit
[at most] per character" (about 0.87 bits I believe, in fact) of
"supplementary information" yielded by case-sensitivity.


>> I consider the desire to draw all of these distinctions by lexical
>> conventions quite close to the concepts of "hungarian notation", and
>> exactly as misguided as those.
>
> <horrified> Hungarian notation is an abomination you cannot put on
> the same foot with case sensitivity! </horrified>

They're both (as generally used) attempts to draw type-distinctions
by means of lexical conventions. Case sensitivity is worse because
it doesn't wreck its damage only at the START of an identifier -- it
percolates INSIDE the identifier, too, making it (absurdly) an error to
try and catch a "zipfile.BadZipFile" or instantiate a "zipfile.Zipfile".


> Case preservation is an interesting concept which would solve some
> of my objections against case insensitivity, but not all of them. We would
> need more letters!

Use 6 instead of 5 letters -- quite sufficient to give you PLENTY
more identifiers to choose from.

Most paladins of case sensitivity would probably be horrified to see
that the main point in its "favour" now appears to be that it
encourages you to use shorter (e.g. 1-letter) identifiers (and thus
more cryptic ones) because it gives you more of them to choose from...!!!


> For example, Scheme and Lisp are case insensitive, but they are richer
> than Python in the character set of their identifiers: so they can
> distinguish a class from an instance writing something like "c"
> for the instance and "c*" or "c#" or "c-" etc. for the class. How would
> you do that in Python? "c" for the class and "ac" for the instance? Not

I've tried (e.g. in Dylan) the concept of having punctuation freely
embeddable in identifiers and didn't particularly like it (I guess it
works better with a NON-infix-syntax language -- I don't recall it
feeling like a problem in either Forth or Scheme -- but in Dylan the
inability of writing a sum as
a+b
because that's an identifier, so you have to write
a + b
instead, _was_ rather uncomfortable to me [maybe I just didn't get
long-enough practice and experience with it]).

> readable at all, IMHO. And think again to mathematical formulae, they
> would really suffer from case insensitivity.

I disagree -- once you have to spell out e.g. pi, capital-sigma, etc,
in Ascii letters anyway, having to make sure you do so in letters that
are unambiguous in terms of capitalization differences is no big loss.
Personally, in terms of formulas, I've never found Fortran any less
readable than C, for example.

And no, I definitely don't want Unicode characters in identifiers --
that would ensure a LOT of new and diverse errors as people use the
wrong "decoration" (accent, circumflex, etc, etc) on letters. Plain
ascii's just great...!-)


Alex

Alex Martelli

unread,
Nov 13, 2003, 10:58:49 AM11/13/03
to
Ron Adam wrote:
...

> 4: The editor or IDE matches what I enter to the names and then
> substitutes the proper case of the name at some definitive point.
> This ensures that the case is correct and the program compiles and
> runs normally. If I choose a different editor then see #1 or #2.
...

> correcting while editing. Number 4 is possible to do now, but I
> don't know of any editors that currently do it. It would be a nice
> option to include in one I think.

Yes, looks like a nice idea for a middling-difficulty project with
IDLE, and it would be useful even if made _particularly_ unintrusive
(spelling correction would be done only on specific request, and
only when feasible without ambiguity regarding e.g. standard library
modules and names therein -- a really minimal part of [4], yet it
would STILL save quite some trouble/hassle to those using it...).


Alex

SBru...@trisystems.co.uk

unread,
Nov 13, 2003, 10:16:17 AM11/13/03
to pytho...@python.org, nes...@mit.edu
> From: Douglas Alan [SMTP:nes...@mit.edu]

>
> I agree with Alex. Case sensitivity is evil! When color monitors
> started becoming common, I began to worry that programming languages
> would come to allow you to have blue variable names, and red and green
> variables names, and they would all be different. Or maybe even
> variable names in mixed color! Then in mixed color and font. I
> better be quiet now, lest I give anyone ideas.

Too late!

http://www.brunningonline.net/simon/blog/archives/000666.html

BTW, some of the other ideas expressed in JSR-666 might be applicable to
Python. I'm thinking particularly of "import *".

;-)

Cheers,
Simon Brunning.


-----------------------------------------------------------------------
The information in this email is confidential and may be legally privileged.
It is intended solely for the addressee. Access to this email by anyone else
is unauthorised. If you are not the intended recipient, any disclosure,
copying, distribution, or any action taken or omitted to be taken in
reliance on it, is prohibited and may be unlawful. TriSystems Ltd. cannot
accept liability for statements made which are clearly the senders own.

Michele Simionato

unread,
Nov 13, 2003, 1:57:40 PM11/13/03
to
Alex Martelli <al...@aleax.it> wrote in message news:<3gNsb.20789$hV.7...@news2.tin.it>...

> Michele Simionato wrote:
>
> > Alex Martelli <al...@aleax.it> wrote in message
> > news:<yRssb.11182$9_.4...@news1.tin.it>...
> >> So, when I used to have a factory function (as 'int' was), and change
> >> it into a type (or class, same thing), I should rename it and break all
> ...
> > But these are very rare cases, so probably I could live with an
> > enforced capitalization too.
>
> You think it's rare, during refactoring, to change between types and
> factory functions?! I suspect you may not have been maintaining and
> enhancing code (in languages allowing interchange of the two things)
> for long enough. Consider that *ALL* types in Python's builtins started
> life as factory functions -- that's 100%... "very rare"?!-)

It is very rare in my own code, but I haven't maintained code written
by others, so I will accept your experience on this.

> >> remember that module FCNTL has an all-uppercase name, htmllib all-lower,
> >> cStringIO weirdly mixed, mimetypes lower, MimeWriter mixed, etc, etc --
> >> totally wasted mnemonic effort.
> >
> > This is more a problem of inconsistent conventions. It is true that
> > it will disappear with case insensitivity enforced, but somewhat I
>
> [[ probably mean "case sensivity enforced" ? ]]

No, this time I really meant case *insensitivity*: if case
insensitivity
was enforced, the issue with FCNTL,cStringIO, MimeWriter, etc. etc.
would
disappear and a normal memory would be enough to grasp everything.



> How am I "exaggerating" in claiming that the SAME module, zipfile,
> spells "zipfile" differently in the module name itself, in class
> zipfile.ZipFile, and in class zipfile.BadZipfile? Maybe you have a
> photographic memory so that having seen each of these ONCE you are
> never going to forget which ones uppercase exactly which letters, but
> even back when my memory was outstanding (when I was younger) it was
> always more "auditory" than "visual": I could easily recite by heart
> long quotes from books I had read once, but never could recall the
> details of punctuation (or capitalization, when non-systematic, as
> it often was e.g. in 17th/18th century english) without painstaking
> and painful explicit memorization effort.

No, I don't have a photographics memory and sometimes (few times,
actually) I don't remember the right capitalization, but few seconds
with the on-line help (trying zipfile or ZipFile or BadZipfile, for
instance) are usually enough to solve the issue. So, as I said,
capitalization does not give big headaches to me. Also, I am
absolutely unconvinced that capitalization gives big headaches to you
(except as a point of principle, of course). I am not saying case
sensitivity is perfect, I am saying its disadvantages (in real life)
are not so serious as you claim. People has written tons of C, but I
am sure capitalization bugs are scarcely relevant as compared, for
instance, to pointer arithmetic bugs ;)


> Should a language cater mostly to the "crowd" (?) of people with
> photographic memories, or shouldn't it rather help the productivity
> of people whose memories aren't _quite_ that good and/or visual...?

I don't have an auditive memory, nor a visual memory, but still I
manage
to survive with case sensitivity, so I guess everybody can do the same
...

> > You are still exaggerating. 99% of times uppercase constants denote
> > numbers or strings. I don't remember having ever seen an all uppercase
> > function, even if I am sure you do ;)
>
> Maybe my defect is knowing the Python standard library too well? It's
> got SEVERAL all-uppercase functions, Michele! Check out modules
> difflib (functions IS_LINE_JUNK and IS_CHARACTER_JUNK), gzip
> (functions U32 and LOWU32), stat (all the S_IMODE etc functions),
> token (functions ISTERMINAL and ISNONTERMINAL)...!

Ubi major, minor cessat ;)

I confess I never used these functions: not only their capitalization
is new to me, but even their names! Still, I am sure that knowing the
names I will be able to remember the capitalization: 100% of times
for all caps identifiers, 80% of times for camel case identifiers.
I do think this is an average performance.

> Maybe the sum total IS 1% or so of the functions in the library, but
> that's _STILL_ a silly, arbitrary memorization chore which I shouldn't
> have had to undergo in the first place -- and I'm not even sure I
> have in fact remembered all of them...

Even if you enforce case insensitivity, the library will still have
inconsistencies due to different code conventions: think to the use of
underscores to separate names, for instance. The standard library
index gives plenty of cases, i.e. "add_something" versus
"addsomething"
etc.


>
> > For instance, I can define a matrix type, overload "*" and write the
> > multiplication of a matrix "A" times a vector "a" as
> >
> > b=A*a
> >
> > Much more readable to me, that something like
>
> Please note that here you are suddenly and undocumentedly _switching
> conventions on the fly_ regarding capitalization. One moment ago,
> leading cap had to mean "type" and all caps had to mean "numeric
> constant" (which in turn made a single-caracter capital identifier
> ambiguous already...) -- now suddenly neither of these conventions
> exists any more, since that uppercase A means 'matrix' instead of
> 'vector' (and a _number_, i.e. even lower dimensionality, would be
> indicated *HOW*? Don't you EVER multiply your matrices by scalars?!
> Or is it so crucial to distinguish matrices from vectors but totally
> irrelevant to distinguish either from scalars?!).

That's rethoric and you know that. As I already said, readability is
more important than foolish consistency; also in the context a matrix
computations, how big is the possibility to misunderstand the
meaning of variables such as

A=Matrix(2,2); b=vector(2); s=scalar() ??

> My opinion is that, while _habit_ in mathematical formulas may surely
> make one hanker for such case-sensitivity, the preference just does not
> stand up to critical analysis, as above. You're trying to overload WAY
> too many different and conflicting "conventions" onto a meager "one bit
> [at most] per character" (about 0.87 bits I believe, in fact) of
> "supplementary information" yielded by case-sensitivity.

I strongly like operator overloading because of my mathematical
background. Mathematicians overloads the meaning of operators all
the time and never get confused, since the context is always made
well clear. Nevertheless, many programmers are against operator
overloading, because it can be abused. In my opinion the advantage
is worth the risk (the same for case sensitivity) but I do accept
that other may disagree. Insisting too much, we risk to enter in
a religious discussion, so it is better to stop here.


>
> Most paladins of case sensitivity would probably be horrified to see
> that the main point in its "favour" now appears to be that it
> encourages you to use shorter (e.g. 1-letter) identifiers (and thus
> more cryptic ones) because it gives you more of them to choose from...!!!

In mathematical formulas, at least, shorter identifiers are clearer,
not more cryptic; also, it is nice to import modules with syntaxes
such as ``import math as m``, using a single letter, which does not
clash with some other ``M`` (for instance the mass of an
object in a Physics program, or a pluggable metaclass in an object
oriented program, or anything else).


>
> I've tried (e.g. in Dylan) the concept of having punctuation freely
> embeddable in identifiers and didn't particularly like it (I guess it
> works better with a NON-infix-syntax language -- I don't recall it
> feeling like a problem in either Forth or Scheme -- but in Dylan the
> inability of writing a sum as
> a+b
> because that's an identifier, so you have to write
> a + b
> instead, _was_ rather uncomfortable to me [maybe I just didn't get
> long-enough practice and experience with it]).

I am against too much punctuation, that's one of the reason why
I do like case insensitivity, so you don't need extra identifiers:
did you miss my point or I am misreading you?

> I disagree -- once you have to spell out e.g. pi, capital-sigma, etc,
> in Ascii letters anyway, having to make sure you do so in letters that
> are unambiguous in terms of capitalization differences is no big loss.
> Personally, in terms of formulas, I've never found Fortran any less
> readable than C, for example.

I don't like Fortran verbosity, but others could agree with you.
That's just a matter of personal preference.



> And no, I definitely don't want Unicode characters in identifiers --
> that would ensure a LOT of new and diverse errors as people use the
> wrong "decoration" (accent, circumflex, etc, etc) on letters. Plain
> ascii's just great...!-)
>

Who wants Unicode characters ?? I am not so foolish yet !!

> Alex

Michele

Tim Hochberg

unread,
Nov 13, 2003, 12:31:51 PM11/13/03
to pytho...@python.org
Alex Martelli wrote:
> Michele Simionato wrote:

[SNIP]

>>For instance, I can define a matrix type, overload "*" and write the
>>multiplication of a matrix "A" times a vector "a" as
>>
>>b=A*a
>>
>>Much more readable to me, that something like
>
>
> Please note that here you are suddenly and undocumentedly _switching
> conventions on the fly_ regarding capitalization.

Non issue, relatively speaking. Context makes this clear.

> One moment ago,
> leading cap had to mean "type" and all caps had to mean "numeric
> constant" (which in turn made a single-caracter capital identifier
> ambiguous already...) -- now suddenly neither of these conventions
> exists any more, since that uppercase A means 'matrix' instead of
> 'vector' (and a _number_, i.e. even lower dimensionality, would be
> indicated *HOW*?

Number crunching with Python, by which I mean implementing big nasty
formulas from obscure journals. It's a hard game all the way around. The
problem is over constrained and making things case insensitive would
just make things worse.

One would like to keep your formulas as close as possible to their
sources. This helps both to get the formulate correct, but allows future
readers of the code to be referred to the relevant journal and have some
prospect of matching up code to article. This is impossible to do
exactly of course since python doesn't support arrows and overbars,
boldface and italic in identifiers. Using case sensitivity can help
here, although it certainly doesn't solve all problems. The convention
of capitalizing the matrices, lower-casing the vectors and writing out
the scalars (see below) is often effective.

> Don't you EVER multiply your matrices by scalars?!

Scalars in my experience are frequently represented using Greek
characters, so they get written out and are therefore easy to
distinguish. They also tend to represent only a small portion of the
typical equation, so that fact that they are written out doesn't have
that large an effect. When the scalars are not represented using Greek,
you just do the best you can.

> Or is it so crucial to distinguish matrices from vectors but totally
> irrelevant to distinguish either from scalars?!).

Just because it's difficult to represent formulas well using ASCII is
not reason to make it more difficult, nor to throw up our hands and not
try to represent them as best we can.

>>b=a_matrix*a
>>
>>or even
>>
>>b=c*a # c is a matrix
>>
>>Mathematical formulas are the first reason why I like case sensitivity.
>
>
> My opinion is that, while _habit_ in mathematical formulas may surely
> make one hanker for such case-sensitivity, the preference just does not
> stand up to critical analysis, as above.

In theory, there is no difference between theory and practice. In
practice.... I've tried many ways over the years to represent equations
legibly using Python and my experience that case sensitivity, while
certainly no panacea, helps.


> You're trying to overload WAY
> too many different and conflicting "conventions" onto a meager "one bit
> [at most] per character" (about 0.87 bits I believe, in fact) of
> "supplementary information" yielded by case-sensitivity.

I believe it's much closer to 1 full bit for length-1 sequences since
numbers cannot start an identifier, decreasing relatively quickly to
0.87 (I'll take your word for the 0.87 being the asymptotic value.)

[SNIP]

> Most paladins of case sensitivity would probably be horrified to see
> that the main point in its "favour" now appears to be that it
> encourages you to use shorter (e.g. 1-letter) identifiers (and thus
> more cryptic ones) because it gives you more of them to choose from...!!!

I find this argument silly. I have all the freedom I need to make my
code illegible by using short identifiers without exploiting case. I'm
certain I could rewrite all my code to use two letter lowercase
identifiers and the lack of mixed case certainly wouldn't make it any
clearer.

> I disagree -- once you have to spell out e.g. pi, capital-sigma, etc,
> in Ascii letters anyway, having to make sure you do so in letters that
> are unambiguous in terms of capitalization differences is no big loss.

Interestingly all of the math typesetting programs I've seen, including
LaTex and MathML us Sigma (or SIGMA) and sigma for upper and lower case
sigma respectively. None write it out.

[SNIP]


In the end, this is a tools issue. If people spent half the time working
on their favorite editor as discussing case-sensitivity, the problem
would be long solved. SciTe comes pretty close with its auto completion
stuff, but it doesn't order the completions appropriately. The correct
order would be to ignore both captitalization and underscores. Or,
perhaps, just non-leading underscores. I once fixed one of wxPython IDEs
to do this mostly right, but sadly I've forgotten which one. I suppose
it's time to dig into SciTe, but it's unfortunately not in Python.

Which brings me to something I can't understand about the great
capitalization debate. Why is 'runmethod' versus 'runMethod' confusing,
while 'runmethod' vs 'run_method' is not? To do a full job I'd think
you'd have to axe underscores as well. Far better to just improve the
tools.

-tim


Ronald Oussoren

unread,
Nov 13, 2003, 10:12:09 AM11/13/03
to Ron Adam, pytho...@python.org

On 13 nov 2003, at 6:53, Ron Adam wrote:

> On Thu, 13 Nov 2003 02:12:38 GMT, "Rainer Deyke" <rai...@eldwood.com>
> wrote:
>
>> Ron Adam wrote:
>>> Which would you choose from the following?
>>
>> Here are the options I see, in order of preference:
>>
>> 1. The compiler enforces a consistent capitalization scheme,
>> preferably
>> all_lower_case. Note that MixedCase is only consistent if
>> PsychoTheRapist
>> is a different identifier than Psychotherapist. Different syntactical
>> elements (identifiers vs keywords) are allowed to use different
>> schemes.

A slighty different scheme would be to disallow names that differ only
in case. This would make it possible to talk about code ("the foo
function is buggy") without confusion ("which one, the one in capitals
or lower-case?"), without having having the confusing notion that 'FOO'
and 'foo' are the same. To me at least 'foo = FOO' looks like something
different than 'foo = foo'.

Ronald


Ron Adam

unread,
Nov 13, 2003, 5:51:31 PM11/13/03
to
On Thu, 13 Nov 2003 22:40:25 +1300, Paul Foley <s...@below.invalid>
wrote:

>On Thu, 13 Nov 2003 05:53:32 GMT, Ron Adam wrote:
>
>>> 3. Case insensitity.
>
>> Then 'Bob and 'bOb' would be the same thing. Even though they look a
>> little different, I can understand this. Simple, easy to remember,
>> easy to use.
>

>But "Bob" and "Barb" wouldn't be the same thing, even though they look
>a little different...Americans saying "Bob" pronounce it so that I
>think they're saying "Barb" (or perhaps "Baab"), so I think these two
>(three) identifiers should be the same, to avoid confusion! Heh.


<smile> Ok, yes we have to draw a line somewhere when it comes o
similarities. I don't think editors are smart enough at this time to
distinguish similar meanings across differing languages, or differing
dialects of the same language.

At some point though, in the <far( future)>, it should be possible,
and it will be needed due to the likely popularity of voice input.
(along with good translation software too) This is another reason
that names should not be too similar. We would have to depreciate
terms that sound alike and do not have a clear meaning from the
context. Of course it may be awhile before that is needed. I would
prefer my computer not to stop me with interruptions to ask me which
similar sounding class I want to use. ;-)

I have a voice input program someone gave me a couple of years ago
I've never tried. Maybe I'll install it in the <near(future)> and see
what kind of problems it has entering programs.

_Ron Adam


Ron Adam

unread,
Nov 13, 2003, 6:47:48 PM11/13/03
to
On Thu, 13 Nov 2003 14:26:42 GMT, Alex Martelli <al...@aleax.it>
wrote:

>Ron Adam wrote:
> ...
>> If an option for case insensitivity were implemented it would just be
>> a matter of doing a lower() function on all source code as a first
>> step in the compile process. Then case in the source code need not
>> matter, or you could choose to have it matter if that's what you want.
>> It probably isn't that simple. I haven't looked into the source code
>> far enough yet. Doing so would probably cause errors in existing
>> programs where names do use same spelling/different case for different
>
>And all uses of standard Python modules such as random and fileinput,
>which do exactly that sort of thing systematically.

Also it would need to avoid lowering strings and literals too.


>> Using a case correcting editor is one way of doing it that doesn't
>> change pythons core and lets the programmer choose the behavior they
>> want.
>
>Nope, can't do. Consider:
>
>>>> import random
>>>> x=random.Random()
>>>> y=random.random()
>
>now x and y are two VERY different things:
>
>>>> x
><random.Random object at 0x81aa9d4>

Is this very common, I tried to find other examples of this. Is
there another way to get a base class of an object? Is this different
for different modules, or is it a standard?


>>>> y
>0.93572104869999828
>
>...but how would a poor "case correcting editor" distinguish them...?
>

Something like this where 'word' is a possible name:

if word matches any name in both spelling and case:
pass # leave it alone
elif word matches a single name, but case is incorrect:
correct case
elif word matches several names spelled the same, but neither in
correct case:
give a hint
get choice from hint

>Such a smart editor might HELP a little by SUGGESTING a case-correction
>when it appears unambiguous, even just for standard modules and the
>functions therein. Maybe a menu-command for "suggest case corrections
>if any" WOULD be helpful in IDLE, and offer good cost/benefit ratio as
>a fun, not-too-terribly-hard project reducing human misery a bit...:-).
>
>
>Alex

I think so, especially for people first starting out or switching
from another language.

I think there could different levels of correction/suggestion modes.

None == turn it off

Polite == suggest choices if the case doesn't match, but don't
actually correct anything.

Assertive == Correct when it's obvious to do so, and suggest when
there is more than one choice.


What one would choose would be dependant on how well they know python
and how accurate they type.


_Ron Adam


Ron Adam

unread,
Nov 13, 2003, 7:31:56 PM11/13/03
to
On Thu, 13 Nov 2003 15:58:49 GMT, Alex Martelli <al...@aleax.it>
wrote:

>Ron Adam wrote:

Maybe someone will try it. I've only just started with Python about a
month ago. However I did pick up your 'Python in a Nutshell' last
night and have already read though the first 4 chapters. Great book
Alex!

I've programmed lightly in c, c++, java, several basics, and even a
little assembly. Took a course in fortran, although I don't remember
any of it. Also learned pascal once upon a time.

Python addresses many if not most of the complaints I've had with
those other languages. Most of which were either low level languages
that lacked high level functionality, or high level languages that
were difficult to extend. And then there are the visual stuff that
requires 3/4 of the code just to initialize everything. ack! What
surprises me most is why I haven't found Python sooner?

_Ron Adam

Ron Adam

unread,
Nov 13, 2003, 8:06:42 PM11/13/03
to

I agree, I don't know how often it occurs in the libraries, and so
can't say how difficult it would be to change at this time. But I do
think it is a good thing not to use case as the only indicator of a
difference.

I think it should be discouraged as a bad or poor programming practice
in any case. In my opinion it more often than not makes code less
readable when we use case as the only difference between names.

_Ron Adam

Ron Adam

unread,
Nov 13, 2003, 8:18:44 PM11/13/03
to
On Thu, 13 Nov 2003 14:26:42 GMT, Alex Martelli <al...@aleax.it>
wrote:

>Such a smart editor might HELP a little by SUGGESTING a case-correction


>when it appears unambiguous, even just for standard modules and the
>functions therein. Maybe a menu-command for "suggest case corrections
>if any" WOULD be helpful in IDLE, and offer good cost/benefit ratio as
>a fun, not-too-terribly-hard project reducing human misery a bit...:-).
>
>
>Alex

It occurs to me that using a menu to suggest choices for name with
differing caps may actually encourage the use of differing caps. I
hope not. That is something to consider.

I wonder how difficult it would be to write a program that searches
the library and counts the number of instances like spelling with
differing case are used?

_Ron Adam


Alex Martelli

unread,
Nov 14, 2003, 5:46:04 AM11/14/03
to
Ron Adam wrote:
...

> I wonder how difficult it would be to write a program that searches
> the library and counts the number of instances like spelling with
> differing case are used?

You mean "used within the same namespace"? Not too hard, since the
key test is nothing more than something like:

o

so basically it boils down to finding all namespaces of interest.

Easy for modules, easy for classes, NOT easy for class-instances
as you'd really have to create the instances to check for such
cases as, e.g.:

class Foo(object):
def blab(self): return self.BLAB
def __init__(self, BLAB): self.BLAB = BLAB

So here's a q&d check for such module-level conflicts I just
cobbled together (avoiding obsolete modules):

import sys, glob, os.path, sets

avoid = sets.Set('''
FCNTL posixfile pre regsub statcache TERMIOS this tzparse xmllib
'''.split())

for where in sys.path:
modules = glob.glob(os.path.join(where, '*.py'))
modnams = [os.path.basename(m)[:-3] for m in modules]
for m in modnams:
if m in avoid: continue
try: modobj = __import__(m)
except ImportError: continue
dd = dir(modobj)
lowdd = [ n.lower() for n in dd ]
slowd = sets.Set(lowdd)
if len(dd) != len(slowd):
print '%s:'%m,
n = 0
for d in dd:
if lowdd.count(d.lower()) != 1:
print d,
n += 1
print

The hits in the top-level of the standard libraries are:

binhex: BinHex HexBin binhex hexbin
copy: Error error
popen2: Popen3 Popen4 popen3 popen4
pydoc: Doc doc
random: Random random
repr: Repr repr
sre_parse: SUBPATTERN SubPattern
sre: TEMPLATE template
tarfile: VERSION version
threading: _VERBOSE _Verbose
tokenize: COMMENT Comment NAME NUMBER Name Number STRING String string
xmlrpclib: Boolean boolean


there are more in lib-tk and Numeric, but not everybody will be
interested in those, I guess.


Alex

Anthony Briggs

unread,
Nov 14, 2003, 6:36:37 AM11/14/03
to pytho...@python.org
At 4:03 PM +0000 12/11/03, Alex Martelli wrote:
>Michele Simionato wrote:
> > I never understood why you advocate case insensitivity. I would expect
>> case insensitivity to be a source of bugs: for instance, identifiers
>> with similar names could be confused (es. myfunction vs. myFunction):
>> one would expect them to be different (at least people coming from
> > case insensitive languages) whereas they would be the same.
>
>People coming from (an exclusive diet of) case _sensitive_ (not, as you
>say, INsensitive!)

Personally, I'm _case sensitive insensitive_. I can't bring myself to
be sensitive towards people who are case sensitive ;)

Ant
--
----------------------------------------------------
HyPEraCtiVE? HeY, WhO aRE YoU cALliNg HypERaCtIve?!
aBR...@wEStNeT.cOm.aU
----------------------------------------------------

Ron Adam

unread,
Nov 14, 2003, 7:24:54 AM11/14/03
to
On Fri, 14 Nov 2003 10:46:04 GMT, Alex Martelli <al...@aleax.it>
wrote:

>Ron Adam wrote:

Thanks Alex, I'll play around with this a bit.

It looks like the number of them is low enough to build in exceptions
for already existing instances, and it may be possible to have a
policy of avoiding it in the future.

In any case, this is helping understand how python works. I'm
finding it very interesting that so much of python is programmed in
python.

_Ron Adam


Alex Martelli

unread,
Nov 14, 2003, 8:10:17 AM11/14/03
to
Ron Adam wrote:
...

> Maybe someone will try it. I've only just started with Python about a
> month ago. However I did pick up your 'Python in a Nutshell' last
> night and have already read though the first 4 chapters. Great book
> Alex!

Thanks!


> I've programmed lightly in c, c++, java, several basics, and even a
> little assembly. Took a course in fortran, although I don't remember
> any of it. Also learned pascal once upon a time.

You do have just about the perfect background in term of target
audience for the Nutshell -- several varied, typical lower-level
languages, plus a smattering of Python. Though one doesn't NEED
as many different languages as you've used and studied, of course.


> Python addresses many if not most of the complaints I've had with
> those other languages. Most of which were either low level languages
> that lacked high level functionality, or high level languages that
> were difficult to extend. And then there are the visual stuff that
> requires 3/4 of the code just to initialize everything. ack! What
> surprises me most is why I haven't found Python sooner?

Good question; I asked it of myself just a few years ago, when I
finally did "find" it. I have no satisfactory answer, though.


Alex

Bengt Richter

unread,
Nov 14, 2003, 2:14:13 PM11/14/03
to

You didn't mean to exclude presenting the choices when there _was_ ambiguity??

Following is a list of lib files that use the same name in differing case formats
(though not necessarily in the same name space -- this list does not distinguish
between e.g. global names and attribute/method names -- it's only looking for what
the tokenizer recognizes as names).

BTW, if all this were suddenly case-insensitive, there would be a fair amount of
work to do, I suspect. A few modules even have 3 variations. ;-)


d:\python23\lib\aifc.py:
SetParams * 2 setparams * 2
Error * 40 error * 3
Chunk * 3 chunk * 28

d:\python23\lib\audiodev.py:
SUNAUDIODEV * 3 sunaudiodev * 3
AL * 25 al * 11

d:\python23\lib\BaseHTTPServer.py:
Message * 1 message * 11

d:\python23\lib\Bastion.py:
BastionClass * 2 bastionclass * 2
RExec * 1 rexec * 2

d:\python23\lib\binhex.py:
HexBin * 2 hexbin * 2
Creator * 5 creator * 2
BinHex * 2 binhex * 2
Flags * 5 flags * 2
FName * 2 fname * 8
FInfo * 11 finfo * 19
LINELEN * 3 linelen * 4
Type * 6 type * 6

d:\python23\lib\cgitb.py:
NAME * 1 name * 38

d:\python23\lib\cmd.py:
Cmd * 1 cmd * 15
IDENTCHARS * 2 identchars * 2
PROMPT * 2 prompt * 3

d:\python23\lib\codecs.py:
Reader * 6 reader * 14
Writer * 6 writer * 8

d:\python23\lib\codeop.py:
Compile * 2 compile * 2

d:\python23\lib\Cookie.py:
K * 30 k * 6

d:\python23\lib\copy.py:
C * 2 c * 2
Error * 4 error * 1

d:\python23\lib\csv.py:
Dialect * 4 dialect * 9
M * 1 m * 4

d:\python23\lib\dis.py:
EXTENDED_ARG * 1 extended_arg * 4

d:\python23\lib\doctest.py:
Tester * 3 tester * 11

d:\python23\lib\filecmp.py:
BUFSIZE * 2 bufsize * 3

d:\python23\lib\ftplib.py:
FTP * 2 ftp * 9
Error * 6 error * 5
Netrc * 2 netrc * 2

d:\python23\lib\gettext.py:
True * 1 true * 2
Catalog * 1 catalog * 3
False * 3 false * 2

d:\python23\lib\gzip.py:
FNAME * 3 fname * 4
READ * 6 read * 17
WRITE * 6 write * 15

d:\python23\lib\httplib.py:
BUFSIZE * 2 bufsize * 4

d:\python23\lib\ihooks.py:
VERBOSE * 4 verbose * 14
Hooks * 2 hooks * 27

d:\python23\lib\imaplib.py:
Flags * 2 flags * 14
USER * 4 user * 8
Literal * 2 literal * 15
Debug * 4 debug * 14
HMAC * 1 hmac * 2

d:\python23\lib\imputil.py:
Importer * 3 importer * 5

d:\python23\lib\inspect.py:
INDENT * 1 indent * 11
NAME * 2 name * 22

d:\python23\lib\macpath.py:
File * 4 file * 2

d:\python23\lib\mhlib.py:
Error * 21 error * 23
MH * 2 mh * 13
MultiFile * 1 multifile * 2
Folder * 2 folder * 4
PATH * 2 path * 67

d:\python23\lib\mimetypes.py:
USAGE * 2 usage * 3

d:\python23\lib\mimify.py:
File * 5 file * 9
I * 9 i * 9

d:\python23\lib\optparse.py:
TYPES * 2 types * 7
Values * 2 values * 27
Option * 6 option * 67
ATTRS * 2 attrs * 8

d:\python23\lib\os.py:
PATH * 2 path * 24

d:\python23\lib\pdb.py:
Cmd * 3 cmd * 4
Bdb * 3 bdb * 11
Repr * 2 repr * 3

d:\python23\lib\pickle.py:
UNICODE * 4 unicode * 7
PUT * 3 put * 2
INT * 3 int * 4
MARK * 9 mark * 13
TRUE * 3 True * 2
LONG * 3 long * 3
REDUCE * 3 reduce * 11
PROTO * 3 proto * 16
FALSE * 3 False * 2
LIST * 3 list * 4
POP * 4 pop * 9
FLOAT * 3 float * 1
DICT * 3 dict * 4
NONE * 3 None * 42
GET * 3 get * 15
APPEND * 4 append * 37
OBJ * 3 obj * 120
INST * 3 inst * 5
TUPLE * 4 tuple * 3

d:\python23\lib\pickletools.py:
I * 55 i * 6

d:\python23\lib\pipes.py:
FILE * 2 file * 17

d:\python23\lib\platform.py:
System * 2 system * 51

d:\python23\lib\popen2.py:
Popen3 * 5 popen3 * 5
Popen4 * 3 popen4 * 3

d:\python23\lib\pre.py:
I * 1 i * 14
M * 1 m * 9

d:\python23\lib\profile.py:
Stats * 2 stats * 3

d:\python23\lib\pstats.py:
Cmd * 2 cmd * 3
Stats * 6 stats * 32

d:\python23\lib\pyclbr.py:
NAME * 5 name * 16
Class * 5 class * 2

d:\python23\lib\pydoc.py:
GUI * 2 gui * 3
Doc * 3 doc * 44
Scanner * 3 scanner * 9
Message * 5 message * 2
Entry * 1 entry * 10
Repr * 6 repr * 26
S * 2 s * 4
I * 2 i * 10
Tk * 1 tk * 1

d:\python23\lib\Queue.py:
Queue * 1 queue * 6
Empty * 3 empty * 1
Full * 3 full * 1

d:\python23\lib\random.py:
Random * 7 random * 47
VERSION * 6 version * 8
N * 17 n * 21

d:\python23\lib\repr.py:
Repr * 2 repr * 3

d:\python23\lib\rexec.py:
RExec * 2 rexec * 14
Hooks * 2 hooks * 6

d:\python23\lib\rfc822.py:
AddressList * 5 addresslist * 21

d:\python23\lib\robotparser.py:
Entry * 5 entry * 19

d:\python23\lib\sets.py:
Set * 1 set * 3

d:\python23\lib\shutil.py:
Error * 2 error * 1

d:\python23\lib\SimpleXMLRPCServer.py:
Fault * 4 fault * 5

d:\python23\lib\smtpd.py:
COMMAND * 5 command * 16
DATA * 3 data * 18
Options * 2 options * 15

d:\python23\lib\smtplib.py:
I * 1 i * 4
HMAC * 1 hmac * 2

d:\python23\lib\sre.py:
TEMPLATE * 1 template * 14
S * 1 s * 9
SUBPATTERN * 2 SubPattern * 2
Pattern * 1 pattern * 35
I * 1 i * 8
M * 1 m * 6
Scanner * 1 scanner * 3

d:\python23\lib\sre_compile.py:
LITERAL * 10 literal * 2
RANGE * 4 range * 5
IN * 2 in * 23
NEGATE * 3 negate * 3
CHARSET * 2 charset * 22
ASSERT * 1 assert * 2

d:\python23\lib\sre_constants.py:
IN * 3 in * 2

d:\python23\lib\sre_parse.py:
FLAGS * 4 flags * 11
LITERAL * 31 literal * 7
SUBPATTERN * 2 SubPattern * 5 subpattern * 25
Pattern * 2 pattern * 16
IN * 11 in * 42

d:\python23\lib\string.py:
L * 3 l * 3

d:\python23\lib\symtable.py:
Class * 2 class * 5

d:\python23\lib\tarfile.py:
VERSION * 2 version * 1
BUFSIZE * 4 bufsize * 13
TarFile * 4 tarfile * 18
TarInfo * 8 tarinfo * 229
TOREAD * 2 toread * 5

d:\python23\lib\telnetlib.py:
DEBUGLEVEL * 2 debuglevel * 9
SB * 2 sb * 9

d:\python23\lib\tempfile.py:
Random * 1 random * 1

d:\python23\lib\threading.py:
_VERBOSE * 2 _Verbose * 14
Lock * 4 lock * 9
Thread * 11 thread * 6

d:\python23\lib\timeit.py:
Timer * 2 timer * 8

d:\python23\lib\token.py:
NAME * 1 name * 2

d:\python23\lib\tokenize.py:
COMMENT * 4 Comment * 3
INDENT * 1 indent * 1
Token * 2 token * 23
NAME * 1 Name * 3
NUMBER * 1 Number * 3
STRING * 3 String * 2 string * 2
ContStr * 2 contstr * 10

d:\python23\lib\trace.py:
Trace * 2 trace * 11
Ignore * 2 ignore * 2

d:\python23\lib\unittest.py:
TestLoader * 3 testLoader * 5

d:\python23\lib\urllib.py:
FTP * 1 ftp * 13
I * 1 i * 31
IC * 1 ic * 4
Close * 1 close * 14

d:\python23\lib\urllib2.py:
H * 10 h * 20
I * 1 i * 23

d:\python23\lib\uu.py:
Error * 5 error * 1

d:\python23\lib\warnings.py:
I * 1 i * 3

d:\python23\lib\wave.py:
Chunk * 3 chunk * 22

d:\python23\lib\webbrowser.py:
Error * 2 error * 1

d:\python23\lib\xdrlib.py:
Error * 3 error * 2

d:\python23\lib\xmlrpclib.py:
Transport * 3 transport * 5
Parser * 1 parser * 16
Boolean * 6 boolean * 2
Server * 1 server * 3

d:\python23\lib\zipfile.py:
CRC * 16 crc * 2

d:\python23\lib\_strptime.py:
LC_TIME * 1 LC_time * 4


Regards,
Bengt Richter

Greg Ewing (using news.cis.dfn.de)

unread,
Nov 20, 2003, 6:22:37 PM11/20/03
to
Douglas Alan wrote:
> I agree with Alex. Case sensitivity is evil! When color monitors
> started becoming common, I began to worry that programming languages
> would come to allow you to have blue variable names, and red and green
> variables names, and they would all be different.

It's already happened:

http://www.colorforth.com/cf.html

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Douglas Alan

unread,
Dec 5, 2003, 3:11:54 AM12/5/03
to
mi...@pitt.edu (Michele Simionato) writes:

> I never understood why you advocate case insensitivity. I would
> expect case insensitivity to be a source of bugs: for instance,
> identifiers with similar names could be confused (es. myfunction
> vs. myFunction): one would expect them to be different (at least
> people coming from case insensitive languages) whereas they would be
> the same.

When you use a case-insensitive language, you do not typically use
StudlyCaps at all, so you wouldn't ever write "myFunction". Instead,
you would write "my_function" or "my-function", depending on the
language. Then you might use "MY-FUNCTION" for ephasis. For
instance, you might write:

(defun MY-FUNCTION (x)
(if (= x 0)
1
'else
(* x (my-function (- x 1)))))


Here "MY-FUNCTION" in in upper case, just so it stands out more
easily, kind of like how editors now show your function names in red
where they are defined, only you could do this back in the day of
black and white screens.

> Also, now I can write

> ONE=1

> and

> def one(): return 1

> and it is clear that the first name (ONE) refers to a constant
> whereas the second name (one) refers to something which is not a
> constant.

Personally, I hate this style, because I can't stand to have
constants shouting at me in upper case all of the time. Save the
shouting for when it's important, DAMNIT!

I prefer constants to be written as c_one, or something like that that
is less loud on my delicate ears^H^H^H^Heyes.

|>oug

Peter Hansen

unread,
Dec 5, 2003, 10:26:42 AM12/5/03
to
Douglas Alan wrote:
>
> mi...@pitt.edu (Michele Simionato) writes:
>
> > I never understood why you advocate case insensitivity. I would
> > expect case insensitivity to be a source of bugs: for instance,
> > identifiers with similar names could be confused (es. myfunction
> > vs. myFunction): one would expect them to be different (at least
> > people coming from case insensitive languages) whereas they would be
> > the same.
>
> When you use a case-insensitive language, you do not typically use
> StudlyCaps at all, so you wouldn't ever write "myFunction". Instead,
> you would write "my_function" or "my-function", depending on the
> language.

This is the second ludicrous thing I've seen you write today. The
first was when you claimed Fredrik Lundh was "dead wrong" about the
use of tuples vs. lists, when your own view is in direct contradiction
to a very widely used convention in the Python programming world,
and supported by the FAQ entry and Guido's own views.

When *I* have used case-insensitive languages, I have certainly used
various forms of capitalization to represent different types of
information, such as functions or constants. I am definitely not
alone in this approach, as I have learned it from reading others'
code.

*You* might not do so, but your opinions are clearly not held by
all other programmers, nor perhaps even the majority, so please
stop writing as though they are.

-Peter

It is loading more messages.
0 new messages