Erlang 为什么不是';t和ALSO/2是否作为适当的BIF实施?

Erlang 为什么不是';t和ALSO/2是否作为适当的BIF实施?,erlang,Erlang,我能够编写前缀布尔表达式,如erlang:'and'(true,false),但不能编写相应的和或orelse表达式。为什么? 当我查看核心输出时,它看起来像是和和orelse只是宏-例如: a(A,B) -> A and B. 转化为核心 'a'/2 = %% Line 4 fun (_cor1,_cor0) -> call 'erlang':'and' (_cor1, _cor0) 但安达索也从 b(A,B) ->

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

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

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=
%%第6行
乐趣(\u cor1,\u cor0)->
(第1号案件)
(当“true”时->
_cor0
-|['compiler_generated'])
(当“true”时->
“假”
-|['compiler_generated'])
(当“true”时->
(调用('erlang'
-|['compiler_generated']):('error'
-|['compiler_generated'])
(({('badarg'
-|['compiler_generated']),\u cor2}
-|['compiler_generated']))
-|['compiler_generated'])
-|['compiler_generated'])
结束
-|['compiler_generated'])
它看起来是以这种方式实现的,以保持惰性,但它不必在这一步中——例如,仍然可能有一个
调用'erlang':'andalso'
行,稍后会进行翻译


erlang:'andalso'(A,B)
不等同于
A andalso B
,这仅仅是一种疏忽,还是某种“过早扩展”使之变得困难?

主要原因是对BIF的调用与对“正常”函数的调用行为相同,因为它们的参数严格,在调用BIF/函数之前,对所有参数进行求值。
andalso
orelse
的区别在于它们不
计算所有参数,而只计算第一个参数。然后,根据第一个参数的值,它们可以计算第二个参数,也可以不计算第二个参数。这意味着,即使它们是BIF,编译器也必须对它们进行特殊处理,因此使它们成为BIF没有什么意义


此外,扩展非常简单,因此作为他们专门处理的BIF不会有什么好处。

但是,用户不能编写例如
erlang:'andalso'(true,false)
,将其分解为保留惰性的大小写表达式?@amindfv
andalso
orelse
用于中缀形式
erlang:'和'/2
erlang:'或'/2
作为BIF实现,因为必须在某处实现
andalso
orelse
在编译器中作为扩展实现,因为它们必须以这种方式实现才能正常工作,但是
erlang:'andalso'/2
erlang:'orelse'/2
不必在任何地方实现,所以它们不需要。摆脱多余(浪费)是Erlang spirit。@amindfv是的,如果您有BIF调用
Erlang:'andalso'/2
Erlang:''orelse/2
,那么编译器必须对它们进行特殊处理,并将它们扩展到与您今天得到的代码大致相同的代码。所以,是的,接吻规则。太糟糕了;我不喜欢中缀-operators@amindfv它们是中缀运算符,只是在Erlang中实现,而不是在C中实现。正如我试图证明的那样,它们在Erlang中很容易实现,在C中实现要困难得多。
'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'] )