On Nov 16, 2010, at 5:26 PM, Alyssa Kwan wrote: > I ran into this while working on making functions durable. Here's a > contrived example: > > => (defn a > ([x] x) > ([x y] (+ (a x) (a y)))) > #'user/a > > => (a 1 2) > 3 > > => (def b a) > #'user/b > > => (b 1 2) > 3 > > => (defn a [x] > (- x)) > #'user/a > > => (b 1 2) > -3 >
I'm confused here. Are you saying that this is what _you_ expect to see? Because that's not how Clojure actually behaves. You assign the function 'a' to 'b', and 'b' continues to refer to the original function after you redefine 'a'. So your second call to (b 1 2) still returns 3. That's interesting since the function assigned to 'b' (the original version of 'a') retains the self-reference after 'a' is redefined. The call to 'a' in 'b' still refers to the original 'a'. In other words, Clojure is not looking up the current value of 'a' when 'b' is invoked. But that is what happens with non-self-referencing functions (There must be a clearer way to say that...a function which references a function other than itself): (defn d [x y] (* x y)) (defn c [x] (d x 2)) (def f d) (defn e [x] (f x 2)) user=> (c 5) 10 user=> (e 5) 10 (defn d [x y] (< x y)) user=> (c 5) false user=> (e 5) 10 Here the value of (c 5) changes depending on how 'd' is defined, whereas 'f' continues to refer to the original definition. I suppose the answer comes from expanding 'defn': (macroexpand '(defn a ([x] x) ([x y] (+ (a x) (a y)))) ) => (def a (.withMeta (clojure.core/fn a ([x] x) ([x y] (+ (a x) (a y)))) (.meta (var a)))) (macroexpand '(defn c [x] (d x 2))) => (def c (.withMeta (clojure.core/fn c ([x] (d x 2))) (.meta (var c)))) And the documentation (http://clojure.org/special_forms#fn) says: If a name symbol is provided, it is bound within the function definition to the function object itself, allowing for self-calling, even in anonymous functions. So I guess technically the self-referential 'a' in the function definition actually refers to the name inside the 'fn' form not the variable that is getting def'd? > Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en