I made a little proof of concept last night.  You could always look at 
bytecode that clojure emits in few ways, you can either hack the compiler 
yourself, or force AOT in your project and use javap.  The first approach 
is a bit intrusive, and the second has a somewhat annoying turnaround time, 
and won't work for any code that calls eval at runtime.

This takes another approach.  It uses java's Instrumentation stuff, to 
provide a hook into all classloading past the point at which it's loaded, 
where I store off all the bytes of defined classes into a big 
ConcurrentHashMap.  Then I use eclipse.jdt.core's disassembler 
functionality to print out the bytecode.

There's a nice lein-plugin that adds the dependency to your project and 
looks itself up in order to add the appropriate -javaagent flag to your jvm 
startup options.

Now you can do something like this:

user=> (require 'no.disassemble)
nil

user=> (in-ns 'no.disassemble)
#<Namespace no.disassemble>

no.disassemble=> (println (disassemble (fn [])))
// Compiled from NO_SOURCE_FILE (version 1.5 : 49.0, super bit)
public final class no.disassemble$eval1174$fn__1175 extends 
clojure.lang.AFunction {

  // Method descriptor #7 ()V
  // Stack: 0, Locals: 0
  public static {};
    0  return
      Line numbers:
        [pc: 0, line: 1]

  // Method descriptor #7 ()V
  // Stack: 1, Locals: 1
  public disassemble$eval1174$fn__1175();
    0  aload_0
    1  invokespecial clojure.lang.AFunction() [10]
    4  return
      Line numbers:
        [pc: 0, line: 1]

  // Method descriptor #12 ()Ljava/lang/Object;
  // Stack: 1, Locals: 1
  public java.lang.Object invoke();
    0  aconst_null
    1  areturn
      Line numbers:
        [pc: 0, line: 1]
      Local variable table:
        [pc: 0, pc: 1] local: this index: 0 type: java.lang.Object

}
nil
no.disassemble=> 


Potential use cases:

Writing fast code faster.
Proving to newbies that clojure is not interpreted, further evidence of 
eval's coolness.
Checking to make sure primitives are being used where you expect.

-- 
-- 
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