I would prefer the examples to be in the Lisp variant (bonus points for Clojure or the scheme) since I am most familiar, but any feedback regarding DBC in functional lanugages would certainly be valuable to the larger community.
Here is the obvious way:
(defn foo [action options] (when-not (#{"go-forward" "go-backward" "turn-right" "turn-left"} action) (throw (IllegalArgumentException. "unknown action"))) (when-not (and (:speed options) (> (:speed options) 0)) (throw (IllegalArgumentException. "invalid speed"))) ; finally we get to the meat of the logic)
What I don't like about this implementation is that the logic of the contract hides the core functions; the true purpose of the function is lost in conditional checks. This is the same problem that I raised in this matter . In an imperative language such as Java, I can use annotations or metadata / attributes built into the documentation to transfer the contract from the method implementation.
Has anyone looked at adding metadata contracts to Clojure? How to use higher order functions? What other options are there?
functional-programming clojure scheme design-by-contract
rcampbell
source share