A failing in a predicate in a list of {{:pre}} or {{:post}} conditions currently causes messages similar to one below to be displayed:
(defn must-be-a-map [m] {:pre [(map? m)]} m)
(must-be-a-map [])
;;=> AssertionError Assert failed: (map? m) user/must-be-a-map (form-init.....clj:1)
These exception messages could be made significantly more descriptive by allowing specific messages strings to be associated with each predicate in {{:pre}} and {{:post}} conditions.
Predicate functions and there associated messages strings could be specified as a pair of values in a map:
(defn must-be-a-map
[m]
{:pre [{(map? m) "m must be a map due to some domain specific reason."}]}
m)
The following would then produce an error message as follows:
(must-be-a-map 10)
AssertionError Assert failed: m must be a map due to some domain specific reason.
(map? m) user/must-be-a-map (form-init.....clj:1)
This would allow predicates without messages to specified alongside pairs of associated predicate message pairs as follows:
(defn n-and-m [n m] {:pre [(number? n) {(map? m) "You must provide a map!"}]})
This change would not break any existing functionality and still allow for predicates to be predefined elsewhere in code.
As a result pre and post conditions could provide a natural means of further documenting the ins and outs of a function, simplify the process of providing meaningful output when developing libraries and perhaps make the language better suited to teaching environments[1]
[1]
http://wiki.science.ru.nl/tfpie/images/2/22/TFPIE2013_Steps_Towards_Teaching_Clojure.pdf