-
Notifications
You must be signed in to change notification settings - Fork 9
Misshapen structures
If a structure is so misshapen that, for example, built-like
tries to follow the path [:a :b]
into {:a 1}
, an error results. These errors are handled the same as errors from failing checkers. For example:
user=> (built-like {[ALL :a] even?}
[{:a 1} {:a 2} :not-a-map])
[0 :a] should be `even?`; it is `1`
[2 :a] encountered `:not-a-map` when a map or record was expected
=> nil
The rest of this page describes what kinds of values count as "misshapen". What happens if a path is too long for a structure - such as following [:a :b] into {} - is described in truncated structures. nil
presents issues that deserve their own page.
-
Keywords and strings require maps or records
Whereas Clojure is happy to extract the
:a
field from an integer:user=> (get 1 :a) => nil
... this library is less forgiving:
user=> (built-like {:a even?} 1) :a encountered `1` when a map or record was expected nil
-
ALL requires non-map collections
user=> (built-like {[ALL] string?} 1) [ALL] encountered `1` when a collection was expected => nil user=> (built-like {[ALL] string?} {:a 1}) [ALL] encountered map or record `{:a 1}`; ALL doesn't allow that => nil
Maps are rejected because I think that an attempt to descend into each of the key-value pairs making up the map is awfully likely to indicate a map is where it didn't belong. Far more likely, in fact, than that descending into a map as a collection of pairs provides some useful checking that couldn't be done more clearly otherwise. But I could be convinced to change my mind.
-
RANGE and integers require sequential collections
user=> (built-like {[(RANGE 1 2)] even?} 1) [(RANGE 1 2)] encountered `1` when a sequential collection was expected => nil user=> (built-like {[1] even?} #{1 2 3}) [1] encountered `#{1 3 2}` when a sequential collection was expected => nil
Given that collections like sets and maps are unordered, selecting a range of indexes makes no sense.
-
Predicates that blow up count as falsey.
Predicates prevent further descent unless they have a truthy value. An exception is not a truthy value, so it prevents further descent. There's no indication of the exception in the output.
user=> (built-like {[ALL even?] pos?} [-1 :boom 3]) [-1 :boom 3]
In this example, all even values (of which there are none) are in fact positive.