I'm able to write prefix boolean expressions like erlang:'and'(true, false)
, but not the corresponding andalso
or orelse
expressions. Why?
When I look at the core output, it looks like andalso
and orelse
are just macros - for example:
a(A,B) -> A and B.
translates to the core
'a'/2 =
%% Line 4
fun (_cor1,_cor0) ->
call 'erlang':'and'
(_cor1, _cor0)
but andalso goes from
b(A,B) -> A andalso B.
to
'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'] )
It looks like it's implemented this way to preserve laziness, but it wouldn't have to be in this step -- e.g. there could still be a call 'erlang':'andalso'
line, which is translated later.
Is it just an oversight that erlang:'andalso'(A,B)
isn't equivalent to A andalso B
, or does some kind of "premature expansion" make that difficult?
The main reason is that calls to BIFs behave in the same way as calls to "normal" functions in that they are strict in their arguments, all the arguments are evaluated before the BIF/function is called. The distinguishing thing with andalso
and orelse
is that they don't evaluate all their arguments but only the first argument. Then depending on what value of the first argument they may or may not evaluate the second. This means that even if they were BIFS they would have to be specially treated by the compiler anyway so there is very little point in making them BIFs.
Also the expansion is very straightforward so there would be little gain in doing as a they specially handled BIF.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With