Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't andalso/2 implemented as a proper BIF?

Tags:

erlang

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?

like image 984
amindfv Avatar asked Jul 13 '13 22:07

amindfv


1 Answers

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.

like image 192
rvirding Avatar answered Nov 15 '22 03:11

rvirding