2017-04-06 30 views
7

使用兩個Int64s的元組+函數返回的總和:爲什麼+函數似乎在元組上工作?

julia> +((1, 2)) 
3 

然而,在使用上引用一個元組提供了以下錯誤的變量的+功能:

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

我m很難理解爲什麼它的行爲如此,特別是當下面的代碼返回true時。

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

這很奇怪!我不知道爲什麼會發生這種情況,但我懷疑這是一種奇怪的「促進」的怪癖。爲了得到一個元組的總和,你可以使用'sum'函數。 'sum(a)' –

+0

我的猜測是它不會將'1,2'識別爲'Int64'。不知道'julia'是否允許類型轉換,但是如果它嘗試將你的元組轉換爲'(Int64,Int64)' –

+0

偉大的發現!你正在研究哪個版本的Julia? –

回答

6

需要注意的是,相反的是,你可能會認爲,

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)並不算太壞。

相關問題