Live data from Hacker News

A “frozen” dictionary for Python

lwn.net

161–170 of 172 posts

Re: A “frozen” dictionary for Python

#161

Earlier quoted context omitted.

Not sure we're talking about the same thing. Inline TypedDicts are already in the process of being formalized, see https://peps.python.org/pep-0764/ , and have experimental support in e.g. Pyright. What I meant was that foo = {"a": 5} should be inferred as foo: TypedDict[{ "a": Literal[5] }] = {"a": 5}

Ah, I didn't know about PEP 795. I don't really know if I like it though. It looks like something someone invented because they don't want to write classes or specifically want to be able to access a data structure like a dict, for whatever reason. It basically provides data types, but also ensures that you have no easy way to reuse them, and it will miss cases where two data structures happen to have the same signat…

> it will miss cases where two data structures happen to have the same signature.

Huh. That's exactly the point: TypedDicts are structural types.

> we have class, namedtuple and TypedDict, which all can do much the same thing.

No, they can't. The former two are nominal types.

Re: A “frozen” dictionary for Python

#162

Concurrency is a good motivation, but this is super useful even in straight line code. There’s a huge difference between functions that might mutate a dictionary you pass in to them and functions that definitely won’t. Using Mapping is great, but it’s a shallow guarantee because you can violate it at run time.

> There’s a huge difference between functions that might mutate a dictionary you pass in to them and functions that definitely won’t. Maybe I misunderstood, but it sounds to me like you're hoping for the following code to work: def will_not_modify_arg(x: frozendict) -> Result: ... foo = {"a": 1, "b": 2} # type of foo is dict r = will_not_modify_arg(foo) But this won't work (as in, type checkers will complain) because…

No, I’d type the function argument as a Mapping. Frozendict is so that the function will raise an exception if it violates its type signature.

Edit: that is, if as the caller you want foo to be immutable, then you make it a frozendict

Re: A “frozen” dictionary for Python

#163

Regarding the spooky-action-at-a-distance concerns of a `.freeze()` method on dict: `.freeze()` should probably just return a frozendict instead of in-place mutating the dict, and they should be separate types. Under the hood, you'll have to build the hashtable anyway to make the frozendict; as long as you're doing that work, you may as well build an object to contain the hashtable and just have that object be separa…

The point is that freeze could work in constant time, whereas the copying takes linear time. Another alternative mentioned was `move`, which would create a frozen version in constant time and clear the original dict.

Freeze can't work in constant time if it builds a hash when the dict is frozen so that the dict can be used as a key.

If all it does is set a flag that prevents modifications, that's different.

Re: A “frozen” dictionary for Python

#164

Earlier quoted context omitted.

True, but the original comment that we're talking about here (by sundarurfriend) just mentioned an LLM's output in passing as part of their (presumably) human-written comment. Nothing you've linked to prohibits that.

Presaging your bot produced comment with "A bot said this" is not human written

That is still true and still irrelevant here. The comment we're talking about was not written by a bot with a disclaimer at the start. They just asked about its output. They didn't even quote its output - they paraphrased it and added their own commentary!

I know HN rules prohibit saying "did you even read it?" but you surely can't have read the comment to have come to this view, or at least significantly misread it. Have another look.

Most of all, HN guidelines are about encouraging thoughtful discussion. sundarurfriend's comment asked a genuinely interesting question and inspired interesting discussion. This subthread of "but AI!" did not.

Re: A “frozen” dictionary for Python

#165

Earlier quoted context omitted.

> There’s a huge difference between functions that might mutate a dictionary you pass in to them and functions that definitely won’t. Maybe I misunderstood, but it sounds to me like you're hoping for the following code to work: def will_not_modify_arg(x: frozendict) -> Result: ... foo = {"a": 1, "b": 2} # type of foo is dict r = will_not_modify_arg(foo) But this won't work (as in, type checkers will complain) because…

No, I’d type the function argument as a Mapping. Frozendict is so that the function will raise an exception if it violates its type signature. Edit: that is, if as the caller you want foo to be immutable, then you make it a frozendict

[deleted]

Re: A “frozen” dictionary for Python

#166

Earlier quoted context omitted.

