Should Python have user-defined constants?

Hey guys I am thinking of perhaps writing a PEP to introduce user-defined constants to Python. Something along the lines of Swift’s “let” syntax (e.g. “let pi = 3.14”). Do you guys think it would be a good idea? Why or why not? Do you think there’s a better way to do it? I’d like to know what others think about this idea before making any formal submission (I’ve already posted this same question on python-list, but I just wanted to gauge opinion here too).

Javascript (ES6) has 'let' and 'const' for mutable and constant variables, respectively. When programming in JS, I find myself aggressively aiming for as little 'let' and as much 'const' as reasonably possible, since reasoning about constants is much easier than about variables. In this context, 'const' is used as a marker, a runtime checker, and, with proper tooling (IDE or linter), a coding-time reminder to differentiate between these two fundamental behaviours. I'm not +1 on introducing this idea to Python yet, but not -1 either - this deserves some discussion, if this has not been discussed already. Cheers, S. On Tue, Nov 21, 2017 at 9:13 AM, Steven D'Aprano <steve@pearwood.info> wrote:
-- Stefane Fermigier - http://fermigier.com/ - http://twitter.com/sfermigier - http://linkedin.com/in/sfermigier Founder & CEO, Abilian - Enterprise Social Software - http://www.abilian.com/ Chairman, Free&OSS Group / Systematic Cluster - http://www.gt-logiciel-libre.org/ Co-Chairman, National Council for Free & Open Source Software (CNLL) - http://cnll.fr/ Founder & Organiser, PyData Paris - http://pydata.fr/ --- “You never change things by fighting the existing reality. To change something, build a new model that makes the existing model obsolete.” — R. Buckminster Fuller

This could also be useful if one eventually wanted to implement constant optimizations in the interpreter as it would be possible to detect constants when they are declared without any code analysis. This would be "constant" as in Java constants right? Referential constants, so that if an object were mutable you would still be able to change its internal state. -- Bernardo Sulzbach http://www.mafagafogigante.org/ mafagafogigante@gmail.com

-1. I don't see how this would improve any programs I've written or seen. Tools like mypy or linters might benefit from a feature to track constants and ensure they don't get changed, but I don't think it's needed as a language feature. Seriously, has anyone ever written "math.pi = 5" and been surprised that their code broke? Or even modified an application constant like BUFFER_LIMIT? Do you have any evidence that this would avoid bugs in real-world code? Paul PS Please fix your font - your posts are coming through with a huge font size for some reason, which makes them extremely difficult to read. On 21 November 2017 at 06:33, Saeed Baig <saeedbaig616@icloud.com> wrote:

On 21 November 2017 at 10:47, Paul Moore <p.f.moore@gmail.com> wrote:
It is actually likely that something like this will appear in ``typing``: from typing import Final, List x: Final = 42 x = 1 # Fails type check lst: Final[List[int]] = [] lst.append(5) # OK lst = [1, 2, 3] # Fails type check -- Ivan

Note that no other feature in typing is about the reference - everything is about the objects themselves. Final makes less sense as a general type. We can't enforce A[T]().foo() not to reassign a Final T. Elazar בתאריך יום ג׳, 21 בנוב׳ 2017, 12:42, מאת Ivan Levkivskyi < levkivskyi@gmail.com>:

