Re: [Python-ideas] Should Python have user-defined constants?

Hi. Just to respond to some peoples’ points… Bernardo asked '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.’ Um, I’m not entirely sure what you mean, since I’ve never used Java. But if it means what I think it means, I would be INCLINED to say no. If, for example, I saw code like this: x = [9, 5, 7, 1] let y = x y[0] = 42 print(y) … I would expect that code to raise an error, not print “[42, 5, 7, 1]”, since you’re trying to modify the “constant” y in place, which… well, would kind of go against the idea of y being a constant, I thought (unless I’m misunderstanding what you meant by “object", since everything in Python’s an object). However, I might change my opinion if I heard a good reason why Java-like constants would be better. Serhiy asked, in relation to constants, “To do what? What problem do you need to solve?”. No problem in particular, to be honest. I just thought they’d be nice since they’d increase confidence that my variables-intended-to-be-constants wouldn’t get reassigned, and just to increase readability/explicitness to other programmers.

21.11.17 11:34, Saeed Baig пише:
For increasing readability/explicitness you can use a name convention (UPPER_CASE), comments and documentation. As for increasing confidence that your variables-intended-to-be-constants wouldn’t get reassigned, you can use read-only properties. This is a tricky to implement read-only properties for modules, but see PEP 562 which should help to do this. Please don't use GIGANTIC font in your messages. And please don't create a new thread when answer. And *please* don't include unrelated text in your messages.

On Tue, Nov 21, 2017 at 11:03 AM, Serhiy Storchaka <storchaka@gmail.com> wrote:
UPPER_CASE variable names are a reasonable convention for global constants. I wouldn't like to read something like: for i in range(0, 100): FOO = f(i) BAR = g(i, FOO) do_something_with(BAR) but rather: for i in range(0, 100): const foo = f(i) const bar = g(i, foo) do_something_with(bar) or: for i in range(0, 100): let foo = f(i) let bar = g(i, foo) do_something_with(bar) If we move on with this idea (which is a long shot of course), choosing between 'let' and 'const' is a matter of taste and being consistent with other languages. As for increasing confidence that your variables-intended-to-be-constants
+1. S.
-- 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 Tue, Nov 21, 2017 at 11:40:14AM +0100, Stéfane Fermigier wrote:
I wouldn't expect that to work. You are binding some value f(0) to the constant name "foo" on the first loop, then on the second loop you try to rebind a new value to the same name "foo". I would expect that to be an error. -- Steve

Are there any 3rd party tools that already implement this? By my understanding, type annotations started as 3rd party tools that became popular and so are now incorporated into the language proper. I could see a 'const' syntax making its way into the language that way, but not directly. Certainly this idea has been hashed out multiple times before.

