Live data from Hacker News

Don't let dicts spoil your code

roman.pt

91–100 of 121 posts

Re: Don't let dicts spoil your code

#92

Earlier quoted context omitted.

Who does this still??

In bioinformatics, one of our main dataflow platforms, Nextflow, is built with unnamed tuples in mind. Implementing the ability to conveniently pass data with HashMaps instead of unnamed tuples was a huge boost to usability for me.

i really want to go on a rant about the general state and historical choices regarding data formats and data structures in bioinformatics, plus all the wheel reinvention.

but i’m also trying to move on and do things differently today.

let’s just say the situation is displeasing and leave it at that.

Re: Don't let dicts spoil your code

#93

This is absolute key advice. Another way to look at it is the functional core, imperative shell pattern. Wrapping up your dict in a value object (dataclass or whatever that is in you language) early on means you handle the ugly stuff first. Parse don't validate. Resist the temptation of optional fields. Is there really anything you can do if the field is null? No, then don't make it optional. Let it crash early on. C…

The "loosey-goosey" approach to data in coding is one of my biggest pet peeves. Some people absolutely insist on making everything as dynamic as possible, and then wonder why we end up with a buggy mess. I always found it very natural to move as much as possible into the type system, because why wouldn't I want the machine to find all my inevitable mistakes for me?

My personal favorite of this has got to be a particular mess of a Python API that led to me implementing "type veryFlexibleUint64": https://github.com/sapcc/limes/blob/9ea9d1f86383f8a5fe0fa1d1...

Re: Don't let dicts spoil your code

#94
I largely moved away from dictionaries when switching to swift. Usually we only use them now when going from legacy code. For the example in the article with JSON, Swift has the Codable protocol, which cleaned all my client code for our back end from the old NSJSONSerialization code.

Re: Don't let dicts spoil your code

#95

Earlier quoted context omitted.

The "loosey-goosey" approach to data in coding is one of my biggest pet peeves. Some people absolutely insist on making everything as dynamic as possible, and then wonder why we end up with a buggy mess. I always found it very natural to move as much as possible into the type system, because why wouldn't I want the machine to find all my inevitable mistakes for me?

My personal favorite of this has got to be a particular mess of a Python API that led to me implementing "type veryFlexibleUint64": https://github.com/sapcc/limes/blob/9ea9d1f86383f8a5fe0fa1d1...

So brutal

Re: Don't let dicts spoil your code

#96

This is absolute key advice. Another way to look at it is the functional core, imperative shell pattern. Wrapping up your dict in a value object (dataclass or whatever that is in you language) early on means you handle the ugly stuff first. Parse don't validate. Resist the temptation of optional fields. Is there really anything you can do if the field is null? No, then don't make it optional. Let it crash early on. C…

> Another way to look at it is the functional core, imperative shell pattern.

A good explanation of this is: https://www.destroyallsoftware.com/talks/boundaries

Re: Don't let dicts spoil your code

#97

Earlier quoted context omitted.

Personnaly I became a huge fan of beartype : https://pypi.org/project/beartype/ Leyec, the magic dev behind it managed to make a full python type checker with super advanced features and about 0 overhead. It's crazy

I tried using it, but beartype quickly became a pain with having to decorate things manually. Then I found typeguard which goes even further and never looked back. Instead of manually decorating each individual function, an import hook can be activated that automatically decorates any function with type annotation. Massive QoL improvement. I have it set to only activate during testing though as I'm unsure of the over…

It looks like beartype supports the same sort of implicit decoration, because there's mention of an explicit API:

>Beartype now implicitly type-checks all annotated classes, callables, and variable assignments across all submodules of all packages.

Re: Don't let dicts spoil your code

#98

Here’s an out-there take, but one I’ve held loosely for a long time and haven’t shed yet: dicts are not appropriate for what people mostly use them for, which is named access to member attributes. dict is an implementation of a hash table. Hash table are designed for o(1) lookup of items. As such, they are arrays which are much bigger than the number of items they store, to allow hashing items into integers and sides…

dicts are used internally in the language to look up class and module attributes. They are optimized for this use case. How can it be wrong to use them that way when the very fabric of the language depends on it? namedtuple is widely used in Python code, especially before the introduction of dataclasses.

A hash function will always be more expensive than a pointer lookup, specially concidering a pointer lookuo is still needed after the hash function.

No matter what you do, a lookup into an array will always be quicker than a hash lookup if you don't need to do a linear search, even in a lot of cases the linear search will be quicker.

Structs in other languages is a lookup of pointer + and offset. Which to my knowledge is also true in python classes using __slots__. There's no reason to use a dict if you know the contents of the data, use a dataclass with slots=True purely because there's no hash function run on every lookup into the datastructure.

Re: Don't let dicts spoil your code

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

[]inferface

But the same issue exists as other dynamic languages, how do you know what the type is of the item you are accessing?

If you know the array will be laid out exactly like that before you make the request you can always create a custom parser to return a struct with those fields name what they actually are instead of arbitrary data.

The only valid way to parse that dynamically is to try and fail in a loop which is inefficient enough that you should stop using whatever API returns that monstrosity.

Re: Don't let dicts spoil your code

#100

Earlier quoted context omitted.

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.

Exactly… with strong typing, you can do the refactor automatically, because the IDE knows everywhere that symbol is used. (For codebases in your control—for third party users, you can indicate that something has been deprecated or renamed via a warning or other language feature)
Post reply on HN