> There’s a huge difference between functions that might mutate a dictionary you pass in to them and functions that definitely won’t. Maybe I misunderstood, but it sounds to me like you're hoping for the following code to work: def will_not_modify_arg(x: frozendict) -> Result: ... foo = {"a": 1, "b": 2} # type of foo is dict r = will_not_modify_arg(foo) But this won't work (as in, type checkers will complain) because…

No, I’d type the function argument as a Mapping. Frozendict is so that the function will raise an exception if it violates its type signature. Edit: that is, if as the caller you want foo to be immutable, then you make it a frozendict

Ah, I see. The last sentence in your previous comment makes more sense now ("Mapping is great, but ... you can violate it at run time"). A type checker would normally catch violations but I can still see a frozendict would be useful.

Re: A “frozen” dictionary for Python

#167

Earlier quoted context omitted.

If your dicts are frozen, you shouldn't need to deep-copy. The point of immutability is that if you want a new frozendict based on another one, you just rebuild the indirection data structure up top and leave the values it references alone.

You're absolutely right: an "indirection data structure" is necessary. Freezing the data is the least interesting part - it doesn't give you any of the benefits typically associated with immutable data structures in functional languages. That's my point - Python is shipping a half solution that's being mistaken for a proper one. You think Python developers are going to roll their own HAMT on top of frozendicts? Or ar…

> You think Python developers are going to roll their own HAMT

Python already has an HAMT implementation in use by the contextvars module.

Re: A “frozen” dictionary for Python

#168
post #51

Earlier quoted context omitted.

This was 19 (almost) 20 years ago. As stated in the lwn.net article, a lot of concurrency has been added to python, and it might now be time for something like a frozendict. Things that were not useful in 2006 might be totally useful in 2026 ;P Still, like you, I'm curious wether he has anything to say about it.

I think Raymond Hettinger is called out specially here because he did a well known talk called [Modern Dictionaries]( https://youtu.be/p33CVV29OG8 ) where around 32:00 to 35:00 in he makes the quip about how younger developers think they need new data structures to handle new problems, but eventually just end up recreating / rediscovering solutions from the 1960s. “What has been is what will be, and what has been don…

I think he was always reluctant to add features, and his version of Python would be slimmer, beautiful, and maybe 'finished'. His voice is definitely not guiding the contemporary Python development, which is more expansionist in terms of features.

Re: A “frozen” dictionary for Python

#169
post #46

This subject always seems to get bogged down in discussions about ordered vs. unordered keys, which to me seems totally irrelevant. No-one seems to mention the glaring shortcoming which is that, since dictionary keys are required to be hashable, Python has the bizarre situation where dicts cannot be dict keys, as in... {{'foo': 'bar'}: 1, {3:4, 5:6}: 7} ...and there is no reasonable builtin way to get around this! Yo…

> the glaring shortcoming which is that, since dictionary keys are required to be hashable, Python has the bizarre situation where dicts cannot be dict keys

There is nothing at all bizarre or unexpected about this. Mutable objects should not be expected to be valid keys for a hash-based mapping — because the entire point of that data structure is to look things up by a hash value that doesn't change, but mutating an object in general changes what its hash should be.

Besides which, looking things up in such a dictionary is awkward.

> More generally, sometimes you have an array, and for whatever reason, it is convenient to use its members as keys.

We call them lists, unless you're talking about e.g. Numpy arrays with a `dtype` of `object` or something. I can't think of ever being in the situation you describe, but if the point is that your keys are drawn from the list contents, you could just use the list index as a key. Or just store key-value tuples. It would help if you could point at an actual project where you encountered the problem.

Re: A “frozen” dictionary for Python

#170
post #77
post #55

Earlier quoted context omitted.

Turning a dictionary into a tuple of tuples `((k1, v1), (k2, v2), ...)`; isn't that a reasonable way? If you want to have hash map keys, you need to think about how to hash them and how to compare for equality, it's just that. There will be complications to that such as floats, which have a tricky notion of equality, or in Python mutable collections which don't want to be hashable.

That argument would apply to sets too, and yet frozenset is builtin.

The elements of a frozenset need to be hashable, too.
Post reply on HN