Ich würde Beispiele in einer Lisp-Variante bevorzugen (Bonuspunkte für Clojure oder Scheme), da ich mich damit am besten auskenne, aber jedes Feedback zu DBC in funktionalen Sprachen wäre für die Gemeinschaft natürlich wertvoll.
Hier ist eine offensichtliche Möglichkeit:
(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)
Was mir an dieser Implementierung nicht gefällt, ist, dass die Vertragslogik die Kernfunktionalität verdeckt; der eigentliche Zweck der Funktion geht in bedingten Prüfungen verloren. Dies ist das gleiche Problem, das ich in diese Frage . In einer imperativen Sprache wie Java kann ich Annotationen oder in die Dokumentation eingebettete Metadaten/Attribute verwenden, um den Vertrag aus der Methodenimplementierung herauszulösen.
Hat sich jemand mit dem Hinzufügen von Verträgen zu Metadaten in Clojure beschäftigt? Wie würden Funktionen höherer Ordnung verwendet werden? Welche anderen Möglichkeiten gibt es?