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'] )