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

时间:2013-07-13 22:51:30

标签: erlang

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

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

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

转换为核心

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

但也来自

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的疏忽,还是某种“过早扩张”难以理解?

1 个答案:

答案 0 :(得分:8)

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

此外,扩展也非常简单,因此在他们专门处理BIF时没什么好处。