Re: "Don't rebind built-in names*" - it confuses readers

2013-06-13 Thread Nobody
On Thu, 13 Jun 2013 01:23:27 +, Steven D'Aprano wrote:

> Python does have a globally-global namespace. It is called "builtins", and
> you're not supposed to touch it. Of course, being Python, you can if you
> want, but if you do, you are responsible for whatever toes you shoot off.
> 
> Modifying builtins will effect *all modules*. That's normally too much,
> although it can very, very, very occasionally be useful.

For a specific example, gettext.install() adds the _() function to the
builtins namespace.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Chris Angelico
On Thu, Jun 13, 2013 at 11:08 AM, Steven D'Aprano
 wrote:
> On Thu, 13 Jun 2013 10:08:14 +1000, Chris Angelico wrote:
>
> int="five"
> [__builtins__.int(i) for i in ["1","2","3"]]
>
> Don't use __builtins__, it's an implementation detail.
>
> In Python 2.x, there is __builtins__ with an "s" in the global namespace
> if you are running CPython, but not necessarily other implementations.
> There is __builtin__ with no "s" which is defined by the language, but
> you have to import it first.
>
> In Python 3.x, you just import builtins with an "s" and no underscores,
> no matter what implementation you use.

Oh, sorry, my bad. I tend to just whip something up in IDLE and see if
it works, rather than actually check the spec. Listen to Steven, he
knows what he's about!

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Steven D'Aprano
On Wed, 12 Jun 2013 17:26:43 -0700, Mark Janssen wrote:

>> The builtins don't need to be imported, but they're identifiers like
>> anything else. They're a namespace that gets searched after
>> module-globals.
> 
> Yes, I understand, though for clarity and separability, it seems that
> having them in a namespace that gets explicitly pulled into the global
> space is less messy, despite the extra step (the default python
> distribution could include a STARTUP file that imports the builtin
> types).

No. Having a separate builtin namespace is a design feature. 

In Python, every module has it's own global namespace. Within module X, 
globals() is dfferent from within module Y. (So it's not really globally-
global, it's only locally-global, if you like.) This is a Very Good Thing 
-- it means that each module is compartmentalised away from every other, 
by default.

Python does have a globally-global namespace. It is called "builtins", 
and you're not supposed to touch it. Of course, being Python, you can if 
you want, but if you do, you are responsible for whatever toes you shoot 
off.

Modifying builtins will effect *all modules*. That's normally too much, 
although it can very, very, very occasionally be useful. Especially in 
testing and debugging. But a module can *shadow* the builtins, by simply 
defining a name that matches a builtin name, without affecting any other 
module. So for example, the re module defines a function compile, which 
shadows the built-in compile, but:

- the re module doesn't use the built-in compile

- other modules normally use the fully-qualified re.compile

so, in practice, there is no conflict.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Steven D'Aprano
On Thu, 13 Jun 2013 10:08:14 +1000, Chris Angelico wrote:

 int="five"
 [__builtins__.int(i) for i in ["1","2","3"]]

Don't use __builtins__, it's an implementation detail.

In Python 2.x, there is __builtins__ with an "s" in the global namespace 
if you are running CPython, but not necessarily other implementations. 
There is __builtin__ with no "s" which is defined by the language, but 
you have to import it first.

In Python 3.x, you just import builtins with an "s" and no underscores, 
no matter what implementation you use.


> It's shadowed, not overwritten.

But even if you override it, you can get it back:


py> import builtins
py> builtins.int = "five"  # My monkey has a patch.
py> int("42")  # Oh-oh, trouble ahead
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'str' object is not callable
py> builtins.int = type(5)
py> int("42")
42


It may not be quite so simple to recover from *all* such monkey-patches, 
but you can always exit Python, edit your code, and start it up again. 
It's not like you've patched the actual compiler.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Steven D'Aprano
On Wed, 12 Jun 2013 17:04:48 -0700, Mark Janssen wrote:

>> Apart from Erlang, got any other examples? Because it seems to me that
>> in languages with nested scopes or namespaces, shadowing higher levels
>> is exactly the right thing to do.
> 
> Really?
> 
 int="five"
 [int(i) for i in ["1","2","3"]]
> TypeError:  str is not callable

Yes, really. Not for the example shown above, of course, that's pretty 
useless. But one might define a custom int() function, or more common, 
you want to define a local variable x without caring whether or not there 
is a global variable x.

If you, the programmer, have a good reason for re-defining int as the 
string "five", then presumably you *wanted* to get that TypeError. If 
not, then it's simply a bug, like any other bug: that you get when you 
use the wrong name:

x = 23  # I want x to equal 23, always and forever.
x = 42  # I don't actually want to rebind x, but I can't help myself.
assert x == 23  # This now fails, because I am an idiot.

Should we conclude that, because somebody might accidentally assign a 
value to a name without considering the consequences, that assigning 
values to names should be forbidden? No, of course not. The solution is 
to think before you code, or fix the bug afterwards.

Shadowing builtins is confusing to newbies, I get that. But anyone with 
even a modicum of experience will be able to deal with such errors 
trivially. If you (generic you) cannot work out what is going on, then 
you're not a Python programmer. You're a Python dabbler.


> Now how are you going to get the original int type back?

Trivial. Here are three ways:

py> int = "five"
py> int
'five'
py> del int
py> int("42")
42


Or:

py> int = "five"
py> int
'five'
py> type(5)("42")
42


Or:

py> int = "five"
py> import builtins  # Use __builtin__ in Python 2.
py> builtins.int("42")
42



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Ethan Furman

On 06/12/2013 05:04 PM, Mark Janssen wrote:

Steven D'Aprono wrote:


Apart from Erlang, got any other examples? Because it seems to me that in
languages with nested scopes or namespaces, shadowing higher levels is
exactly the right thing to do.


Really?

--> int="five"
--> [int(i) for i in ["1","2","3"]]
TypeError:  str is not callable

Now how are you going to get the original int type back?


--> del int

Mark Janssen*, you would increase your credibility if you actually *learned* 
Python.

--
~Ethan~

*full name used to distinguish from at least one other Mark on the list.
--
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Steven D'Aprano
On Thu, 13 Jun 2013 09:53:26 +1000, Chris Angelico wrote:

> In Python 2.x, 'print' is actually a keyword. It has its own special
> syntax (eg printing to something other than stdout), and absolutely
> cannot be overridden:

Except that you can:

from __future__ import print_function

Just to make things complicated :-)



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Chris Angelico
On Thu, Jun 13, 2013 at 10:18 AM, Skip Montanaro  wrote:
> Magic. :-)
>
 int = "five"
 int("a")
