Live data from Hacker News

Python 3.8 Makes me Sad Again

ilya-sher.org

31–40 of 48 posts

Re: Python 3.8 Makes me Sad Again

#32

Earlier quoted context omitted.

It makes execution reproducible.

Almost any hash table implementation will give the same iteration order for the same sequence of insertions and deletions across program executions. So this would already be true even if the order was not the insertion order. Golang starts iterations in a random position each run to prevent people from relying on the ordering.

I think Go does it very well here (since they don't want to guarantee the order) - getting consistent order in almost every case is the worst of both worlds, because people won't learn about the underlying implementation, they'll notice that it seems ordered and will rely on this behaviour.

Re: Python 3.8 Makes me Sad Again

#33

Why is it useful for maps to be sorted by insertion order?

There are 2 questions here:

1. Why should it use a stable ordering at all?

2. Why should that ordering be the insertion order?

#2 isn't a particularly deep question. It has at least one fairly obvious reason: because it's the most intuitive thing to iterate through items and get them back in the same order as you inserted them. Anything else would be less intuitive.

#1, though, is more interesting, and it's one of those experience-based things that can be hard to see the significance of initially. One reason for it is that determinism & reproducibility is quite useful in a variety of use cases (e.g. testing), and while it's incredibly easy to lose, it's also quite hard (and often brittle) to gain back afterward (in the cases where it's even possible). By contrast, it's generally far easier to inject randomization at any point when you really need to (e.g. for security). Another reason can be that it reduces degrees of freedom in your program, which is generally a good thing as it helps when reasoning about program behavior. (This is not only during development, but also when debugging: it's incredibly useful to see what see what order items were inserted in to arrive at the current state.) There are probably more, but these are what I can think of off the top of my head.

And finally, another overarching reason for both is simply the notion of "information loss" (basically, entropy): it's easy to lose information, but not so easy to get it back. And in some people's experience (including mine), it often pays off in the long run for clients of an API to go out of your way to minimize unnecessary information loss in your library. (That information in this case being the implicit ordering information.)

Of course, all this hinges on the trade-off being worthwhile in each case. That's why library writers try to test different workloads to see if e.g. the performance trade-off is worth it. In CPython's case, it appeared it was.

Re: Python 3.8 Makes me Sad Again

#34
Clarification: NGS sucks differently. That's it.

Don't know how you guys get from "From my perspective, all languages suck, while NGS aims to suck less than the rest for the intended use cases" to how NGS is generally good or generally better than other languages or did/would avoid mistakes.

Note "aims to suck less", not even "sucks less".

Thanks, OP

Re: Python 3.8 Makes me Sad Again

#35
post #32

Earlier quoted context omitted.

Almost any hash table implementation will give the same iteration order for the same sequence of insertions and deletions across program executions. So this would already be true even if the order was not the insertion order. Golang starts iterations in a random position each run to prevent people from relying on the ordering.

I think Go does it very well here (since they don't want to guarantee the order) - getting consistent order in almost every case is the worst of both worlds, because people won't learn about the underlying implementation, they'll notice that it seems ordered and will rely on this behaviour.

As lightgreen points out in a sibling comment, it's common recently for languages to use a secure randomized hash like siphash and generate different orderings per program execution. It seems like that's the approach more languages should take.

Re: Python 3.8 Makes me Sad Again

#36
post #27

Earlier quoted context omitted.

However the author did not mention stable order does not come for free. It is not a trivial decision to make, between ordered and unordered dicts.

Actually in this case I believe it did come for free due to a change in the way dict was implemented in 3.6: https://mail.python.org/pipermail/python-dev/2016-September/...

It is not as simple as that. It might looks "free" in this particular implementation, but it obviously prevents further optimizations.

Re: Python 3.8 Makes me Sad Again

#37
post #24

Earlier quoted context omitted.

You can use the same structure to output data to the screen (or elsewhere) and to find stuff by the key.

In other words, I must pay the cost of maintaining the ordering even in the 99% of cases when it will not be used.

Indeed, if you find e.g. PHP too slow, you can switch to Python for speed. To Python. For speed. Compared to PHP.

Re: Python 3.8 Makes me Sad Again

#38

I don't understand the parameter section. What fundamental mistake is python trying to remedy with the must-be-positional parameter? I don't get why you would want to force people to not name a parameter. Like, why is it so bad that I write: myval = mydict.get(mykey, default=mydefault) Who does it help that this throws an error?

In many languages you can do whatever you want with parameter names because they’re an implementation detail. In Python it’s always been frustrating that perhaps a less experienced developer can rename a parameter “inside the function” and break calling code that happened to refer to the name. (And since it isn’t static/compiled, how long after the change will you see this break?)

Re: Python 3.8 Makes me Sad Again

#39
post #27

Earlier quoted context omitted.

Actually in this case I believe it did come for free due to a change in the way dict was implemented in 3.6: https://mail.python.org/pipermail/python-dev/2016-September/...

It is not as simple as that. It might looks "free" in this particular implementation, but it obviously prevents further optimizations.

To follow up on lightgreen's comment, in arijun's own linked-to URI they specifically mention the new level of indirection right away. Indirection is not "free" at all. For very large dict()s in main memory/DRAM it could be 2X slower. A hot loop benchmark where the CPU can perfectly predict its near future work and its prefetcher can mask DRAM latency may not reveal this, but a less "simple" benchmark would.

The primary point of the ordering feature (and insertion ordering) is because Python uses that very same dict implementation for language features such as keyword args {def foo(\\kwargs)}. Changing to hash-order from "source code"-order can be confusing.

Re: Python 3.8 Makes me Sad Again

#40
post #9

I don’t get the part about unordered maps. Python never promised ordered dicts (until 3.7) it wasn’t a secret nor did you have any reason to believe that they would be ordered. I mean they’re ordered now and that provide some benefit in terms of simpler code in some cases, but it was never a problem as such.

I think it refers to the fact that, if dictionaries do not promise to be ordered but have predictable (and consistent between runs) iteration order (e.g. by insertion order), code can start depending on that.

Some people think that, if code ‘out there’ starts depending on that, it’s better to update the documented API to promise what it actually does.

Post reply on HN