Julia是否动态输入?

Lyn*_*ite 65 types type-inference julia

许多博客和手册本身都说Julia是动态类型的.但是从我的手册的阅读,它的声音,我更喜欢它是 静态类型类型推断,像F# .

  • Julia是否静态输入类型推断?
  • 它是动态输入的吗?
  • 我假设它是动态类型的,手册似乎不太可能出错.
  • 类型推断是否涉及朱莉娅?

Ste*_*ski 103

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

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

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

朱莉娅正处于动态阵营中:类型是价值而不是表达的属性.结果类型的代码由值在执行时如何流过它来确定; 该语言不包括在执行表达式之前为表达式分配类型的任何规则.然而,与许多动态语言不同,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中,大多数情况下,类型推断只是一种优化 - 您的代码在使用或不使用时都会以相同的方式工作 - 但是通过成功的类型推断,它将运行得更快.

  • @Steven_Obua,我不相信我的回答说或暗示类型注释没有语义意义,是吗? (4认同)
  • “行为相同”是指“具有相同的语义”,但是,是的,我可以澄清这种区别。 (4认同)
  • 删除类型注释不会改变Julia程序的含义当然是不正确的。当然可以,因为Julia的方法分派是如何工作的。 (2认同)

tho*_*oly 27

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

常见问题解答中对此进行了一些讨论.