speced.def icon indicating copy to clipboard operation
speced.def copied to clipboard

speced/get-in

Open vemv opened this issue 6 years ago • 4 comments

(speced/get-in {:foo 2} [:foo :bar :baz]) => error message explaining that 2 does not contain :bar

(speced/get-in {:foo {:bar {}}} [:foo :bar :baz] ::default) => ::default

(speced/get-in {:foo 2} [:foo :bar :baz] ::default) => error message explaining that 2 does not contain :bar

The latter behavior is interesting. Fallback values should only be offered if the last member of the chain was missing, but not for intermediate values.

Essentially it ensures the structure is as expressed.

vemv avatar Apr 17 '19 23:04 vemv

Interesting feature!

Fallback values should only be offered if the last member of the chain was missing, but not for intermediate values.

I don't agree, it also deviates from core/get-in behavior. if the desired shape is required there's other ways of ensuring that.

thumbnail avatar Aug 29 '19 09:08 thumbnail

Thanks for the feedback!

it also deviates from core/get-in behavior

quite obviously I'm aware of this.

A core idea of speced.def (or clojure.spec in general?) is that a given app has a specific schema and that it should be honored, with fail-fast behavior when that premise is broken.

clojure.core/get-in (and update-in, etc) go in the opposite direction: they give you a free ticket to act liberally towards your data.

let's say that after a schema change, [:some :path 42] should have been refactored to [:some :42], but it wasn't, due to human mistake.

Now something fails, possibly in another ns, or even a different project. How do you debug it? Fail-fast behavior points right at the culprit instead of making you go in a bug hunt from defn to defn / from ns to ns.

vemv avatar Aug 29 '19 19:08 vemv

Now something fails, possibly in another ns, or even a different project. How do you debug it? Fail-fast behavior points right at the culprit instead of making you go in a bug hunt from defn to defn / from ns to ns.

I see, but aren't speced/(let|defn|def) more appropriate to make sure such a contract are held? destructuring in speced/* doesn't raise errors unless you add a spec.


I was thinking about allowing the consumer to specify specs on keys in the get-in vector; but metadata can't be applied to to keywords/numbers so that wouldn't work 🤔

thumbnail avatar Aug 30 '19 06:08 thumbnail

I see, but aren't speced/(let|defn|def) more appropriate to make sure such a contract are held?

They are not more appropiate for the precise stated reason: their error reports can happen arbitrarily later (and farther away) than the actual source of the error.

To put it in another POV: when you refactor shapes in a codebase, you often have to refactor get-ins as well. This tool would make that refactoring much safer / less tedious to perform.

destructuring in speced/* doesn't raise errors unless you add a spec.

Not sure of how destructuring is related to the topic

vemv avatar Sep 01 '19 16:09 vemv