2013-07-13 15 views
5

Sono in grado di scrivere prefissi espressioni booleane come erlang:'and'(true, false), ma non le corrispondenti andalso o orelse espressioni. Perché?Perché non è andalso/2 implementato come un BIF corretto?

Quando guardo l'uscita principale, sembra che andalso e orelse sono solo le macro - ad esempio:

a(A,B) -> A and B. 

traduce al nucleo

'a'/2 = 
    %% Line 4 
    fun (_cor1,_cor0) -> 
     call 'erlang':'and' 
      (_cor1, _cor0) 

ma andalso va da

b(A,B) -> A andalso B. 

a

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

Sembra che sia implementato in questo modo per preservare la pigrizia, ma non dovrebbe essere in questo passaggio - ad es. potrebbe esserci ancora una riga call 'erlang':'andalso', che verrà tradotta in seguito.

È solo una svista che erlang:'andalso'(A,B) non è equivalente a A andalso B o una sorta di "espansione prematura" rende difficile?

risposta

8

Il motivo principale è che le chiamate a BIF si comportano allo stesso modo delle chiamate a funzioni "normali" in quanto sono rigide nei loro argomenti, tutti gli gli argomenti vengono valutati prima che venga chiamato il BIF/funzione. La cosa che distingue con andalso e orelse è che essi non hanno valutare tutti i loro argomenti ma solo il primo argomento. Quindi, a seconda del valore del primo argomento, possono o meno valutare il secondo. Ciò significa che anche se fossero BIFS, dovrebbero comunque essere trattati in modo speciale dal compilatore, quindi non ha molto senso renderli BIF.

Anche l'espansione è molto semplice quindi non ci sarebbe molto da fare in quanto hanno gestito in modo speciale il BIF.

+0

Ancora, non è possibile consentire all'utente di scrivere per es. 'erlang: 'andalso' (true, false)', che verrebbe smontato nell'espressione caso di conservazione della pigrizia? – amindfv

+0

@amindfv 'and',' or', 'andalso' e' orelse' sono destinati all'uso in formato infisso. 'erlang: 'e'/2' e' erlang: 'or'/2' sono implementati come BIF perché devono essere implementati da qualche parte. 'andalso' e' orelse' sono implementati come espansione nel compilatore perché devono essere implementati in questo modo per funzionare correttamente ma 'erlang: 'andalso'/2' e' erlang: 'orelse'/2' non deve essere implementato ovunque così non lo fanno. Sbarazzarsi di eccedenze (rifiuti) è lo spirito di Erlang. –

+0

@amindfv Sì, se hai il BIF chiama 'erlang: 'andalso'/2' e' erlang: '' orelse/2', allora il compilatore dovrebbe caso speciale ed espanderli allo stesso codice che ottieni oggi. Quindi, sì, le regole KISS. – rvirding

Problemi correlati