What is the advantage of defining an “or” operation in clojure as a macro rather than just as a function?

I hope the explanation gives me a better idea of ​​the benefits of using macros.

+4
source share
2 answers

In a function, all arguments are evaluated before it is called.

This means that, oras a function, it cannot be lazy, while a macro can be rewritten orinto an operator ifthat only evaluates branches when necessary.


A bit more specific:

(or (cached-lookup) (expensive-operation))

... what he is rewriting is as follows:

(let [or__1234__auto (cached-lookup)]
  (if or__1234__auto
    or__1234__auto
    (expensive-operation)))

... , (expensive-operation), (cached-lookup) nil false. JVM: expensive-operation , , .


, , . :

(defn or*
  ([] false)                                                ; 0-arg case
  ([func-one] (func-one))                                   ; 1-arg case
  ([func-one func-two]                                      ; optimized two-arg case
   (let [first-result (func-one)]
     (if first-result
       first-result
       (func-two))))
  ([func-one func-two & rest]                               ; general case
   (let [first-result (func-one)]
     (if first-result
       first-result
       (apply or* func-two rest)))))

, , "thunks" ( ) , ; , , , partial , .

+8

, , or and ?

(defn some [f l]
  (and (seq l)
       (or (f (first l)) 
           (some f (rest l))))) 

, , ! - , if. , - , , .

0
source

Source: https://habr.com/ru/post/1667595/


All Articles