2011-05-17 55 views
25

我很好奇爲什麼在守衛測試中逗號<,>是and而不是andalso的快捷方式。什麼時候在保護測試中傾向於`和```

因爲我稱自己爲「C native」,所以我沒有看到短路布爾評估的缺點。

我使用to_core標誌編譯了一些測試代碼,以查看實際生成的代碼。使用逗號,我看到左手的價值和權利和價值評估和兩個和。在andalso的情況下你有一個大小寫區塊,並且沒有致電erlang:and/2

我沒有做基準測試,但我敢說andalso變種更快。

回答

25

鑽研過去:

  • 原本在後衛只有,分離有測試這是從評估由左到右,直到有沒有更多的和防範成功或測試失敗了,整個後衛失敗了。後來增加了;以允許在同一條款中使用替代警衛。如果警衛在測試之前評估,的雙方,那麼有人在此過程中得到了錯誤。 @凱的例子似乎暗示他們確實應該從左到右。

  • 布爾運營商只能在後期才被允許。

  • and,連同orxornot,是布爾算子,並沒有打算用於控制。它們都是嚴格並首先評估它們的參數,如算術運算符+,-,*和'/'。 C中也存在嚴格的布爾運算符。

  • 的短路控制運營andalsoorelse後來加入到簡化一些代碼。正如你所說的那樣,編譯器確實將它們擴展爲嵌套的case表達式,所以在使用它們時沒有性能增益,只是代碼的方便和清晰。這將解釋你看到的結果代碼。

  • N.B.在後衛有測試而不是表達式。有細微的差別,這意味着在使用andandalso相當於使用orelse,不等同於;。這留給另一個問題。提示:這都是關於失敗。

因此,無論andandalso有自己的位置。

4

這是一個歷史原因。 and是在Erlang 5.1中引入的andalso之前實現的(我現在可以找到的唯一參考是EEP-17)。由於向後兼容,後衛沒有改變。

7

Adam Lindbergs link是對的。使用逗號確實生成比使用andalso更好的束碼。我編譯使用+ to_asm標誌下面的代碼:

a(A,B) -> 
    case ok of 
     _ when A, B -> true; 
     _ -> false 
    end. 
aa(A,B) -> 
    case ok of 
     _ when A andalso B -> true; 
     _ -> false 
    end. 

產生

{function, a, 2, 2}. 
    {label,1}. 
    {func_info,{atom,andAndAndalso},{atom,a},2}. 
    {label,2}. 
    {test,is_eq_exact,{f,3},[{x,0},{atom,true}]}. 
    {test,is_eq_exact,{f,3},[{x,1},{atom,true}]}. 
    {move,{atom,true},{x,0}}. 
    return. 
    {label,3}. 
    {move,{atom,false},{x,0}}. 
    return. 

{function, aa, 2, 5}. 
    {label,4}. 
    {func_info,{atom,andAndAndalso},{atom,aa},2}. 
    {label,5}. 
    {test,is_atom,{f,7},[{x,0}]}. 
    {select_val,{x,0},{f,7},{list,[{atom,true},{f,6},{atom,false},{f,9}]}}. 
    {label,6}. 
    {move,{x,1},{x,2}}. 
    {jump,{f,8}}. 
    {label,7}. 
    {move,{x,0},{x,2}}. 
    {label,8}. 
    {test,is_eq_exact,{f,9},[{x,2},{atom,true}]}. 
    {move,{atom,true},{x,0}}. 
    return. 
    {label,9}. 
    {move,{atom,false},{x,0}}. 
    return. 

我只能看着與+ to_core標誌生成了什麼,但顯然還有to_core之間的優化步驟to_asm。

4

布爾運算符「」和「」始終評估對運營商的兩側arguements。而如果你想C運算& &的功能||(其中第二arguement評估只有needed..for例如,如果我們想安勤「真否則別指望假」只要真正被發現是第一arguement,第二arguement將不被計算這是不是這樣的有 「」 被使用)去 「andalso」 和 「否則別指望」。

相關問題