我能够编写前缀布尔表达式erlang:'and'(true, false),但不能写相应的andalso或orelse表达式.为什么?
当我看核心输出,它看起来像andalso和orelse只是宏-例如:
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,还是某种"过早扩张"难以实现?
主要原因是对BIF的调用与调用"普通"函数的行为方式相同,因为它们的参数是严格的,所有参数都是在调用BIF /函数之前计算的.有一个显着的事情andalso并orelse是他们没有评估所有他们的论据,但只有第一个参数.然后,根据第一个参数的值,他们可能会或可能不会评估第二个参数.这意味着即使它们是BIFS,它们也必须由编译器进行特殊处理,因此制作它们的BIF几乎没有意义.
此外,扩展非常简单,因此作为专门处理BIF的工作几乎没有什么好处.