hashable datastructures as rule inputs and outputs...
# development
c
hashable datastructures as rule inputs and outputs 🧵
1
So, I’ve just run into a (to me) weird situation, where a value I just got from a
await Get()
call, isn’t hashable. I thought that all return values must also be hashable, but this maybe isn’t enforced?
I noticed it, as when attempting to use this value as input to another
Get
it threw..
just tossing this out here, in case it is a known issue, or something worth looking into further…
h
are you confident there isn't a bug in code? For example, a common mistake I make is to forget to wrap interpreter constraints in the
InterpreterConstraints
object, so I'm passing a
[list]
to
Get()
c
I’m positive I had a
list
object in a dataclass where it was meant to be a tuple. So the value returned was never hashed, it tells me.
(but it took me a while to figure this one out… 😛 )
h
yeah it always confuses me so much hah
c
but just to be clear, return values from rules should or must be hashable?
or is it just the inputs that must be hashable, and return values whatever… 😬
h
this always confuses me. I think technically it just needs to be eq, but there are some times it needs to be hash. Making it always hash is a good rule of thumb
or is it just the inputs that must be hashable, and return values whatever…
yeah, I think that's it
c
so, should be, then.. ok. Yeah agree to stick with always hashable is a good rule of thumb, and enforcing it would help catch situtations where a previously returned value is used as input to another rule
👍 1
(refactoring the dockerfile parser to be more ergonomic)
🙌 1
w
I thought that all return values must also be hashable, but this maybe isn’t enforced?
only
@rule
inputs must be hashable/eq’able, as they are used as part of cache keys
👍 1
@rule
outputs should be eq’able (for best cache performance), but don’t need to be hashable
c
makes sense, dunno why I thought also return values had to be hashable.. (still think it makes sense to strive for, though, given the above reason)
h
But very very often rule outputs are also rule inputs, so...
1
w
the nice thing about hashing is that it is impossible to miss it.
(…in python 3)
c
Yeah, but frozen dataclasses don't enforce hashability, so the missing can go undetected until you attempt to hash it, and then the root of the issue is obscured..
w
the root of the issue is still that it doesn’t have hash… and you discover that immediately.
while it’s fine to implement hash, blindly requiring it in all cases does more to muddy the water around when it is actually needed, imo
👍 1
for example: if this were typesafe, we’d clearly only implement Hash in positions that require it… but the runtime checking is equivalent, in that it tells you that a position requires it.
(determining that an implementation of Hash is dead/unused is harder… even when it is typesafe. rust doesn’t detect dead trait implementations, for example)
c
Well, the case I had was less than immediate and clear. I got “list is not hashable” but no clue where that list came from.. or even at what line. Only within which rule.