Re: Evaluating an anonymous function with closure

2012-10-16 Thread Gergely Szabó
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

2012-10-16 Thread Jim foo.bar

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

2012-10-16 Thread Michael Gardner
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

2012-10-16 Thread Tassilo Horn
"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

2012-10-16 Thread Jim foo.bar

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

2012-10-16 Thread Tassilo Horn
"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

2012-10-16 Thread Jim foo.bar

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

2012-10-15 Thread Michael Gardner
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

2012-10-15 Thread Jim - FooBar();

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

2012-10-15 Thread Andy Fingerhut

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

2012-10-15 Thread Jim - FooBar();

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

2012-10-15 Thread Alan Malloy
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

2012-10-15 Thread Jim - FooBar();

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

2012-10-15 Thread Jonathan Fischer Friberg
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

2012-10-15 Thread Lee Spector

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

2012-10-15 Thread Ben Smith-Mannschott
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

2012-10-15 Thread Lee Spector
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

2012-10-15 Thread Alan Malloy
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

2012-10-15 Thread Alan Malloy
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

2012-10-15 Thread Gergely Szabó
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