relaxing keyword usage restrictions

Hi, Apologies if this has been asked already: why can't the usage of at least some keywords as identifiers be allowed with the context of the usage being used to identify if a keyword or a variable is being referred to. For example, if = 3 # if is identifier if if = 3: # first if is keyword, second if is identifer A more complex usage may require some rules: a = not or and and ==> parse left to right to interpret as a = ( (not or) and (and) ). 'or' and the last 'and' are identifiers While some of the usage may be confusing to the user, that is not for the language to dictate but for the user to choose. Almost all keywords have specific semantics which (in my limited understanding) do not conflict with their usage as identifiers. Regards, Krishnan

H Krishnan <hetchkay@gmail.com> wrote:
By itself, enough to show this is a bad idea.
While some of the usage may be confusing to the user, that is not for the language to dictate but for the user to choose.
Wrong. It's for the community to decide. The python community regularly decides to reject changes for no more reason than they might confuse a reader and provide no real benefit. Your examples show no benefit, and are obviously confusing. However, there may be some merit to the basic idea. In particular, allowing class to be used as a method parameter has an obvious use case (class methods), and would not produce those confusing cases you used as examples. -- Sent from my Android phone with K-9 Mail. Please excuse my brevity.

On Mon, Sep 5, 2011 at 3:18 PM, Mike Meyer <mwm@mired.org> wrote:
However, there may be some merit to the basic idea. In particular, allowing class to be used as a method parameter has an obvious use case (class methods), and would not produce those confusing cases you used as examples.
The main advantage of making things out-and-out keywords is that it greatly simplifies the task of *parsing* the language. It's a trade-off between occasional inconvenience in users having to choose slightly clunky variable and attribute names (such as 'cls', 'class_' or 'klass') and the simplicity Python parser developers gain by defining certain words as keywords that can never appear as variable names. One benefit users gain directly from that simplicity is that it makes syntax highlighters more likely to work correctly - the highlighters can just always mark keywords as keywords, without needing to worry about the usage context. It's easy to say "hey, let's allow keywords to be identifiers in places where they aren't being used as syntax". However, it doesn't look like such a great idea when you start considering the amount of change that would be needed to update the likes CPython, PyPy, IronPython, Jython, Cython/Pyrex, assorted syntax highlighting rules for various editors, Pygments, etc, etc. So, not impossible, but not worth the hassle either, especially since it would actually make the language *harder* to learn. Learning not to use keywords as variable names is fairly easy. Learning the ins and outs of when pseudo-keywords could be used as identifiers and when they were disallowed would be annoying. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Sep 05, 2011, at 03:50 PM, Nick Coghlan wrote:
The main advantage of making things out-and-out keywords is that it greatly simplifies the task of *parsing* the language.
While I agree with this, and the other justifications Nick mentions, I *could* see a potential middle ground, by allowing keywords as attributes. I think I'd still be -0 (at least) on it, but IIRC Jython did allow these at one point (e.g. `foo.class`), mostly through an accident of its implementation. -Barry

On Wed, Sep 7, 2011 at 6:41 AM, Barry Warsaw <barry@python.org> wrote:
The main objection to that approach is that it breaks down when you go to explicitly define class (or module) attributes that make use of the feature: class Foo: for = "Demonstrating a flaw in the 'keywords as attributes' concept" While there's a definite appeal to the idea of allowing keywords-as-attributes, it comes at the cost of breaking the symmetry between the identifiers that are permitted in module and class definition code and the attributes that are accessible via those namespaces. You could answer "but the feature is for programmatically generated attributes, such as CSV column names, not ones you type in a class definition" and make a reasonable case for the feature on that basis, but the conceptual symmetry is still broken. Ultimately, it's the "keep the rules simple" argument that holds the most weight with me on this topic, so the twin rules of "keywords can only be used as keywords" and "attribute names must be legal identifiers" end up being my preferred approach. The occasional inconvenience of a deliberate misspelling or the addition of a trailing underscore to convert a keyword into a legal identifier seems like a worthwhile trade-off for the corresponding simplification of the language syntax and semantics. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Sep 07, 2011, at 07:54 AM, Nick Coghlan wrote:
Still not disagreeing with you, but in some sense, you *can* use keywords as attributes today: Python 3.2.2 (default, Sep 5 2011, 21:17:14) [GCC 4.6.1] on linux2 Type "help", "copyright", "credits" or "license" for more information.
You just have to use "weird" syntax to set and get the values of those attributes. ;) So much for consistency. -Barry

Matt Joiner wrote:
I see nothing "least surprising" about allowing keywords to be used as identifiers. I see that as causing more, not less, confusion in a language that allows me to write things like: from as import import as from for for in in: if = elif if if else else if break: continue elif continue: break Easier for humans to parse? I don't think so. I think this is an anti-feature that is good for obfuscating Python code, and nothing else. If "consistency" is an argument in favour for allowing code like the above, then it's a foolish consistency. In my opinion, we can't save this idea by only allowing keywords as attributes. If you want to talk about surprising behaviour, try explaining to a beginner why of = instance.of is allowed, but if = instance.if is prohibited. -- Steven

On Wed, Sep 7, 2011 at 8:33 AM, Barry Warsaw <barry@python.org> wrote:
Still not disagreeing with you, but in some sense, you *can* use keywords as attributes today:
You can actually use arbitrary strings, such as "1234" and "not a legal identifier" that way, so I see that behaviour as still being consistent. Some implementations, including CPython, even let you use arbitrary non-string objects via the attribute dict interface, but whether or not that works has been explicitly deemed an implementation detail by Guido. If you treat a namespace like a string-keyed dictionary, you can use any string, even those that aren't valid identifiers. Treat it like an actual namespace, though, and the identifier restrictions come into play (including those disallowing the use of keywords). While it is indeed another rule, it's still a fairly simple and consistent one, since the identifier rules are there to allow consistent parsing without dedicated delimiters. That does give me an idea, though. Rather than allowing keywords-as-attributes, it may make more sense to allow string literals to stand in for identifiers without obeying the normal rules, permitting things like: class Foo: normal = 1 'class' = 'This is probably a terrible idea' '1234' = 'as is this' 'or does it' = 'have some merit?'
I'm still -1 myself, but such a delimited approach at least has the virtue of addressing the *entire* scope of the identifier syntax limitation rather than singling out keywords for special treatment. Legitimate use cases for such a feature would include at least those currently handled by the 'rename' flag on the namedtuple constructor (the latter would still be needed to handle duplicate field names, but illegal identifiers could just be quoted). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan wrote:
Could be rather confusing, since the interpretation of a string literal would depend somewhat subtly on its position in an expression. And it's not just a LHS/RHS distinction, because presumably the following would still parse with all the string literals being literals... or would it? 'foo'['blarg'] = 'asdf' -- Greg