On Tue, Nov 21, 2017 at 08:34:31PM +1100, Saeed Baig wrote:
That depends on what we mean by constant. If you mean that the *values* are immutable and cannot be changed, then Python already has constants. The object 99 (an int) is always equal to 99, you cannot change its value. Operations on it return a new object, not the same one modified. The same applies to strings and tuples. For example, consider the difference between a *mutable* object like a list, and an immutable one like a tuple: a = b = [1, 2] a += [999] print(b) # prints [1, 2, 999] Clearly the value [1, 2] is not "constant" in the sense of being immutable, unlike tuples: a = b = (1, 2) a += (999,) print(b) # prints (1, 2) So if that's what you mean by "constant", then most Python values (strings, ints, floats, bools, tuples, frozensets...) are already constants -- and the ones which aren't, we *want* to be mutable. But what Bernardo refers to, "referential constants", are more like constants in languages like C, Pascal, Java, etc. The value itself may or may not be mutable, or immutable, but the *name binding* is fixed. That is, once you have defined a constant, e.g. in Pascal you use a const declaration: const a = 1; in other languages you may use a "let": let a = 1 a = 2 # an error from this point on, the variable name "a" always refers to the same value. In this case, that value will be 1, which is an immutable object but it could be a mutable object like a list: let b = [] b.append(999) # modifies the object # but the name still refers to the same object b = [1, 2, 3] # an error The language we might choose here is to say that constants are "bind-once". That is, we can bind an object to the name once: let c = some(expression) but any subsequent attempts to re-bind or unbind the name should fail: c = something_else # fails del c # also fails That is, I think, what Bernardo means by referential constants, and that's what I mean when I talk about constants in Python. The question of mutability and immutability is orthogonal to the concept of being able to re-bind a name. They refer to two different concepts: - if the value is a fixed object, unable to be modified, we call the object "immutable"; otherwise the object is mutable; - if the *name* is fixed to the same object, unable to be changed to a different object, we might call the *name* a constant; otherwise the name is a variable. Because they are independent concepts, a language might support any combination of: - constant name with immutable value; - constant name with mutable value; - variable name with immutable value; - variable name with mutable value. Constants in Pascal and C are both constant *names* and immutable *values*. The closest they have to constant names with mutable values would be if you set a constant to a pointer (if the compiler supports that). In Pascal, if it were allowed, that might look something like: const a = ^x; {a is set to the address of x} In C, it might be something similar to: const int *a = &x; (I think). In either case, if the compiler supported this, you wouldn't be able to modify the pointer a itself, but you could modify the area of memory that a points to (that is, x). I don't think there is anything interesting about "constants" which are nothing more than immutable objects. We already have that. The interesting (but is it useful?) concept is constant identifiers which cannot be re-bound or re-assigned once they are set the first time. P.S. Please do not reply to digests without trimming all the excessive quoted emails that are not relevant to the discussion. -- Steve

On Tue, Nov 21, 2017 at 3:31 AM, Steven D'Aprano <steve@pearwood.info> wrote: <snip>
This would actually be a substantial shift in what Python is about -- currently the concept of type is all about values, not names -- there are various rules about scope, and they can be adjusted with global and nonlocal, but it's only about scope -- a name is still a name, and can be bound to any type of object, etc. static languages, on the other hand often (always) assign type to the name itself -- so adding constants and the like makes sense. But changing the property of a name (this name can not be rebound) is a big shift in what names are about in Python -- and I don't think a good one. And what's the use-case, really? beyond the use case for all sorts of static typing... in case it's not obvious: -1 -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

On Tue, Nov 21, 2017 at 6:34 PM, Chris Barker <chris.barker@noaa.gov> wrote:
And what's the use-case, really? beyond the use case for all sorts of static typing...
Javascript is dynamically typed, and has 'const' variable declaration which were added in ES6. Static typing is not the only use case. Discouraging reuse of variables of favouring functional style over imperative is a strong use case for 'const' in JS. But I agree that the scoping rules are different in Javascript, and this argument is much less convincing in Python. S. -- 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

בתאריך יום ג׳, 21 בנוב׳ 2017, 19:36, מאת Chris Barker < chris.barker@noaa.gov>:
...
And what's the use-case, really? beyond the use case for all sorts of
static typing...
I don't understand the question. The use case was explained before - people want to have better ways to reason about their programs. Statically. Why dismiss it as a non-usecase? It's helpful for both tools and humans. It was mentioned that there are related conventions in Python. Good point. But they are not as strong as the "convention" that tuples and strings cannot change, and this is useful in reasoning about code - in understanding the program, essentially. When I read "final int x = 5;" in Java, I don't have to think about it anymore - it's 5. When I read "X = 5" in Python, it might be a constant, but it might also be a misnomer, or something that used to be a constant, or a class reassigned. I still have to watch whether it will be changed, intentionally or accidentally, by this or other module. It does not even communicate intention in an unambiguous way. In my opinion, the inability to control mutation in Python is the biggest readability issue of the language (thank god monkey-patching is discouraged). I see why the proposal can be rejected, but I don't understand the "you don't gain anything" responses. There are significant gains there. Elazar

