首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么动态类型经常与解释语言联系在一起?

问为什么动态类型经常与解释语言联系在一起?
EN

Stack Overflow用户
提问于 2009-09-08 13:00:36
回答 7查看 6.9K关注 0票数 44

简单的问题:我用编译语言(如C++/Java )和解释语言(如Python/Javascript )进行了大量的编程(专业的和个人的)。我个人发现,当我用静态类型语言编程时,我的代码几乎总是更健壮。但是,我遇到的几乎每种解释语言都使用动态类型(PHP、Perl、Python等)。我知道为什么编译语言使用静态类型(大多数时候),但我不明白在解释语言设计中对静态类型的反感。

为什么会出现这种陡峭的脱节?这是解释型语言的一部分吗?OOP?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-09-11 22:27:47

这个问题很有趣。顺便说一句,我是phc (PHP编译器)的作者/维护者,我正在做动态语言编译器的PhD工作,所以我希望我能提供一些见解。

我认为这里有一个错误的假设。PHP、Perl、Python、Ruby、Lua等的作者并没有设计“解释型语言”,他们设计了动态语言,并使用解释器来实现它们。他们这样做是因为解释器比编译器更容易编写。

Java的第一个实现是解释的,它是一种静态类型的语言。静态语言的解释器确实存在: Haskell和OCaml都有解释器,曾经有一个流行的C解释器,但那是很久以前的事了。它们之所以流行,是因为它们允许使用REPL,这可以使开发变得更容易。

也就是说,正如您所预期的那样,在动态语言社区中存在对静态类型的反感。他们认为由C,C++和Java提供的静态类型系统是冗长的,不值得努力。我想我在一定程度上同意这一点。用Python编程要比用C++有趣得多。

要解决其他人的观点:

  • dlamblin says:“我从来没有强烈地感觉到编译和解释有什么特别之处,那就是动态而不是静态类型。”那你就大错特错了。编译动态语言是非常困难的。主要需要考虑的是eval语句,它在Javascript和Ruby中被广泛使用。phc提前编译PHP,但我们仍然需要一个运行时解释器来处理eval。eval也不能在优化编译器中进行静态分析,尽管如果你不需要健壮性,有一个cool technique。
  • to damblin对Andrew Hare的响应:你当然可以在解释器中执行静态分析,并在运行前发现错误,这正是Haskell的ghci所做的。我希望函数式语言中使用的解释器风格需要这样做。dlamblin说分析不是interpretation.
  • Andrew Hare's answer的一部分,这当然是正确的,这是基于提问者错误的假设,同样也有错误的方式。然而,他提出了一个有趣的问题:“动态语言的静态分析有多难?”非常非常难。基本上,你会得到一个PhD来描述它是如何工作的,这正是我正在做的。
  • 到目前为止,最正确的答案是Ivo Wetzel的答案。但是,他描述的这些点可以在运行时在编译器中处理,并且存在许多具有这种动态绑定类型的Lisp和Scheme编译器。但是,是的,这很棘手。
票数 54
EN

Stack Overflow用户

发布于 2009-09-08 14:34:27

我认为这是因为解释型语言的本质,他们希望是动态的,这样你就可以在运行时改变事情。因此,在执行完下一行代码后,编译器永远不会确切地知道程序的状态。

想象一下以下场景(在Python中):

代码语言:javascript
复制
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()

正如您希望看到的,编译器在这种情况下不会有任何意义。实际上,它可能会警告您"myValue“可能不是数字。但在JavaScript中,这将失败,因为如果"myValue“是一个字符串,20也会隐式地转换为字符串,因此不会发生错误。所以你可能会收到成千上万的无用的警告,我不认为这是一个编译器的意图。

灵活性总是要付出代价的,你需要更深入地研究你的程序,或者更仔细地对它进行编程,换句话说,在上述情况下,你就是编译器。

那么你作为编译器的解决方案呢?-用"try: except“来修复它:)

票数 5
EN

Stack Overflow用户

发布于 2009-09-08 13:04:56

解释语言使用动态类型,因为没有编译步骤来执行静态分析。编译语言在编译时进行静态分析,这意味着任何类型错误都会在开发人员工作时报告给开发人员。

如果您认为静态类型语言具有在执行上下文之外强制执行类型规则的编译器,则更容易理解。解释型语言从来不是静态分析的,因此类型规则必须由解释器在执行上下文中强制执行。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1393883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档