4

Using Clojure 1.2, this code works

(defn A [] (fn [a] (+ a 2)))
(println ((A) 0))
(println (eval (list (A) 0)))

but the following code fails on the third line

(defn A [b] (fn [a] (+ a b)))
(println ((A 3) 0))
(println (eval (list (A 3) 0)))

Why?

1
  • 1
    do you have a pressing need to use Clojure 1.2? 1.4 is a lot better? fortunately the answer to this question is version agnostic. Commented Jul 27, 2012 at 23:50

1 Answer 1

3

Calling (list (A 3)) returns a function in a list:

user> (list (A 3) 0)
(#<user$A$fn__2934 user$A$fn__2934@2f09b4cb> 0)

eval expects to get a symbol in a list and it was getting the function it's self. if you quote the call to (A 3) then you will get the result you seek

user> (println (eval (list '(A 3) 0)))
3
nil

Part of this code is being evaluated before the call to eval and then eval is evaluating the rest. It is more common to se eval used on quoted forms with perhaps a term or to selectively unquoted (~).

user> (eval '((A 3) 0))
3

or

user> (def my-number 3)
#'user/my-number
user> (eval `((A ~my-number) 0))
3

edit: on the question of why it works with zero args and fails with one arg:

it seems that both forms work if you don't store them in vars (ie define them with defn) and instead manually inline them:

user> (def A (fn [b] (fn [a] (+ a b))))
#'user/A
user> (eval (list (A 3) 0))
; Evaluation aborted.
user> (eval (list (fn [b] (fn [a] (+ a b)) 3) 0))
3
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. If eval is passed a function as the first argument in the list, why is .toString called? Also, why does the first example work, even though it lacked such a quote?
I was totally wrong on the .toString part. I was testing in the repl and printing the intermediate stage and reading it back (which produces a different error)
im still looking into that last part
Using quotes helped for this specific example, but I still ran into a bit of trouble with some more general things I was attempting to do. Turns out, I actually should have been using "apply" (not "eval") to get the behavior I was expecting. Thanks for all the help.
I have yet to see a situation where I actually needed to use eval in one of my programs. Often I think I do and then find some better way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.