On Wed, May 4, 2011 at 8:01 PM, Ken Wesson <kwess...@gmail.com> wrote: > Note that instantiating the class with 4 gives us an add-4-to function > instead of the original add-3-to function here. To actually convert > that particular closure into code that reproduces it, the array of > constructor arguments needs to be [{} 3]. (I'm not sure what the map > argument is used for, but it seems to work when left empty, though not > when omitted entirely. The compiler can always give closure objects > metadata amounting to the correct [{} 3] or whatever needed to > recreate the closure object by calling its class's constructor.
Actually, this would require the arguments to be known at compile time. For (let [x 3] (fn [y] (+ x y))) this is possible, but for a return value from (defn adder-maker [n] (fn [y] (+ n y))) it's not. But what are we really doing here? There are just two situations where the compiler is being called. One is on-the-fly eval at runtime, and then the bytecode could just be built with code that works something along these lines: makeJavaClassWithNullPublicStaticFieldItUses(); TheNewClass.THE_PUBLIC_STATIC_FIELD = someValue; Here "someValue" would be an actual reference to the existing object in memory, and it will work with closures and any other object, even things like io streams backed by open file handles. The second is for AOT compilation of Clojure code. In that case, what we should probably aim for is that a) anything for which print-dup has a method and b) anything that implements Serializable can be externalized. For print-dupables you just print-dup to a string and generate a class whose static initializer puts that back in through the reader: something like static { someVar = RT.readString("(sorted-map [1 2 3 4])"); } The proof of concept for Serializables is similar: static { someVar = (new ObjectInputStream (new ByteArrayInputStream (new byte[] {0x1b, 0xff, 0x3a, 0xa7, ...}))).readObject(); } where the contents of the byte array literal are generated using ObjectOutputStream/ByteArrayOutputStream, natch. Closures, including ones whose arguments can't be known until runtime, can easily be slapped with "implements Serializable" if they haven't been already. Indeed, an "extends Serializable" on IFn, on top of the above compiler modification to externalize anything serializable, would suffice to make it possible to eval (and even AOT-compile) code containing any embedded function objects, save for closures that have closed over non-serializable objects. -- 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