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

Steven D'Aprano steve at pearwood.info
Tue Nov 21 06:31:01 EST 2017

On Tue, Nov 21, 2017 at 08:34:31PM +1100, Saeed Baig wrote:
> 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).

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]
# 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,)
# 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:

  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:

  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.


More information about the Python-ideas mailing list