On 21.11.2017 19:05, אלעזר wrote:
Then type annotations are for them. But please don't clutter the core language with this.
What about using real-world names instead of X? That could make the intentions crystal clear if you ask me. Cheers, Sven PS: it seems to me that this resembles the typing discussions here. Using non-sensical variable names to explain why type annotations are sorely needed.

On Tue, Nov 21, 2017 at 09:34:33AM -0800, Chris Barker wrote:
On Tue, Nov 21, 2017 at 3:31 AM, Steven D'Aprano <steve@pearwood.info> wrote:
I didn't say anything about types. My comments were about names and values (objects): - Mutability is a property of values (objects): some objects are mutable, and other objects are not. - Constantness is a property of names or other identifiers: some names can only be bound once ("constants"), other names can be bound and rebound at will ("variables"). Types are literally irrelevant to this, except in the sense that in many languages, including Python, the distinction between mutable and immutable is usually controlled by the type of object. But that's not fundamental to the concept: we could, if we wanted, decouple the two.
Sure, that's the way Python is now. But that's not fundamental to the concepts. Other languages allow other distinctions between names, not just scope: for instance, names can be static (they keep their value between function invocations), they can be read-only some languages allow you to specify whether they are kept in RAM or in a register.
static languages, on the other hand often (always) assign type to the name itself -- so adding constants and the like makes sense.
Constantness is orthogonal to the concept of static typing of variables.
It is a big shift, although not that big since we already have read-only properties. This would "merely" (hah!) extend that concept to other namespaces apart from instances. I'm undecided as to whether the benefit would justify the cost. -- Steve

On Wed, Nov 22, 2017 at 11:27 AM, Steven D'Aprano <steve@pearwood.info> wrote:
There's a good reason for that - the type of an object determines what operations make sense (you can add two numbers together, but you can't add two open sockets), and mutability impacts the validity of operations. Can you give an example of where it would make sense to decouple mutability from object type? Everything I can think of in Python works by creating a separate type (eg frozenset for set), thus allowing new operations (eg hashing). The only way I can think of to decouple them would be to have a single type with all the operations available, and then raise exceptions where some operations aren't valid: class Foo: def __hash__(self): if self.mutable: raise TypeError return some_hash def __iadd__(self, other): if not self.mutable: return self + other # perform an in-place addition return self def __setitem__(self, key): if not self.mutable: raise TypeError # alter self This makes it hard to reason about the code - particularly in the case of __iadd__, where it'll sometimes behave like a list's += and sometimes like an int's. Where would you, preferably with some sort of real-world example, actually make use of this sort of thing? ChrisA

On Wed, Nov 22, 2017 at 11:47:28AM +1100, Chris Angelico wrote:
On Wed, Nov 22, 2017 at 11:27 AM, Steven D'Aprano <steve@pearwood.info> wrote:
I didn't say we should, or that I would, only that we could if we wanted to. But for the sake of the hypothetical argument, being able to freeze an object may be useful, as opposed to copying it into a new, frozen object. To make the difference clear: a = b = something() a = freeze(a) b would still be mutable; but: a = b = something() freeze(a) now b is immutable, since it is the same frozen object as a. But possibly even more interesting might be to have the concept of code permissions, so that you can grant software components either read/write or read-only permission on values you pass to them. (Immutable views could possibly do the same job.) At the moment every time you pass a list to a library function, you risk it modifying the list without your knowledge. In general that's more of a theoretical risk than an actual risk (we generally know which library functions mutate their arguments), but there may be circumstances where you'd like to pass a mutable object to (let's say) a callback function, or a thread, and trust that it can't modify the object at all. At the moment, the only obvious alternative is to make an arbitrarily expensive deepcopy of the object each time you pass it. Or just hope that the called function doesn't mess with your data. -- Steve

