On 4 September 2011 20:40, Dennis Haupt <d.haup...@googlemail.com> wrote: > > Am 04.09.2011 19:08, schrieb Justin Kramer: >> On Sunday, September 4, 2011 12:21:23 PM UTC-4, HamsterofDeath >> wrote: >> >> >> Some other comments: >> >> - Nested defns are not good. > > why? imo, nested function/method definitions are a tool to fine-tune > accessibility. just like public/private, but much more powerful. why > shouldn't i use that? why make everything flat and confuse the next > guy who's trying to figure out which def is supposed to be used by him > and which is a helper function? >
You are quite correct. Nested function definitions are in fact a good idea, for precisely the reasons you mention. If a function is only to be used locally, within another function then you should make it a local function. However, using nested defn's is not the way to do this, as defn always creates a top-level binding for a function, as is described by the following REPL session: user=> (defn outside [x] (defn inside [y] (println y)) (inside x) (println x)) #'user/outside user=> (outside 10) 10 10 nil user=> (inside 10) 10 nil As you can see, I can call the inside function from the top-level scope, even though the defn is nested inside another defn. The answer to doing what you want is anonymous functions. Using local anonymous functions solves the problem by ensuring that the function does not enter the global namespace. Anonymous functions are created with the fn special form, http://clojure.org/special_forms#fn . The trick is you can of course use let to bind a local-name to an anonymous function within your outer function. Adapting the previous example using anonymous functions, and then using "let" to bind them to a local name, would look like this: user=> (defn outside [x] (let [inside (fn [y] (println y))] (inside x) (println x)) user=> (outside 10) 10 10 nil user=> (inside 10) java.lang.Exception: Unable to resolve symbol: inside in this context (NO_SOURCE_FILE:22) As you can see, the anonymous function is now bound to the local name "inside" only within the"outside" function, and is not accessible from outside. -- 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