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

Reply via email to