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

Luk*_*ham 7 syntax julia

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

julia> +((1, 2))
3
Run Code Online (Sandbox Code Playgroud)

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

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

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

julia> typeof(a) == typeof((1, 2))
Run Code Online (Sandbox Code Playgroud)

Fen*_*ang 7

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

julia> :(+((1, 2)))
:(1 + 2)
Run Code Online (Sandbox Code Playgroud)

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

这种混乱的解决方案是避免在没有明确写括号的情况下将运算符作为函数调用.也就是说,总是写(+)(1, 2)而不是+(1, 2).您可以验证是否会(+)((1, 2))引发您期望的错误.

(这个问题只发生在一元运算符上,因此为什么|而且*不受它约束.)


如果您感兴趣,这个问题的核心是+(x, y)函数调用语法和一元运算符语法之间的基本歧义.以下是一些激发解析+-一元运算符的情况,即使遵循以下情况(:

  • -(x+y)^2,很可能(-)((x+y)^2)意味着,而不是((-)(x+y))^2.所以我们不能简单地无条件地解析-(为函数调用.
  • 相反,必须要做的是在-解析为某个优先级之后的事情,因此将-x * y其解析为(-x) * y,-x + yas (-x) + y,但是-x^yas -(x^y).
  • 例外:但这会使-(1, 2)解析为(-)((1, 2)),即一个在元组上调用的函数.无论出于何种原因,决定在-看起来像函数调用元组之后添加一个异常.这是+(1, 2)可行的,但这实际上只是一个黑客.
  • 但从解析器的角度来看,((1, 2))看起来很像(1, 2); 只是前者用括号括起来.

我个人认为,这种-(1, 2)符号很愚蠢(并且无论如何都不适用于所有情况;例如-(1, 2)^2).如果不存在该异常,并且-(1, 2)一致地将其解析为元组上的一元函数调用,则可以在没有(我认为)很多损失的情况下获得更大的一致性.只是编写1 - 2(-)(1, 2)需要二进制函数调用时并不是太糟糕.