> Traceback (most recent call last):
>   File "", line 1, in 
> TypeError: 'str' object is not callable
 from __builtin__ import int as _int
 _int("5")
> 5
>
> Not sure of the magic necessary in Python 3.  This is definitely
> something you don't want to make a habit of...

Same thing works but with a different name:

from builtins import int as _int

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Mark Janssen
> The builtins don't need to be imported, but they're identifiers like
> anything else. They're a namespace that gets searched after
> module-globals.

Yes, I understand, though for clarity and separability, it seems that
having them in a namespace that gets explicitly pulled into the global
space is less messy, despite the extra step (the default python
distribution could include a STARTUP file that imports the builtin
types).  But I must withhold my personal philosophy lest it get too
complicated.

>> And int, list, tuple, dict and such always seemed
>> like keywords to my CS self because they were included in Python's
>> type system (like "int" would be in C).
>
> Yep, but in Python, types/classes are themselves objects, so you can
> pass them around like anything else. This also downgrades them from
> "language keyword" to "always-available name", which in effect
> upgrades your _own_ classes to the same level.

Yes, and here is where I've been trying to argue that Python's object
model isn't right.  But I must abstain from commenting further.

>> They are all one-step removed from keywords.   And yet, since they are
>> not in a separate namespace, they should not be used as variable
>> names.  Perhaps since they are very different from one another, they
>> should be put in separate namespaces off of a global, root
>> namespace...  (math, string, etc.)
>
> There's no point forcing them to be looked up in a two-step process.
> If you want that, you can simply reference them as
> __builtins__.whatever, but you can instead just reference them as the
> unadorned name whatever. They contribute heavily to the simplicity and
> readability of Python code - imagine if every call to len() had to be
> qualified.

Well I would anticipate a keyword ("load"?) so one could load a
particular namespace into the global scope.  The issue I guess is when
should modules be "on file" vs. "in memory" like the builtins?  The
reason this is coming up, is because I would like to imagine a data
ecosystem, where I can import a set of objects from the network as if
they are local right into my interpreter environment.

-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Skip Montanaro
>>> int="five"
>>> [int(i) for i in ["1","2","3"]]
TypeError:  str is not callable

> Now how are you going to get the original int type back?

Magic. :-)

>>> int = "five"
>>> int("a")
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'str' object is not callable
>>> from __builtin__ import int as _int
>>> _int("5")
5

Not sure of the magic necessary in Python 3.  This is definitely
something you don't want to make a habit of...

S
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Chris Angelico
On Thu, Jun 13, 2013 at 10:26 AM, Mark Janssen
 wrote:
>> There's no point forcing them to be looked up in a two-step process.
>> If you want that, you can simply reference them as
>> __builtins__.whatever, but you can instead just reference them as the
>> unadorned name whatever. They contribute heavily to the simplicity and
>> readability of Python code - imagine if every call to len() had to be
>> qualified.
>
> Well I would anticipate a keyword ("load"?) so one could load a
> particular namespace into the global scope.  The issue I guess is when
> should modules be "on file" vs. "in memory" like the builtins?  The
> reason this is coming up, is because I would like to imagine a data
> ecosystem, where I can import a set of objects from the network as if
> they are local right into my interpreter environment.

The syntax you describe is effectively:

from __builtins__ import *

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Chris Angelico
On Thu, Jun 13, 2013 at 10:04 AM, Mark Janssen
 wrote:
> Really?
>
 int="five"
 [int(i) for i in ["1","2","3"]]
> TypeError:  str is not callable
>
> Now how are you going to get the original int type back?

Either del it from your module namespace, or use the qualified name:

>>> int="five"
>>> [__builtins__.int(i) for i in ["1","2","3"]]
[1, 2, 3]
>>> del int
>>> [int(i) for i in ["1","2","3"]]
[1, 2, 3]

It's shadowed, not overwritten.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Skip Montanaro
> Okay, now I'm a bit confused.  "print" is both a  and a
> member of the builtins.  What happens then?

It's a keyword in Python < 3, a built-in function in Python >= 3:

~% python3
Python 3.4.0a0 (default:96f08a22f562, Feb 24 2013, 23:37:53)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print

>>> x = print
>>>
~% python2
Python 2.7.5+ (2.7:4657d0eebe42, Jun  2 2013, 07:46:59)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print

>>> x = print
  File "", line 1
x = print
^
SyntaxError: invalid syntax


Skip
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Mark Janssen
>> This has caused more trouble than it has solved.
>
> I take it you have never programmed in a programming language with a
> single, flat, global namespace? :-)

Hey, the purpose a programming language (i.e. a language which has a
consistent lexical specification), is to provide some modicum of
structure.  Yes, that implies that you're implicitly following a
language designers tacit philosophy (their "ObjectArchitecture") for
relating data to computers, but that's fine.  People always have the
option of going back to assembly and starting over.

> Apart from Erlang, got any other examples? Because it seems to me that in
> languages with nested scopes or namespaces, shadowing higher levels is
> exactly the right thing to do.

Really?

>>> int="five"
>>> [int(i) for i in ["1","2","3"]]
TypeError:  str is not callable

Now how are you going to get the original int type back?

> Certainly it would be a PITA, and defeat
> the purpose of having nested scopes, if inner names had to be globally
> unique. Wouldn't it be absolutely horrible if adding a global variable
> "foo"[1] suddenly meant that all your functions that used "foo" as a
> local variable stopped working?

Not necessarily, but this is what I'm talking about in defining a
ObjectArchitecture (or in some circles a "type system").
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Chris Angelico
On Thu, Jun 13, 2013 at 9:07 AM, Mark Janssen  wrote:
>>> You're right.  I was being sloppy.
> Okay, now I'm a bit confused.  "print" is both a  and a
> member of the builtins.  What happens then?

Ah! I see where we are getting confused. When you said keyword, did
you mean keyword, a person who has lost his parents... oops, that's
Pirates of Penzance. Ahem.

