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

Reply via email to