Live data from Hacker News

Don't let dicts spoil your code

roman.pt

51–60 of 121 posts

Re: Don't let dicts spoil your code

#51
Can someone educate me in why dicts are uncool for explained reasons, but clojure (which seems to be highly recommended on hn) seems to suffer the same issues when dealing with a map as a parameter (ring request etc).

I know how to deal with missing values or variability in maps, and so do a lot of people.. what am I missing here?

Re: Don't let dicts spoil your code

#52

Earlier quoted context omitted.

Duck typing is so fragile… Once you have implementations that are depending on your naming or property structure, you can’t update the model without breaking them all. If you use a real type, you never have to worry about this.

You would still have to update everything if you rename a field in a struct, what do you mean you never have to worry?

If you use type checking, the breakage occurs when you introduce the change: the author of the change is the one who can figure out what it means if 'foo' is no longer being passed into this function.

If you're duck typing, you find this out in the best case when your unit tests exercise it, and in the worst case by a support call when that 1/1000 error handling path finally gets exercised in production.

Re: Don't let dicts spoil your code

#53
post #48
post #41

Earlier quoted context omitted.

If external API adds a new field but your software already worked, you didn't need it in the first place, so why should it matter? Dropping unknown/unused fields makes sense in 99% of cases.

Unfortunately some APIs assume that they will get all the fields as part of the update. If field doesn't exist in the input it gets it will drop the original value during the update.

yet, again, most of the libraries already deal with extra fields... i.e. for pydantic https://docs.pydantic.dev/latest/concepts/models/#extra-fiel...

Re: Don't let dicts spoil your code

#54
post #21

For better or for worse, Python doesn't do typing well. I don't disagree that I prefer well defined types, but if that is your desire then I think Python is perhaps not the correct choice of language.

> Python doesn't do typing well Golang does typing, but JSONs are PITA to handle. Try parsing something like `[{"a': 1, "b": "c", "d": [], "e": {}}, null, 1, "2"]` in go. Types are a bless as well as a curse.

And if you got that JSON back in Python, how would you do anything with it? This API is essentially useless. You can deserisalise it, sure, but then what?

Re: Don't let dicts spoil your code

#55

Earlier quoted context omitted.

Is there any advantage to using a TypedDict for a record over a dataclass?

TypedDicts "aren't real" in the sense that they're a compile-time feature, so you're getting typing without any deserialization cost beyond the original JSON. Dataclasses and Pydantic models are slow to construct, so that's not nothing. This of course means TypeDicts don't give you run-time validation. For that, and for full-blown custom types in general, I tend to favor msgspec Structs: https://jcristharif.com/msgsp…

> Dataclasses and Pydantic models are slow to construct

Citation needed? Pydantic is really quite fast, and you can pass raw JSON responses into it.

It may be slower (depending on the validators or structure), but I’d expect it to be comparably fast to the stdlib JSON module.

Re: Don't let dicts spoil your code

#57

It's a bit of an odd article because the second part kind of shows why dicts aren't a problem. You basically just need to apply the most old school of OO doctrines: "recipients of messages are responsible for how they interpret them", and that's exactly what the author advocates when he talks about treating dict data akin to data over the wire, which is correct. If you're programming correctly and take encapsulation…

I assume you're basically referring to this quote from the article?

"Ignore fields coming from the API if you don’t need them. Keep only those that you use."

IMO this addresses only one part of the problem, namely "sanitize your inputs". But if you follow this, and therefore end up with a dict whose keys are known and always the same, using something "struct-like" (dataclasses, attrs, pydantic, ...) is just SO much more ergonomic :)

Re: Don't let dicts spoil your code

#58

Can someone educate me in why dicts are uncool for explained reasons, but clojure (which seems to be highly recommended on hn) seems to suffer the same issues when dealing with a map as a parameter (ring request etc). I know how to deal with missing values or variability in maps, and so do a lot of people.. what am I missing here?

Maps arent nearly as problematic in clojure because data is immutable by default on top of the functional paradigm where your program is basically a big composition of functions and the language is built around using maps. In Python I largely agree with the author. In clojure I love my maps.

Here is Rich Hickey with an extreme counter example although I would argue he's really demonstrating against getters and setters. https://www.youtube.com/watch?v=aSEQfqNYNAc

Re: Don't let dicts spoil your code

#59

Can someone educate me in why dicts are uncool for explained reasons, but clojure (which seems to be highly recommended on hn) seems to suffer the same issues when dealing with a map as a parameter (ring request etc). I know how to deal with missing values or variability in maps, and so do a lot of people.. what am I missing here?

[deleted]

Re: Don't let dicts spoil your code

#60
> convert [dicts] immediately to data structures providing semantics [...] You can simplify your work by employing a library that makes “better classes” for you

Python seems to have many different kinds of "better classes" - the article mentions `dataclass` and `TypedDict`, and AFAIK there are also two different kinds of named tuple (`collections.namedtuple` and `Typing.NamedTuple`).

What are the advantages of these "better classes" over traditional classes? How would you choose which of the four (or more?) kinds to use?

Post reply on HN