In Python 2.x, 'print' is actually a keyword. It has its own special
syntax (eg printing to something other than stdout), and absolutely
cannot be overridden:

Python 2.7.4 (default, Apr  6 2013, 19:54:46) [MSC v.1500 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print=1
  File "", line 1
print=1
 ^
SyntaxError: invalid syntax

But in Python 3, it's a builtin function:

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (In
tel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> foo=print
>>> print=1
>>> foo("Hello, world!")
Hello, world!

> And abs(), max(), hex()  and such seemed like keywords to my
> scientific self (due to never having to "include"/import them), but
> clearly their not.

The builtins don't need to be imported, but they're identifiers like
anything else. They're a namespace that gets searched after
module-globals.

int = 1
def foo():
   int = 2
   print(int)

This has double shadowing :) It'll print 2, because locals get
searched first, but if you remove that assignment then it'll print 1,
and if you remove _that_ one, then it'll print "".
There's nothing magical about the name int, but before raising
NameError, the interpreter will look for it in builtins. You can even
add more "builtins", though I would *strongly* advise against this
unless you have a really REALLY good reason:

>>> __builtins__.helloworld=123
>>> helloworld
123
>>> helloworld=234
>>> helloworld
234
>>> del helloworld
>>> helloworld
123

> And int, list, tuple, dict and such always seemed
> like keywords to my CS self because they were included in Python's
> type system (like "int" would be in C).

Yep, but in Python, types/classes are themselves objects, so you can
pass them around like anything else. This also downgrades them from
"language keyword" to "always-available name", which in effect
upgrades your _own_ classes to the same level.

> They are all one-step removed from keywords.   And yet, since they are
> not in a separate namespace, they should not be used as variable
> names.  Perhaps since they are very different from one another, they
> should be put in separate namespaces off of a global, root
> namespace...  (math, string, etc.)

There's no point forcing them to be looked up in a two-step process.
If you want that, you can simply reference them as
__builtins__.whatever, but you can instead just reference them as the
unadorned name whatever. They contribute heavily to the simplicity and
readability of Python code - imagine if every call to len() had to be
qualified.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Mark Janssen
>> You're right.  I was being sloppy.
>
> ['ArithmeticError', 'AssertionError', 'AttributeError',
> 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError',
> 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError',
> 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError',
> 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
> 'Exception', 'False', 'FileExistsError', 'FileNotFoundError',
> 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError',
> 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError',
> 'InterruptedError', 'IsADirectoryError', 'KeyError',
> 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError',
> 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError',
> 'OSError', 'OverflowError', 'PendingDeprecationWarning',
> 'PermissionError', 'ProcessLookupError', 'ReferenceError',
> 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopIteration',
> 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit',
> 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError',
> 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError',
> 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
> 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_',
> '__build_class__', '__debug__', '__doc__', '__import__', '__name__',
> '__package__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool',
> 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile',
> 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
> 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format',
> 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex',
> 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len',
> 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min',
> 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
> 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr',
> 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple',
> 'type', 'vars', 'zip']
>
> I think I can safely say that all the names beginning with an
> uppercase letter (exceptions, True/False/None/Ellipsis), and the ones
> beginning with underscores, should not be overridden. Well and good.
> Still leaves 72 builtins. Obviously overriding len, print, range, etc
> would be risky (unless, as mentioned above, you're making a drop-in
> replacement), but there are plenty that you'd never notice (eg if you
> use "hash" for an encoded password, or "input" for the string the user
> typed into an HTML form). I would hope, for instance, that an editor
> would not color-highlight 'credits' differently, as it's designed for
> interactive work. There are plenty in the grey area - is it safe to
> use "sum" as an accumulator or "min" for a unit of time? What about
> using "super" to store the amount of retirement money you've put away?
> I'd be inclined to avoid this sort any time I'm aware of them, just
> because it'll make debugging easier on the day when something goes
> wrong.

Okay, now I'm a bit confused.  "print" is both a  and a
member of the builtins.  What happens then?

And abs(), max(), hex()  and such seemed like keywords to my
scientific self (due to never having to "include"/import them), but
clearly their not.  And int, list, tuple, dict and such always seemed
like keywords to my CS self because they were included in Python's
type system (like "int" would be in C).

They are all one-step removed from keywords.   And yet, since they are
not in a separate namespace, they should not be used as variable
names.  Perhaps since they are very different from one another, they
should be put in separate namespaces off of a global, root
namespace...  (math, string, etc.)

Despite that, seems like PEP8 should suggest this not shadowing these
built-ins which are at global scope.

MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Chris Angelico
On Thu, Jun 13, 2013 at 5:40 AM, Mark Janssen  wrote:
> On Wed, Jun 12, 2013 at 7:24 AM, Grant Edwards  
> wrote:
>> On 2013-06-11, Mark Janssen  wrote:
 list = []
 Reading further, one sees that the function works with two lists, a list of
 file names, unfortunately called 'list',
>>>
>>> That is very good advice in general:  never choose a variable name
>>> that is a keyword.
>>
>> You can't choose a vriable name that is a keyword: the compiler won't
>> allow it.
>>
>> "list" isn't a keyword.
>
> You're right.  I was being sloppy.

We're talking about builtins, and unfortunately there are... well, let
me ask Thespis, from the play of the same name:

Thespis: Oh, then I suppose there are some complaints?
Mercury: Yes, there are some.
Thespis (disturbed): Oh, perhaps there are a good many?
Mercury: There are a good many.
Thespis: Oh, perhaps there are a thundering lot?
Mercury: There are a thundering lot.
Thespis (very much disturbed): Oh.

>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError',
'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError',
'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError',
'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError',
'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
'Exception', 'False', 'FileExistsError', 'FileNotFoundError',
'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError',
'ImportError', 'ImportWarning', 'IndentationError', 'IndexError',
'InterruptedError', 'IsADirectoryError', 'KeyError',
'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError',
'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError',
'OSError', 'OverflowError', 'PendingDeprecationWarning',
'PermissionError', 'ProcessLookupError', 'ReferenceError',
'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopIteration',
'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit',
'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError',
'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError',
'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_',
'__build_class__', '__debug__', '__doc__', '__import__', '__name__',
'__package__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool',
'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile',
'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format',
'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex',
'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len',
'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min',
'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr',
'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple',
'type', 'vars', 'zip']

