I certainly like that better than the binding solution, especially if
hotspot can potentially inline the functions. It still tricky to do
that in a macro, especially when the code to be evaled depends on the
current lexical scope, but I can maybe work around that. Thanks.

On 29 August 2013 04:50, Jason Wolfe <ja...@w01fe.com> wrote:
> 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> 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> 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> wrote:
>> >> > On Wed, Aug 28, 2013 at 9:27 AM, Jamie Brandon
>> >> > <ja...@scattered-thoughts.net> 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
>> >> > 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=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_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
>> >> 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=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_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
>> > 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=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_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.

Reply via email to