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 a new value as argument and returns a logical true on success, or throws exception/returns a logical false (false
and nil
values) on error. They all honor what the validator function returns. On success, the update goes through and on encountering an error, an exception is thrown instead. The following is the syntax of how 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, value after increment (2) is positive (swap! t (constantly -3)) ; throws exception (def v 10) (set-validator! (var v) pos?) (set-validator! t #(>= % 10)) (set-validator! g #(>= % 10)) (set-validator! r #(>= % 10))
Validators cause actual failure within a reference type while updating...