I think I can safely say that all the names beginning with an
uppercase letter (exceptions, True/False/None/Ellipsis), and the ones
beginning with underscores, should not be overridden. Well and good.
Still leaves 72 builtins. Obviously overriding len, print, range, etc
would be risky (unless, as mentioned above, you're making a drop-in
replacement), but there are plenty that you'd never notice (eg if you
use "hash" for an encoded password, or "input" for the string the user
typed into an HTML form). I would hope, for instance, that an editor
would not color-highlight 'credits' differently, as it's designed for
interactive work. There are plenty in the grey area - is it safe to
use "sum" as an accumulator or "min" for a unit of time? What about
using "super" to store the amount of retirement money you've put away?
I'd be inclined to avoid this sort any time I'm aware of them, just
because it'll make debugging easier on the day when something goes
wrong.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Mark Janssen
On Wed, Jun 12, 2013 at 7:24 AM, Grant Edwards  wrote:
> On 2013-06-11, Mark Janssen  wrote:
>>> list = []
>>> Reading further, one sees that the function works with two lists, a list of
>>> file names, unfortunately called 'list',
>>
>> That is very good advice in general:  never choose a variable name
>> that is a keyword.
>
> You can't choose a vriable name that is a keyword: the compiler won't
> allow it.
>
> "list" isn't a keyword.

You're right.  I was being sloppy.
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Grant Edwards
On 2013-06-11, Mark Janssen  wrote:
>> list = []
>> Reading further, one sees that the function works with two lists, a list of
>> file names, unfortunately called 'list',
>
> That is very good advice in general:  never choose a variable name
> that is a keyword.

You can't choose a vriable name that is a keyword: the compiler won't
allow it.

"list" isn't a keyword.

-- 
Grant Edwards   grant.b.edwardsYow! Maybe I should have
  at   asked for my Neutron Bomb
  gmail.comin PAISLEY --
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Chris Angelico
On Tue, Jun 11, 2013 at 1:30 PM, rusi  wrote:
> Or by example:
>
> def foo(x)...
> def bar(x,y)...
> there is no reason to confuse the two xes.
>
> Whereas
>
> x = ...
> def foo(x)...
> Now there is!
>
> The first should be encouraged, the second discouraged.

Again, there can be good reason for it, such as snapshotting globals:

qwer=123
def asdf(qwer=qwer):
print("qwer",qwer)

asdf()
qwer=234
asdf()

Done for performance (avoiding lookups), could also be done for
stability (as depicted here) though I've never seen it needed for
that.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-12 Thread Mark Janssen
> list = []
> Reading further, one sees that the function works with two lists, a list of
> file names, unfortunately called 'list',

That is very good advice in general:  never choose a variable name
that is a keyword.
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Chris Angelico
On Wed, Jun 12, 2013 at 1:22 AM, Rick Johnson
 wrote:
> PS: Is that "D" in last name short for "DevilsAdvocate"? Steven 
> "DevilsAdvocate" Prano.

I don't think so. Somehow it seems unlikely that he'll argue for you.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Steven D'Aprano
On Tue, 11 Jun 2013 08:22:19 -0700, Rick Johnson wrote:

> On Monday, June 10, 2013 9:56:43 PM UTC-5, Steven D'Aprano wrote:
>> On Mon, 10 Jun 2013 20:14:55 -0400, Terry Jan Reedy wrote:

>> > Reading further, one sees that the function works with two lists, a
>> > list of file names, unfortunately called 'list', and a list of
>> > subdirectories, more sensibly call 'subdirs'.
>>
>> Yes, that is a poor choice of names. But sometimes you are dealing with
>> a generic list, and calling it "filenames" would be equally
>> inappropriate :-)
> 
> I agree, however hopefully you're joking, because in the past you've
> argued that programmers should never use variables as generic as "list",
> "string", "integer", "float", etc... even though there are instances
> when all you need to know is what type your working with.

Do you have a reference for me saying that one should NEVER use generic 
names? That doesn't sound like something I would say. Sometimes you're 
writing a generic function that operates on a generic variable in a 
generic fashion, so of course you should use a generic name.


> One of the most important side-effects of using an editor with
> colorizing capabilities is to show you that you're using a built-in or
> keyword as a variable! 

I wouldn't exactly call it a "side-effect", since distinguishing tokens 
in your source code by category is the whole purpose of colouring source 
code in the first place.


> I love when people comment on subjects they have
> no direct experience with, like for instance, you commenting on
> colonizers or GUI's -- LOL!

I must admit I have no experience with colonizers, although of course I 
do have a colon of my very own. It works away absorbing water and 
nutrients without my active supervision.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Mark Lawrence

On 11/06/2013 16:43, Rick Johnson wrote:

On Tuesday, June 11, 2013 8:34:55 AM UTC-5, Steven D'Aprano wrote:


GvR is saying that it's okay to use the names of built-in functions or
types as the names of local variables, even if that causes the built-in
to be inaccessible within that function.


Looks like we've finally found the traitor! Code smells propagating down from 
the apex of the pyramid... well thanks for the wonderful advice Guido, and with 
it you've cursed Python's stdlib to another decade of unprofessional code!

PS: Excuse me whilst i brew myself a nice cup of HEMLOCK TEA!!! ಠ_ಠ



At long last I've received some good news.  But blast it, you've only 
said you'll brew it, not that you'll drink it.  Still, I can but hope.


--
"Steve is going for the pink ball - and for those of you who are 
watching in black and white, the pink is next to the green." Snooker 
commentator 'Whispering' Ted Lowe.


Mark Lawrence

--
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Grant Edwards
On 2013-06-11, Mark Janssen  wrote:
>>> list = []
>>> Reading further, one sees that the function works with two lists, a list of
>>> file names, unfortunately called 'list',
>>
>> That is very good advice in general:  never choose a variable name
>> that is a keyword.
>
> Btw,  shouldn't it be illegal anyway?  Most compilers don't let you do
> use a keyword as a variable name

We're not talking about keywords.  We're talking about built-ins -- 
which are just global symbols that are pre-imported for your shopping
convenience.  Other than the fact that they're pre-imported for you,
they're no different than symbols imported from any other module.

