On Nov 17, 10:35 pm, Ken Wesson <kwess...@gmail.com> wrote: > On Wed, Nov 17, 2010 at 9:57 PM, Alyssa Kwan <alyssa.c.k...@gmail.com> wrote: > > How are you planning to persist a function? The clojure reader can't > read functions output with spit or println.
I'm not persisting functions at compile time. fns are first class objects, and I want to be able to persist them after creation like any other object. (def foo (fn [x y] (+ x y))) (dref foo :key "store") Then later: (def bar (dref nil :key "store")) bar is given the ref. Calling: (@bar 1 2) returns 3 Because it's not at compile time, I don't have access to the expr that generates the function. Stuart Halloway mentioned an invoke-time check for recompilation, which I assume requires the function to hang onto the expr and lexical environment which generates it. AFAICT, there is no such reference, and invoke-time lookups through vars are still being used; I'm probably not looking in the right place. Therefore, all I have at persist-time is the fn object, which is an instance of a subclass of AFunction. The framework does in instanceof check, then grabs the bytecode of the class. It saves the bytecode. It looks at the constructor and figures out if there are any instance variables, which are lexical bindings. It saves those objects. At deserialize/load-time, the framework grabs the bytecode. It renames the class to something guaranteed not to collide with any other class, existing or future/potential. It loads the class, then instantiates an object. If there were lexical bindings, it instantiates it with the instance variables that were saved at persist- time. Note that there's no official way to get the bytecode of a class object. If it's on disk, you can call getResourceAsStream on the ClassLoader. Otherwise, you're SOL. So at compile time I save a cache of WeakReference'd classes to their bytecode. All fn creation incurs this tax, but I hope it's light enough; it's certainly lighter than hanging onto the expr and lexical environment. > > I can think of at least three ways to build a framework for persisting > functions but none run into problems with vars. All solutions run into problems with vars at deserialize/load time, because the var in the expr may not exist. You have to do *something* at that point, even if it's just throwing an exception for the missing var. Thanks, Alyssa Kwan -- 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