Live data from Hacker News

Don't let dicts spoil your code

roman.pt

71–80 of 121 posts

Re: Don't let dicts spoil your code

#71
post #63
post #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…

To me, the proliferation of "better classes" implies there's a problem with Python's built-in classes - but what's wrong? Are they just too flexible and/or too verbose? Or actually deficient in some way?

People enjoy the flexibility and many Python systems rely on duck-typing via dicts, etc.

So people are trying to force Python to be something it isn’t in adherence to their ideology — but it fails to gain consensus because there’s a sizable cohort that use Python because it isnt those things.

So we get repeated implementations, from each ideologically motivated group.

Re: Don't let dicts spoil your code

#72

This has merit in some cases but let me try to make a counterpoint. You lose the algebra of dict’s - and it’s a rich algebra to lose since in python it’s not just all the basic obvious stuff but it’s also powerful things like dict comprehensions and ordering guarantees (3.7+ only). You tightly couple to a definition - in the simple GitHubRepository example this is unlikely to be problematic. In the real world, coupli…

You also make a nightmare of dynamically adding middleware — which can piggyback on a generic dict and have no meaningful way to insert themselves into your type maze.

Re: Don't let dicts spoil your code

#73

I think one really nice thing about Python is duck typing. Your interfaces are rarely asking for a dict as much as they’re asking for a dict-like. It’s pretty great how often you can worry about this kind of problem at the appropriate time (now, later, never) without much pain. There’s useful ideas in this post but I’d be careful not to throw the baby out with the bath water. Dicts are right there. There’s dict liter…

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.

And now inserting every middleware is an exercise in retyping the system, rather than piggybacking on the parameter dict.

Re: Don't let dicts spoil your code

#74
post #61

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?

Dicts are great when the data is uniform and dynamic, like an address book mapping names to contact info. You never assume that a key must be in there. Lookups can always fail. That's normal for this kind of use-case. When the data is not uniform (different keys point to differently-typed values), and not as dynamic (maybe your data model evolves over time, but certain functions always expect certain keys to be prese…

This should be the top answer. It's not about using dicts in their primary use case, it's about abusing them as a catch all variadic parameter for quick prototyping and "future expansion"

Re: Don't let dicts spoil your code

#75
post #53
post #48

Earlier quoted context omitted.

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...

I don't deal with external APIs often, but this is a development nightmare. You can't just magically let data flow through your system without knowing about it, because this is not how programming works. Your API has a contract and your code is written to support that contract, if the contract changes it should either be a very consciously decided breaking change that is versioned somehow, or it should be an unversioned non breaking change. Apparently whatever data is added like this is completely meaningless to your program so why do you need to be in charge of passing it back to the API.

Changing your API and assuming everything just keeps working is a nonsense cowboy attitude to software compatibility, even if some frameworks bend over backwards to support it through magic that's hidden from the developer. Furthermore, many programming languages are simply incapable of doing this, and this approach to APIs is immediately restricting those languages from use.

Finally, transforming objects to an internal domain model is really the cornerstone of a lot of recent well-thought-out programming discipline, and this API design is throwing that in the garbage. It's explicitly asking you to mess up your service architecture, spreading bad architecture like a virus to all systems that interact with the API.

Re: Don't let dicts spoil your code

#76
post #55

Earlier quoted context omitted.

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.

Pydantic's JSON parsing is faster than the built-in module, on par with orjson, but creating model instances and run-time type checking net out to be much slower. I linked msgspec's benchmarks in the previous post.

Re: Don't let dicts spoil your code

#77

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?

In Clojure, maps don’t have either of the flaws highlighted in the article. They are neither opaque (they are self-describing with namespaces keys) nor mutable.

As a result, they are very powerful and simple to use.

Re: Don't let dicts spoil your code

#78

>"unstructured data is problematic" >"solution : use dataclasses" Damn, it's almost like using an untyped language for large projects is not a great idea.

And yet we are overwhelmed by javascript nonsense... I get it - it's so easy to get up to speed with tiny snippets but it quickly becomes hot mess.

Yes, decades ago I was also fascinated by python and it's ease of doing stuff (compiler doesn't complain that I missed something) but with time I grew fond of statically typed languages... they simply catch swaths of errors earlier...

Re: Don't let dicts spoil your code

#79

Earlier quoted context omitted.

[flagged]

Dynamic languages demand self discipline, they teach you to respect runtime and think ahead of execution time. I've written software with both typed and untyped languages and never had problems (out of the ususal) with them.

> Dynamic languages demand self discipline, they teach you to respect runtime and think ahead of execution time.

Ah... yes... because static languages doesn't do that by forcing you to properly model everything. And as a bonus you can easily navigate between everything and not fear that you miss something while refactoring...

Re: Don't let dicts spoil your code

#80
post #67

I don't think dicts themselves are the problem. In typescript using plain JS objects is very straightforward. Of course you have to validate the schema at your system boundaries. But you'll have to do this either way. So: If this works very well in TS it can't be dicts themselves but must be the way they integrate into- and are handled in python. This leads me to the conclusion that arguments presented in the article…

This. I think types really make the difference here. You can get very far with just plain old JS objects as long as you've got strong types in place.
Post reply on HN