Live data from Hacker News

Don't let dicts spoil your code (2020)

roman.pt

71–80 of 91 posts

Re: Don't let dicts spoil your code (2020)

#71
post #4

Interesting how Clojure takes the complete opposite approach by simply making dicts immutable. https://chasemerick.files.wordpress.com/2011/07/choosingtype...

You still need to know what keys to expect. The Clojure map that get replaced with a new map have the same problem as a mutable dict.

Re: Don't let dicts spoil your code (2020)

#72
post #7

The article is not explaining the point, which I believe is: type your dicts if you want to provide strict guarantees to your downstream about data shape. If you know precisely what the data is used for - great, go ahead - type system is your friend. If you don't know how the data should be used, it's often a different story. Wrapping data in hand typed classes is a terrible idea in the typical data engineering scena…

This is one of the things I appreciate about languages like Go and Rust (I'm sure there are others as well). If the data is static, use a struct. If the data is dynamic, use a map/HashMap. No need to worry about TypedDict vs classes vs DataClasses vs etc, and no one uses HashMap for static data (they could , but virtually no one in those communities is such a glutton for punishment). From Zen of Python: > There shoul…

Python is one of those languages where everything starts to look like a nail.

Re: Don't let dicts spoil your code (2020)

#74
post #51
post #40

Earlier quoted context omitted.

Having a proper type system can be immensely powerful. IMHO, duck typing is just adding the burden of type checking to the application layer instead of letting a compiler or linter deal with it. Pythons lack of a good type system is what I miss most

Duck typing is a superset of inheritance. If your language only supports polymorphism via inheritance, then it is strictly less expressive than a language with duck typing.

What does superset mean, here? Inheritance can mandate the presence of certain fields at compile time, which duck typing cannot do, so it doesn't fit my traditional definition of "superset".

Re: Don't let dicts spoil your code (2020)

#75
post #8

I don't program professionally, and I struggle with dicts and classes. On one hand, I want to avoid the Java world of needing to learn 8 new classes to use any library. So dicts are lightweight and extensible and feel like the modern way of doing things. One the other hand, all the problems listed in the article are right. You really do need to document different expected dicts somehow, which is basically structs/cla…

Python implicit string iteration is an annoying trap.

  COMPLETE_STATES = 'done', 'cancelled'

  if state in COMPLETE_STATES:
      …
Then you decide to handle cancelled tasks separately.

  COMPLETE_STATES = 'done'
Boom!

Can't remember a less contrived example right away, but I have broken real code by inadvertently calling string iteration and spent some time scratching my head. Granted, don't think I've seen something like this in a PR, only in local development.

P.S. I think last time I stumbled on this, it actually involved Django ORM and changing filter(state__in=COMPLETE_STATES) to filter(state__in=DONE).

Re: Don't let dicts spoil your code (2020)

#76

I would really like a language where you can swap simple data collections like dicts or arrays with others, better defined, employing better suited algorithms without changing everywhere in your code how you access them. So if getting a field using simple structure is mycol[key] it should look exacty the same when mycol is no longer a flexible dict containing adhoc objects but complex strongly typed immutanble trie o…

You can do this in any language that has operator overloading, right? C# or C++ for example. Or in fact, you can just define an interface with Get/Set methods. Any language with interfaces supports that and you can swap them out as you please. Doesn't seem like the language is really the restricting factor for implementing this if you really wanted it.

> You can do this in any language that has operator overloading, right?

The thing is that language and standard library designers don't do that.

And if you are not hellbent on creating your own collection library and using it everywhere, even when interfacing with system functions that don't understand it you pretty much have no way of swapping out your data structures without carefully replacing all lines that access them.

Scala standard collection library designers are the only ones I know of that actually went through the trouble of making this for us.

Re: Don't let dicts spoil your code (2020)

#77
post #74
post #51

Earlier quoted context omitted.

Duck typing is a superset of inheritance. If your language only supports polymorphism via inheritance, then it is strictly less expressive than a language with duck typing.

What does superset mean, here? Inheritance can mandate the presence of certain fields at compile time, which duck typing cannot do, so it doesn't fit my traditional definition of "superset".

[deleted]

Re: Don't let dicts spoil your code (2020)

#79
This opinion gets at the heart of the reason to use type languages or not. After all, what is a dict but an untyped struct?

Untyped languages are excellent for smaller code bases because they are more comfortable to program in and faster and more general. Types of polymorphism possible in these languages are simply not possible or much harder in typed languages. Also, as others have said, the problem domain may not be as explored yet.

Typed languages really start to shine as a code base gets huge. In these instances well maintained untyped language code bases start collapsing under the weight of their own unit tests, while moderately well or poorly well maintained instances of untyped language code bases become a mess. Mostly this is due to difficulties in communication when the code base gets worked on by so many people that it's hard for them all to communicate with each other. In these cases a typed language keeps everyone on the same page to some extent.

Both camps will hate me for saying this I think, but it's what I've observed over the years.

It also may sound like I prefer typed languages, but in fact my favorite languages to work in are Clojure and Python. My code bases as a DevOps engineer rarely pass the 10,000 line mark and never pass 100,000 line mark. It's much more comfortable for me in these untyped languages.

Untyped languages also really shine in microservices for the same reason.

Re: Don't let dicts spoil your code (2020)

#80

> Don't let dicts spoil your code (2020) (roman.pt) * Conditions applies * Apply only for when parsing I/O. Do not substitute primitives with classes inside your code base for no good reason. Unless validation is needed, prefer a NamedTuple.

Other than validation, I can imagine several good reasons why one might want to wrap a primitive inside a class. For example, you may have a function: group_by_age() -> Dict[int, List[str]] which might be perfectly good for your use case, but I can see why one might instead prefer: group_by_age() -> Dict[Age, List[CustomerId]] for self-documentation and expressiveness. Your test assertions may also become easier to r…

Use NewType for this: https://mypy.readthedocs.io/en/stable/more_types.html?highli...
Post reply on HN