私が最もよく知っているのはLispバリアント(ClojureまたはSchemeのボーナスポイント)の例であることが望ましいですが、機能言語でのDBCに関するフィードバックは、もちろん、より大きなコミュニティにとって価値があります。
明らかな方法は次のとおりです。
(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)
この実装について私が気に入らないのは、コントラクトロジックがコア機能を覆い隠していることです。関数の真の目的は、条件付きチェックで失われます。これは、この質問で提起したのと同じ問題です。Javaのような命令型言語では、ドキュメントに埋め込まれたアノテーションまたはメタデータ/属性を使用して、メソッドの実装からコントラクトを移動できます。
Clojureのメタデータにコントラクトを追加することを検討した人はいますか?高階関数はどのように使用されますか?他にどのようなオプションがありますか?