Hello, I have yet another idea regarding the the clashes between new keywords and already used names. How about introducing two new keywords *wink* that would serve as lexical keyword/nonkeyword declarations, similarly to nonlocal and global declarations? def f(): nonkeyword if if = 2 # we use 'if' as an identifier def g(): keyword if if x > 0: pass # now 'if' again introduces a conditional statement This allows to have a name as both identifier and keyword in a single module, and since it's lexical, it could be in principle syntax-highlighted correctly. When a new keyword is added to the list of standard keywords like 'given' or 'where', a module that uses the name as identifier could be easily fixed by a global declaration 'nonkeyword given'. Maybe even exception messages pointing to this could be added. If 'nonkeyword keyword' is allowed, we can also fix code using the name 'keyword' as an identifier, but doing so in the global scope couldn't be undone. On the other hand, new language features depending on new keywords could be made provisionary by not adding the keywords to the standard list, so people who would like to use them would need to opt in by e.g. 'keyword given'. Surely, this provisional mechanism isn't robust at all since new features may just extend the usage of current keywords. Declaring a keyword that has no meaning in the language would result in an exception: keyword foo # SyntaxError: undefined keyword 'foo' It should be possible to use a keyword as a parameter name without need to declare it in the surrounding scope, the local declaration would suffice: # nonkeyword if # not needed def f(if=3): # ok nonkeyword if Other option is to interpret parameters always as nonkeywords or to raise a special syntax error when a keyword occurs at a place of a formal parameter (similarly to 'def f(x): nonlocal x'). Clearly, even if this proposal diminished the cost of adding new keywords, the cost would still be high. Best regards, Adam Bartoš
On 5/16/2018 1:24 PM, Adam Bartoš wrote:
Hello,
I have yet another idea regarding the the clashes between new keywords and already used names. How about introducing two new keywords *wink* that would serve as lexical keyword/nonkeyword declarations, similarly to nonlocal and global declarations?
def f(): nonkeyword if if = 2 # we use 'if' as an identifier def g(): keyword if if x > 0: pass # now 'if' again introduces a conditional statement
These are not at all similar to 'global' and 'nonlocal'. These would make Python into a syntactically context-dependent language, rather than a restricted (ll(1)) context-free language. I am pretty sure that the current parser generator could not handle this. 'Global' and 'nonlocal' have NO effect on what is syntactically legal and therefore no effect on syntax parsing. They only affect the meaning (semantics) of other statements within the same function. The compiler handles this by making two passes over a function body. -- Terry Jan Reedy
If `def(if=3)...` works implicitly, then why not make `if = 3`, `x.if
= 3`, `import
if`, `def if` and `class if` implicit too?
Another issue is what happens here:
keyword if
import if
f(if=3)
f.if = 3
The keyword will be a valid name in old code, so you need to be able to
reference it as a name in code that uses it as a keyword.
-- Carl Smith
carl.input@gmail.com
On 16 May 2018 at 18:24, Adam Bartoš
Hello,
I have yet another idea regarding the the clashes between new keywords and already used names. How about introducing two new keywords *wink* that would serve as lexical keyword/nonkeyword declarations, similarly to nonlocal and global declarations?
def f(): nonkeyword if if = 2 # we use 'if' as an identifier def g(): keyword if if x > 0: pass # now 'if' again introduces a conditional statement
This allows to have a name as both identifier and keyword in a single module, and since it's lexical, it could be in principle syntax-highlighted correctly.
When a new keyword is added to the list of standard keywords like 'given' or 'where', a module that uses the name as identifier could be easily fixed by a global declaration 'nonkeyword given'. Maybe even exception messages pointing to this could be added. If 'nonkeyword keyword' is allowed, we can also fix code using the name 'keyword' as an identifier, but doing so in the global scope couldn't be undone.
On the other hand, new language features depending on new keywords could be made provisionary by not adding the keywords to the standard list, so people who would like to use them would need to opt in by e.g. 'keyword given'. Surely, this provisional mechanism isn't robust at all since new features may just extend the usage of current keywords.
Declaring a keyword that has no meaning in the language would result in an exception:
keyword foo # SyntaxError: undefined keyword 'foo'
It should be possible to use a keyword as a parameter name without need to declare it in the surrounding scope, the local declaration would suffice:
# nonkeyword if # not needed def f(if=3): # ok nonkeyword if
Other option is to interpret parameters always as nonkeywords or to raise a special syntax error when a keyword occurs at a place of a formal parameter (similarly to 'def f(x): nonlocal x').
Clearly, even if this proposal diminished the cost of adding new keywords, the cost would still be high.
Best regards, Adam Bartoš
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
My proposal assumes we want to be able to reference the name as defined in
external libraries, but never have it be a name and a keyword in the same
namespace. Your proposal (and the others I've seen) seem to be deliberately
aiming to allow that.
Do you want to have keywords that are names in the same namespace because
that would be nice in itself, or are you only tolerating that to solve the
original problem?
If being free to do `\if if not \not else \else or \or` is something people
want for its own upsides, my proposal is useless, but I thought we only
wanted a way to introduce keywords that are already names.
-- Carl Smith
carl.input@gmail.com
On 16 May 2018 at 20:03, Carl Smith
If `def(if=3)...` works implicitly, then why not make `if = 3`, `x.if = 3`, `import if`, `def if` and `class if` implicit too?
Another issue is what happens here:
keyword if import if f(if=3) f.if = 3
The keyword will be a valid name in old code, so you need to be able to reference it as a name in code that uses it as a keyword.
-- Carl Smith carl.input@gmail.com
On 16 May 2018 at 18:24, Adam Bartoš
wrote: Hello,
I have yet another idea regarding the the clashes between new keywords and already used names. How about introducing two new keywords *wink* that would serve as lexical keyword/nonkeyword declarations, similarly to nonlocal and global declarations?
def f(): nonkeyword if if = 2 # we use 'if' as an identifier def g(): keyword if if x > 0: pass # now 'if' again introduces a conditional statement
This allows to have a name as both identifier and keyword in a single module, and since it's lexical, it could be in principle syntax-highlighted correctly.
When a new keyword is added to the list of standard keywords like 'given' or 'where', a module that uses the name as identifier could be easily fixed by a global declaration 'nonkeyword given'. Maybe even exception messages pointing to this could be added. If 'nonkeyword keyword' is allowed, we can also fix code using the name 'keyword' as an identifier, but doing so in the global scope couldn't be undone.
On the other hand, new language features depending on new keywords could be made provisionary by not adding the keywords to the standard list, so people who would like to use them would need to opt in by e.g. 'keyword given'. Surely, this provisional mechanism isn't robust at all since new features may just extend the usage of current keywords.
Declaring a keyword that has no meaning in the language would result in an exception:
keyword foo # SyntaxError: undefined keyword 'foo'
It should be possible to use a keyword as a parameter name without need to declare it in the surrounding scope, the local declaration would suffice:
# nonkeyword if # not needed def f(if=3): # ok nonkeyword if
Other option is to interpret parameters always as nonkeywords or to raise a special syntax error when a keyword occurs at a place of a formal parameter (similarly to 'def f(x): nonlocal x').
Clearly, even if this proposal diminished the cost of adding new keywords, the cost would still be high.
Best regards, Adam Bartoš
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
On Wed, May 16, 2018 at 07:24:19PM +0200, Adam Bartoš wrote:
Hello,
I have yet another idea regarding the the clashes between new keywords and already used names. How about introducing two new keywords *wink* that would serve as lexical keyword/nonkeyword declarations, similarly to nonlocal and global declarations?
def f(): nonkeyword if if = 2 # we use 'if' as an identifier def g(): keyword if if x > 0: pass # now 'if' again introduces a conditional statement
This is absolutely no help at all for the common case that we have an identifier that is a keyword and want to use it as a keyword in the same block. For example, we can currently write: try: value = data.except_ except: value = data.missing() say. We're using "except_" because the data comes from some external interface where it uses "except", but we can't use that because its a keyword. I also challenge to think about how you will document the complicated rules for when you can and can't use keywords as names, especially think about explaining them to beginners: def spam(None=42): print(None) # What will this print? x = None # Fine, but what does it do? None = 999 # Is this an error or not? Remember the KISS principle. -- Steve
participants (4)
-
Adam Bartoš
-
Carl Smith
-
Steven D'Aprano
-
Terry Reedy