Steven D'Aprano wrote:
In C, it might be something similar to:
const int *a = &x;
Not quite, that makes whatever a points to constant, not a itself. But you can do this: typedef int *ip; int x, y; const ip p = &x; void f(void) { *p = 42; /* ok */ p = &y; /* not ok */ } Compiling this gives: % gcc -c constptr.c constptr.c: In function ‘f’: constptr.c:7: error: assignment of read-only variable ‘p’ BTW, this shows that gcc thinks of const-declared things as "read-only variables" rather than constants. Which is a bit of a silly term when you think about it! -- Greg

21.11.17 11:34, Saeed Baig пише:
For increasing readability/explicitness you can use a name convention (UPPER_CASE), comments and documentation. As for increasing confidence that your variables-intended-to-be-constants wouldn’t get reassigned, you can use read-only properties. This is a tricky to implement read-only properties for modules, but see PEP 562 which should help to do this. Please don't use GIGANTIC font in your messages. And please don't create a new thread when answer. And *please* don't include unrelated text in your messages.

On Tue, Nov 21, 2017 at 11:03 AM, Serhiy Storchaka <storchaka@gmail.com> wrote:
UPPER_CASE variable names are a reasonable convention for global constants. I wouldn't like to read something like: for i in range(0, 100): FOO = f(i) BAR = g(i, FOO) do_something_with(BAR) but rather: for i in range(0, 100): const foo = f(i) const bar = g(i, foo) do_something_with(bar) or: for i in range(0, 100): let foo = f(i) let bar = g(i, foo) do_something_with(bar) If we move on with this idea (which is a long shot of course), choosing between 'let' and 'const' is a matter of taste and being consistent with other languages. As for increasing confidence that your variables-intended-to-be-constants
+1. S.
-- 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 Tue, Nov 21, 2017 at 11:40:14AM +0100, Stéfane Fermigier wrote:
I wouldn't expect that to work. You are binding some value f(0) to the constant name "foo" on the first loop, then on the second loop you try to rebind a new value to the same name "foo". I would expect that to be an error. -- Steve

Are there any 3rd party tools that already implement this? By my understanding, type annotations started as 3rd party tools that became popular and so are now incorporated into the language proper. I could see a 'const' syntax making its way into the language that way, but not directly. Certainly this idea has been hashed out multiple times before.

On Tue, Nov 21, 2017 at 08:34:31PM +1100, Saeed Baig wrote:
That depends on what we mean by constant. If you mean that the *values* are immutable and cannot be changed, then Python already has constants. The object 99 (an int) is always equal to 99, you cannot change its value. Operations on it return a new object, not the same one modified. The same applies to strings and tuples. For example, consider the difference between a *mutable* object like a list, and an immutable one like a tuple: a = b = [1, 2] a += [999] print(b) # prints [1, 2, 999] Clearly the value [1, 2] is not "constant" in the sense of being immutable, unlike tuples: a = b = (1, 2) a += (999,) print(b) # prints (1, 2) So if that's what you mean by "constant", then most Python values (strings, ints, floats, bools, tuples, frozensets...) are already constants -- and the ones which aren't, we *want* to be mutable. But what Bernardo refers to, "referential constants", are more like constants in languages like C, Pascal, Java, etc. The value itself may or may not be mutable, or immutable, but the *name binding* is fixed. That is, once you have defined a constant, e.g. in Pascal you use a const declaration: const a = 1; in other languages you may use a "let": let a = 1 a = 2 # an error from this point on, the variable name "a" always refers to the same value. In this case, that value will be 1, which is an immutable object but it could be a mutable object like a list: let b = [] b.append(999) # modifies the object # but the name still refers to the same object b = [1, 2, 3] # an error The language we might choose here is to say that constants are "bind-once". That is, we can bind an object to the name once: let c = some(expression) but any subsequent attempts to re-bind or unbind the name should fail: c = something_else # fails del c # also fails That is, I think, what Bernardo means by referential constants, and that's what I mean when I talk about constants in Python. The question of mutability and immutability is orthogonal to the concept of being able to re-bind a name. They refer to two different concepts: - if the value is a fixed object, unable to be modified, we call the object "immutable"; otherwise the object is mutable; - if the *name* is fixed to the same object, unable to be changed to a different object, we might call the *name* a constant; otherwise the name is a variable. Because they are independent concepts, a language might support any combination of: - constant name with immutable value; - constant name with mutable value; - variable name with immutable value; - variable name with mutable value. Constants in Pascal and C are both constant *names* and immutable *values*. The closest they have to constant names with mutable values would be if you set a constant to a pointer (if the compiler supports that). In Pascal, if it were allowed, that might look something like: const a = ^x; {a is set to the address of x} In C, it might be something similar to: const int *a = &x; (I think). In either case, if the compiler supported this, you wouldn't be able to modify the pointer a itself, but you could modify the area of memory that a points to (that is, x). I don't think there is anything interesting about "constants" which are nothing more than immutable objects. We already have that. The interesting (but is it useful?) concept is constant identifiers which cannot be re-bound or re-assigned once they are set the first time. P.S. Please do not reply to digests without trimming all the excessive quoted emails that are not relevant to the discussion. -- Steve