On Tue, Sep 6, 2011 at 9:01 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
I seem to remember them being banned for all use in Python forever, but backticks are used for a similar purpose in SQL without ambiguity. `blarg baz` = 3 `foo`[`blarg baz`] = `asdf` I'd definitely prefer them to overloaded quotes. Devin

On Wed, Sep 7, 2011 at 11:57 AM, Barry Warsaw <barry@python.org> wrote:
Even worse: class Foo: '' = True Utterly untenable :) It would also be horribly ambiguous in several places where strings and identifiers are already both allowed, so the full concept fails on multiple counts. That means the scope would have to be limited to potentially supporting string literals on the RHS of the dot operator. Essentially it would just become further syntactic sugar for the getattr(), setattr() and delattr() builtins, with the string delimiters remaining optional for valid identifiers. I still don't really like the idea, but I have to admit that it would at least arguably be more elegant than attribute renaming or builtin function based workarounds for attribute names from external sources that aren't legal Python identifiers. As with other recurring discussions, I suggest that someone particularly interested in the topic put together a PEP so we can avoid rehashing the same details every couple of years - even rejected PEPs can serve as useful repositories for the reasons why certain things *aren't* done. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 9/6/2011 10:47 PM, Nick Coghlan wrote:
And completely possible with set/getattr ;=) I personally think the current de facto rule is fine: any identifier can be and must be acceptable as an attribute name; the use of anything else by indirect non-attribute-reference means (set/getattr, .__dict__, or otherwise) is implementation dependent. -- Terry Jan Reedy

Barry Warsaw writes:
setattr(f, 'class', 'evil')
You just have to use "weird" syntax to set and get the values of those attributes. ;) So much for consistency.
I don't see this as anything but an optimization of dict. You could easily encapsulate the syntax above in a class, no?

Seems that unadorned keywords and adorned keywords could be a touch independent. By that I mean the the following could be illegal: if if>5: pass #...and... class thingy: class="example of bad syntax" while possible to allow the following: class thingy: thingy.class="example of possible syntax" However, even if you could, I don't think you should. I just don't see sufficient value in this idea to be worth the change. -1 ( I guess that's how that works) -Nate

Nick Coghlan wrote:
You could answer "but the feature is for programmatically generated attributes, such as CSV column names,
I'd argue that it's for interfacing with libraries written in a different language. Your point about consistency still stands, but consistency doesn't necessarily trump all other considerations. Having to translate the API of a wrapped library by prepending underscores, or whatever convention is chosen, carries a mental burden as well. Not only do you have to remember to do it, you have to remember what convention the author of the wrapper used. -- Greg

Wrong. It's for the community to decide. The python community regularly decides to reject changes for no more reason than they might confuse a reader and provide no real benefit. Your examples show no benefit, and are obviously confusing.
Not sure I understand this point very well. Could I start a separate thread to say that Python should grab 'was' and 'were' as keywords so that a user is not able to write: if was is were: was = not were Sorry, that was tongue in cheek... Regards, Krishnan

H Krishnan writes:
No, if you're all that serious about messing with the sematics of keywords, what you should do instead is skim PEPs 221, 318, 343, and 359,[1] and note how much attention is paid to the cost of adding keywords in the rationales. There may be other good examples. Executive summary of the PEP list: the cost of keywords like "class" is well understood; there was a deliberate decision that this cost would be paid. But there is also strong resistence to adding new ones that are not absolutely required to implement a new feature. These same considerations apply to any new syntax in the language; see PEP 3003. Also read PEP 20, aka "python -m this" aka "The Zen of Python." The Python community considers language development to be an art. Implicit in that philosophical position is the possibility that you may not like the result. It's also possible that you may be able to convince the community of your position. But that is going to be much more likely (and you are much less likely to be defeated by windmills) if you understand the philosophy and tastes behind Python language features. Some of them may not be obvious unless you are Dutch (I guess you aren't :-), so PEP 3009 is required reading. Footnotes: [1] http://www.python.org/dev/peps/

Hi, I have read through the comments and the (largely negative) votes for this idea. The main argument against it seems to be readability. I feel the examples I chose were distracting. The intent of the examples was to show the semantics and not to suggest that anyone should write such code. One can write totally unreadable code even with the current syntax: if not was is can: return take One cannot however write readable code such as the following: if yield > principal: return = yield - principal def send(from, to, message): .. Syntax is something people will get used to. The following is perfectly valid 'scheme' code: (define define 3) (* define 5) In my 10+ years in scheme, I have never used 'define' as a symbol, nor have I seen anyone else do it, even though there is no language restriction. 'self' is not a keyword in python, but I have not so far seen anyone use 'self' other than as the first argument of a class method. The second argument was about the domino effect of such a change on parsing and syntax highlighting tools. That is true for any change to the core language, though the proposed change might cause more impact than most others. If syntax highlighting tools can use python's ast and other modules to identify keywords (instead of using their own parsers), the domino effect will be lesser. The use-case I had in mind was related to a customization tool we are developing. We want to allow users to define expressions and assign them to names. We 'eval' the expressions subsequently. We have to currently prevent users from using any python keyword as a name, which I felt was an unnecessary restriction. I don't think a partial solution like allowing keywords as attributes will work. It will be quite confusing and actually complicate the syntax highlighters more than a full solution would. Anyway, thanks for all the comments. Regards, Krishnan

On Thu, Sep 8, 2011 at 11:04 PM, H Krishnan <hetchkay@gmail.com> wrote:
Now that you've defined the actual use case you had in mind, it's a good reason not to use this. Using 'eval' on user-provided expressions is risky in many ways. If you restrict the expressions to simple operators like +-*/ then that's easy (and safer) to process without using eval (or if you are using eval, it's easy to replace every variable X with something like data["X"] completely eliminating the possibility of information leakage). If you're allowing calls to arbitrary functions then you're probably going to have some security holes in your app. For example, you better make sure to disallow expressions like: __import__('sys').exit() or [i for i in range(2**100) if i < 1] and lots of others. --- Bruce Follow me: http://www.twitter.com/Vroo http://www.vroospeak.com P.S.. Yes, that's valid scheme? So what? Redefining 'define' pretty much guarantees that the rest of your program will fail. (define define 3)(display (* define 5)) => 15(define x 4) => FAIL The fact that another language allows you to shoot yourself in the foot isn't a good argument that Python should allow that too.