That's one way to do it with no changes to the language, though syntaxically I find it lacking a bit of elegance (maybe a matter of getting accustomed with it?). Also, I'm not sure "Final" really conveys what it means (at first glance, I thought it was about immutability, not constantness). Maybe "Const" would be better in this context ? (Or maybe you've discussed this question already and come to the conclusion that "Final" is better for some reason?) S. On Tue, Nov 21, 2017 at 11:41 AM, Ivan Levkivskyi <levkivskyi@gmail.com> wrote:
-- Stefane Fermigier - http://fermigier.com/ - http://twitter.com/sfermigier - http://linkedin.com/in/sfermigier Founder & CEO, Abilian - Enterprise Social Software - http://www.abilian.com/ Chairman, Free&OSS Group / Systematic Cluster - http://www.gt-logiciel-libre.org/ Co-Chairman, National Council for Free & Open Source Software (CNLL) - http://cnll.fr/ Founder & Organiser, PyData Paris - http://pydata.fr/ --- “You never change things by fighting the existing reality. To change something, build a new model that makes the existing model obsolete.” — R. Buckminster Fuller

On 21 November 2017 at 12:12, Stéfane Fermigier <sf@fermigier.com> wrote:
It is not set in stone, but it looks like most people like Final (although the initial proposal was Const, see https://github.com/python/mypy/issues/1214) -- Ivan

Ivan, you mean this thread "Can't index named tuple by defined constant" <https://github.com/python/mypy/issues/3078>? With kind regards, -gdg

2017-11-21 7:33 GMT+01:00 Saeed Baig <saeedbaig616@icloud.com>:
If you want to work on a PEP, you will have to write a strong rationale for it :-)
Python has different kinds of namespaces: module globals, class attributes, function local variables, etc. The https://github.com/fijal/quill programming language looks like Python but makes module globals *mapping* "immutable": setattr(module, 'var', new_value). Only the mapping is immutable, a value can be mutable. I guess that the motivation here is to help the optimizer to emit more efficient code. See also previous attempts: "PEP 416 -- Add a frozendict builtin type" https://www.python.org/dev/peps/pep-0416/ => my motivation was to develop a sandbox for Python "PEP 351 -- The freeze protocol" https://www.python.org/dev/peps/pep-0351/ => I guess that the main motivation was to previous programming mistakes, misuse of an API The question is if you only want to have a technical solution to prevent modification of module globals, or if you would like to advertize that a variable is constant and use it somehow. Victor

ISTM that using the already widely used convention of ALL_CAPS for constants is plenty for linters to warn about rebinding names. Python believes "we're all adults here" after all. So even though it's worth *warning* users if BUFFER_LIMIT gets redefined, there can be reasons between consenting adults for doing so when you know what you are doing. It feels similar to the fact that I *can* call: instance._Klass__secret() But the spelling suggests a strong recommendation to use a more public API. Exact same story with redefining an implied constant. On Tue, Nov 21, 2017 at 7:47 AM, Victor Stinner <victor.stinner@gmail.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.

Javascript (ES6) has 'let' and 'const' for mutable and constant variables, respectively. When programming in JS, I find myself aggressively aiming for as little 'let' and as much 'const' as reasonably possible, since reasoning about constants is much easier than about variables. In this context, 'const' is used as a marker, a runtime checker, and, with proper tooling (IDE or linter), a coding-time reminder to differentiate between these two fundamental behaviours. I'm not +1 on introducing this idea to Python yet, but not -1 either - this deserves some discussion, if this has not been discussed already. Cheers, S. On Tue, Nov 21, 2017 at 9:13 AM, Steven D'Aprano <steve@pearwood.info> wrote:
-- Stefane Fermigier - http://fermigier.com/ - http://twitter.com/sfermigier - http://linkedin.com/in/sfermigier Founder & CEO, Abilian - Enterprise Social Software - http://www.abilian.com/ Chairman, Free&OSS Group / Systematic Cluster - http://www.gt-logiciel-libre.org/ Co-Chairman, National Council for Free & Open Source Software (CNLL) - http://cnll.fr/ Founder & Organiser, PyData Paris - http://pydata.fr/ --- “You never change things by fighting the existing reality. To change something, build a new model that makes the existing model obsolete.” — R. Buckminster Fuller

This could also be useful if one eventually wanted to implement constant optimizations in the interpreter as it would be possible to detect constants when they are declared without any code analysis. This would be "constant" as in Java constants right? Referential constants, so that if an object were mutable you would still be able to change its internal state. -- Bernardo Sulzbach http://www.mafagafogigante.org/ mafagafogigante@gmail.com

-1. I don't see how this would improve any programs I've written or seen. Tools like mypy or linters might benefit from a feature to track constants and ensure they don't get changed, but I don't think it's needed as a language feature. Seriously, has anyone ever written "math.pi = 5" and been surprised that their code broke? Or even modified an application constant like BUFFER_LIMIT? Do you have any evidence that this would avoid bugs in real-world code? Paul PS Please fix your font - your posts are coming through with a huge font size for some reason, which makes them extremely difficult to read. On 21 November 2017 at 06:33, Saeed Baig <saeedbaig616@icloud.com> wrote:

On 21 November 2017 at 10:47, Paul Moore <p.f.moore@gmail.com> wrote:
It is actually likely that something like this will appear in ``typing``: from typing import Final, List x: Final = 42 x = 1 # Fails type check lst: Final[List[int]] = [] lst.append(5) # OK lst = [1, 2, 3] # Fails type check -- Ivan

Note that no other feature in typing is about the reference - everything is about the objects themselves. Final makes less sense as a general type. We can't enforce A[T]().foo() not to reassign a Final T. Elazar בתאריך יום ג׳, 21 בנוב׳ 2017, 12:42, מאת Ivan Levkivskyi < levkivskyi@gmail.com>:

That's one way to do it with no changes to the language, though syntaxically I find it lacking a bit of elegance (maybe a matter of getting accustomed with it?). Also, I'm not sure "Final" really conveys what it means (at first glance, I thought it was about immutability, not constantness). Maybe "Const" would be better in this context ? (Or maybe you've discussed this question already and come to the conclusion that "Final" is better for some reason?) S. On Tue, Nov 21, 2017 at 11:41 AM, Ivan Levkivskyi <levkivskyi@gmail.com> wrote:
-- Stefane Fermigier - http://fermigier.com/ - http://twitter.com/sfermigier - http://linkedin.com/in/sfermigier Founder & CEO, Abilian - Enterprise Social Software - http://www.abilian.com/ Chairman, Free&OSS Group / Systematic Cluster - http://www.gt-logiciel-libre.org/ Co-Chairman, National Council for Free & Open Source Software (CNLL) - http://cnll.fr/ Founder & Organiser, PyData Paris - http://pydata.fr/ --- “You never change things by fighting the existing reality. To change something, build a new model that makes the existing model obsolete.” — R. Buckminster Fuller

On 21 November 2017 at 12:12, Stéfane Fermigier <sf@fermigier.com> wrote:
It is not set in stone, but it looks like most people like Final (although the initial proposal was Const, see https://github.com/python/mypy/issues/1214) -- Ivan

Ivan, you mean this thread "Can't index named tuple by defined constant" <https://github.com/python/mypy/issues/3078>? With kind regards, -gdg

2017-11-21 7:33 GMT+01:00 Saeed Baig <saeedbaig616@icloud.com>:
If you want to work on a PEP, you will have to write a strong rationale for it :-)
Python has different kinds of namespaces: module globals, class attributes, function local variables, etc. The https://github.com/fijal/quill programming language looks like Python but makes module globals *mapping* "immutable": setattr(module, 'var', new_value). Only the mapping is immutable, a value can be mutable. I guess that the motivation here is to help the optimizer to emit more efficient code. See also previous attempts: "PEP 416 -- Add a frozendict builtin type" https://www.python.org/dev/peps/pep-0416/ => my motivation was to develop a sandbox for Python "PEP 351 -- The freeze protocol" https://www.python.org/dev/peps/pep-0351/ => I guess that the main motivation was to previous programming mistakes, misuse of an API The question is if you only want to have a technical solution to prevent modification of module globals, or if you would like to advertize that a variable is constant and use it somehow. Victor

ISTM that using the already widely used convention of ALL_CAPS for constants is plenty for linters to warn about rebinding names. Python believes "we're all adults here" after all. So even though it's worth *warning* users if BUFFER_LIMIT gets redefined, there can be reasons between consenting adults for doing so when you know what you are doing. It feels similar to the fact that I *can* call: instance._Klass__secret() But the spelling suggests a strong recommendation to use a more public API. Exact same story with redefining an implied constant. On Tue, Nov 21, 2017 at 7:47 AM, Victor Stinner <victor.stinner@gmail.com> wrote:
-- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th.
participants (13)
-
Bernardo Sulzbach
-
David Mertz
-
INADA Naoki
-
Ivan Levkivskyi
-
Joseph Jevnik
-
Kirill Balunov
-
Paul Moore
-
Saeed Baig
-
Serhiy Storchaka
-
Steven D'Aprano
-
Stéfane Fermigier
-
Victor Stinner
-
אלעזר