On Tue, Nov 21, 2017 at 3:31 AM, Steven D'Aprano <steve@pearwood.info> wrote: <snip>
This would actually be a substantial shift in what Python is about -- currently the concept of type is all about values, not names -- there are various rules about scope, and they can be adjusted with global and nonlocal, but it's only about scope -- a name is still a name, and can be bound to any type of object, etc. static languages, on the other hand often (always) assign type to the name itself -- so adding constants and the like makes sense. But changing the property of a name (this name can not be rebound) is a big shift in what names are about in Python -- and I don't think a good one. And what's the use-case, really? beyond the use case for all sorts of static typing... in case it's not obvious: -1 -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

On Tue, Nov 21, 2017 at 6:34 PM, Chris Barker <chris.barker@noaa.gov> wrote:
And what's the use-case, really? beyond the use case for all sorts of static typing...
Javascript is dynamically typed, and has 'const' variable declaration which were added in ES6. Static typing is not the only use case. Discouraging reuse of variables of favouring functional style over imperative is a strong use case for 'const' in JS. But I agree that the scoping rules are different in Javascript, and this argument is much less convincing in Python. S. -- 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

בתאריך יום ג׳, 21 בנוב׳ 2017, 19:36, מאת Chris Barker < chris.barker@noaa.gov>:
...
And what's the use-case, really? beyond the use case for all sorts of
static typing...
I don't understand the question. The use case was explained before - people want to have better ways to reason about their programs. Statically. Why dismiss it as a non-usecase? It's helpful for both tools and humans. It was mentioned that there are related conventions in Python. Good point. But they are not as strong as the "convention" that tuples and strings cannot change, and this is useful in reasoning about code - in understanding the program, essentially. When I read "final int x = 5;" in Java, I don't have to think about it anymore - it's 5. When I read "X = 5" in Python, it might be a constant, but it might also be a misnomer, or something that used to be a constant, or a class reassigned. I still have to watch whether it will be changed, intentionally or accidentally, by this or other module. It does not even communicate intention in an unambiguous way. In my opinion, the inability to control mutation in Python is the biggest readability issue of the language (thank god monkey-patching is discouraged). I see why the proposal can be rejected, but I don't understand the "you don't gain anything" responses. There are significant gains there. Elazar

On 21.11.2017 19:05, אלעזר wrote:
Then type annotations are for them. But please don't clutter the core language with this.
What about using real-world names instead of X? That could make the intentions crystal clear if you ask me. Cheers, Sven PS: it seems to me that this resembles the typing discussions here. Using non-sensical variable names to explain why type annotations are sorely needed.