On 9/9/2011 3:21 AM, H Krishnan wrote:
In the above, 'define' is not a keyword, it is a built-in function or macro name. Python allows those to be over-ridden too, with the same consequence. list = 3 list(1,2,3) # TypeError: 'int' object is not callable Because of its simple one-syntax-fits-all-needs design, I do not think Scheme has or needs functional keywords in the way Python does. For instance, the class statement, with it 'class' keyword, can be replaced by a call to the builtin 'type' class. The name 'type' can be over-ridden just like 'define' above. Perhaps Scheme has value keywords like Common Lisp (NIL?), I don't know. From https://secure.wikimedia.org/wikipedia/en/wiki/Keyword_%28computer_programmi... "In Common Lisp, the term "keyword" (or "keyword symbol") is used for a special sort of symbol, or identifier. Unlike other symbols, which usually stand for variables or functions, keywords are self-quoting and evaluate to themselves. Keywords are usually used to label named arguments to functions, and to represent symbolic values." Python has keyword values None, False, and True. These used to just be builtin identifiers that could be over-ridden, but were made keywords to prevent that.
But nothing (but syntax highlighters)
and the parser -- see my other post and Paul Moore's followup.
will break in Python by allowing keywords as identifiers,
If you disagree, try changing the grammar to do what you want while keeping Python an LL(1) language.
and so it is a less drastic change for Python.
We seem to have different ideas of 'drastic' ;-). -- Terry Jan Reedy

Hi, As someone pointed out, I think PEP 342 (coroutines via enhanced generators) anyway kills this proposal since it is currently possible to do something like: val = yield where yield is a keyword. The fact that another language allows you to shoot yourself in the foot
isn't a good argument that Python should allow that too.
If I do: __builtins__.exit = os._exit = os.kill = sys.exit = lambda *args: False is there a way to programmatically exit? Regards, Krishnan

On Thu, Sep 8, 2011 at 11:04 PM, H Krishnan <hetchkay@gmail.com> wrote:
"You can write FORTRAN [(or rather, bad code)] in any language"
As an example of how problematic the proposal is, that last line (modulo some var names, obviously) contains a valid yield-expression (see PEP 342 - http://www.python.org/dev/peps/pep-0342/ ). Subtle bugs and parser complexity ahoy!
This would seem to argue against the proposed language feature. If nobody does it even when they can do it, then why should we bother to change our rules to allow it? <snip>
Define a name-mangling convention then, and escape the problematic (or just all) names. Or use a dictionary instead of a normal namespace to store and refer to the expressions (as Bruce suggested excellently). Or accept the fact that since the users are really writing in Python (and not some custom scripting language), they should observe Python's rules. Cheers, Chris -- http://rebertia.com

On 9/9/2011 2:04 AM, H Krishnan wrote:
The parser has to be ready for and work correctly with the worst horror anyone *could* write. if in in in or and and and: One can write totally unreadable code even with the current syntax:
if not was is can: return take
Except that *is* readable *because* keywords are keywords and identifiers are identifiers. 'if not x is y' implies that x and y should be boolean values and we want them to have opposite values to proceed.
Funny you should choose that example. With a slight change myreturn = yield - principal it is legal syntax today with 'yield' interpreted as a keyword. So it cannot be interpreted as an identifier without making Python grammar ambiguous and unparseable with its current parser. Because C grammar allows typedef names, which are just identifiers, to be used as pseudo-keywords, without being distinguished by a real keyword or other mechanism, it is ambiguous. The ambiguity is resolved by making C globally context sensitive. Therefore, C cannot be parsed and compiled with a LR or LL compiler, such as produced by YACC. The parser has to be escaped to resolve the ambiguity and everyone who writes C parsers has to patch the output of any automatic parser generator. Having a sequence of characters be ambiguously either a keyword or an identifier is a bad idea. They are really different things. They have different grammatical functions. If one wants everything that looks like an identifier by be usable as an identifier, then there should be no identifier-like keywords. Require that all keystrings not be legal identifiers. Make them consist of or include some non-identifier character. Guido could had decided that all keystrings should start or end with a symbol such as '$' or '`', : $if, $yield, etc. Your problem would have been solved. And most everyone would have a problem with harder code entry.
Hardly in the same ballpark, I think. 3.2 had no core language changes. 3.3 might add 'yield from'. Syntax highlighters should not be affected. Adding a new keyword should also have no impact as any such tool should get the current keywords from keyword.kwlist.
Right now, it is a simple lookup.
For the present, you can remove the restriction on keywords that cannot appear in expressions by mechanically transforming them. -- Terry Jan Reedy

On 9 September 2011 08:48, Terry Reedy <tjreedy@udel.edu> wrote:
Here is some currently legal syntax: globals()['return'] = lambda x:x def f(): return(12) print(f()) Currently, that prints 12. If keywords are allowed as variable names, presumably it should produce 'None'? Or should we break the semantics of globals()? Or what? And given that the globals() line could be arbitrarily far away from the definition of f(), the parser would need arbitrary lookbehind. And lookahead, as the globals() line could be in a function defined after f but called before it. If you don't like me using globals(), the line could be replaced by def g(): global return return = lambda x:x g() but that's not currently legal syntax, so it obscures my point slightly... Python's parser is simple by design. This isn't going to be accepted (even if it were a good idea :-)) Paul.

On 9/9/2011 4:11 AM, Paul Moore wrote:
C now has a very similar problem. (According to Eli Bendersky) The C statememnt f(a); can either be a function call (presumably with side-effects) or a declaration that a is a variable of type f.
The C typedef ambiguity has to be resolved according to whether there is or is not a typedef for f in effect at that particular spot. This can even change within a statement. That determination requires arbitrary lookbehind, including the effect of #include directives. For Python, the runtime statements from module import * # or somewhat equivalently for k,v in parse_config_file(config_file): globals()[k] = v would makes global lookbehinds unresolvable at compile time. So Python solves the potential keyword/namespace-name ambiguity with a builltin keyword definition list. Similarly, avoiding global/local ambiguity is the reason why 'import *' is now prohibited within function defs and why "locals[k] = v" has no effect on the actual function local namespace. Python requires that the status of names within functions be determined and determinable at compile time. -- Terry Jan Reedy

On Fri, Sep 9, 2011 at 10:31 AM, Georg Brandl <g.brandl@gmx.net> wrote:
Not always. That code is indeed valid (unless something changed in Python 3.2). Python 3.1.2: def foo(): bar = yield 42 # look Ma, no parens! print(bar) a = foo() print(next(a)) a.send(7) Output: 42 7 Traceback (most recent call last): File "prog.py", line 7, in <module> a.send(7) StopIteration Cheers, Chris

