我正在浏览球拍指南,刚刚完成此页面:
https://docs.racket-lang.org/guide/contracts-first.html
由此产生的合同是如此令人费解,以至于我无法相信自己的眼睛:
(provide
(contract-out
[argmax
(->i ([f (-> any/c real?)] [lov (and/c pair? list?)]) ()
(r (f lov)
(lambda (r)
(cond
[(empty? (rest lov)) (eq? (first lov) r)]
[else
(define f@r (f r))
(define flov (map f lov))
(and (is-first-max? r f@r (map list lov flov))
(dominates-all f@r flov))]))))]))
我敢打赌,这份合同的复杂程度远高于所需的实际执行情况,尽管这份合同实际上并没有透露任何实施细节。更让我感到困惑的是,合同甚至不是编译时组件,就像Curry-Howard同构通过类型系统对属性的证明一样,所以它在任何意义上都不是认证编程方法,并且具有运行时效果。在这种复杂程度的情况下,我认为签订合同没有任何好处,比如一些简单的数据类型检查,我可以看到它更有意义。
你能指出我错过了这种合同的必要性吗?r
答案 0 :(得分:1)
这是文件;文件的重点是尽可能多地涵盖合同制度的特征。
假设我烤婚礼蛋糕。我想告诉你你的婚礼蛋糕上可以有什么样的东西,所以我用你可能做的每一种装饰做一个蛋糕,然后把它放在一个简单的底座上 - 甚至可能是一块纸板。你会看看这个蛋糕并抱怨它太花哨吗?不,重点是这是一个功能菜单;阅读本文档后,您应该能够理解所有不同部分的功能。
答案 1 :(得分:1)
您链接的页面开始:
7.4合同:一个完整的例子
本节为一个和另一个开发了几种不同的合同 相同的例子:球拍的argmax功能。
最终的味道是最彻底的(“复杂的”)。
您似乎认为该网页试图说服合同是“必需品”。我没有看到。我看到它解释了什么是可能与合同有关 - 如果/ as /当你认为收益超过成本时。如果你认为永远不会,那很好。
为了它的价值,我已经阅读了相当数量的球拍代码,而且我很少看到这么复杂的合同。此外,Racketeers非常清楚合同的运行成本;通常人们只在重要的“边界”使用它们。
最后,如果您更喜欢静态类型,您可能更喜欢Typed Racket。请注意,您可以混合使用动态和静态类型的Racket模块。为了确保静态类型不变量,边界受......契约的保护。