Skip to content

Shorthand for rejecting nil and missing values

Brian Marick edited this page Mar 20, 2016 · 4 revisions

requires is shorthand for using required-path on the right-hand side of maps.

(type! :X (requires :a :b))  ; same as:
(type! :X {:a required-path
           :b required-path})

Note that requires can take any path, not just isolated keywords:

user=> (type! :X (requires [ALL :b :c]))
user=> (built-like :X [{} {:b 1} {:b {}} {:b {:c nil}}])
[0 :b] does not exist
[1 :b :c] encountered `1` when a map or record was expected
[2 :b :c] does not exist
[3 :b :c] has a `nil` value
=> nil

If you want to describe all fields of a structure and also mark them as required, you can use requires-mentioned-paths:

user=> (type! :X (requires-mentioned-paths {:a odd? [:b ALL] even?}))
user=> (built-like :X {})
:a does not exist
:b does not exist
=> nil

One note on requires-mentioned-paths: you have to mention a path for it to be required. The preceding example would not require a :c key. The easiest way to require it is with requires:

(type! :X (requires-mentioned-paths {:a odd? [:b ALL] even?}
                                    (requires :c)))

You're being very emphatic that :c is required (by stating it twice). That doesn't hurt; the duplication will be removed when the canonical type description is created.