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