-- 
Grant Edwards   grant.b.edwardsYow! Could I have a drug
  at   overdose?
  gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Serhiy Storchaka

11.06.13 06:02, Steven D'Aprano написав(ла):

On Mon, 10 Jun 2013 19:36:44 -0700, rusi wrote:

And so languages nowadays tend to 'protect' against this feature.


Apart from Erlang, got any other examples?


C#? At least local variable can't shadow other local variable in outer 
scope (and it looks reasonable). I'm not sure about globals and instance 
fields.



--
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Rick Johnson
On Tuesday, June 11, 2013 8:34:55 AM UTC-5, Steven D'Aprano wrote:

> GvR is saying that it's okay to use the names of built-in functions or 
> types as the names of local variables, even if that causes the built-in 
> to be inaccessible within that function.

Looks like we've finally found the traitor! Code smells propagating down from 
the apex of the pyramid... well thanks for the wonderful advice Guido, and with 
it you've cursed Python's stdlib to another decade of unprofessional code! 

PS: Excuse me whilst i brew myself a nice cup of HEMLOCK TEA!!! ಠ_ಠ
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Rick Johnson
On Monday, June 10, 2013 9:56:43 PM UTC-5, Steven D'Aprano wrote:
> On Mon, 10 Jun 2013 20:14:55 -0400, Terry Jan Reedy wrote:
> > For instance, open Lib/idlelib/GrepDialog.py in an editor that colorizes
> > Python syntax, such as Idle's editor, jump down to the bottom and read
> > up, and (until it is patched) find
> >  list.append(fn)
> > with 'list' colored as a builtin. Stop. That looks wrong. List.append
> > needs two arguments: a list instance and an object to append to the
> > list. The 'solution' is in a previous line
> >  list = []
> > Reading further, one sees that the function works with two lists, a list
> > of file names, unfortunately called 'list', and a list of
> > subdirectories, more sensibly call 'subdirs'. 
> Yes, that is a poor choice of names. But sometimes you are
> dealing with a generic list, and calling it "filenames"
> would be equally inappropriate :-)

I agree, however hopefully you're joking, because in the past you've argued 
that programmers should never use variables as generic as "list", "string", 
"integer", "float", etc... even though there are instances when all you need to 
know is what type your working with.

> > I was initially confused
> > and reading the code still takes a small bit of extra mental energy.
> > Idle stays confused and will wrongly color the list instance name until
> > it is changed. Calling the file list 'fnames' or 'filenames' would have
> > been clearer to both me and Idle.
> Correct. The downside of editors that colourise text is
> that sometimes they colourise it wrong. 

One of the most important side-effects of using an editor with colorizing 
capabilities is to show you that you're using a built-in or keyword as a 
variable! I love when people comment on subjects they have no direct experience 
with, like for instance, you commenting on colonizers or GUI's -- LOL!

> In this case, how is the editor supposed to know that list
> no longer refers to the built-in list? 

Colonizers should ALWAYS colorize built-in (as built-in symbols) symbols EXCEPT 
when that symbol is part of a string or comment. 

> This is yet another good argument for being cautious about
> shadowing built- ins.

In a language designed like Python, yes. Unfortunately Python not only decided 
to expose built-in functions for constructing types instead of class 
identifiers, they also stole the best generic names! 

Sometimes all you need to know is the type of an object, not what it contains. 
I remember someone *cough-steven* talking about duck typing and how great it 
was to just treat a duck like a duck. Well, here we find ourselves treating a 
list like a list and your taking the opposite argument... why am i not 
surprised?

PS: Is that "D" in last name short for "DevilsAdvocate"? Steven 
"DevilsAdvocate" Prano.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Joshua Landau
On 11 June 2013 01:14, Terry Jan Reedy  wrote:
> Many long-time posters have advised "Don't rebind built-in names*.
>
> For instance, open Lib/idlelib/GrepDialog.py in an editor that colorizes
> Python syntax, such as Idle's editor, jump down to the bottom and read up,
> and (until it is patched) find
> list.append(fn)
> with 'list' colored as a builtin. Stop. That looks wrong. List.append needs
> two arguments: a list instance and an object to append to the list. The
> 'solution' is in a previous line
> list = []
> Reading further, one sees that the function works with two lists, a list of
> file names, unfortunately called 'list', and a list of subdirectories, more
> sensibly call 'subdirs'. I was initially confused and reading the code still
> takes a small bit of extra mental energy. Idle stays confused and will
> wrongly color the list instance name until it is changed. Calling the file
> list 'fnames' or 'filenames' would have been clearer to both me and Idle.

The problem here is the problem with all of this - names should be
descriptive. There is rarely a case where "str" or "string", even, is
sufficiently detailed, and "file" often really refers to a "path" for
example.

You should really not worry about shadowing builtins because if you're
using sufficiently long names you almost ne'er accidentally will. In
one of my recent posts I was chastised by someone (I remember not who)
for overwriting the "property" builtin - obviously this would *never*
happen in real life. If you call your property "property" you are a
fool. It means nothing!

Secondly, shadowing will _almost never_ be a problem, as you
invariably, given that you don't use "list" or "str" as variable
names, will have shadowed a completely contextually useless variable.
And thus, in the one-in-a hundred-in-a-thousand chance that you
accidentally shadow a builtin that happens to be important, you can
assume that your editor has a half-decent variable replacement
mechanism - it's only shadowed in a single scope!



But enough of that, you asked about syntax highlighting.

Personally, the current method is good - it reminds you when you are
shadowing, but does it gently. If you're adamant that the most
sensible name for your variable is "format", use it. The highlighting
shouldn't be taken to mean "this is from __builtins__", but a little
reminder that __builtins__ uses the name. Chances are, you won't be
using "format", so do. The little colour change, though, reminds you
to check that it really is the best name.

Or, well, do what I do and use a proper editor, and set syntax not to
highlight keywords if you care enough. My editor makes a good choice
only to highlight those keywords that you really don't want to shadow
- list, str, etc. - where they're just too vague to be good variable
names. "Format"'s unusual and as such do what you want with it.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Steven D'Aprano
On Tue, 11 Jun 2013 04:12:38 -0700, rusi wrote:

[...]
> then what the message of the Guido-quote is, is not clear (at least to
> me).

