Sounds interesting, I'd love to hear more about the use case. 
 
We ran into this issue as well when implementing the new positional 
compilation for Graph.  We filed a ticket [1], and worked around it with a 
funny trick:

Suppose you want to eval a complicated thing, and the crux of the issue is 
that this fails: 

(let [y 1 f (fn [x] (+ x y))] (eval `(~f 1)))

A solution is to rework what you eval, so that it has a 'hole' for the 
function and you slot the function into this hole afterwards (which Hotspot 
seems to be able to optimize just fine):

(let [y 1 f (fn [x] (+ x y))] ((eval `(fn [g#] (g# 1))) f))

Happy to elaborate if you like.  

Cheers,
Jason

[1] http://dev.clojure.org/jira/browse/CLJ-1206

On Wednesday, August 28, 2013 10:59:19 AM UTC-7, Jamie Brandon wrote:
>
> That sort of works for my use case. 
>
> What I want to do is define a grammar... 
>
> (def num-graph 
>   (graph 
>      num ~(or ~succ ~zero) 
>      succ (succ ^x ~num) 
>      zero zero)) 
>
> ... attach actions .... 
>
> (def num-out 
>   (output-in num-graph 
>      'zero (fnk [] 0) 
>      'succ (fnk [x] (inc x)))) 
>
> ... and compile the result ... 
>
> strucjure.regression.tests> (graph->view 'num num-out) 
> (clojure.core/letfn 
>  [(num ...) 
>   (succ ...) 
>   (zero ...)] 
>  (clojure.core/fn 
>   [input__2288__auto__] 
>     (num input__2288__auto__))) 
>
> This works fine as long as the fnks dont close over anything, but 
> that's very limiting. 
>
> If I eval that code and *then* wrap it in (binding ...) I can have 
> closures but that now means that I can't do call-site compilation. 
> I'll have to poke around a bit more... 
>
> On 28 August 2013 18:32, Aaron Cohen <aa...@assonance.org <javascript:>> 
> wrote: 
> > I'm not sure if you'll consider this hacky or not. 
> > 
> >  (def ^:dynamic *fn-helper*) 
> > 
> > (defn eval-at-one [f] (binding [*fn-helper* f] (eval '(*fn-helper* 1)))) 
> > 
> > 
> > On Wed, Aug 28, 2013 at 1:28 PM, Jamie Brandon 
> > <ja...@scattered-thoughts.net <javascript:>> wrote: 
> >> 
> >> You will also run into problems if your functions close over any data: 
> >> 
> >> user> (let [f (fn [] 1)] (eval `(~f))) 
> >> 1 
> >> nil 
> >> user> (let [x 1 f (fn [] x)] (eval `(~f))) 
> >> IllegalArgumentException No matching ctor found for class 
> >> user$eval38616$f__38617  clojure.lang.Reflector.invokeConstructor 
> >> (Reflector.java:163) 
> >> 
> >> I'm struggling with this as well, I'm definitely interested in finding 
> >> a non-hacky way to pass closures through eval without leaking memory. 
> >> 
> >> Perhaps something like: 
> >> 
> >> (let [x 1 
> >>        f (fn [] x) 
> >>        f-sym (gensym)] 
> >>   (intern *ns* gensym (weak-ref f)) 
> >>   (with-meta (eval `(fn [] (do-stuff-with @~f))) {::strong-ref f})) 
> >> 
> >> So that way f will be freed up when the resulting fn is gced. 
> >> 
> >> On 28 August 2013 17:59, Ben Wolfson <wol...@gmail.com <javascript:>> 
> wrote: 
> >> > On Wed, Aug 28, 2013 at 9:27 AM, Jamie Brandon 
> >> > <ja...@scattered-thoughts.net <javascript:>> wrote: 
> >> >> 
> >> >> 
> >> >> If you aren't worried about leaking memory, a possible workaround is 
> >> >> to intern the fn in some namespace and then put the symbol in the 
> >> >> macro output. 
> >> > 
> >> > 
> >> > Hrm, I hope it doesn't come to that---as long as I'm creating the 
> >> > functions 
> >> > with their metadata, I can make things work, because I can add extra 
> >> > information to the with-meta call or do extra things when making the 
> >> > call. 
> >> > What I'd like, though, is for it to be possible to copy the metadata 
> >> > over to 
> >> > a new function by client code, just using the regular (with-meta (fn 
> >> > [blah] 
> >> > blah) (meta old-fn)) mechanism. But then the sneaky symbol, or 
> whatever 
> >> > extra thing, in the metadata, that's used in the form to be eval-ed 
> is 
> >> > pointing to the original function, not the one passed in. Maybe just 
> >> > providing a utility for fixing up the metadata is the right move, 
> though 
> >> > it's kidn of dissatisfying. 
> >> > 
> >> > 
> >> > -- 
> >> > 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 
> >> > clo...@googlegroups.com<javascript:> 
> >> > 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 clo...@googlegroups.com<javascript:> 
> >> 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 clo...@googlegroups.com<javascript:> 
> > 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.

Reply via email to