Julia是否动态输入?

时间:2015-01-21 22:33:00

标签: types type-inference julia

很多博客和manual itself都说Julia是dynamically typed。 但是从我对手册的阅读中,听起来更像是它 statically typedtype inference F#,{{3}}。

  • Julia是否通过类型推断进行静态输入?
  • 是动态输入的吗?
  • 我假设它是动态类型的,手册似乎不太可能出错。
  • Julia中是否涉及类型推断?

4 个答案:

答案 0 :(得分:93)

Tim Holy的答案非常正确,但我会详细说明一下。首先,让我们定义一些术语 - 你可能不同意我的定义,但至少你会知道我在说什么。在我看来,静态语言和动态语言之间的主要区别在于:在静态语言中,表达式具有类型;在动态语言中,值具有类型。

在静态语言中,有一些规则可用于确定程序中每个表达式的类型。表达式的类型决定了程序的行为。不允许为每个表达式确定一致类型的程序被认为是不正确的,不会编译。在存在多态性的情况下,表达式的类型可能不是单一的具体类型:参数多态可以被认为是让相同的代码描述由类型的参数索引的具体类型算法的整个族的一种方式;子类型多态性可以被认为是将有限量的动态行为引入到静态语言中。

另一方面,

动态语言没有将类型分配给表达式的规则:数据在执行时执行的方式隐含了类型。通常,表达式可能会产生任何类型的值。因此,类型理论家有时将动态语言描述为“统一” - 即从静态角度来看,“类型”本质上是表达式的属性,动态语言中的所有表达式都具有类型Any。当然,这是将类型的静态概念 - 仅对表达式有意义 - 应用于一种语言,其中类型的概念仅对值有意义。

朱莉娅正处于动态阵营中:类型是价值而不是表达的属性。结果类型的代码由值在执行时如何流过它来确定;该语言不包括在执行表达式之前为表达式分配类型的任何规则。然而,与许多动态语言不同,Julia有一种相当复杂的语言来讨论类型,你可以使用类型来注释表达式。例如,x::T是一个断言,xT类型的值;如果是,则x::T计算为x的值,否则引发错误,表达式不返回任何值。方法签名中的类型注释具有略微不同的含义:它们表示该方法仅适用于相应参数属于指定类型的情况,而不是断言现有值的类型。在任何一种情况下,以下代码都可以安全地假设x的值为T类型。

[旁白:在某些使用“渐进”或“可选”类型的语言中,键入注释会将语言从动态切换为静态模式:没有类型注释的方法是动态的;类型注释的方法是静态的。在静态代码中,存在用于将类型分配给所有表达式的规则,并且代码必须满足这些规则。这不是Julia的工作方式 - 带有类型注释的代码仍然是动态的,并且与没有类型注释的代码具有相同的语义。]

F#,OCaml或Haskell等语言中的类型推断是如何确定表达式类型的一部分。如果编译器无法推断任何表达式的类型,则程序将被破坏且无法编译。这些语言都使用某种形式的Hindley-Milner类型推断,这是从代码结构中派生表达式类型的一种非常聪明的方法,而不必写出显式类型(将其与动态语言进行比较,其中类型是隐含的)执行代码)。很多时候根本不需要类型注释,与在C ++,C#和Java等语言中可能需要的冗长类型声明相比,这是非常令人愉快的。然而,这与Julia和Python等动态语言非常不同,因为它们不需要类型注释,因为它对于没有预定类型的表达式是完全可以接受的。在Hindley-Milner语言中,您可能不必编写与C ++或Java中类似的类型,但每个表达式都具有编译器可以计算的预定类型。

Julia的编译器进行类型推断,但它是非常不同的:每个表达式都没有必要具有可推断的类型。编译器分析代码以尝试预测表达式的类型,并使用该信息生成更高效的机器代码。但是如果它无法确定表达式的类型,那就没什么大不了的了:编译器只使用运行时类型信息发出无论如何都会工作的通用代码。在Julia中,大多数情况下,类型推断只是一种优化 - 无论是否使用它,您的代码都将以相同的方式工作 - 但是通过成功的类型推断,它将运行得更快。

答案 1 :(得分:27)

两者都是真的。 Julia是动态类型的,但在编写良好的julia代码中,通常可以推断出类型。在可能的情况下,您通常会获得重大的性能提升。

对此in the FAQ进行了一些讨论。

答案 2 :(得分:2)

它是动态类型的,但是如果指定类型为变量:: type,则可以将该变量视为静态类型(这将在编译器无法自动推断类型的情况下提高性能)

答案 3 :(得分:0)

以下摘自Getting Started with Julia Programming Language book

  

指示用于限制的参数类型也很有用   调用时传递的参数类型。我们的函数头   然后浮点数看起来像函数mult(x :: Float64,   Ÿ:: Float64)。当我们用mult(5,6)调用这个函数时,我们收到一个   错误,错误:' mult'没有匹配mult(:: Int64,:: Int64)的方法,   证明朱莉娅确实是一种强类型语言。它不是   接受浮点参数的整数参数。

这是本书中的示例函数:

function mult(x::Float64, y::Float64)
  x * y
end
mult(5, 6) # raises an error
mult(5.0, 6.0) # => 30.0

我不确定这本书是否正确,但它与所有其他答案相矛盾。