The relevant part is in the bit that you deleted. Let me quote it for you 
again:

"locals hiding built-ins is okay"
-- Guido van Rossum, inventor and BDFL of Python

[deadpan]
Sorry for such a long quote, and I realise it's quite tricky to 
interpret, so let me summarise for anyone still having difficulty:

GvR is saying that it's okay to use the names of built-in functions or 
types as the names of local variables, even if that causes the built-in 
to be inaccessible within that function.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Peter Otten
rusi wrote:

> On Jun 11, 12:09 pm, Peter Otten <__pete...@web.de> wrote:
>> Terry Jan Reedy wrote:
>> > Many long-time posters have advised "Don't rebind built-in names*.
>>
>> I'm in that camp, but I think this old post by Guido van Rossum is worth
>> reading to put the matter into perspective:
> 
> Not sure what you are saying Peter… If it is this (taken without
> context):
> 
>> (Not that it isn't a good idea to avoid obvious clashes --
>> 'str' for string variables and 'type' for type variables being the
>> most obvious stumbling blocks.)
> 
> then I guess we are saying the same thing??
> 
> If however we consider the context of that message:
> First there was only open, then there came file, and file was
> considered better than open, now again file seems to have disappeared
> from python3… and this message is written in the context of making the
> 'kosherness' of one python generation become the *different*
> kosherness of the next…
> 
> then what the message of the Guido-quote is, is not clear (at least to
> me).

As I understand it we should be a bit more relaxed about the matter of 
shading builtins with local variables than we usually are ;)

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread rusi
On Jun 11, 12:09 pm, Peter Otten <__pete...@web.de> wrote:
> Terry Jan Reedy wrote:
> > Many long-time posters have advised "Don't rebind built-in names*.
>
> I'm in that camp, but I think this old post by Guido van Rossum is worth
> reading to put the matter into perspective:

Not sure what you are saying Peter… If it is this (taken without
context):

> (Not that it isn't a good idea to avoid obvious clashes --
> 'str' for string variables and 'type' for type variables being the
> most obvious stumbling blocks.)

then I guess we are saying the same thing??

If however we consider the context of that message:
First there was only open, then there came file, and file was
considered better than open, now again file seems to have disappeared
from python3… and this message is written in the context of making the
'kosherness' of one python generation become the *different*
kosherness of the next…

then what the message of the Guido-quote is, is not clear (at least to
me).
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-11 Thread Peter Otten
Terry Jan Reedy wrote:

> Many long-time posters have advised "Don't rebind built-in names*.

I'm in that camp, but I think this old post by Guido van Rossum is worth 
reading to put the matter into perspective:

"""
> That was probably a checkin I made.  I would have left it alone except the
> code was
> 
> file = open(...)
> 
> As long as I was changing the variable name to not mask the builtin I
> changed the call as well.  Had it been
> 
> f = open(...)
> 
> I probably would have kept my hands off.

Hm...  I'm not particularly concerned over fixing all code that uses
file as a local variable name, unless it actually is likely to need to
reference the file class by name; builtins are in the last scope
searched for the very reason that no programmer is expected to keep up
with all additions to the built-in library, so locals hiding built-ins
is okay.  (Not that it isn't a good idea to avoid obvious clashes --
'str' for string variables and 'type' for type variables being the
most obvious stumbling blocks.)

> In any case, I was under the impression that file() was the wave of the
> future and open() a nod to the past.

Now you know better...

--Guido van Rossum (home page: http://www.python.org/~guido/)
"""




-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Terry Jan Reedy

On 6/10/2013 10:56 PM, Steven D'Aprano wrote:


I was initially confused
and reading the code still takes a small bit of extra mental energy.
Idle stays confused and will wrongly color the list instance name until
it is changed. Calling the file list 'fnames' or 'filenames' would have
been clearer to both me and Idle.


Correct. The downside of editors that colourise text is that sometimes
they colourise it wrong. In this case, how is the editor supposed to know
that list no longer refers to the built-in list?

This is yet another good argument for being cautious about shadowing
built-ins.


After posting I remembered that there are also colorized text blocks on 
web pages. Each person will have to decide for themselves whether the 
convenience of reusing a builtin name is worth having their code 
mis-colorized. As a reader, I decided that it is not.


tjr



--
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Steven D'Aprano
On Mon, 10 Jun 2013 20:30:41 -0700, rusi wrote:

>> Certainly it would be a PITA, and defeat the purpose of having nested
>> scopes, if inner names had to be globally unique. Wouldn't it be
>> absolutely horrible if adding a global variable "foo"[1] suddenly meant
>> that all your functions that used "foo" as a local variable stopped
>> working?
>>
>> [1] For some value of "foo".
> 
> Your opinion.

Well duh :-)

Mind you, I don't hear very many people *defending* the idea that local 
variables should be globally unique, or designing languages where this is 
the case. So if it's just an opinion, it's an opinion shared by the 
majority of programmers and language designers.


> Not so convincing if the sequence of composing the program was the
> other-way-round:
> if I have a global variable, say errno, and 'lose' it by introducing a
> local variable errno.

The consequences of inadvertent local-shadows-global are *much* less than 
the other way around. Any harm is local to the one function.

If you've shadowed a global with a local, there are two possibilities:

- You intended to shadow the global, in which case, good for you. I'm not 
going to past judgement and say you mustn't do this, so long as you're 
aware of what you're doing and have your reasons.

- You didn't intend to shadow the global, in which case you've just made 
a bug, and you'll soon find out and fix it.


> And in fact for a reader of a program, the order of its writing should
> not matter.

It doesn't. However, edits to working code can make it become non-
working. That's part of the business of being a programmer. Consider two 
scenarios:

- Add a local variable, and suddenly the function which you were editing 
stops working? Painful, but business as usual. At least you know that the 
bug exists within the function you just edited.

- Add a global variable, and suddenly dozens of functions all over the 
place stop working? Or worse, only a small handful of functions stop 
working, and you don't find out for a while. It's a lot harder to fix a 
bug caused by a new global shadowing your local when you might not even 
know that global exists.


> Which brings us pat into Terry's example.  [Also notice that changing
> from a 'parametric-semantic' name like foo to a more 'fixed-semantic'
> name like 'errno' or 'list' changes the desirability of this feature.

