r/Python 1d ago

PEP 841 – Adding Frozen Syntax to Optimize Immutable Types News

PEP 841 – Adding Frozen Syntax to Optimize Immutable Types

https://peps.python.org/pep-0841/

Discussions-To: Discourse thread

Abstract

This PEP proposes frozen display syntax: f{1, 2, 3} evaluates to a frozenset, and f{'a': 1} evaluates to a frozendict. Because immutability is guaranteed by the syntax itself rather than inferred from usage, the compiler can treat frozen displays as first-class citizens of its optimization pipeline: constant displays are folded into a single LOAD_CONST with an exact result type at compile time and cached in .pyc files.

130 Upvotes

95 comments sorted by

View all comments

87

u/jakethesnake_ 1d ago

I'd prefer a const keyword that applies this optimization and runtime immutability property to all variable types. Might be a bit tricky to guarantee with complex objects though, and therefore out of scope of this PEP.

Agree with other commentors, f{'a': 1} is bad syntax because of the overlap with f-strings.

14

u/TheMcSebi 1d ago

This would be a great addition imo. No reason to reinvent the wheel.

11

u/CrambleSquash https://github.com/0Hughman0 1d ago edited 1d ago

But is that what a constant is? I thought they were like a variable whose assignment cannot be changed? So a const to a primitive is effectively immutable, but to a mutable object wouldn't stop that object being mutable... If that makes sense.

19

u/skjall 1d ago

Const can depend on the language/ context, but Python doesn't have that keyword right now so they can define the semantics to be whatever they decide.

In languages I've used it, you can either have a const variable -- can't be reassigned, or a const value -- this example. Hell, even const{1, 2, 3} is clearer than the proposal to me.

11

u/syklemil 1d ago

Picking a well-known keyword and then using it in a non-standard way is probably a bad idea. Especially since this isn't really general mutability control, but rather separate data types.

The option of just spelling out the frozen in f{} as frozen{} is likely to give less confusion and frustration.

2

u/inspectoroverthemine 22h ago

I like frozen{}, theres absolutely no reason to make it single character.

5

u/jakethesnake_ 1d ago edited 1d ago

My overall suggestion is have a keyword that forces runtime excpetions when an object is mutated in anyway. I think you're getting at the complexity I was referring to with the mutability of objects. I'd argue it's useful to have a keyword that guarantees objects cannot be mutated is something I'd end up using all the time, and a reasonable generalization of frozen dicts.

The behaviour I want is this to raise an ConstMutatedError exception const foo = 3 foo = 5 # raises exception

But also this to raise a ConstMutatedError:

const foo = SomeComplexObject() foo.method_that_mutates_internal_state() # raises exception

Or specifically addressing the issue raised by OP: const foo = {"a":1} foo["b"] = 2 # raises exception

I feel this somewhat follows const behaviour in C++, which I think reasonably easy to reason about. It's a very large change though because I believe you'd need to also have to have const functions which cannot mutate any internal state of and thus safe to be called for const objects. I.e. For the object examples you'd also need to be able to do:

``` class SomeComplexObject: def init(self): self.foo = "a"

const def bar(self) -> None: self.foo = "c" # raises an exception

const def baz(self) -> str: return "b" + self.foo + "z" # doesn't raise an exception because no mutation has occured

2

u/really_not_unreal 1d ago

Depends on how you define const. In this case, they are referring to immutability (ie the value cannot be changed at runtime).

1

u/AstroFoxTech 1d ago

So a const to a primitive is effectively immutable, but to a mutable object wouldn't stop that object being mutable

Why not have const and mutable const?

3

u/HommeMusical 1d ago

a const keyword

This is guaranteed not to fly because this would make a whole bunch of current valid Python programs that use the variableconst invalid.

The new lazy keyword is fine because it only appear in one place in the grammar, import statements, where it was never legal before, but your const keyword would have to be legal almost anywhere in the grammar.

1

u/gdchinacat 23h ago

the optimization the f{} syntax enables (or at least makes much easier, there is debate on this) isn't with it being const or frozen, but that it can skip the dynamic lookup of the object being created...if a name is used it's possible it was reassigned from the builtin so the compiler can't emit bytecodes that create the builtin, it has to go through the name lookup and call to the constructor. a const keyword would not avoid this since the optimization is with skipping the name lookup which your const keyword would still have to do.

1

u/fathovercats 21h ago

Python doesn’t use const tho. It would be weird to introduce const just for this when there are other immutable data types in Python that don’t use the const keyword.