从静态打字到动态打字

时间:2009-09-28 22:23:05

标签: java c++ ruby clojure type-systems

我一直致力于静态类型语言(C / C ++,Java)。我一直在玩Clojure,我真的很喜欢它。

我担心的一件事是:假设我有一个窗口,需要3个模块作为参数,并且需求发生变化,我需要将另一个模块传递给该函数。我只是更改了函数,编译器在我使用它的任何地方都会抱怨。但在Clojure中,在调用函数之前不会抱怨。我可以做一个正则表达式搜索和替换,但似乎有机会错过一个调用,它将被忽视,直到该函数实际被调用。你们怎么处理这个?

8 个答案:

答案 0 :(得分:8)

这是动态类型语言中自动化测试/测试驱动开发更为重要的原因之一。我没有使用Clojure(我主要使用Ruby),所以不幸的是我不推荐一个特定的测试框架。

答案 1 :(得分:3)

我要提的第一件事是Bruce Eckel撰写了一篇非常有趣的文章,名为Strong Typing vs Strong Testing(不幸的是,该链接目前正在关闭,但希望它会快点起来。)

他的想法是,在处理编译语言时,编译器只是自动测试的第一个自动步骤。当转向动态语言时,您将失去第一级自动测试。但在这两种情况下,第一个自动水平只是测试的一部分,甚至不是一个非常重要的部分。

他的观点是,如果你正在正确地开发程序,即进行某种形式的测试和回归测试,缺少编译器只会迫使你添加一些更基本的测试,这就是为什么它不大损失。

所以我想我给你的第一个答案是,专注于你的测试,你应该做的事情,这些改变不应该对你造成太大影响。

我要提到的第二件事是我见过的许多动态语言(例如,Python)在不破坏现有代码的情况下,能够更好地更改方法/类的功能。

例如,对于Python,如果您的方法用于接受两个参数但现在需要第三个参数,则可以始终添加默认参数而不破坏任何现有代码,但现在可以使用。这是一种非常基本的技术,但在Python的情况下(我还假设大多数其他动态语言),这些技术可以变得更有趣;因为它们是动态的,你几乎可以改变特定模块的函数实现,改变变量的含义等等。

我建议看看Clojure有哪些技术允许类似的东西,并决定它们是否适用于你的情况。

答案 2 :(得分:2)

如果该方法是您不是唯一用户的公共接口的一部分,那么您执行的操作与此相同。

您使用额外模块添加新方法,并更改旧方法以使用合适的默认值调用新方法。

哦,如果你的程序很大,请确保你有好的测试(测试 - 应该比Java更简单)

答案 3 :(得分:1)

测试覆盖率绝对重要。但是动态类型语言将允许您以不同的方式工作。在强类型语言(如Java)中,接口的更改需要修改所有调用者。在Ruby中,你可以这样做 - 但可能不会。相反,您可能会通过以下几种方式之一为方法增加灵活性。即:

  • 你往往只有很少的方法在Ruby中使用多达三个参数(而不是Java)。因为您没有强大的Java类型接口,所以您可以将问题分解为更小的部分和步骤。编写仅占用1个参数的方法更为常见,然后在它变得更复杂时进行重构。
  • 在添加更多参数的同时保留旧行为是可能的 - 也是常见的。例如,如果必须向两个参数方法添加第三个参数,则将设置其默认值以保留旧行为(并保存重构)。如果您熟悉jQuery之类的Javascript库,那么他们可以通过“可选”参数随处利用它。
  • 类似于可选参数,方法可以增长以获取灵活的参数列表。通过可靠的测试覆盖,您可以非常轻松地向现有方法添加新行为,并安全地知道您没有破坏现有代码。在Rails中,像“render”这样的方法有很多选项。

答案 4 :(得分:1)

在Clojure中你并不完全没有编译器支持。在您给出的具体示例中,它是更改的函数的arity,可以通过编译Clojure代码来获取。我仍然坚强 - >动态打字转换,找到这个安慰!

答案 5 :(得分:0)

当您转向动态语言时,您会失去一定程度的重构和类型安全性。编译器拥有的信息越多,它在编译时就能为您做的越多。

答案 6 :(得分:0)

Tim Bray讨论here,Cedric对here的批评,以及关于artima的post的讨论。

答案 7 :(得分:0)

如果你真的需要静态类型,你可以使用https://github.com/clojure/core.typed和它的leiningen模块来测试静态变量传递。