我目前正致力于设计一个受控实验 希望衡量动态类型编程语言的好处 与静态类型相比。
我不是在寻找另一个“哪个更好” - 在这里进行辩论 关于这个主题的讨论是否充分(例如 Dynamic type languages versus static type languages 要么 What do people find so appealing about dynamic languages?)。 我也问过关于LtU的同样问题,最后是另一个问题 讨论。 : - )
所有这些讨论都提到了一些好处,但几乎所有的都缺失了 一些具体的代码(!) - 证明了他们观点的例子。
所以我的问题是:你们中的任何人都可以给我一些示例代码吗? 直接揭示动态类型语言的一些好处或显示一个 静态类型系统更多是障碍而不是有用的情况 工具
提前致谢。
答案 0 :(得分:1)
定义:鸭子打字。但是你想要更具体的例子,让我们说:构建对象。在静态类型语言中,您需要声明类型或使用内置方法来生成运行时代码。在动态语言中,您可以专门构建对象。例如,要在groovy中创建一个模拟,你可以编写一个你需要模拟的方法并将其作为一个对象传递:http://groovy.codehaus.org/Developer+Testing+using+Closures+instead+of+Mocks
在静态语言中,人们编写大而复杂的库以使其更容易。而且它仍然很冗长,并且经常有局限性
答案 1 :(得分:0)
有一段时间,不久前,这些是我们必须做出的选择:我是否希望它能够快速而轻松地编写程序,但有时会有更多的运行时错误?或者我是否希望在编译时受到更多这些错误的保护,但代价是不得不浪费更多时间编写更多的样板?
现在已经结束了。当动态语言是避免为代码添加更多官僚作风的唯一方法时,动态语言非常令人兴奋,但动态类型现在正被类型推断所淘汰。所以你实际上是正确的 - 动态类型不再增加价值,现在更强大的强类型系统正在流行。
咦?哪里?怎么样?
像Haskell,ML,Scala,Rust和一些.NET系列这样的语言将强类型与类型推断相结合,因此您可以充分利用这两种语言:所有内容都具有强大的强制类型,但您不会除非编译器能够解决这个问题,否则必须将其写下来,这通常可以。
不要因为学业而忽视他们。事情变了。这些具有强大打字系统的语言在过去几年中越来越受欢迎。 (2)而且,我发现现在听到一种全新的语言越来越少见没有&运动结合了强类型的安全性和类型推断方便,至少在某种程度上。今天,全新的深奥语言是未来十年的企业标准"所以我认为每个人最终都会采用这种两全其美的方法。
即便是老人,Java正朝这个方向缓慢前进! (示例:菱形运算符;推断lambda表达式的功能接口)
现在第一次学习动态语言已经太晚了,就像整个20世纪90年代你推迟用CD播放器取代你的录音带一样,然后在2002年左右你就开始购买CD播放器了。
编辑:我重读了你的问题。我同情你对具体代码的渴望。这是罗塞塔石碑。检查列表是否已排序的通用过程,以及调用它的代码。调用它的代码每天都做正确的事情而在闰日做错事,作为一个例子,当你在很少执行的代码中遇到错误时,编译时错误如何在运行时错误中获胜。代码未经测试,只是草图。特别是,我还在学习Haskell(因此对新转换的......:P的热情)并没有像以前那样使用Python几年,所以原谅传统的静态输入:
// Java 7 - strong typing but no type inference
// Notice that you get safety, because the wrong usage is caught at compile time
// But you have to type a lot :-(
static interface Comparable { boolean compare(Comparable other); }
...
boolean isListSorted( List<T extends Comparable> xs ) {
T prev = null; for( T x: xs ) {
if( prev!=null && !prev.compare(xs) ) return false;
prev = x;
}
return true;
}
...
public final class String implement Comparable { ... }
public final class Animal /* definitely does not implement Comparable! :-) */ { ... }
...
// proper usage
List<String> names = Lists.newArrayListOf("Red", "Spinelli", "Ankh", "Morporkh", "Sam");
boolean areTheNamesSorted = isListSorted(names);
if(todayIsALeapDay()) {
// bad usage -- the compiler catches it, so you don't have to worry about this happening
// in production when a user enters data that send your app down a rarely-touched codepath
List<Animal> pets = Lists.newArrayListOf( Animal.getCat(), Animal.getDog(), Animal.getBird() );
boolean areTheNamesSorted = isListSorted(pets);
}
动态类型:
class Animal:
...
# Python 2.6 -- dynamic typing
# notice how little keystrokes are needed
# but the bug is now
def isListSorted(xs):
# to keep it more similar to the Java7 version, zip is avoied
prev = None
for x in xs:
if prev is not None and not prev.compare(x): return False
prev = x
return True
...
# usage -- beautiful, isn't it?
names = ["Raph", "Argh", "Marge"]
areNamesSorted = isListSorted(names)
if isLeapDayToday():
# ...but here comes trouble in paradise!
animals = [Animal.getCat(), Animal.getDog()]
# raises a runtime exception. I hope your unit tests catch it, but unlike type
# systems it's hard to make absolutely sure you'll be alerted if you forget a test
# besides, then you've just traded the Evil of Having to Write Lots of Type Signatures
# for the Evil of Having to Write Lots of Unit Tests. What kind of terrible deal is that?
areAnimalsSorted = isListSorted(animals)
强大的打字:
-- Haskell - full safety of strong typing, but easy on the fingers and eyes
class Comparable a where
compare :: a -> a -> Bool
end
instance Comparable String where
...
end
data Animal = ...
isListSorted [] = True
isListSorted x:[] = True
isListSorted x1:x2:xs = (compare x1 x2) && (isListSorted xs)
names = ["Raplph", "Argh", "Blarge"]
areNamesSorted = isListSorted names
animals = [Cat, Dog, Parrot]
-- compile time error because [Animal] is not compatible with Comparable a => [a] since
-- Animal is not an instance of comparable
areAnimalsSorted = isListSorted animals
详细强大的输入:
-- Same Haskell program as before, but we explicitly write down the types
-- Just for educational purposes. Like comments, you can omit them if you don't think
-- the reader needs them because it's obvious. Unlike comments, the compiler verifies their truth!
class Comparable a where
compare :: a -> a -> Bool
end
instance Comparable String where
...
end
data Animal = Cat | Dog | Parrot
isListSorted :: Ord a => [a] -> Bool
isListSorted [] = True
isListSorted x:[] = True
isListSorted x1:x2:xs = (compare x1 x2) && (isListSorted xs)
names :: [String]
names = ["Raplph", "Argh", "Blarge"]
areNamesSorted = isListSorted names
-- compile time error because [Animal] is not compatible with Comparable a => [a] since
-- Animal is not an instance of comparable
animals :: [Animal]
animals = [Cat, Dog, Parrot]
areAnimalsSorted = isListSorted animals