0

随着动态类型语言的发展,因为它们给了我们更多的灵活性,人们很可能会编写超出规范允许范围的程序。

当我阅读bobince的答案时,我的想法受到了这个问题的影响: 关于JavaScript的切片和拼接方法的问题

基本思想是splice,在 Javascript 中,被指定为仅在某些情况下使用,但是,它可以在其他情况下使用,并且该语言无法阻止它,因为该语言被设计为非常灵活.

除非有人通读规范并决定遵守它,否则我相当肯定会发生许多此类违规行为。

这是一个问题,还是编写这种灵活语言的自然延伸?或者我们应该期望像 JSLint 这样的工具来帮助成为规范警察?

我喜欢这个问题的一个答案,python 的实现就是规范。我很好奇这是否真的更接近这些类型的语言的真相,基本上,如果语言允许你做某事,那么它在规范中。 有 Python 语言规范吗?

更新:

在阅读了一些评论之后,我想我会检查规范中的拼接方法,这就是我在 pg 104 底部找到的,http://www.mozilla.org/js/language/E262-3。 pdf,所以看来我可以在不违反规范的情况下在子数组上使用拼接。我只是不希望人们在我的示例中陷入困境,但希望能够考虑这个问题。

    The splice function is intentionally generic; it does not require that its this value be an Array object. 
Therefore it can be transferred to other kinds of objects for use as a method. Whether the splice function 
can be applied successfully to a host object is implementation-dependent.

更新 2: 我对 JavaScript 不感兴趣,但对语言灵活性和规范不感兴趣。例如,我希望 Java 规范指定您不能将代码放入接口中,但使用 AspectJ 我经常这样做。这可能是一种违规,但作者并没有预测到 AOP,并且该工具足够灵活,可以用于此用途,就像 JVM 也足够灵活,可用于 Scala 和 Clojure。

4

4 回答 4

1

一种语言是静态类型的还是动态类型的实际上只是这里问题的一小部分:静态类型的语言可能会使代码更容易执行其规范,但这里的关键词却很少。只有“契约式设计”——一种让您明确声明前置条件、后置条件和不变量并强制执行的语言它们——可以帮助你对抗你的图书馆的用户,凭经验发现图书馆究竟会让他们逃脱,并利用这些发现超越你的设计意图(可能限制你未来改变设计或其实现的自由)。主流语言不支持“按合同设计”——埃菲尔是最接近的,现在很少有人称它为“主流”——大概是因为它的成本(主要是,不可避免地,在运行时)似乎不是以其优势为由。“参数 x 必须是素数”,“方法 A 必须在调用方法 B 之前已经被调用”,“方法 C 不能再调用,一旦方法 D 被调用”,等等——典型的种类约束你'声明(并且已经隐式执行,而不必自己花费大量的编程时间和精力来检查它们)只是不适合在静态类型语言的编译器可以执行的很少的上下文中构建。

于 2009-11-28T01:46:42.633 回答
0

我认为,只要您的方法是围绕定义良好的接口而不是一些人为的外部“类型”元数据设计的,这种灵活性就是一个优势。大多数数组函数只需要一个具有长度属性的对象。它们都可以通用地应用于许多不同类型的对象这一事实是代码重用的福音。

任何高级语言设计的目标都应该是减少为完成工作而需要编写的代码量,同时又不会过多地损害可读性。必须编写的代码越多,引入的错误就越多。限制性类型系统(如果设计得不好)在最坏的情况下可能是一个普遍的谎言,在最好的情况下是过早的优化。我不认为过于严格的类型系统有助于编写正确的程序。原因是类型只是一个断言,不一定基于证据。

相比之下,数组方法检查它们的输入值以确定它们是否具有执行其功能所需的东西。这是鸭式打字,我相信这更科学和“正确”,它会产生更多可重用的代码,这就是你想要的。您不希望有一种方法拒绝您的输入,因为他们的论文没有按顺序排列。那是共产主义。

于 2009-11-28T01:23:51.827 回答
0

在我看来,最初的问题有点无关紧要。如果规范明确允许特定行为(如必须、可能、应该或应该),那么根据定义,任何允许/实现该行为的编译器/解释器都符合该语言。这似乎是 OP 在评论部分提出的情况 - JavaScript 规范应该*说有问题的函数可以在不同的情况下使用,因此它是明确允许的。

另一方面,如果编译器/解释器实现或允许规范明确禁止的行为,则根据定义,编译器/解释器在规范之外运行。

还有第三种情况,以及一个相关的、定义明确的术语,用于规范未定义行为的情况:未定义。如果规范实际上并未指定特定情况下的行为,则该行为是未定义的,并且可能由编译器/解释器有意或无意地处理。然后开发人员有责任意识到该行为不是规范的一部分,并且如果她/他选择利用该行为,则开发人员的应用程序因此依赖于特定的实现。提供该实现的解释器/编译器没有义务维护官方未定义的行为,除了向后兼容性和生产者可能做出的任何承诺。此外,

*“据说”是因为我自己没有看过规范。我按照上面的陈述进行。

于 2009-11-28T01:39:09.690 回答
0

我认为您的问题与动态与静态类型没有太大关系。真的,我可以看到两种情况:一方面,马丁克莱顿提到的达夫装置之类的东西;这种用法在您第一次看到时会非常令人惊讶,但语言的语义明确允许这种用法。如果有标准,这种成语可能会作为具体例子出现在标准的后续版本中。这些没有错;事实上,它们可以(除非过度使用)极大地提高生产力。

The other case is that of programming to the implementation. Such a case would be an actual abuse, coming from either ignorance of a standard, or lack of a standard, or having a single implementation, or multiple implementations that have varying semantics. The problem is that code written in this way is at best non-portable between implementations and at worst limits the future development of the language, for fear that adding an optimization or feature would break a major application.

于 2009-11-28T01:54:40.877 回答