[Python-ideas] 'const' and 'require' statements

Steven D'Aprano steve at pearwood.info
Fri Jan 18 05:52:09 CET 2013


On 18/01/13 12:52, Harding, James wrote:
> Hello,
>
> I am new here but am itching with an idea. Here are two separate ideas
>but they are related so they shall both be presented at the same time.
>
> The first idea is for a 'const' statement for declaring constant names.
>Its syntax would be:
>
>      'const' identifier '=' expression
>
> The expression would be restricted to result in an immutable object


What is the purpose of this restriction?

I would like to see the ability to prevent rebinding or unbinding of
names, with no restriction on the value. If that is useful (and I think
it is), then it is useful for mutable objects as well as immutable.



> such as 17, "green", or (1,2,3). The compiler would effectively replace
>any use of the identifier with this expression when seen.

Is that the driving use-case for your suggestion? Compile-time efficiency?
If so, then I suspect that you're on the wrong track. As I understand it,
the sort of optimizations that PyPy can perform at runtime are far more
valuable than this sort of constant substitution.

There are also complications that need to be carefully thought about.
For example, in Python today, you can be sure that this assertion will
always pass:


k = ("Some value", "Another value")  # for example
x = k
y = k
assert x is y  # this always passes, no matter the value of k


But if k is a const, it will fail, because the lines "x = k" and "y = k"
will be expanded at compile time:

x = ("Some value", "Another value")
y = ("Some value", "Another value")
assert x is y  # not guaranteed to pass


So Python would have to intern every const, not just do a compile-time
substitution. And that will have runtime consequences.


Another question: what happens if the constant expression can't be
evaluated until runtime?

x = random.random()
const k = x + 1

y = k - 1

What value should the compiler substitute for y?



> Constant names would be limited in scope. A constant defined in a function
>would only have a life to the end of the function, for instance.

I don't think that makes sense. Since you're talking about something known
to the compiler, it is meaningless to talk about the life of the constant
*at runtime*. Consider:


def f(n):
     const k = ("something", "or", "other")
     if n == 0:
         return k
     else:
         return k[n:]


This will compile to the byte-code equivalent of:

def f(n):
     if n == 0:
         return ("something", "or", "other")
     else:
         return ("something", "or", "other")[n:]


I recommend you run that function through dis.dis to see what it will
be compiled to. In the compiled code, there are two calls to the
LOAD_CONST byte-code. The literal ("something", "or", "other") needs
to be compiled into the byte-code, and so it will exist for as long
as the function exists, not just until the function exits.



> Now why should there be such a syntax if the existing language already
>has a mechanism for effectively declaring constants, which it does?

I dispute that Python has a mechanism for effectively declaring constants.
It has a *convention* for declaring constants, and hoping that neither
you, the developer, nor the caller, accidentally (or deliberately) rebind
that pseudo-constant.



-- 
Steven



More information about the Python-ideas mailing list