Live data from Hacker News

Don't let dicts spoil your code (2020)

roman.pt

81–90 of 91 posts

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

#81
post #26
post #24

Earlier quoted context omitted.

The normal way to handle this is to deserialize into your application specific type, and store extraneous data in an extra field that is private but included in reserializations. Because your application will fail if fields you need aren't there.

That can turn into an enormous amount of work to provide all the permutations of type conversions between 3+ classes, and then manually shuffle between them over and over. It's even harder when you don't have the power to add similar conversions for the classes you're trying to convert to/from. Classes aren't a great abstraction when enforcing program invariants like "this object must at least have fields a and b." W…

> Classes aren't a great abstraction when enforcing program invariants like "this object must at least have fields a and b."

Can you elaborate on the functional difference between

- an enhanced dictionary where certain keys are guaranteed as part of the type, and

- a record type (class, struct, whatever) with named fields?

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

#82
post #17

Earlier quoted context omitted.

> so inevitably you get slight variations depending on what you need If you have a generic collection, you know it's generic. It does remove a class of errors when you start adding types, but it also adds problems in making changes as a tradeoff. Now I have to make a PR that is the change I want AND I have to modify the type, which comes with explaining/understanding that there isn't a reason to use 2 different types…

I'm not sure if I'm misunderstanding your point or you're understanding mine, so I'll just carefully say that the PHP array is really a dictionary + array combination type, and I was referring specifically to its use as a dictionary (since that's what TFA is about). If you're returning a list of things that are all the same type I agree that an array, or an array of a certain type if generics are available is totally…

> if you're passing in/out some monstrosity which has a structure that you can only really find out by reading the code

This is conflating multiple issues. Using generic collections (dictionaries, if you like) and then trying to work out what's in them. Modern stacks include a debugger, so figuring out what's in them is trivial in a given code path, if you have a test environment.

Figuring out how to use them (or how to not abuse them) when you have an immature development environment, is the issue at hand.

The author of the blog implies that they will necessarily be problematic. That's incorrect on it's face, but let's get into a codebase where we have no frame of reference, documentation, a limited dev environment, and/or the tests are missing/ignore the ramifications of the dictionary containing a variety. The question then becomes one of ascribing blame in these conversations:

1. is it the fault of the original programmer in selecting a dictionary? - No

2. is it the natural outcome of using a dictionary? - No

3. is there a compelling reason to use a dictionary at all (over a typed list)? - Yes and I would say more than one.

That's all aside to the issue of "what do you do now?" Well you do research and work, same as any of these tangled codebases (which may not be tangled at all). You break it up, you write tests and then you reason about the choices made. None of this is particularly special in regards to dictionaries. It's a particular practice that is sometimes expedient or efficient and that seems to offend the author's sensibilities. It's zealotry.

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

#83
post #3

Earlier quoted context omitted.

Who needs hashes when you've got variable variables? ~ me, 20 years ago, learning the hard way

I still don't know how I feel about the fact that in PHP $$var (a) works, and (b) does exactly what you'd expect.

This level of introspection can be useful in some cases. Perhaps the flaw is just in giving it such simple, attractive syntax.

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

#84

Earlier quoted context omitted.

Could you clarify a bit here? Python also has destructuring for its dicts and I'm not entirely sure what you mean by symbol keys.

Symbol keys are string keys for the more sophisticated among us. See :some-name vs "some_name". ;)

they're closer to a (namespace) global enum imo

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

#85

Earlier quoted context omitted.

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…

Forget about DataClasses, TypedDict etc. Can't you achieve the same in python with a class and a dict? Is there a difference, other than perhaps being overloaded with options?

There’s also implementation differences. Accessing attributes and methods on a regular class may be slower because (IIRC) it has to do a lookup on each instance’s dict, whereas I believe dataclass implementation is more optimized (I’ve clearly forgotten the details).

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

#86

Earlier quoted context omitted.

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.

Yeah, I’ve programmed in Python professionally for about a decade and I used it for hobby stuff for about 5 years before that. I still don’t feel like I’ve mastered it, whereas I felt I had mastered Go after about ~2 years. I think Go implements Python’s “zen” a lot better than Python does.

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

#87
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".

Some forms of duck typing absolutely can do this. "Row polymorphism" is the general feature that allows this, some duck typing can handle this, some can't.

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

#88
post #40
post #16

Python's strapped on type annotations have been designed around traditional OOP, and it feels like a bad fit for the language. Duck typing is a tremendously powerful form of polymorphism, and none of the PEPs for type annotations do a great job of supporting it. Protocols don't work well with dataclasses and not at all with dicts. TypedDicts could have been perfect, but they explicitly disallow extra keys. Why even u…

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

The compiler can still do type checking even when using duck typing. It's important to note that duck typing and weak typing are entirely orthogonal. You can have either, both, or neither.

E.g. an example in D of a function that doesn't care too much about the type you pass in:

    T doublify(T)(T v){
        return v*2;
    }
These are all fine:

    writeln(doublify(3));
    writeln(doublify(3.0));
    writeln(doublify(3u));
But this still throws a compile error like you'd expect:

    writeln(doublify("3"));

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

#89
post #20

When JavaScript added hash/object deconstruction (both at the argument level and assigning variables) I noticed code has been using Dict-like function arguments everywhere. It makes typing them a bit more of a pain in the ass (especially without default arguments). I haven’t decided if I like it better than just breaking up objects into arguments in a more simple functional style. On one hand it’s more predictable bu…

Whether to pass in a single dict/object/map/assoc-list or individually separated arguments is a tale as old as LISP (JS has some FP roots if you squint hard enough) and most LISPs (and JS has started doing this as well) mitigates this with destructuring:

Common Lisp: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node252.html

Clojure: http://blog.jayfields.com/2010/07/clojure-destructuring.html

JS: https://simonsmith.io/destructuring-objects-as-function-para...

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

#90

Earlier quoted context omitted.

I still don't know how I feel about the fact that in PHP $$var (a) works, and (b) does exactly what you'd expect.

This level of introspection can be useful in some cases. Perhaps the flaw is just in giving it such simple, attractive syntax.

I think so. You can get at the __globals__ dict in python to similar effect, and I've rarely seen that abused.
Post reply on HN