dav*_*lab 40 type-systems language-design static-typing typing dynamic-typing
简单的问题:我在编译语言(如C++/Java)和Python/Javascript等解释语言中进行了大量编程(专业和个人).我个人发现,当我使用静态类型语言编程时,我的代码几乎总是更强大.但是,我遇到的几乎所有解释语言都使用动态类型(PHP,Perl,Python等).我知道为什么编译语言使用静态类型(大多数时候),但我无法弄清楚解释语言设计中对静态类型的厌恶.
为什么陡峭断开?它是解释语言性质的一部分吗?OOP?
Pau*_*gar 48
有趣的问题.顺便说一句,我的作者/维护者PHC(编译器为PHP),和我做我的博士对编译器的动态语言,所以我希望我可以提供一些见解.
我认为这里有一个错误的假设.PHP,Perl,Python,Ruby,Lua等的作者没有设计"解释语言",他们设计了动态语言,并使用解释器实现了它们.他们这样做是因为解释器比编译器更容易编写.
Java的第一个实现被解释,它是一种静态类型语言.对于静态语言存在解释器:Haskell和OCaml都有解释器,并且过去常常是C的流行解释器,但这是很久以前的事了.它们很受欢迎,因为它们允许REPL,这可以使开发更容易.
也就是说,正如您所期望的那样,动态语言社区存在对静态类型的厌恶.他们认为C,C++和Java提供的静态类型系统是冗长的,不值得努力.我认为我在一定程度上同意这一点.使用Python编程比C++更有趣.
为了解决他人的观点:
dlamblin说:"我从来没有强烈地认为编译与解释有任何特殊之处,这表明动态的静态打字." 嗯,那里你错了.动态语言的编译非常困难.主要是eval要考虑的语句,它在Javascript和Ruby中广泛使用.phc提前编译PHP,但我们仍然需要一个运行时解释器来处理evals.eval也不能在优化编译器中静态分析,但如果你不需要健全,有一种很酷的技术.
对于damblin对Andrew Hare的回应:您当然可以在解释器中执行静态分析,并在运行时发现错误,这正是Haskell ghci所做的.我希望函数式语言中使用的解释器风格需要这样.dlamblin当然可以说分析不是解释的一部分.
安德鲁·哈尔的回答是基于提问者错误的假设,同样也有错误的方法.然而,他提出了一个有趣的问题:"动态语言的静态分析有多难?".非常非常努力.基本上,你将获得一个博士学位来描述它是如何工作的,这正是我正在做的事情.另见前一点.
到目前为止,最正确的答案是Ivo Wetzel.但是,他描述的要点可以在编译器中的运行时处理,并且Lisp和Scheme存在许多具有这种动态绑定的编译器.但是,是的,它很棘手.
我认为这是因为解释语言的本质,它们希望是动态的,所以你可以在运行时改变东西。因此,编译器永远无法确切知道执行下一行代码后程序的状态是什么。
想象一下以下场景(Python):
import random
foo = 1
def doSomeStuffWithFoo():
global foo
foo = random.randint(0, 1)
def asign():
global foo
if foo == 1:
return 20
else:
return "Test"
def toBeStaticallyAnalyzed():
myValue = asign()
# A "Compiler" may throw an error here because foo == 0, but at runtime foo maybe 1, so the compiler would be wrong with its assumption
myValue += 20
doSomeStuffWithFoo() # Foo could be 1 or 0 now... or 4 ;)
toBeStaticallyAnalyzed()
Run Code Online (Sandbox Code Playgroud)
正如您所希望看到的,编译器在这种情况下没有任何意义。实际上,它可能会警告您“myValue”可能不是数字的可能性。但在 JavaScript 中,这会失败,因为如果“myValue”是一个字符串,20 也会隐式转换为字符串,因此不会发生错误。因此,您可能会在各处收到数千个无用的警告,我认为这不是编译器的意图。
灵活性总是有代价的,你需要更深入地审视你的程序,或者更仔细地编程它,换句话说,在上述情况下你就是编译器。
那么你作为编译器的解决方案是什么呢?- 用“尝试:除了”修复它:)
| 归档时间: |
|
| 查看次数: |
5445 次 |
| 最近记录: |