Julia 是动态类型的吗?
Posted
技术标签:
【中文标题】Julia 是动态类型的吗?【英文标题】:Is Julia dynamically typed? 【发布时间】:2015-03-20 14:44:22 【问题描述】:很多博客和manual itself 都说Julia 是dynamically typed。 但是从我对手册的阅读来看,在我看来更像是 statically typed 和 type inference,比如 F#。
Julia 是否使用类型推断进行静态类型化? 是动态类型的吗? 我假设它是动态类型的,手册似乎不太可能是错误的。 Julia 中是否涉及类型推断?【问题讨论】:
【参考方案1】:Tim Holy 的回答非常正确,但我会详细说明一下。首先,让我们定义一些术语——你可能不同意我的定义,但至少你会知道我在说什么。在我看来,静态语言和动态语言的主要区别在于:在静态语言中,表达式有类型;在动态语言中,值具有类型。
在静态语言中,有一些规则可以确定程序中每个表达式的类型。表达式的类型决定了程序的行为。不允许为每个表达式确定一致类型的程序被认为是不正确的并且不会编译。在存在多态性的情况下,表达式的类型可能不是单一的具体类型:参数多态性可以被认为是让相同的代码描述整个具体类型算法家族的一种方式,这些算法由类型的参数索引;子类型多态性可以被认为是在静态语言中引入了有限数量的动态行为。
另一方面,动态语言没有将类型分配给表达式的规则:数据在执行时流经程序的方式隐含了类型。一般来说,表达式可能会产生任何类型的值。正因为如此,类型理论家有时将动态语言描述为“单一类型”——即从静态角度来看,“类型”本质上是表达式的属性,动态语言中的所有表达式都具有类型 Any
。当然,这是将静态类型概念(仅对表达式有意义)应用于类型概念仅对值有意义的语言。
Julia 完全属于动态阵营:类型是值而不是表达式的属性。代码的结果类型由执行时值如何流经它决定;该语言不包括在执行表达式之前为表达式分配类型的任何规则。然而,与许多动态语言不同,Julia 有一种相当复杂的语言来讨论类型,你可以用类型注释表达式。例如,x::T
是断言x
是T
类型的值;如果为真,x::T
的计算结果为 x
,否则将引发错误并且表达式不返回任何值。方法签名中的类型注释具有稍微不同的含义:它们不是断言现有值的类型,而是表明该方法仅在相应的参数属于指定类型时才适用。无论哪种情况,以下代码都可以安全地假定x
的值是T
类型。
[旁白:在某些具有“渐进”或“可选”类型的语言中,类型注释将语言从动态模式切换到静态模式:没有类型注释的方法是动态的;带有类型注释的方法是静态的。在静态代码中,有为所有表达式分配类型的规则,并且代码必须满足这些规则。这不是 Julia 的工作方式——带有类型注释的代码仍然是动态的,并且与没有类型注释的代码具有相同的语义。]
F#、OCaml 或 Haskell 等语言中的类型推断是确定表达式类型的一部分。如果编译器无法推断出任何表达式的类型,那么您的程序就会损坏并且无法编译。这些语言都使用某种形式的 Hindley-Milner 类型推断,这是一种非常聪明的方法,可以从代码结构中导出表达式类型,而无需写出显式类型(将其与类型隐含的动态语言进行比较代码的执行)。很多时候根本不需要类型注释,与 C++、C# 和 Java 等语言中可能需要的冗长类型声明相比,这非常令人愉快。然而,这与 Julia 和 Python 等不需要类型注释的动态语言非常不同,因为表达式没有预先确定的类型是完全可以接受的。在 Hindley-Milner 语言中,您可能不必像在 C++ 或 Java 中那样编写那么多类型,但每个表达式都必须具有编译器可以计算的预定类型。
Julia 的编译器会进行类型推断,但它非常不同:并非每个表达式都必须具有可推断的类型。编译器分析代码以尝试预测表达式的类型,并使用该信息生成更有效的机器代码。但是如果它不能确定表达式的类型,那也没什么大不了的:编译器只是使用运行时类型信息发出无论如何都可以工作的通用代码。在 Julia 中,大多数情况下,类型推断只是一种优化——无论有没有它,你的代码都会以相同的方式工作——但如果类型推断成功,它会运行得更快。
【讨论】:
删除类型注释并不会改变 Julia 程序的含义当然不是真的。当然可以,因为 Julia 的方法调度是如何工作的。 @Steven_Obua,我不相信我的回答说或暗示类型注释没有语义意义,是吗? 很棒且内容丰富的答案,但您确实会说“这不是 Julia 的工作方式——带有类型注释的代码仍然是动态的,并且与没有类型注释的代码的行为方式相同。” “行为相同”我的意思是“具有相同的语义”,但是,是的,我可以澄清这种区别。【参考方案2】:两者都是正确的。 Julia 是动态类型的,但在编写良好的 Julia 代码中,通常可以推断出类型。在可能的情况下,您通常会获得重大的性能提升。
有一些关于这个in the FAQ的讨论。
【讨论】:
【参考方案3】:它是动态类型的,但如果你指定一个变量::type 之类的类型,你可以认为该变量是静态类型的(这将在编译器无法自动推断类型的情况下提高性能)
【讨论】:
以上是关于Julia 是动态类型的吗?的主要内容,如果未能解决你的问题,请参考以下文章
集 PythonCRRuby 之所长,动态编程语言 Julia 1.0 正式发布