clojurelazy-evaluation

How to prevent the evaluation of arguments of clojure function?


(defn fun
  [& args]
  (println args))
(fun (+ 1 1) (+ 1 1))

I want the output of fun to be ((+ 1 1) (+ 1 1)). I know quoting a form can make it unevaluated. But when I quote args as below,

(defn fun
  [& args]
  (println 'args))

the output is args, though. How can I do this?


Solution

  • Clojure, like all non-lazy languages (which are almost all), evaluates arguments to a function call before calling the function. When you call:

    (foo (+ 1 1) (+ 1 1))
    

    first the arguments are evaluated

    (foo 2 2)
    

    then the function is called, so in your foo, args is (2 2). There is no connection to the forms that produced those values.

    If you want to prevent evaluation, you need to quote before evaluation, i. e. in your calling form:

    (defn foo [& args]
      (println args))
    
    (foo '(+ 1 1) '(+ 1 1))