Re: Evaluating an anonymous function with closure
Thanks for the explanation. My assumption was that evaling a compiled function would not work. When I tried it I was really surprised that it did for some simple cases. I think it would be better if it never worked. This inconsistent behavior is confusing. Anyway, the workaround I found is to call the 'invoke' method of my compiled functions. So far so good. /Gergely On Monday, October 15, 2012 6:28:51 PM UTC+2, Alan Malloy wrote: > > Evaluating function literals is not intended to work; that it works > for non-closure functions should be treated as a coincidence. > > On Oct 15, 2:19 am, Gergely Szabó wrote: > > Hello, > > > > could someone please explain the behavior that is shown in the gist > below? > > > > https://gist.github.com/3891587 > > > > Regards, > > Gergely > -- 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
Re: Evaluating an anonymous function with closure
On 16/10/12 13:20, Michael Gardner wrote: On Oct 16, 2012, at 5:16 AM, Jim foo.bar wrote: so you're saying that if I write a for-loop in Java that populates an array with constants from 1-1 and then a 2nd loop to add them up, it would happen at compile-time and i would get the same timing-result? Maybe, maybe not. Compilers are very smart these days, but I don't know if they can fold complex expressions like for-loops. I see... so Clojure macros could indeed have the advantage over regular Java methods with regards to my trivial example? I do understand that most of the times you simply don't have the data at compile time but there must be occasions where you do and replacing a complex expression with a scalar might provide stunning performance...I've not had the time to go back to the project of mine where performance really really matters but I will soon do and let you know if I find anything... thanks again... Jim -- 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
Re: Evaluating an anonymous function with closure
On Oct 16, 2012, at 5:16 AM, Jim foo.bar wrote: > so you're saying that if I write a for-loop in Java that populates an array > with constants from 1-1 and then a 2nd loop to add them up, it would > happen at compile-time and i would get the same timing-result? Maybe, maybe not. Compilers are very smart these days, but I don't know if they can fold complex expressions like for-loops. -- 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
Re: Evaluating an anonymous function with closure
"Jim foo.bar" writes: Hi Jim, >> One example that does things like constant-folding like macrology is >> the unit conversion macro in Let Over Lambda that compiles to >> constants if both value and unit are given literally (recursively). > > unit conversion! this is exactly what i had in mind!!! when doing unit > conversion we have all the numbers + the formula upfront! where can I > find this macro that you're describing? Have you got the book? Could > you copy and paste it here please? You are lucky, the early chapters are online. See unit-of-time in http://letoverlambda.com/index.cl/guest/chap3.html defunits and defunits-chaining in http://letoverlambda.com/index.cl/guest/chap5.html There's also a Clojure version floating around the web, and I think I've seen it in some of Stu's presentations. But I think that doesn't try to compile to constants, e.g., it omits the "defunits chaining" part. > could the same be done in Java? I think, Java compilers do a bit of constant folding for things like int x = 1 + 2 * 3; // -> int x = 7; or final static int MAX=10; // ... int x = MAX + 1; // -> int x = 11; Bye, Tassilo -- 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
Re: Evaluating an anonymous function with closure
On 16/10/12 11:49, Tassilo Horn wrote: One example that does things like constant-folding like macrology is the unit conversion macro in Let Over Lambda that compiles to constants if both value and unit are given literally (recursively). unit conversion! this is exactly what i had in mind!!! when doing unit conversion we have all the numbers + the formula upfront! where can I find this macro that you're describing? Have you got the book? Could you copy and paste it here please? could the same be done in Java? Jim -- 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
Re: Evaluating an anonymous function with closure
"Jim - FooBar();" writes: >> You add the numbers at compile time, and then time how long it takes >> to...do nothing to them, at runtime. You are comparing N to zero, not >> to some smaller factor of N. > > yes but this seems almost unbelievable...i mean for simple numeric > operations this little trick could provide a tremendous speedup. No, not really. To add the numbers at compile-time, they need to be known at compile-time. That doesn't apply in almost all situations. If it would, you would just write 49995000 directly instead of (apply + (range 1)). Or in other words, your `plus` won't work with (let [maxno (gimme-max)] (plus (range maxno))) cause (eval (range max)) will complain about `maxno` being undefined. One example that does things like constant-folding like macrology is the unit conversion macro in Let Over Lambda that compiles to constants if both value and unit are given literally (recursively). Bye, Tassilo -- 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
Re: Evaluating an anonymous function with closure
On 16/10/12 03:50, Michael Gardner wrote: On Oct 15, 2012, at 7:45 PM, Andy Fingerhut wrote: For the case of arithmetic on compile-time constants, I believe that many C, Java, etc. compilers already perform the arithmetic at compile time. Known as "constant folding", yes. so you're saying that if I write a for-loop in Java that populates an array with constants from 1-1 and then a 2nd loop to add them up, it would happen at compile-time and i would get the same timing-result? Jim -- 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
Re: Evaluating an anonymous function with closure
On Oct 15, 2012, at 7:45 PM, Andy Fingerhut wrote: > For the case of arithmetic on compile-time constants, I believe that many C, > Java, etc. compilers already perform the arithmetic at compile time. Known as "constant folding", yes. -- 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
Re: Evaluating an anonymous function with closure
On 16/10/12 01:45, Andy Fingerhut wrote: On Oct 15, 2012, at 5:41 PM, Jim - FooBar(); wrote: On 15/10/12 22:44, Alan Malloy wrote: You add the numbers at compile time, and then time how long it takes to...do nothing to them, at runtime. You are comparing N to zero, not to some smaller factor of N. yes but this seems almost unbelievable...i mean for simple numeric operations this little trick could provide a tremendous speedup. How come this has not been 'advertised' enough? It is my understanding that not even Java could go that fast simply because you cannot tap into the compilation process...is there code that uses this sort of thing for performance? I'd love to take a peek... Jim Most of the time you aren't adding up 1 values known at compile time. More often you are doing arithmetic on values you do not yet know until run time. This trick won't help you in that case. For the case of arithmetic on compile-time constants, I believe that many C, Java, etc. compilers already perform the arithmetic at compile time. Andy Ok you're right I get that...what about when we're doing conversion arithmetic like from farenheit to Celcius or from cm to inches where the formula is known and the number we really want to calculate is always 1? this will work there yes? Jim -- 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
Re: Evaluating an anonymous function with closure
On Oct 15, 2012, at 5:41 PM, Jim - FooBar(); wrote: > On 15/10/12 22:44, Alan Malloy wrote: >> >> You add the numbers at compile time, and then time how long it takes >> to...do nothing to them, at runtime. You are comparing N to zero, not >> to some smaller factor of N. >> > > yes but this seems almost unbelievable...i mean for simple numeric operations > this little trick could provide a tremendous speedup. How come this has not > been 'advertised' enough? It is my understanding that not even Java could go > that fast simply because you cannot tap into the compilation process...is > there code that uses this sort of thing for performance? I'd love to take a > peek... > > Jim Most of the time you aren't adding up 1 values known at compile time. More often you are doing arithmetic on values you do not yet know until run time. This trick won't help you in that case. For the case of arithmetic on compile-time constants, I believe that many C, Java, etc. compilers already perform the arithmetic at compile time. Andy -- 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
Re: Evaluating an anonymous function with closure
On 15/10/12 22:44, Alan Malloy wrote: On Oct 15, 1:07 pm, "Jim - FooBar();" wrote: On 15/10/12 19:42, Ben Smith-Mannschott wrote: If the distinction I'm trying to make is not clear to you, I'd suggest having a look athttp://www.infoq.com/presentations/Clojure-Macros (It does a good job exploring these kinds of distinctions as it's vital to have an accurate mental model of how Clojure is evaluated if one intends to write macros.) after watching this talk I tried this at a repl: (defmacro plus "Perform addition at compile time." [numbers] (apply + (eval numbers))) user=> (time (plus (vec (range 1 "Elapsed time: 0.015635 msecs" ;;WOW 49995000 user=> (time (apply + (vec (range 1 "Elapsed time: 16.732054 msecs" ;;160 times slower 49995000 before jumping to any conclusions (and rushing to change some of my code) would you say timing is realistic? Is it expected to see such a dramatic speed increase? To be honest I'm a bit surprised...Regardless of when the actual calculation will be performed (compile vs run time), it will eventually be performed. why is at compile time so much faster? You add the numbers at compile time, and then time how long it takes to...do nothing to them, at runtime. You are comparing N to zero, not to some smaller factor of N. yes but this seems almost unbelievable...i mean for simple numeric operations this little trick could provide a tremendous speedup. How come this has not been 'advertised' enough? It is my understanding that not even Java could go that fast simply because you cannot tap into the compilation process...is there code that uses this sort of thing for performance? I'd love to take a peek... Jim -- 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
Re: Evaluating an anonymous function with closure
On Oct 15, 1:07 pm, "Jim - FooBar();" wrote: > On 15/10/12 19:42, Ben Smith-Mannschott wrote: > > > If the distinction I'm trying to make is not clear to you, I'd suggest > > having a look athttp://www.infoq.com/presentations/Clojure-Macros (It > > does a good job exploring these kinds of distinctions as it's vital to > > have an accurate mental model of how Clojure is evaluated if one > > intends to write macros.) > > after watching this talk I tried this at a repl: > > (defmacro plus > "Perform addition at compile time." > [numbers] > (apply + (eval numbers))) > > user=> (time (plus (vec (range 1 > "Elapsed time: 0.015635 msecs" ;;WOW > 49995000 > > user=> (time (apply + (vec (range 1 > "Elapsed time: 16.732054 msecs" ;;160 times slower > 49995000 > > before jumping to any conclusions (and rushing to change some of my > code) would you say timing is realistic? Is it expected to see such a > dramatic speed increase? To be honest I'm a bit surprised...Regardless > of when the actual calculation will be performed (compile vs run time), > it will eventually be performed. why is at compile time so much faster? You add the numbers at compile time, and then time how long it takes to...do nothing to them, at runtime. You are comparing N to zero, not to some smaller factor of N. -- 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
Re: Evaluating an anonymous function with closure
On 15/10/12 19:42, Ben Smith-Mannschott wrote: If the distinction I'm trying to make is not clear to you, I'd suggest having a look athttp://www.infoq.com/presentations/Clojure-Macros (It does a good job exploring these kinds of distinctions as it's vital to have an accurate mental model of how Clojure is evaluated if one intends to write macros.) after watching this talk I tried this at a repl: (defmacro plus "Perform addition at compile time." [numbers] (apply + (eval numbers))) user=> (time (plus (vec (range 1 "Elapsed time: 0.015635 msecs" ;;WOW 49995000 user=> (time (apply + (vec (range 1 "Elapsed time: 16.732054 msecs" ;;160 times slower 49995000 before jumping to any conclusions (and rushing to change some of my code) would you say timing is realistic? Is it expected to see such a dramatic speed increase? To be honest I'm a bit surprised...Regardless of when the actual calculation will be performed (compile vs run time), it will eventually be performed. why is at compile time so much faster? Jim -- 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
Re: Evaluating an anonymous function with closure
I agree with Lee. Everything that works in standard clojure should also work in an eval. Jonathan On Mon, Oct 15, 2012 at 8:11 PM, Lee Spector wrote: > On Oct 15, 2012, at 12:51 PM, Alan Malloy wrote: > > > Evaluating function literals is not intended to work; that it works > > for non-closure functions should be treated as a coincidence. > > Really? Eval "Evaluates the form data structure (not text!) and returns > the result." Why would certain things like function literals be excluded? > IMHO they shouldn't be, and in fact I've built some code around dynamically > constructed and evaluated function literals. > > -Lee > > -- > 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 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
Re: Evaluating an anonymous function with closure
On Oct 15, 2012, at 2:42 PM, Ben Smith-Mannschott wrote: > > I think you're confusing: > > (eval (list '(fn [x] x) 1)) > > with: > > (eval (list (fn [x] x) 1)) > > In both cases, eval is being passed a list of two items. The first > element of the list differs, however: > > In the first case, it is a list beginning with the special form fn: a > function literal that has not yet been evaluated. Eval will have no > trouble with this. > > In the second case it is a reference to an object implementing the > clojure.lang.IFn interface. That's not a function literal, it's the > result of evaluating one. This, as you've discovered, may or may not > work with eval. > > If the distinction I'm trying to make is not clear to you, I'd suggest > having a look at http://www.infoq.com/presentations/Clojure-Macros (It > does a good job exploring these kinds of distinctions as it's vital to > have an accurate mental model of how Clojure is evaluated if one > intends to write macros.) Ah -- thanks Ben. You are right -- I was confused. FWIW the stuff that I sometimes do is: (let [value-function (eval (list 'fn '[x] individual))] bunch of stuff including a call to value-function on an input ...) Yes, that's your first case, which the OPs example was not. -Lee -- 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
Re: Evaluating an anonymous function with closure
On Mon, Oct 15, 2012 at 8:11 PM, Lee Spector wrote: > On Oct 15, 2012, at 12:51 PM, Alan Malloy wrote: > >> Evaluating function literals is not intended to work; that it works >> for non-closure functions should be treated as a coincidence. > > Really? Eval "Evaluates the form data structure (not text!) and returns the > result." Why would certain things like function literals be excluded? IMHO > they shouldn't be, and in fact I've built some code around dynamically > constructed and evaluated function literals. I think you're confusing: (eval (list '(fn [x] x) 1)) with: (eval (list (fn [x] x) 1)) In both cases, eval is being passed a list of two items. The first element of the list differs, however: In the first case, it is a list beginning with the special form fn: a function literal that has not yet been evaluated. Eval will have no trouble with this. In the second case it is a reference to an object implementing the clojure.lang.IFn interface. That's not a function literal, it's the result of evaluating one. This, as you've discovered, may or may not work with eval. If the distinction I'm trying to make is not clear to you, I'd suggest having a look at http://www.infoq.com/presentations/Clojure-Macros (It does a good job exploring these kinds of distinctions as it's vital to have an accurate mental model of how Clojure is evaluated if one intends to write macros.) // ben -- 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
Re: Evaluating an anonymous function with closure
On Oct 15, 2012, at 12:51 PM, Alan Malloy wrote: > Evaluating function literals is not intended to work; that it works > for non-closure functions should be treated as a coincidence. Really? Eval "Evaluates the form data structure (not text!) and returns the result." Why would certain things like function literals be excluded? IMHO they shouldn't be, and in fact I've built some code around dynamically constructed and evaluated function literals. -Lee -- 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
Re: Evaluating an anonymous function with closure
Evaluating function literals is not intended to work; that it works for non-closure functions should be treated as a coincidence. On Oct 15, 2:19 am, Gergely Szabó wrote: > Hello, > > could someone please explain the behavior that is shown in the gist below? > > https://gist.github.com/3891587 > > Regards, > Gergely -- 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
Re: Evaluating an anonymous function with closure
Evaluating function literals is not intended to work; that it works for non-closure functions should be treated as a coincidence. On Oct 15, 2:19 am, Gergely Szabó wrote: > Hello, > > could someone please explain the behavior that is shown in the gist below? > > https://gist.github.com/3891587 > > Regards, > Gergely -- 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
Evaluating an anonymous function with closure
Hello, could someone please explain the behavior that is shown in the gist below? https://gist.github.com/3891587 Regards, Gergely -- 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