On 2011-09-09 19:31, Georg Brandl wrote:
Actually it is, at least in 3.1 (I don't have a more recent version to test on ATM). It is the same as myreturn = yield (-principal) It computes and yields the value (-principal). When resumed by a "send" on the generator the argument is assigned to myreturn. If resumed by "next" instead, this is treated as send(None). I agree that this is confusing. In spite of all my work hashing out the details of PEP 380, I still initially thought it would work like myreturn = (yield) - principal probably because of the context where "yield" was supposed to be a regular variable name. (An idea I'm -1 on, btw). Based on this, I would support a change to outlaw myreturn = yield - principal forcing you to add the parentheses to clearly show which interpretation is intended. However, I would still want to keep the statement form yield -principal legal, so I am not sure if that proposal has a chance to fly. - Jacob

Am 09.09.2011 20:21, schrieb Jacob Holm:
Of course. I'm not new to PEP 342 :) But I have to apologize: what I did test was the confusingly similar return yield - principal which isn't allowed (yes, I know that even return (yield -principal) isn't allowed, but that's not for syntactical reasons.) Now I checked properly: In fact, "yield" expressions after assignment operators are special-cased by the grammar, so that they don't need to be parenthesized [1]. In all other places, yield expressions must occur in parentheses. For example: myreturn = principal - yield Georg [1] I guess that's because it was thought to be a common case. I agree that it's not really helping readability.

On Fri, 2011-09-09 at 21:23 +0200, Georg Brandl wrote:
Concerning yield without the parentheses. x = yield I really think it should have been "x = (yield)" or "x yield None". Here is my reasoning. What if yield was an assignment operator with similar usage rules as '='? x = y Assign x the object(s) y is assigned to. x yield y assign x from yield, yield out y In other words, the "yield" would never appear to represent a value directly. That's one of the things that makes them confusing to read and write. Heres how the examples in pep 342 would change if yield worked more like '='. x = yield 42 -> x yield 42 x = yield -> x yield None x = 12 + (yield 42) y yield 42 x = 12 + y x = 12 + (yield) y yield None # explicit is better than special casing None here. x = 12 + y foo(yield 42) y yield 42 foo(y) foo(yield) y yield None foo(y) So it only adds one line to some things, but it makes for easier to read code. Once we have yield statements like these, we can then add the ability to do yield expressions by wrapping a yield statement inside parentheses. And special casing (yield None) as (yield) Oh, wait.. we already have that part. <wink> It looks to me, that having yield statements, could help with explaining yield expressions. It may be worth doing just for that. Cheers, Ron

ron3200, 09.09.2011 23:34:
Whoa, that's ugly. It totally hides the fact that an assignment is taking place at all. Here, yield isn't operating on x, it's operating on y. Your syntax adds symmetry where there is none. (And, BTW, I agree that the yield should always be in parentheses, but I guess it's too late to change that before Py4.) Stefan

