Racket Scheme的“按合同设计”与Eiffel有何不同?

| 我知道Eiffel(祖先)和Racket都可以实现“按合同设计”功能。可悲的是,我不确定一个与另一个有何不同。埃菲尔(Eiffel)的DBC依赖于OOP范式和继承,但是,非常不同的语言Racket如何解释这种差异呢?     
已邀请:
Racket赢得合同声誉的主要主张是怪罪的概念,并且肯定地,处理ho函数是日常Racket编程的重要组成部分。 您可能还需要查看本文的前两部分: http://www.ccs.neu.edu/scheme/pubs/oopsla01-ff.pdf     
首先,这时您最好的信息来源是《球拍指南》,该指南旨在作为介绍性文本,而非参考手册。具体来说,有一章关于合同的广泛章节会有所帮助。编辑:还看到罗比指出的论文,他是球拍合同的主要负责人。 关于您的问题-我对Eiffel合同系统了解不多,但我认为它先于Racket的系统。但是,(又是一个“ IIRC”),我认为Racket的合同系统是第一个引入高阶合同的系统。具体来说,当您处理高阶函数时,分配适当的责备会变得更加复杂-例如,如果您使用具有
X? -> Y?
合同的
foo
函数,并且向其发送的值与ѭ2match不匹配,则客户端将此值发送到“ 0”的代码应归咎于此。但是,如果您的函数是
(X? -> Y?) -> Z?
且不满足
X?
谓词,则责任归于
foo
本身,而不是客户(如果不满足
Y?
,则责任仍由客户承担)。     
我想您是在问,没有OOP和继承的合同系统如何工作?作为不熟悉Eiffel的Racket的用户,我想知道为什么合同系统与OOP和继承有关。 :) 从实际的角度来看,我认为Racket契约是一种在保持动态类型语言灵活性的同时获得静态类型声明的某些好处的方法。另外,合同不仅限于类型,还可以充当断言的角色。 例如,我可以说一个函数需要一个参数,它是一个精确的整数...但也可以说它应该是一个精确的正整数,或者是某些特定值的并集,或者实际上是对传递的值进行任何任意复杂的测试。这样,Racket中的合同就可以将您在(a)类型声明和(b)C / C ++中的断言两者结合起来。 在球拍中与合同打交道的一个陷阱是,它们可能很慢。一种解决方法是,在开发时首先使用它们,然后有选择地将其删除,尤其是从“内循环”类型的函数中删除它们。我尝试过的另一种方法是打开/关闭它们:制作对模块,例如Contracts-on.rkt和contract-off.rkt,后者提供一些不做任何事情的宏。让您的模块需要使用Contracts.rkt,该文件可以提供-on或-off文件中的全部文件。这就像在DEBUG vs RELEASE模式下进行编译。 如果您来自埃菲尔铁塔,也许我对Racket合同的C / C ++倾向不会有帮助,但我还是想与您分享。     

要回复问题请先登录注册