Absolutely! It makes the ability to shadow globals *more desirable*.

def myfunc(arg, list=list):
do_this()
do_that()
return list(arg)


Now you have a nicely localised, safe, tame monkey-patch, without 
compromising on the best name for "list".


>> I take it you have never programmed in a programming language with a
>> single, flat, global namespace? :-)
> 
> Well Ive used Basic and Assembler -- which are fun in the way that
> childhood and mountaineering respectively are fun.
> 
> What it seems you are not getting about Erlang's outlook about block-
> structure is this: There are two separable aspects to it: 1. Names can
> be created in local scopes which dont leak into (more) global scopes --
> a desirable feature

I can see that it is desirable, although I don't know how this works in 
practice in Erland. If you have a global x, and a local x, how do you 
refer to them both?

x = x 

Which one is which?


> 2. Names in local scopes can override names in global scope -- a
> dangerous feature [BTW which is what this thread is about].  And
> Erlang's approach seems to be the most nuanced -- you can do it if you
> go out of your way to say: "unstick the global namespace".

I can see that this is also desirable, especially in a more "bondage and 
discipline" language that makes you ask permission before doing anything. 
I don't think it is desirable *in Python*, which is a lot more laisse 
faire.


> This is somewhat analogous to gotos in Pascal. For Pascal goto was a
> sufficiently undesirable feature that using it was not completely easy. 
> However if you did surely want it, you had to declare the goto label.
> 
> Or by example:
> 
> def foo(x)...
> def bar(x,y)...
> there is no reason to confuse the two xes.
> 
> Whereas
> 
> x = ...
> def foo(x)...
> Now there is!
> 
> The first should be encouraged, the second discouraged.

Discouraging it means telling people that every time they need a local 
variable, they should consider the entire global environment before 
choosing a name. I call that bogus. Why shouldn't I call a local variable 
"id" if that's the best name for it, just because there's a global "id" 
that hardly anyone ever uses? If there's a global "x", and my function 
doesn't use it, why shouldn't it reuse "x" for a local if "x" is the best 
name in context?

Shadowing has both uses and abuses, pros and cons, and there's no doubt 
that it can be confusing to beginners. There are arguments against it, 
and I agree with them. But there are also arguments in favour, and I 
agree with them too. A good programmer[1] will weigh up the pros and cons 
of "use the m

Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Chris Angelico
On Tue, Jun 11, 2013 at 1:02 PM, Steven D'Aprano
 wrote:
> Apart from Erlang, got any other examples? Because it seems to me that in
> languages with nested scopes or namespaces, shadowing higher levels is
> exactly the right thing to do. Certainly it would be a PITA, and defeat
> the purpose of having nested scopes, if inner names had to be globally
> unique.

I agree, and it's one of the reasons that I like the explicitness of
C's variable declarations. Sure, Python makes it easier to write code;
but it's easier to figure out what's a global and what's not when
locals are all declared. (Yes, it's not that hard for a human to
recognize when a name is being rebound as opposed to merely used, but
it's extra work for a lexer/syntax highlighter.)

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread rusi
On Jun 11, 8:02 am, Steven D'Aprano  wrote:
> On Mon, 10 Jun 2013 19:36:44 -0700, rusi wrote:
> > Pascal introduced the idea of block structure -- introduce a name at one
> > level, override it at a lower level. [Ok ALgol introduced, Pascal
> > popularized].
> > This has caused more trouble than it has solved.
>
> > And so languages nowadays tend to 'protect' against this feature.
>
> Apart from Erlang, got any other examples? Because it seems to me that in
> languages with nested scopes or namespaces, shadowing higher levels is
> exactly the right thing to do.

This is just opening up the definition of block-structure and saying
its a good thing.

> Certainly it would be a PITA, and defeat
> the purpose of having nested scopes, if inner names had to be globally
> unique. Wouldn't it be absolutely horrible if adding a global variable
> "foo"[1] suddenly meant that all your functions that used "foo" as a
> local variable stopped working?
>
> [1] For some value of "foo".

Your opinion.

Not so convincing if the sequence of composing the program was the
other-way-round:
if I have a global variable, say errno, and 'lose' it by introducing a
local variable errno.

And in fact for a reader of a program, the order of its writing should
not matter.
Which brings us pat into Terry's example.  [Also notice that changing
from a 'parametric-semantic' name like foo to a more 'fixed-semantic'
name like 'errno' or 'list' changes the desirability of this feature.

>
> I take it you have never programmed in a programming language with a
> single, flat, global namespace? :-)

Well Ive used Basic and Assembler -- which are fun in the way that
childhood and mountaineering respectively are fun.

What it seems you are not getting about Erlang's outlook about block-
structure is this: There are two separable aspects to it:
1. Names can be created in local scopes which dont leak into (more)
global scopes -- a desirable feature

2. Names in local scopes can override names in global scope -- a
dangerous feature [BTW which is what this thread is about].  And
Erlang's approach seems to be the most nuanced -- you can do it if you
go out of your way to say: "unstick the global namespace".

This is somewhat analogous to gotos in Pascal. For Pascal goto was a
sufficiently undesirable feature that using it was not completely
easy.  However if you did surely want it, you had to declare the goto
label.

Or by example:

def foo(x)...
def bar(x,y)...
there is no reason to confuse the two xes.

Whereas

x = ...
def foo(x)...
Now there is!

The first should be encouraged, the second discouraged.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Steven D'Aprano
On Mon, 10 Jun 2013 19:36:44 -0700, rusi wrote:

> Pascal introduced the idea of block structure -- introduce a name at one
> level, override it at a lower level. [Ok ALgol introduced, Pascal
> popularized].
> This has caused more trouble than it has solved.

I take it you have never programmed in a programming language with a 
single, flat, global namespace? :-)


> And so languages nowadays tend to 'protect' against this feature.

Apart from Erlang, got any other examples? Because it seems to me that in 
languages with nested scopes or namespaces, shadowing higher levels is 
exactly the right thing to do. Certainly it would be a PITA, and defeat 
the purpose of having nested scopes, if inner names had to be globally 
unique. Wouldn't it be absolutely horrible if adding a global variable 
"foo"[1] suddenly meant that all your functions that used "foo" as a 
local variable stopped working?




