2013-07-13 52 views
5

Tôi có thể viết các biểu thức boolean tiền tố như erlang:'and'(true, false), nhưng không phải là các biểu thức andalso hoặc orelse tương ứng. Tại sao?Tại sao không phải là andalso/2 được triển khai như một BIF phù hợp?

Khi tôi nhìn vào sản lượng nòng cốt, có vẻ như andalsoorelse chỉ là macro - ví dụ:

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

dịch để lõi

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

nhưng AndAlso đi từ

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

đến

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

Dường như nó được triển khai theo cách này để bảo vệ sự lười biếng, nhưng nó sẽ không phải ở bước này - ví dụ: vẫn có thể có một dòng call 'erlang':'andalso', được dịch sau này.

Chỉ là sự giám sát mà erlang:'andalso'(A,B) không tương đương với A andalso B hoặc một số loại "mở rộng sớm" có gây khó khăn không?

Trả lời

8

Lý do chính là các cuộc gọi đến BIF hoạt động giống như các cuộc gọi đến các hàm "bình thường" ở chỗ chúng được đặt trong đối số của chúng, tất cả các đối số được đánh giá trước khi hàm BIF được gọi. Điều phân biệt với andalsoorelse là chúng không đánh giá tất cả đối số của chúng nhưng chỉ là đối số đầu tiên. Sau đó, tùy thuộc vào giá trị của đối số đầu tiên mà họ có thể hoặc không thể đánh giá thứ hai. Điều này có nghĩa rằng ngay cả khi họ đã được BIFS họ sẽ phải được xử lý đặc biệt bởi trình biên dịch anyway, do đó, có rất ít điểm trong việc đưa họ BIFs.

Ngoài ra việc mở rộng rất đơn giản nên sẽ có ít lợi ích khi thực hiện khi BIF xử lý đặc biệt.

+0

Tuy nhiên, người dùng không được phép viết ví dụ: 'erlang: 'andalso' (đúng, sai)', mà sẽ được tháo rời thành biểu thức trường hợp giữ gìn lười biếng? – amindfv

+0

@amindfv 'và',' hoặc', 'andalso' và' orelse' được thiết kế để sử dụng ở dạng infix. 'erlang: 'và'/2' và' erlang: 'hoặc'/2' được triển khai dưới dạng BIF vì phải thực hiện ở đâu đó. 'andalso' và' orelse' được thực hiện như là mở rộng trong trình biên dịch bởi vì chúng phải được thực hiện theo cách này để hoạt động đúng nhưng 'erlang: 'andalso'/2' và' erlang: 'orelse'/2' không phải được triển khai ở bất cứ đâu nên không. Loại bỏ dư thừa (chất thải) là tinh thần Erlang. –

+0

@amindfv Có, nếu bạn có các cuộc gọi BIF 'erlang: 'andalso'/2' và' erlang: '' orelse/2' thì trình biên dịch sẽ phải xử lý trường hợp đặc biệt và mở rộng chúng thành nhiều mã giống như bạn nhận được hôm nay. Vì vậy, có, KISS quy tắc. – rvirding

Các vấn đề liên quan