On Sat, Sep 10, 2011 at 9:09 AM, Stefan Behnel <stefan_ml@behnel.de> wrote:
(And, BTW, I agree that the yield should always be in parentheses, but I guess it's too late to change that before Py4.)
You can make that a personal style today. And you could lobby for inclusion in PEP 8 (though personally I don't care either way). -- --Guido van Rossum (python.org/~guido)

On Sun, Sep 11, 2011 at 2:39 AM, Guido van Rossum <guido@python.org> wrote:
As the examples in the PEP suggest, the "no parens" usage was for simple evolutions from the pre-existing yield statement syntax: yield None => x = yield yield 42 => x = yield 42 yield y => x = yield y For simple cases like that, the parens would be redundant visual clutter (similar to the ill-advised practice of including redundant parens in if statements: "if (expr):"). Beyond those simple cases, I don't think there needs to be a yield specific recommendation - the general guidelines to use parentheses and named subexpressions to improve readability should cover it. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, Sep 8, 2011 at 11:04 PM, H Krishnan <hetchkay@gmail.com> wrote:
Others have pointed out the parsing problems this would create. I'll point out that Python is not Scheme. I'm a fan of both languages, but they are not the same. Scheme has a history of valuing power, and adding it by removing restrictions. The example above - of allowing people to redefine what are primitives in other languages - fits that model perfectly. Python, on the other hand, has a history of valuing readability. With very few exceptions, changes to Python make some use case more readable, without adding a way to write really unreadable code. The change to have non-reserved keywords clashes badly with that model. <mike

H Krishnan writes:
In my 10+ years in scheme, I have never used 'define' as a symbol,
Of course you have used 'define' as a symbol. The rules of expression evaluation in Scheme say "evaluate the first element of a list, and apply the result to the rest of the list as arguments." When 'define' is the first element of a list, it is evaluated as a symbol, ie, the content of the value cell of the symbol 'define' is retrieved. Conventionally, that cell contains a function that sets the value of the second argument to the value of the third argument. You can't really get away with saying, "I haven't used it as a variable", either, since taking the value of a symbol is using it as a variable. So the design of Scheme (and Lisps in general) is very elegant, because everything is determined by the arrangement of parentheses. There is no need for reserving keywords. However, not all languages are Lisps. Vive la difference![1] Except that as somebody pointed out, there is a need. It turns out that users want keywords in the form of "constants that evaluate to themselves". So in the end you're at the same place, just a different balance. (I know that Scheme does not have them, although they can be created using define -- that's Schemingly correct, of course. But other languages have made a deliberate choice to introduce them, cf. http://stackoverflow.com/questions/1527548/why-does-clojure-have-keywords-in....)
They can't. Think editors written in Lisp. Footnotes: [1] With apologies to the Francophones present for my spelling.

On Sat, Sep 10, 2011 at 8:39 AM, Stephen J. Turnbull <stephen@xemacs.org>wrote:
I didn't realize that my proposal was not backward compatible. As some of you pointed out, currently, "return (val)" and "yield (val)" are legal python with 'return' and 'yield' used as keywords. So, I'll withdraw my proposal. I did want to reply to a few specific comments (e.g. 'python parser is simple') but I don't subscribe to the mailing list and didn't want to break the threading in the list. Thanks, Krishnan

H Krishnan <hetchkay@gmail.com> writes:
While some of the usage may be confusing to the user, that is not for the language to dictate but for the user to choose.
This statement makes the entirely unjustified assumption that the code will be read by exactly one “user”. Python is a language designed for writing code that isn't limited to just one reader. So no, every individual author of code doesn't get to choose what is readable for others; the Python community as a whole has a large say in that. -- \ “There are no chaplains in foxholes.” —Sergeant Justin | `\ Griffith, 2011-07-27 | _o__) | Ben Finney

Devin Jeanpierre wrote:
The "as" keyword used to be a pseudokeyword that functioned this way. Apparently the experiment didn't go well,
I think that was only done because the __future__ mechanism hadn't been invented then. As far as I know, it was always intended to become a full keyword at some point. -- Greg

Greg Ewing writes:
That may be true, but the PEP says "this word 'as' is not intended to become a keyword." For my point it doesn't matter exactly what the intention was; what matters is that people pay attention to the cost of reserving keywords globally, but also accept the need for a few keywords.

H Krishnan <hetchkay@gmail.com> wrote:
By itself, enough to show this is a bad idea.
While some of the usage may be confusing to the user, that is not for the language to dictate but for the user to choose.
Wrong. It's for the community to decide. The python community regularly decides to reject changes for no more reason than they might confuse a reader and provide no real benefit. Your examples show no benefit, and are obviously confusing. However, there may be some merit to the basic idea. In particular, allowing class to be used as a method parameter has an obvious use case (class methods), and would not produce those confusing cases you used as examples. -- Sent from my Android phone with K-9 Mail. Please excuse my brevity.

On Mon, Sep 5, 2011 at 3:18 PM, Mike Meyer <mwm@mired.org> wrote:
However, there may be some merit to the basic idea. In particular, allowing class to be used as a method parameter has an obvious use case (class methods), and would not produce those confusing cases you used as examples.
The main advantage of making things out-and-out keywords is that it greatly simplifies the task of *parsing* the language. It's a trade-off between occasional inconvenience in users having to choose slightly clunky variable and attribute names (such as 'cls', 'class_' or 'klass') and the simplicity Python parser developers gain by defining certain words as keywords that can never appear as variable names. One benefit users gain directly from that simplicity is that it makes syntax highlighters more likely to work correctly - the highlighters can just always mark keywords as keywords, without needing to worry about the usage context. It's easy to say "hey, let's allow keywords to be identifiers in places where they aren't being used as syntax". However, it doesn't look like such a great idea when you start considering the amount of change that would be needed to update the likes CPython, PyPy, IronPython, Jython, Cython/Pyrex, assorted syntax highlighting rules for various editors, Pygments, etc, etc. So, not impossible, but not worth the hassle either, especially since it would actually make the language *harder* to learn. Learning not to use keywords as variable names is fairly easy. Learning the ins and outs of when pseudo-keywords could be used as identifiers and when they were disallowed would be annoying. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Sep 05, 2011, at 03:50 PM, Nick Coghlan wrote:
The main advantage of making things out-and-out keywords is that it greatly simplifies the task of *parsing* the language.
While I agree with this, and the other justifications Nick mentions, I *could* see a potential middle ground, by allowing keywords as attributes. I think I'd still be -0 (at least) on it, but IIRC Jython did allow these at one point (e.g. `foo.class`), mostly through an accident of its implementation. -Barry

On Wed, Sep 7, 2011 at 6:41 AM, Barry Warsaw <barry@python.org> wrote:
The main objection to that approach is that it breaks down when you go to explicitly define class (or module) attributes that make use of the feature: class Foo: for = "Demonstrating a flaw in the 'keywords as attributes' concept" While there's a definite appeal to the idea of allowing keywords-as-attributes, it comes at the cost of breaking the symmetry between the identifiers that are permitted in module and class definition code and the attributes that are accessible via those namespaces. You could answer "but the feature is for programmatically generated attributes, such as CSV column names, not ones you type in a class definition" and make a reasonable case for the feature on that basis, but the conceptual symmetry is still broken. Ultimately, it's the "keep the rules simple" argument that holds the most weight with me on this topic, so the twin rules of "keywords can only be used as keywords" and "attribute names must be legal identifiers" end up being my preferred approach. The occasional inconvenience of a deliberate misspelling or the addition of a trailing underscore to convert a keyword into a legal identifier seems like a worthwhile trade-off for the corresponding simplification of the language syntax and semantics. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Sep 07, 2011, at 07:54 AM, Nick Coghlan wrote:
Still not disagreeing with you, but in some sense, you *can* use keywords as attributes today: Python 3.2.2 (default, Sep 5 2011, 21:17:14) [GCC 4.6.1] on linux2 Type "help", "copyright", "credits" or "license" for more information.
You just have to use "weird" syntax to set and get the values of those attributes. ;) So much for consistency. -Barry

Matt Joiner wrote:
I see nothing "least surprising" about allowing keywords to be used as identifiers. I see that as causing more, not less, confusion in a language that allows me to write things like: from as import import as from for for in in: if = elif if if else else if break: continue elif continue: break Easier for humans to parse? I don't think so. I think this is an anti-feature that is good for obfuscating Python code, and nothing else. If "consistency" is an argument in favour for allowing code like the above, then it's a foolish consistency. In my opinion, we can't save this idea by only allowing keywords as attributes. If you want to talk about surprising behaviour, try explaining to a beginner why of = instance.of is allowed, but if = instance.if is prohibited. -- Steven

On Wed, Sep 7, 2011 at 8:33 AM, Barry Warsaw <barry@python.org> wrote:
Still not disagreeing with you, but in some sense, you *can* use keywords as attributes today:
You can actually use arbitrary strings, such as "1234" and "not a legal identifier" that way, so I see that behaviour as still being consistent. Some implementations, including CPython, even let you use arbitrary non-string objects via the attribute dict interface, but whether or not that works has been explicitly deemed an implementation detail by Guido. If you treat a namespace like a string-keyed dictionary, you can use any string, even those that aren't valid identifiers. Treat it like an actual namespace, though, and the identifier restrictions come into play (including those disallowing the use of keywords). While it is indeed another rule, it's still a fairly simple and consistent one, since the identifier rules are there to allow consistent parsing without dedicated delimiters. That does give me an idea, though. Rather than allowing keywords-as-attributes, it may make more sense to allow string literals to stand in for identifiers without obeying the normal rules, permitting things like: class Foo: normal = 1 'class' = 'This is probably a terrible idea' '1234' = 'as is this' 'or does it' = 'have some merit?'
I'm still -1 myself, but such a delimited approach at least has the virtue of addressing the *entire* scope of the identifier syntax limitation rather than singling out keywords for special treatment. Legitimate use cases for such a feature would include at least those currently handled by the 'rename' flag on the namedtuple constructor (the latter would still be needed to handle duplicate field names, but illegal identifiers could just be quoted). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

Nick Coghlan wrote:
Could be rather confusing, since the interpretation of a string literal would depend somewhat subtly on its position in an expression. And it's not just a LHS/RHS distinction, because presumably the following would still parse with all the string literals being literals... or would it? 'foo'['blarg'] = 'asdf' -- Greg

On Tue, Sep 6, 2011 at 9:01 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
I seem to remember them being banned for all use in Python forever, but backticks are used for a similar purpose in SQL without ambiguity. `blarg baz` = 3 `foo`[`blarg baz`] = `asdf` I'd definitely prefer them to overloaded quotes. Devin

On Wed, Sep 7, 2011 at 11:57 AM, Barry Warsaw <barry@python.org> wrote:
Even worse: class Foo: '' = True Utterly untenable :) It would also be horribly ambiguous in several places where strings and identifiers are already both allowed, so the full concept fails on multiple counts. That means the scope would have to be limited to potentially supporting string literals on the RHS of the dot operator. Essentially it would just become further syntactic sugar for the getattr(), setattr() and delattr() builtins, with the string delimiters remaining optional for valid identifiers. I still don't really like the idea, but I have to admit that it would at least arguably be more elegant than attribute renaming or builtin function based workarounds for attribute names from external sources that aren't legal Python identifiers. As with other recurring discussions, I suggest that someone particularly interested in the topic put together a PEP so we can avoid rehashing the same details every couple of years - even rejected PEPs can serve as useful repositories for the reasons why certain things *aren't* done. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 9/6/2011 10:47 PM, Nick Coghlan wrote:
And completely possible with set/getattr ;=) I personally think the current de facto rule is fine: any identifier can be and must be acceptable as an attribute name; the use of anything else by indirect non-attribute-reference means (set/getattr, .__dict__, or otherwise) is implementation dependent. -- Terry Jan Reedy

Barry Warsaw writes:
setattr(f, 'class', 'evil')
You just have to use "weird" syntax to set and get the values of those attributes. ;) So much for consistency.
I don't see this as anything but an optimization of dict. You could easily encapsulate the syntax above in a class, no?

Seems that unadorned keywords and adorned keywords could be a touch independent. By that I mean the the following could be illegal: if if>5: pass #...and... class thingy: class="example of bad syntax" while possible to allow the following: class thingy: thingy.class="example of possible syntax" However, even if you could, I don't think you should. I just don't see sufficient value in this idea to be worth the change. -1 ( I guess that's how that works) -Nate

Nick Coghlan wrote:
You could answer "but the feature is for programmatically generated attributes, such as CSV column names,
I'd argue that it's for interfacing with libraries written in a different language. Your point about consistency still stands, but consistency doesn't necessarily trump all other considerations. Having to translate the API of a wrapped library by prepending underscores, or whatever convention is chosen, carries a mental burden as well. Not only do you have to remember to do it, you have to remember what convention the author of the wrapper used. -- Greg

Wrong. It's for the community to decide. The python community regularly decides to reject changes for no more reason than they might confuse a reader and provide no real benefit. Your examples show no benefit, and are obviously confusing.
Not sure I understand this point very well. Could I start a separate thread to say that Python should grab 'was' and 'were' as keywords so that a user is not able to write: if was is were: was = not were Sorry, that was tongue in cheek... Regards, Krishnan

H Krishnan writes:
No, if you're all that serious about messing with the sematics of keywords, what you should do instead is skim PEPs 221, 318, 343, and 359,[1] and note how much attention is paid to the cost of adding keywords in the rationales. There may be other good examples. Executive summary of the PEP list: the cost of keywords like "class" is well understood; there was a deliberate decision that this cost would be paid. But there is also strong resistence to adding new ones that are not absolutely required to implement a new feature. These same considerations apply to any new syntax in the language; see PEP 3003. Also read PEP 20, aka "python -m this" aka "The Zen of Python." The Python community considers language development to be an art. Implicit in that philosophical position is the possibility that you may not like the result. It's also possible that you may be able to convince the community of your position. But that is going to be much more likely (and you are much less likely to be defeated by windmills) if you understand the philosophy and tastes behind Python language features. Some of them may not be obvious unless you are Dutch (I guess you aren't :-), so PEP 3009 is required reading. Footnotes: [1] http://www.python.org/dev/peps/

Hi, I have read through the comments and the (largely negative) votes for this idea. The main argument against it seems to be readability. I feel the examples I chose were distracting. The intent of the examples was to show the semantics and not to suggest that anyone should write such code. One can write totally unreadable code even with the current syntax: if not was is can: return take One cannot however write readable code such as the following: if yield > principal: return = yield - principal def send(from, to, message): .. Syntax is something people will get used to. The following is perfectly valid 'scheme' code: (define define 3) (* define 5) In my 10+ years in scheme, I have never used 'define' as a symbol, nor have I seen anyone else do it, even though there is no language restriction. 'self' is not a keyword in python, but I have not so far seen anyone use 'self' other than as the first argument of a class method. The second argument was about the domino effect of such a change on parsing and syntax highlighting tools. That is true for any change to the core language, though the proposed change might cause more impact than most others. If syntax highlighting tools can use python's ast and other modules to identify keywords (instead of using their own parsers), the domino effect will be lesser. The use-case I had in mind was related to a customization tool we are developing. We want to allow users to define expressions and assign them to names. We 'eval' the expressions subsequently. We have to currently prevent users from using any python keyword as a name, which I felt was an unnecessary restriction. I don't think a partial solution like allowing keywords as attributes will work. It will be quite confusing and actually complicate the syntax highlighters more than a full solution would. Anyway, thanks for all the comments. Regards, Krishnan

On Thu, Sep 8, 2011 at 11:04 PM, H Krishnan <hetchkay@gmail.com> wrote:
Now that you've defined the actual use case you had in mind, it's a good reason not to use this. Using 'eval' on user-provided expressions is risky in many ways. If you restrict the expressions to simple operators like +-*/ then that's easy (and safer) to process without using eval (or if you are using eval, it's easy to replace every variable X with something like data["X"] completely eliminating the possibility of information leakage). If you're allowing calls to arbitrary functions then you're probably going to have some security holes in your app. For example, you better make sure to disallow expressions like: __import__('sys').exit() or [i for i in range(2**100) if i < 1] and lots of others. --- Bruce Follow me: http://www.twitter.com/Vroo http://www.vroospeak.com P.S.. Yes, that's valid scheme? So what? Redefining 'define' pretty much guarantees that the rest of your program will fail. (define define 3)(display (* define 5)) => 15(define x 4) => FAIL The fact that another language allows you to shoot yourself in the foot isn't a good argument that Python should allow that too.

On 9/9/2011 3:21 AM, H Krishnan wrote:
In the above, 'define' is not a keyword, it is a built-in function or macro name. Python allows those to be over-ridden too, with the same consequence. list = 3 list(1,2,3) # TypeError: 'int' object is not callable Because of its simple one-syntax-fits-all-needs design, I do not think Scheme has or needs functional keywords in the way Python does. For instance, the class statement, with it 'class' keyword, can be replaced by a call to the builtin 'type' class. The name 'type' can be over-ridden just like 'define' above. Perhaps Scheme has value keywords like Common Lisp (NIL?), I don't know. From https://secure.wikimedia.org/wikipedia/en/wiki/Keyword_%28computer_programmi... "In Common Lisp, the term "keyword" (or "keyword symbol") is used for a special sort of symbol, or identifier. Unlike other symbols, which usually stand for variables or functions, keywords are self-quoting and evaluate to themselves. Keywords are usually used to label named arguments to functions, and to represent symbolic values." Python has keyword values None, False, and True. These used to just be builtin identifiers that could be over-ridden, but were made keywords to prevent that.
But nothing (but syntax highlighters)
and the parser -- see my other post and Paul Moore's followup.
will break in Python by allowing keywords as identifiers,
If you disagree, try changing the grammar to do what you want while keeping Python an LL(1) language.
and so it is a less drastic change for Python.
We seem to have different ideas of 'drastic' ;-). -- Terry Jan Reedy

Hi, As someone pointed out, I think PEP 342 (coroutines via enhanced generators) anyway kills this proposal since it is currently possible to do something like: val = yield where yield is a keyword. The fact that another language allows you to shoot yourself in the foot
isn't a good argument that Python should allow that too.
If I do: __builtins__.exit = os._exit = os.kill = sys.exit = lambda *args: False is there a way to programmatically exit? Regards, Krishnan

On Thu, Sep 8, 2011 at 11:04 PM, H Krishnan <hetchkay@gmail.com> wrote:
"You can write FORTRAN [(or rather, bad code)] in any language"
As an example of how problematic the proposal is, that last line (modulo some var names, obviously) contains a valid yield-expression (see PEP 342 - http://www.python.org/dev/peps/pep-0342/ ). Subtle bugs and parser complexity ahoy!
This would seem to argue against the proposed language feature. If nobody does it even when they can do it, then why should we bother to change our rules to allow it? <snip>
Define a name-mangling convention then, and escape the problematic (or just all) names. Or use a dictionary instead of a normal namespace to store and refer to the expressions (as Bruce suggested excellently). Or accept the fact that since the users are really writing in Python (and not some custom scripting language), they should observe Python's rules. Cheers, Chris -- http://rebertia.com

On 9/9/2011 2:04 AM, H Krishnan wrote:
The parser has to be ready for and work correctly with the worst horror anyone *could* write. if in in in or and and and: One can write totally unreadable code even with the current syntax:
if not was is can: return take
Except that *is* readable *because* keywords are keywords and identifiers are identifiers. 'if not x is y' implies that x and y should be boolean values and we want them to have opposite values to proceed.
Funny you should choose that example. With a slight change myreturn = yield - principal it is legal syntax today with 'yield' interpreted as a keyword. So it cannot be interpreted as an identifier without making Python grammar ambiguous and unparseable with its current parser. Because C grammar allows typedef names, which are just identifiers, to be used as pseudo-keywords, without being distinguished by a real keyword or other mechanism, it is ambiguous. The ambiguity is resolved by making C globally context sensitive. Therefore, C cannot be parsed and compiled with a LR or LL compiler, such as produced by YACC. The parser has to be escaped to resolve the ambiguity and everyone who writes C parsers has to patch the output of any automatic parser generator. Having a sequence of characters be ambiguously either a keyword or an identifier is a bad idea. They are really different things. They have different grammatical functions. If one wants everything that looks like an identifier by be usable as an identifier, then there should be no identifier-like keywords. Require that all keystrings not be legal identifiers. Make them consist of or include some non-identifier character. Guido could had decided that all keystrings should start or end with a symbol such as '$' or '`', : $if, $yield, etc. Your problem would have been solved. And most everyone would have a problem with harder code entry.
Hardly in the same ballpark, I think. 3.2 had no core language changes. 3.3 might add 'yield from'. Syntax highlighters should not be affected. Adding a new keyword should also have no impact as any such tool should get the current keywords from keyword.kwlist.
Right now, it is a simple lookup.
For the present, you can remove the restriction on keywords that cannot appear in expressions by mechanically transforming them. -- Terry Jan Reedy

On 9 September 2011 08:48, Terry Reedy <tjreedy@udel.edu> wrote:
Here is some currently legal syntax: globals()['return'] = lambda x:x def f(): return(12) print(f()) Currently, that prints 12. If keywords are allowed as variable names, presumably it should produce 'None'? Or should we break the semantics of globals()? Or what? And given that the globals() line could be arbitrarily far away from the definition of f(), the parser would need arbitrary lookbehind. And lookahead, as the globals() line could be in a function defined after f but called before it. If you don't like me using globals(), the line could be replaced by def g(): global return return = lambda x:x g() but that's not currently legal syntax, so it obscures my point slightly... Python's parser is simple by design. This isn't going to be accepted (even if it were a good idea :-)) Paul.

On 9/9/2011 4:11 AM, Paul Moore wrote:
C now has a very similar problem. (According to Eli Bendersky) The C statememnt f(a); can either be a function call (presumably with side-effects) or a declaration that a is a variable of type f.
The C typedef ambiguity has to be resolved according to whether there is or is not a typedef for f in effect at that particular spot. This can even change within a statement. That determination requires arbitrary lookbehind, including the effect of #include directives. For Python, the runtime statements from module import * # or somewhat equivalently for k,v in parse_config_file(config_file): globals()[k] = v would makes global lookbehinds unresolvable at compile time. So Python solves the potential keyword/namespace-name ambiguity with a builltin keyword definition list. Similarly, avoiding global/local ambiguity is the reason why 'import *' is now prohibited within function defs and why "locals[k] = v" has no effect on the actual function local namespace. Python requires that the status of names within functions be determined and determinable at compile time. -- Terry Jan Reedy

On Fri, Sep 9, 2011 at 10:31 AM, Georg Brandl <g.brandl@gmx.net> wrote:
Not always. That code is indeed valid (unless something changed in Python 3.2). Python 3.1.2: def foo(): bar = yield 42 # look Ma, no parens! print(bar) a = foo() print(next(a)) a.send(7) Output: 42 7 Traceback (most recent call last): File "prog.py", line 7, in <module> a.send(7) StopIteration Cheers, Chris

On 2011-09-09 19:31, Georg Brandl wrote:
Actually it is, at least in 3.1 (I don't have a more recent version to test on ATM). It is the same as myreturn = yield (-principal) It computes and yields the value (-principal). When resumed by a "send" on the generator the argument is assigned to myreturn. If resumed by "next" instead, this is treated as send(None). I agree that this is confusing. In spite of all my work hashing out the details of PEP 380, I still initially thought it would work like myreturn = (yield) - principal probably because of the context where "yield" was supposed to be a regular variable name. (An idea I'm -1 on, btw). Based on this, I would support a change to outlaw myreturn = yield - principal forcing you to add the parentheses to clearly show which interpretation is intended. However, I would still want to keep the statement form yield -principal legal, so I am not sure if that proposal has a chance to fly. - Jacob

Am 09.09.2011 20:21, schrieb Jacob Holm:
Of course. I'm not new to PEP 342 :) But I have to apologize: what I did test was the confusingly similar return yield - principal which isn't allowed (yes, I know that even return (yield -principal) isn't allowed, but that's not for syntactical reasons.) Now I checked properly: In fact, "yield" expressions after assignment operators are special-cased by the grammar, so that they don't need to be parenthesized [1]. In all other places, yield expressions must occur in parentheses. For example: myreturn = principal - yield Georg [1] I guess that's because it was thought to be a common case. I agree that it's not really helping readability.

On Fri, 2011-09-09 at 21:23 +0200, Georg Brandl wrote:
Concerning yield without the parentheses. x = yield I really think it should have been "x = (yield)" or "x yield None". Here is my reasoning. What if yield was an assignment operator with similar usage rules as '='? x = y Assign x the object(s) y is assigned to. x yield y assign x from yield, yield out y In other words, the "yield" would never appear to represent a value directly. That's one of the things that makes them confusing to read and write. Heres how the examples in pep 342 would change if yield worked more like '='. x = yield 42 -> x yield 42 x = yield -> x yield None x = 12 + (yield 42) y yield 42 x = 12 + y x = 12 + (yield) y yield None # explicit is better than special casing None here. x = 12 + y foo(yield 42) y yield 42 foo(y) foo(yield) y yield None foo(y) So it only adds one line to some things, but it makes for easier to read code. Once we have yield statements like these, we can then add the ability to do yield expressions by wrapping a yield statement inside parentheses. And special casing (yield None) as (yield) Oh, wait.. we already have that part. <wink> It looks to me, that having yield statements, could help with explaining yield expressions. It may be worth doing just for that. Cheers, Ron

ron3200, 09.09.2011 23:34:
Whoa, that's ugly. It totally hides the fact that an assignment is taking place at all. Here, yield isn't operating on x, it's operating on y. Your syntax adds symmetry where there is none. (And, BTW, I agree that the yield should always be in parentheses, but I guess it's too late to change that before Py4.) Stefan