[1] For some value of "foo".


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Steven D'Aprano
On Mon, 10 Jun 2013 20:14:55 -0400, Terry Jan Reedy wrote:

> For instance, open Lib/idlelib/GrepDialog.py in an editor that colorizes
> Python syntax, such as Idle's editor, jump down to the bottom and read
> up, and (until it is patched) find
>  list.append(fn)
> with 'list' colored as a builtin. Stop. That looks wrong. List.append
> needs two arguments: a list instance and an object to append to the
> list. The 'solution' is in a previous line
>  list = []
> Reading further, one sees that the function works with two lists, a list
> of file names, unfortunately called 'list', and a list of
> subdirectories, more sensibly call 'subdirs'. 

Yes, that is a poor choice of names.

But sometimes you are dealing with a generic list, and calling it 
"filenames" would be equally inappropriate :-)


> I was initially confused
> and reading the code still takes a small bit of extra mental energy.
> Idle stays confused and will wrongly color the list instance name until
> it is changed. Calling the file list 'fnames' or 'filenames' would have
> been clearer to both me and Idle.

Correct. The downside of editors that colourise text is that sometimes 
they colourise it wrong. In this case, how is the editor supposed to know 
that list no longer refers to the built-in list?

This is yet another good argument for being cautious about shadowing 
built-ins.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Steven D'Aprano
On Mon, 10 Jun 2013 17:20:58 -0700, Mark Janssen wrote:

>>> list = []
>>> Reading further, one sees that the function works with two lists, a
>>> list of file names, unfortunately called 'list',
>>
>> That is very good advice in general:  never choose a variable name that
>> is a keyword.
> 
> Btw,  shouldn't it be illegal anyway?  Most compilers don't let you do
> use a keyword as a variable name

list is not a keyword.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread rusi
On Jun 11, 5:14 am, Terry Jan Reedy  wrote:
> Many long-time posters have advised "Don't rebind built-in names*.
>
> * Unless you really mean to mask it, or more likely wrap it, such as
> wrapping print to modify some aspect of its operation than one cannot do
> with its keyword parameters. The point for this post is that such
> wrapping modify or extend the basic meaning of the builtin, but do not
> abolish it.
>
> Reasons have been given in various related forms: 'my long experience
> tells me its bad', 'you may need the builtin later', 'you may forget
> that you rebound the builtin, 'it can lead to subtle bugs, etc.
>
> Leaving aside the code writer and code operation, I recently discovered
> that it is not nice for readers, whether humans or programs.
>
> For instance, open Lib/idlelib/GrepDialog.py in an editor that colorizes
> Python syntax, such as Idle's editor, jump down to the bottom and read
> up, and (until it is patched) find
>                      list.append(fn)
> with 'list' colored as a builtin. Stop. That looks wrong. List.append
> needs two arguments: a list instance and an object to append to the
> list. The 'solution' is in a previous line
>          list = []
> Reading further, one sees that the function works with two lists, a list
> of file names, unfortunately called 'list', and a list of
> subdirectories, more sensibly call 'subdirs'. I was initially confused
> and reading the code still takes a small bit of extra mental energy.
> Idle stays confused and will wrongly color the list instance name until
> it is changed. Calling the file list 'fnames' or 'filenames' would have
> been clearer to both me and Idle.
>
> --
> Terry Jan Reedy

Pascal introduced the idea of block structure -- introduce a name at
one level, override it at a lower level. [Ok ALgol introduced, Pascal
popularized].
This has caused more trouble than it has solved. And so languages
nowadays tend to 'protect' against this feature.

Here is Erlang's 'sticky' feature
http://books.google.co.in/books?id=Qr_WuvfTSpEC&pg=PA181&lpg=PA181&dq=erlang+sticky+directory&source=bl&ots=aLZCjwzUFb&sig=DQiiQgzHCt5EtE5H3WY3bCWh4eM&hl=en&sa=X&ei=gYu2UbD6DMOMrQeNh4HYDA&ved=0CEAQ6AEwAw#v=onepage&q=erlang%20sticky%20directory&f=false
that prevents a programmer from overriding a builtin module unless he
explicitly asks for that.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread rusi
On Jun 11, 5:53 am, Mark Janssen  wrote:
> > There's a subtle difference between a keyword and a built-in.  Good
> > Python style generally avoids masking built-ins but allows it:
>
> Right, thank you for reminding me.  My C-mind put them in the same category.
> --
> MarkJ
> Tacoma, Washington

Dont know what you mean.  This is working C:
-
#include 
int getpid = 4;
main()
{
  printf("pid is %d\n", getpid);
}
-
As is this
-
#include 
main()
{
  printf("pid is %d\n", getpid());
}
-

The first prints 4; the second prints the pid.
gcc 4.7
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Mark Janssen
> There's a subtle difference between a keyword and a built-in.  Good
> Python style generally avoids masking built-ins but allows it:

Right, thank you for reminding me.  My C-mind put them in the same category.
-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Tim Chase
On 2013-06-10 17:20, Mark Janssen wrote:
> >> list = []
> >> Reading further, one sees that the function works with two
> >> lists, a list of file names, unfortunately called 'list',
> >
> > That is very good advice in general:  never choose a variable name
> > that is a keyword.
> 
> Btw,  shouldn't it be illegal anyway?  Most compilers don't let you
> do use a keyword as a variable name

There's a subtle difference between a keyword and a built-in.  Good
Python style generally avoids masking built-ins but allows it:

  >>> "file" in dir(__builtins__)
  True
  >>> file = "hello" # bad style, but permitted
  >>> print file
  hello

Whereas the compiler prevents you from tromping on actual keywords:

  >>> for = 4
File "", line 1
  for = 4
  ^
  SyntaxError: invalid syntax

-tkc




-- 
http://mail.python.org/mailman/listinfo/python-list


Re: "Don't rebind built-in names*" - it confuses readers

2013-06-10 Thread Mark Janssen
>> list = []
>> Reading further, one sees that the function works with two lists, a list of
>> file names, unfortunately called 'list',
>
> That is very good advice in general:  never choose a variable name
> that is a keyword.

Btw,  shouldn't it be illegal anyway?  Most compilers don't let you do
use a keyword as a variable name

-- 
MarkJ
Tacoma, Washington
-- 
http://mail.python.org/mailman/listinfo/python-list