为什么不将andalso/2实现为适当的BIF?

ami*_*dfv 5 erlang

我能够编写前缀布尔表达式erlang:'and'(true, false),但不能写相应的andalsoorelse表达式.为什么?

当我看核心输出,它看起来像andalsoorelse只是宏-例如:

a(A,B) -> A and B.
Run Code Online (Sandbox Code Playgroud)

转化为核心

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

但也来自

b(A,B) -> A andalso B.
Run Code Online (Sandbox Code Playgroud)

'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'] )
Run Code Online (Sandbox Code Playgroud)

看起来它是以这种方式实现的,以保持懒惰,但它不必在这一步 - 例如,仍然可能有一条call 'erlang':'andalso'线,后来翻译.

这只是一种erlang:'andalso'(A,B)不等同的疏忽A andalso B,还是某种"过早扩张"难以实现?

rvi*_*ing 8

主要原因是对BIF的调用与调用"普通"函数的行为方式相同,因为它们的参数是严格的,所有参数都是在调用BIF /函数之前计算的.有一个显着的事情andalsoorelse是他们没有评估所有他们的论据,但只有第一个参数.然后,根据第一个参数的值,他们可能会或可能不会评估第二个参数.这意味着即使它们是BIFS,它们也必须由编译器进行特殊处理,因此制作它们的BIF几乎没有意义.

此外,扩展非常简单,因此作为专门处理BIF的工作几乎没有什么好处.