Re: LoL which style for Clojure
Way back when I started with Clojure i was doing this: (let [constant-data (something-expensive)] (defn my-fn [x] (do-something-with x constant-data))) But was advised instead to do this: (def my-fn (let [constant-data (something-expensive)] (fn [x] (do-something-with x constant-data So, there's that (third) option as well. // ben On Sat, Mar 23, 2013 at 9:56 AM, Marko Topolnik marko.topol...@gmail.comwrote: What if there's some computation in there, but such that should be performed at compile time? I still prefer the outside let whenever I want to make dead sure it's not getting reallocated on each call. If there was some well-specified and easily understood guarantee (for example, like the one Java has for compile-time constants), only then I would prefer the inner let. On Friday, March 22, 2013 8:05:10 PM UTC+1, Laurent PETIT wrote: 2013/3/22 jamieorc jami...@gmail.com Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) In either case, AFAIK, the compiler will recognize {:foo 1 :bar 2 :baz 3} as constant and will only create it once when compiling. First version is preferred. Cheers, Jamie -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@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+u...@**googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@**googlegroups.com. For more options, visit https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out . -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
Doug Hoyte's book Let Over Lambda—50 Years of Lisp devotes its very title to the technique of (let...(fn...)). On Friday, March 22, 2013 2:59:43 PM UTC-4, jamieorc wrote: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) Cheers, Jamie -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
On Sunday, March 24, 2013 10:53:28 AM UTC+1, bsmith.occs wrote: Way back when I started with Clojure i was doing this: (let [constant-data (something-expensive)] (defn my-fn [x] (do-something-with x constant-data))) But was advised instead to do this: (def my-fn (let [constant-data (something-expensive)] (fn [x] (do-something-with x constant-data The problem with this is that it gets messy when setting up metadata is involved. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
What if there's some computation in there, but such that should be performed at compile time? I still prefer the outside let whenever I want to make dead sure it's not getting reallocated on each call. If there was some well-specified and easily understood guarantee (for example, like the one Java has for compile-time constants), only then I would prefer the inner let. On Friday, March 22, 2013 8:05:10 PM UTC+1, Laurent PETIT wrote: 2013/3/22 jamieorc jami...@gmail.com javascript: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) In either case, AFAIK, the compiler will recognize {:foo 1 :bar 2 :baz 3} as constant and will only create it once when compiling. First version is preferred. Cheers, Jamie -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
Just out of curiosity, does it have to be a function? (def data {:foo 1 :bar 2 :baz 3}) (def data-keys (keys data)) If one item is constant the other probably is too? Cheers, /thomas On Friday, March 22, 2013 7:59:43 PM UTC+1, jamieorc wrote: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) Cheers, Jamie -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
On Sat, Mar 23, 2013 at 4:16 AM, Thomas Heller th.hel...@gmail.com wrote: Just out of curiosity, does it have to be a function? (def data {:foo 1 :bar 2 :baz 3}) (def data-keys (keys data)) If one item is constant the other probably is too? In this case, yes, but it's easy to imagine cases where neither is a constant. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
def/defn et. al are top-level form definitions...very rarely (I'd say never) you'd have a def/defn inside a 'let' or inside anything for that matter...The 1st one looks good :) Jim On 22/03/13 18:59, jamieorc wrote: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) Cheers, Jamie -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
2013/3/22 jamieorc jamie...@gmail.com Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) In either case, AFAIK, the compiler will recognize {:foo 1 :bar 2 :baz 3} as constant and will only create it once when compiling. First version is preferred. Cheers, Jamie -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
Thanks, that's what I expected, especially after doing some (time... ) experiments. On Friday, March 22, 2013 3:05:10 PM UTC-4, Laurent PETIT wrote: 2013/3/22 jamieorc jami...@gmail.com javascript: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) In either case, AFAIK, the compiler will recognize {:foo 1 :bar 2 :baz 3} as constant and will only create it once when compiling. First version is preferred. Cheers, Jamie -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
For the example given, I would say it depends on what you are trying to express. The function f1 is a function that needs some internal data x to operate -x might be considered an implementation detail. The function f2 operates on well known data x -x might be considered configuration of f2 or a more general concept. Use both appropriately to write more expressive code -constraining yourself to only one is like taking some of the colors off your palette. In addition to the expression differences, there are two closely related issues that should be considered: 1. There is a difference in the evaluation semantics. In the first example, the form bound to x is evaluated every time f1 is called. In the second, the form is invoked just once (at compile time) and then closed over by f2. That can have very real consequences in real world apps (performance, side-effects). In simple cases where the form is effectively constant (as in your example), the compiler may optimize things such that the costs are equivalent -but I don't think that's a guarantee, especially on different runtimes (CLR, ClojureScript, etc). 2. There is a scope difference between the two. The second approach allows you to close over x with multiple functions: (let [x {:foo 1 :bar 2 :baz 3}] (defn f3 [] (keys x)) (defn f4 [] (vals x))) -Chris On Friday, March 22, 2013 2:59:43 PM UTC-4, jamieorc wrote: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) Cheers, Jamie -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
I've certainly seen this at least a few spots within the 4clojure codebase – https://github.com/4clojure/4clojure/blob/develop/src/foreclojure/utils.clj#L66-L70 (quick example, I believe there are more) On Friday, March 22, 2013 3:02:20 PM UTC-4, Jim foo.bar wrote: def/defn et. al are top-level form definitions...very rarely (I'd say never) you'd have a def/defn inside a 'let' or inside anything for that matter...The 1st one looks good :) Jim On 22/03/13 18:59, jamieorc wrote: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) Cheers, Jamie -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: LoL which style for Clojure
The question should probably be asked: is there a benefit in a given situation to having the let be outside the scope of the defn? I would argue that most times it is not, and putting the let outside the function clutters the code and makes it harder to see the functions defined in the namespace. If you truly need a const value, then something like this is better, IMO: (def ^:private ^:const data {:a 1 :b 2}) (defn f1 []) (defn f2 []) I would say that most of the time, the let at the top version could be refactored into a def with no change in semantics, while at the same time gaining a bonus to readability. On Fri, Mar 22, 2013 at 2:41 PM, Robert Pitts rbxbx...@gmail.com wrote: I've certainly seen this at least a few spots within the 4clojure codebase – https://github.com/4clojure/4clojure/blob/develop/src/foreclojure/utils.clj#L66-L70(quick example, I believe there are more) On Friday, March 22, 2013 3:02:20 PM UTC-4, Jim foo.bar wrote: def/defn et. al are top-level form definitions...very rarely (I'd say never) you'd have a def/defn inside a 'let' or inside anything for that matter...The 1st one looks good :) Jim On 22/03/13 18:59, jamieorc wrote: Curious which style is preferred in Clojure and why: (defn f1 [] (let [x {:foo 1 :bar 2 :baz 3}] (keys x))) (let [x {:foo 1 :bar 2 :baz 3}] (defn f2 [] (keys x))) Cheers, Jamie -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@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+u...@**googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@**googlegroups.com. For more options, visit https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.