Validating and watching the reference types
Vars (both static and dynamic), atoms, refs, and agents provide a way to validate the value being set as state—a validator
function that accepts new value as argument, and returns the logical as true if it succeeds, or throws exception/returns logical as false (the false and nil values) if there's an error. They all honor what the validator function returns. If it is a success, the update goes through, and if an error, an exception is thrown instead. Here is the syntax on how the validators can be declared and associated with the reference types:
(def t (atom 1 :validator pos?)) (def g (agent 1 :validator pos?)) (def r (ref 1 :validator pos?)) (swap! t inc) ; goes through, because value after increment (2) is positive (swap! t (constantly -3)) ; throws exception (def v 10) (set-validator! (var v) pos?) (set-validator! t (partial < 10)) ; throws exception (set-validator! g (partial < 10)) ; throws exception (set-validator! r #(< % 10)...