On Fri, Jan 18, 2013 at 9:06 AM, Haoyi Li <haoyi.sg@gmail.com> wrote:
Compiler-enforced immutability is one of those really hard problems which, if you manage to do flexibly and correctly, would be an academically publishable result, not something you hack into the interpreter over a weekend.

If you go the dumb-and-easy route, you end up with a simple "sub this variable with constant" thing, which isn't very useful (what about calculated constants?)

If you go the slightly-less-dumb route, you end up with some mini-language to work with these `const` values, which has some operations but not the full power of python. This basically describes C Macros, which I don't think you'd want to include in python!

If you go the "full python" route, you basically branch into two possibilities.

- enforcement of `const` as part of the main program. If you do it hackily, you end up with C++'s `const` or Java's `final` declaration. Neither of these really make the object (and all of its contents!) immutable. If you want to do it properly, this would involve some sort of effect-tracking-system. This is really hard.

- multi-stage computations, so the program is partially-evaluated at "compile" time and the `const` sections computed. This is also really hard. Furthermore, if you want to be able to use bits of the standard library in the early stages (you probably do, e.g. for things like min, max, len, etc.) either you'd need to manually start annotating huge chunks of the standard library to be available at "compile" time (a huge undertaking) or you'll need an effect-tracking-system to do it for you.


In any case, either you get a crappy implementation that nobody wants (C Macros) something that doesn't really give the guarantees you'd hope for (java final/c++ const) or you would have a publishable result w.r.t. either effect-tracking (!) or multi-stage computations (!!!).

Even though it is very easy to describe the idea (it just stops it from changing, duh!) and how it would work in a few trivial cases, doing it properly will likely require some substantial theoretical breakthroughs before it can actually happen.



On Thu, Jan 17, 2013 at 10:31 PM, Chris Angelico <rosuav@gmail.com> wrote:
On Fri, Jan 18, 2013 at 3:52 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> 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?

That should be disallowed. In the declaration of a constant, you have
to use only what can be handled by the constants evaluator. As a rule
of thumb, it'd make sense to be able to use const with anything that
could safely be evaluated by ast.literal_eval.

As to the issues of rebinding, I'd just state that all uses of a
particular named constant evaluate to the same object, just as would
happen if you used any other form of name binding.

I don't have the post to hand, but wasn't there a project being
discussed recently that would do a lot of that work automatically?

ChrisA
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
http://mail.python.org/mailman/listinfo/python-ideas


_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
http://mail.python.org/mailman/listinfo/python-ideas


As has already been pointed out, syntax to allow compile-time optimisations doesn't really make much sense in python, especially considering the optimisations Pypy already carries out.  Some sort of "finalise" option may be somewhat useful (although I can't say I've ever needed it).  To avoid adding a new keyword it could be implementer as a function, e.g. finalise("varname") or finalise(varname="value").  In a class, this would actually be quite easy to implement by simply replacing the class dict with a custom dict designed to restrict writing to finalised names.  I haven't ever tried changing the globals dict type, but I imagine it would be possible, or at least possible to to provide a method to change it.  I haven't thought through all the implications of doing it this way, but I'd rather see something like this than a new "const" keyword.

David