On Tue, Nov 21, 2017 at 09:34:33AM -0800, Chris Barker wrote:
On Tue, Nov 21, 2017 at 3:31 AM, Steven D'Aprano <steve@pearwood.info> wrote:
I didn't say anything about types. My comments were about names and values (objects): - Mutability is a property of values (objects): some objects are mutable, and other objects are not. - Constantness is a property of names or other identifiers: some names can only be bound once ("constants"), other names can be bound and rebound at will ("variables"). Types are literally irrelevant to this, except in the sense that in many languages, including Python, the distinction between mutable and immutable is usually controlled by the type of object. But that's not fundamental to the concept: we could, if we wanted, decouple the two.
Sure, that's the way Python is now. But that's not fundamental to the concepts. Other languages allow other distinctions between names, not just scope: for instance, names can be static (they keep their value between function invocations), they can be read-only some languages allow you to specify whether they are kept in RAM or in a register.
static languages, on the other hand often (always) assign type to the name itself -- so adding constants and the like makes sense.
Constantness is orthogonal to the concept of static typing of variables.
It is a big shift, although not that big since we already have read-only properties. This would "merely" (hah!) extend that concept to other namespaces apart from instances. I'm undecided as to whether the benefit would justify the cost. -- Steve

On Wed, Nov 22, 2017 at 11:27 AM, Steven D'Aprano <steve@pearwood.info> wrote:
There's a good reason for that - the type of an object determines what operations make sense (you can add two numbers together, but you can't add two open sockets), and mutability impacts the validity of operations. Can you give an example of where it would make sense to decouple mutability from object type? Everything I can think of in Python works by creating a separate type (eg frozenset for set), thus allowing new operations (eg hashing). The only way I can think of to decouple them would be to have a single type with all the operations available, and then raise exceptions where some operations aren't valid: class Foo: def __hash__(self): if self.mutable: raise TypeError return some_hash def __iadd__(self, other): if not self.mutable: return self + other # perform an in-place addition return self def __setitem__(self, key): if not self.mutable: raise TypeError # alter self This makes it hard to reason about the code - particularly in the case of __iadd__, where it'll sometimes behave like a list's += and sometimes like an int's. Where would you, preferably with some sort of real-world example, actually make use of this sort of thing? ChrisA

On Wed, Nov 22, 2017 at 11:47:28AM +1100, Chris Angelico wrote:
On Wed, Nov 22, 2017 at 11:27 AM, Steven D'Aprano <steve@pearwood.info> wrote:
I didn't say we should, or that I would, only that we could if we wanted to. But for the sake of the hypothetical argument, being able to freeze an object may be useful, as opposed to copying it into a new, frozen object. To make the difference clear: a = b = something() a = freeze(a) b would still be mutable; but: a = b = something() freeze(a) now b is immutable, since it is the same frozen object as a. But possibly even more interesting might be to have the concept of code permissions, so that you can grant software components either read/write or read-only permission on values you pass to them. (Immutable views could possibly do the same job.) At the moment every time you pass a list to a library function, you risk it modifying the list without your knowledge. In general that's more of a theoretical risk than an actual risk (we generally know which library functions mutate their arguments), but there may be circumstances where you'd like to pass a mutable object to (let's say) a callback function, or a thread, and trust that it can't modify the object at all. At the moment, the only obvious alternative is to make an arbitrarily expensive deepcopy of the object each time you pass it. Or just hope that the called function doesn't mess with your data. -- Steve

Steven D'Aprano wrote:
In C, it might be something similar to:
const int *a = &x;
Not quite, that makes whatever a points to constant, not a itself. But you can do this: typedef int *ip; int x, y; const ip p = &x; void f(void) { *p = 42; /* ok */ p = &y; /* not ok */ } Compiling this gives: % gcc -c constptr.c constptr.c: In function ‘f’: constptr.c:7: error: assignment of read-only variable ‘p’ BTW, this shows that gcc thinks of const-declared things as "read-only variables" rather than constants. Which is a bit of a silly term when you think about it! -- Greg
participants (11)
-
brent bejot
-
Chris Angelico
-
Chris Barker
-
Clint Hepner
-
Greg Ewing
-
Saeed Baig
-
Serhiy Storchaka
-
Steven D'Aprano
-
Stéfane Fermigier
-
Sven R. Kunze
-
אלעזר