Я бы предпочел, чтобы примеры были в варианте Лиспа (бонусные баллы для Clojure или Scheme), так как это то, что я больше всего знаю, но любые отзывы о DBC в функциональных lanugages, конечно, были бы ценны для большего сообщества.Как вы можете реализовать дизайн по контракту на Clojure специально или функциональных языках в целом?
Вот очевидный способ:
(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)
Что мне не нравится эта реализация является то, что контракт логика затеняет основные функциональные возможности; истинная цель функции теряется при условных проверках. Это та же проблема, которую я поднял в this question. На императивном языке, таком как Java, я могу использовать аннотации или метаданные/атрибуты, встроенные в документацию, чтобы перенести контракт из реализации метода.
Кто-нибудь смотрел на добавление контрактов на метаданные в Clojure? Как использовать функции более высокого порядка? Какие еще существуют варианты?
Вы смотрели на то, как контракты реализуются в PLT-схеме? Взглянуть. http://docs.plt-scheme.org/guide/contracts.html –
@Alexey - Это захватывающий ресурс! Я довольно новичок в Scheme (работая через The Little/Seasoned books), и я не знал, что это существовало, так что спасибо. – rcampbell
Непосредственно ответ на ваш вопрос, но посмотрите QuickCheck и его производные (ClojureCheck). Это, в основном, тестирование на основе свойств, а в контрактах вы определяете свойства, чтобы вы могли легко сгенерировать тесты. – Masse