On Tue, Dec 30, 2008 at 4:56 PM, wubbie <sunj...@gmail.com> wrote: > > Why do we need to specify the second argument(#'func) is a function, > not a variable? > the syntax of send-off required a function as the second arg?
The second argument will be called as a function -- if it's not callable (doesn't implement IFn), you'll get an exception: user=> (send-off (agent nil) 42) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn Perhaps you're asking why #'func is sometimes used instead of just func? This is probably because the code was written to work with older versions of Clojure. The difference is a bit subtle, but the overview is that the #' prefix used to be required if you wanted to be able to update the definition of 'func' and have the next send it made to itself use that new definition. This is no longer necessary, and you can now use simply: (send-off *agent* func) I don't understand all the details of what changed (or when), but here's what I do know. #'func evaluates to the Var named "func" (which in turn holds the current value, presumably a function). On the other hand just plain 'func' evaluates to the *current value* of the Var named func. To demonstrate the difference: user=> filter ; get the current value of filter #<core$filter__3592 clojure.core$filter__3...@c3e9e9> user=> (var filter) ; get the Var named "filter" -- can be written #'filter #'clojure.core/filter user=> (deref (var filter)) ; get the Var, and then the value -- can be written @#'filter #<core$filter__3592 clojure.core$filter__3...@c3e9e9> Note the return value of the first and last examples are the same, because they're doing essentially the same thing. But I said 'send-off' needs a function, so how can we use #'func which actually passes in a Var? That's because Vars implement IFn -- when called, they deref themselves and call their current value: user=> (instance? clojure.lang.IFn #'filter) true user=> (#'filter identity [1 nil 2]) (1 2) Presumably in some older version of Clojure, using the plain symbol 'func' caused the Var to be deref'ed only once, such that the initial value of the Var was used even when if you used 'def' or 'defn' to update the implementation for 'func'. I don't know when this initial deref happened -- I don't think it could have been at compile time, or there would have been no way to forward-declare and have mutually-dependant functions definitions. Perhaps it was the first time 'func' was called? Anyway, it's easy to demonstrate that the #'func format is no longer needed for self-sending agents: user=> (defn act [i] (Thread/sleep 1000) (prn i) (send-off *agent* act) (inc i)) #'user/act user=> (send-off (agent 100) act) #<Agent clojure.lang.ag...@1a61172> user=> 100 101 102 103 (defn act [i]) #'user/act user=> 104 After the manual 'send-off', a number was printed every second. Then I used 'defn' to update the Var named 'act' to be a function that does nothing all. Because 'act' was sitting in it's 'sleep' call, one more number was printed, but the next 'send-off' used the new definition of 'act' and nothing more was done. --Chouser --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---