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?