2013-07-13 9 views
5

erlang:'and'(true, false)のようなプレフィックスブール式を書くことはできますが、対応するandalsoまたはorelseの式はできません。どうして?andalso/2が適切なBIFとして実装されていないのはなぜですか?

私はコア出力を見ると、それはandalsoorelseのように見えるだけのマクロである - 例えば:

a(A,B) -> A and B. 

はコア

'a'/2 = 
    %% Line 4 
    fun (_cor1,_cor0) -> 
     call 'erlang':'and' 
      (_cor1, _cor0) 

に変換けどandalsoは

から行きます
b(A,B) -> A andalso B. 

~

'b'/2 = 
    %% Line 6 
    fun (_cor1,_cor0) -> 
     (case _cor1 of 
      (<('true' 
       -| ['compiler_generated'])> when 'true' -> 
        _cor0 
       -| ['compiler_generated']) 
      (<('false' 
       -| ['compiler_generated'])> when 'true' -> 
        'false' 
       -| ['compiler_generated']) 
      (<_cor2> when 'true' -> 
        (call ('erlang' 
          -| ['compiler_generated']):('error' 
                 -| ['compiler_generated']) 
         (({('badarg' 
           -| ['compiler_generated']),_cor2} 
          -| ['compiler_generated'])) 
        -| ['compiler_generated']) 
       -| ['compiler_generated']) 
      end 
      -| ['compiler_generated']) 

これは怠惰を防ぐためにこのように実装されているようですが、この手順にする必要はありません。後で翻訳されるcall 'erlang':'andalso'行がまだ存在する可能性があります。

erlang:'andalso'(A,B)A andalso Bと等価ではないか、または「時期尚早な拡張」の何らかの種類がそれを難し​​くしていますか?

答えて

8

主な理由は、BIFの呼び出しは、引数が厳密であるという点で「通常の」関数の呼び出しと同じように動作します。すべて BIF /関数が呼び出される前に引数が評価されます。 andalsoorelseとの区別は、ではなく最初の引数だけを評価するということです。最初の引数のどの値に応じて、2番目の引数を評価しても評価しなくてもかまいません。つまり、たとえBIFSであっても、コンパイラによって特別に処理されなければならないため、BIFを作成する際の注意点はほとんどありません。

また、拡張は非常に簡単であるため、BIFを特別に処理しているので、やっていることで得られる利益はほとんどありません。

+0

まだ、ユーザーには書き込みを許可できませんでした。 'erlang: 'や' true(false、false) 'も怠惰保存型のcase式に分解されますか? – amindfv

+0

@amindfv 'and'、' or'、 'andalso'と' orelse'は中置形式での使用を意図しています。 'erlang: 'と'/2'と' erlang: 'または'/2'はどこかに実装する必要があるため、BIFとして実装されています。 'andalso'と' orelse'は、このようにして正しく動作するように実装されなければならないので、コンパイラの拡張として実装されますが、 'erlang: 'と'/2'と 'erlang:' orelse '/ 2'は彼らはどこにでも実装されています。余剰(廃棄物)を取り除くことはアーランの精神です。 –

+0

@amindfv BIFが 'erlang: 'andalso'/2'と' erlang: '' orelse/2'を呼び出した場合、コンパイラは特別な場合にそれらを展開して、今日。そう、はい、KISSのルール。 – rvirding

関連する問題