为什么+函数似乎对元组起作用?

时间:2017-04-06 17:30:18

标签: syntax julia

在两个Int64的元组上使用+函数返回总和:

julia> +((1, 2))
3

但是,在引用元组的变量上使用+函数会出现以下错误:

julia> a = (1, 2)
(1,2)
julia> +(a)
ERROR: MethodError: no method matching +(::Tuple{Int64, Int64})

我无法理解为什么它会像这样,特别是当以下代码返回true时。

julia> typeof(a) == typeof((1, 2))

1 个答案:

答案 0 :(得分:7)

请注意,与您的想法相反,

julia> :(+((1, 2)))
:(1 + 2)

这是一个等同于(+)(1, 2)的单个函数调用。没有元组,虽然语法可能看起来像有一个元组。 (正如您所指出的,+函数对元组不起作用。)这种行为是否合适?好吧它报告为bug #12755,但随后修复。但修复导致bug #12771导致修复被pull #12772还原。

解决这个问题的方法是避免在没有明确写括号的情况下将运算符作为函数调用。也就是说,始终写(+)(1, 2)而不是+(1, 2)。您可以验证(+)((1, 2))是否会引发您所期望的错误。

(这个问题只发生在一元运算符上,因此|*不受其约束的原因。)

如果您有兴趣,这个问题的核心是+(x, y)函数调用语法和一元运算符语法之间的基本歧义。以下是一些促使将+-解析为一元运算符的情况,即使后面跟(

  • -(x+y)^2中,(-)((x+y)^2)很可能是((-)(x+y))^2,而不是-(。因此,我们不能简单地无条件地将-解析为函数调用。
  • 相反,必须要做的是-x * y解析为某个优先级之后的事情,以便将(-x) * y解析为-x + y,将(-x) + y解析为-x^y },但-(x^y)-(1, 2)
  • 例外:但这会使(-)((1, 2))解析为-,即在元组上调用的函数。无论出于何种原因,决定在+(1, 2)之后的事物看起来像函数调用元组时添加一个例外。这样((1, 2))就可以了,但这实际上只是一个黑客。
  • 但从解析者的角度来看,(1, 2)看起来与-(1, 2)完全相同;只是前者用括号括起来。

我个人认为-(1, 2)^2符号是愚蠢的(并且无论如何都不适用于所有情况;例如在-(1, 2)中)。如果该异常不在,并且1 - 2一直被解析为元组上的一元函数调用,则可以在没有(我认为)大量丢失的情况下获得更大的一致性。在需要二进制函数调用时,只需编写(-)(1, 2)ReactiveVar就不错了。

相关问题