Path: csiph.com!usenet.pasdenom.info!news.redatomik.org!newsfeed.xs4all.nl!newsfeed4.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; '"this': 0.03; '*not*': 0.07; 'notice,': 0.07; 'reason,': 0.07; 'feature.': 0.09; 'override': 0.09; 'cc:addr:python-list': 0.11; 'python': 0.11; '"we': 0.16; "'__doc__',": 0.16; "'as',": 0.16; "'for',": 0.16; "'help',": 0.16; "'if',": 0.16; "'in',": 0.16; "'input'": 0.16; "'is',": 0.16; "'not',": 0.16; "'or',": 0.16; "'set',": 0.16; "'with',": 0.16; 'builtins': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'keyword,': 0.16; 'looked-up': 0.16; 'terminate.': 0.16; 'prevent': 0.16; 'wrote:': 0.18; 'things.': 0.19; 'work,': 0.20; '>>>': 0.22; 'otherwise,': 0.22; 'cc:addr:python.org': 0.22; 'either.': 0.24; 'mon,': 0.24; 'cc:2**0': 0.24; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'specifically': 0.29; '[1]': 0.29; "doesn't": 0.30; 'primarily': 0.30; 'said,': 0.30; 'message-id:@mail.gmail.com': 0.30; 'program,': 0.31; 'code': 0.31; "skip:' 10": 0.31; 'keywords,': 0.31; 'steven': 0.31; 'another': 0.32; 'text': 0.33; 'becomes': 0.33; 'could': 0.34; 'problem': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'false': 0.36; 'instances': 0.36; 'keyword': 0.36; 'being': 0.38; 'skip:[ 10': 0.38; 'pm,': 0.38; 'does': 0.39; 'use.': 0.39; 'most': 0.60; 'break': 0.61; 'new': 0.61; 'simply': 0.61; 'name': 0.63; 'skip:n 10': 0.64; 'became': 0.64; 'sound': 0.68; 'incoming': 0.72; '2015': 0.84; 'pardon': 0.84; 'principles.': 0.84; 'shadow': 0.84; 'to:none': 0.92 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=Jmc6QMaJhby9ewr6xgG4C4Rae5JQI0kdHg5SPvOawe8=; b=kygQe50ZW2X+rhkLwXGfeBck/P0eKCqtKJEGHlOKtgbRQntouQhG3BYKfhPM/0tlj6 b+b4YVVm3JEl2/cS11jrdQ+pMmc34JwNfyTVy4k/69L0b2u/TPVKxqyQS+kMGIRPVBI8 4xque6Pn9sr20iqcMP96zRBaedFalegz+08k70RhqoAQ6eoYSeZN45mJQvIJjsPmUAPh 2NijLNQaqNhiKNBb6+sEvCSxbrIHZIq1FDEEtqi7WTJgsDrqH9LIvP7maZrsd5dT2GXd YUfrhpGqQ1/+ToF38yorFc7KKB0nVWWkYT48XTxLxk04ycV8sxORApg+LcZbrZiIX8us o9lg== MIME-Version: 1.0 X-Received: by 10.50.78.100 with SMTP id a4mr9043563igx.34.1431353581068; Mon, 11 May 2015 07:13:01 -0700 (PDT) In-Reply-To: <5550B0CF.208@rece.vub.ac.be> References: <554F9525.5040101@digipen.edu> <5550815E.5080600@rece.vub.ac.be> <5550a1d4$0$13013$c3e8da3$5496439d@news.astraweb.com> <5550B0CF.208@rece.vub.ac.be> Date: Tue, 12 May 2015 00:13:00 +1000 Subject: Re: anomaly From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 81 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1431353589 news.xs4all.nl 2950 [2001:888:2000:d::a6]:59783 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:90383 On Mon, May 11, 2015 at 11:38 PM, Antoon Pardon wrote: > "We allow buitins to be overridden", doesn't sound as a very accurate > description of the underlining reason, when you know that things have > been removed from builtins and made a keyword in order to prevent them > from being overridden. There are principles, and then there are specific instances that go against those principles. The overarching principle has its justification; the violations have to have their own justifications. As Steven said, there are no a priori reasons for most things - or to put it another way, there are very few design decisions that come down to a fundamental "this is right, this is wrong" - but there can be strong and weak justifications for things. Why does Python have most built-ins as simply looked-up names that can be overridden? Because otherwise, there would be a veritable ton of keywords: >>> 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', 'ZeroDivisionError', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', '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'] in addition to these, which _are_ keywords: >>> keyword.kwlist ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'] Python 2 had 'print' as a keyword, and it was specifically turned into a non-keyword in Python 3 to allow it to be overridden. It could have been turned into a function while still being a keyword, but it wasn't. Conversely, True and False became keywords, because there's no practical reason to override them. [1] You may well want to shadow 'copyright' with your own program's copyright notice, given that the built-in name is primarily there for interactive use. You might use 'input' to store the incoming text in a non-interactive program, or 'quit' in an interactive one to store a flag that becomes True when the user wants to terminate. Very frequently, 'id' is used as a database ID. None of these shadowings is a problem to the language; chances are none of them will ever be a problem to your code either. Having most of the built-in names *not* be keywords means that adding new built-ins doesn't break code; code that used the name for some other meaning will still work, but won't be able to use the new feature. That's a good thing. ChrisA [1] http://thedailywtf.com/articles/What_Is_Truth_0x3f_ notwithstanding.