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 , .