On Sat, Sep 10, 2011 at 9:09 AM, Stefan Behnel <stefan_ml@behnel.de> wrote:
(And, BTW, I agree that the yield should always be in parentheses, but I guess it's too late to change that before Py4.)
You can make that a personal style today. And you could lobby for inclusion in PEP 8 (though personally I don't care either way). -- --Guido van Rossum (python.org/~guido)

On Sun, Sep 11, 2011 at 2:39 AM, Guido van Rossum <guido@python.org> wrote:
As the examples in the PEP suggest, the "no parens" usage was for simple evolutions from the pre-existing yield statement syntax: yield None => x = yield yield 42 => x = yield 42 yield y => x = yield y For simple cases like that, the parens would be redundant visual clutter (similar to the ill-advised practice of including redundant parens in if statements: "if (expr):"). Beyond those simple cases, I don't think there needs to be a yield specific recommendation - the general guidelines to use parentheses and named subexpressions to improve readability should cover it. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Thu, Sep 8, 2011 at 11:04 PM, H Krishnan <hetchkay@gmail.com> wrote:
Others have pointed out the parsing problems this would create. I'll point out that Python is not Scheme. I'm a fan of both languages, but they are not the same. Scheme has a history of valuing power, and adding it by removing restrictions. The example above - of allowing people to redefine what are primitives in other languages - fits that model perfectly. Python, on the other hand, has a history of valuing readability. With very few exceptions, changes to Python make some use case more readable, without adding a way to write really unreadable code. The change to have non-reserved keywords clashes badly with that model. <mike

H Krishnan writes:
In my 10+ years in scheme, I have never used 'define' as a symbol,
Of course you have used 'define' as a symbol. The rules of expression evaluation in Scheme say "evaluate the first element of a list, and apply the result to the rest of the list as arguments." When 'define' is the first element of a list, it is evaluated as a symbol, ie, the content of the value cell of the symbol 'define' is retrieved. Conventionally, that cell contains a function that sets the value of the second argument to the value of the third argument. You can't really get away with saying, "I haven't used it as a variable", either, since taking the value of a symbol is using it as a variable. So the design of Scheme (and Lisps in general) is very elegant, because everything is determined by the arrangement of parentheses. There is no need for reserving keywords. However, not all languages are Lisps. Vive la difference![1] Except that as somebody pointed out, there is a need. It turns out that users want keywords in the form of "constants that evaluate to themselves". So in the end you're at the same place, just a different balance. (I know that Scheme does not have them, although they can be created using define -- that's Schemingly correct, of course. But other languages have made a deliberate choice to introduce them, cf. http://stackoverflow.com/questions/1527548/why-does-clojure-have-keywords-in....)
They can't. Think editors written in Lisp. Footnotes: [1] With apologies to the Francophones present for my spelling.

On Sat, Sep 10, 2011 at 8:39 AM, Stephen J. Turnbull <stephen@xemacs.org>wrote:
I didn't realize that my proposal was not backward compatible. As some of you pointed out, currently, "return (val)" and "yield (val)" are legal python with 'return' and 'yield' used as keywords. So, I'll withdraw my proposal. I did want to reply to a few specific comments (e.g. 'python parser is simple') but I don't subscribe to the mailing list and didn't want to break the threading in the list. Thanks, Krishnan

H Krishnan <hetchkay@gmail.com> writes:
While some of the usage may be confusing to the user, that is not for the language to dictate but for the user to choose.
This statement makes the entirely unjustified assumption that the code will be read by exactly one “user”. Python is a language designed for writing code that isn't limited to just one reader. So no, every individual author of code doesn't get to choose what is readable for others; the Python community as a whole has a large say in that. -- \ “There are no chaplains in foxholes.” —Sergeant Justin | `\ Griffith, 2011-07-27 | _o__) | Ben Finney

Devin Jeanpierre wrote:
The "as" keyword used to be a pseudokeyword that functioned this way. Apparently the experiment didn't go well,
I think that was only done because the __future__ mechanism hadn't been invented then. As far as I know, it was always intended to become a full keyword at some point. -- Greg

Greg Ewing writes:
That may be true, but the PEP says "this word 'as' is not intended to become a keyword." For my point it doesn't matter exactly what the intention was; what matters is that people pay attention to the cost of reserving keywords globally, but also accept the need for a few keywords.
participants (23)
-
Antoine Pitrou
-
Barry Warsaw
-
Ben Finney
-
Bruce Leban
-
Chris Rebert
-
Devin Jeanpierre
-
Ethan Furman
-
Georg Brandl
-
Greg Ewing
-
Guido van Rossum
-
H Krishnan
-
Jacob Holm
-
Jakob Bowyer
-
Matt Joiner
-
Mike Meyer
-
Nick Coghlan
-
Paul Moore
-
ron3200
-
Spectral One
-
Stefan Behnel
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Terry Reedy