Error formatting macro: pagetree: java.lang.NullPointerException

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.


Users will be compilers and tools, as well as REPL users through an interactive wrapper interface.

Design Decisions

  • using Clojure symbols to represent class and method names
    • pro: matches Clojure's use of symbols, easy literal rep
    • con: requires [] to <> conversion (but this conversion is already in place elsewhere in Clojure!)
    • also considered keywords and a new datatype. 
      • rejected keywords as they have the same cons as symbols, and feel less idiomatic
      • rejected new datatype as too much pain for not enough gain. Literal rep is a huge advantage
  • get the data out as quickly as possible
    • APIs convert reflection/asm APIs into Clojure data before doing anything else
    • gives you the entire Clojure data API to manipulate
    • simplest to implement
    • will be less performant for the case where you only want a tiny bit of info, but I don't have a use case needed that perf
  • create my own table of java access bitflags (flag-descriptors), instead of using constants from reflection or ASM
    • at first glance the existing constants might seem fundamental, but the spec actually dominates
    • the existing constants don't capture all the information (different flags apply to different types)
    • existing flags can't change, and if new ones emerge the code would have to change even if I was using the existing constants
  • use defrecords for constructor, field, method
    • wanted types for polymorphic dispatch for printing
    • the print dispatch is not general, I still want map-ish printing through pprint (note Rich questions this below)
  • keep fields/methods/records in a set
    • they are logically a set (no order imposed by spec)
    • they have a lot in common (flags, name, etc.)
    • considered three separate sets for fields/methods/constructors, but given that no choice is ideal for all API consumers decided to keep it simple. Classes have members of different types.
  • two levels of reflection: class, or class-plus-ancestors
    • does not correspond to Java reflection's distinction of declared here vs. visible-from-here
    • I have always believed Java had this wrong: visible from here is a derived fact. Class or class+ancestors reflects the reality of the data, while visible-from-here is driven by a single use case
    • that said, the compiler will want visible-from-here, so when the compiler starts using this API we will need to derive it
  • reflection is parameterized by Reflector protocol
    • there will be one or more implementations per platform
    • reflection is scoped to Reflector's notion of how to find classes
      • toyed with making this implicit in some way, scarily complex for no benefit
    • considered dynamic scope for default reflector
      • bad idea: just creates more stateful magic
      • defaulting to platform reflecting by arity provides ease-of-use without the complexity of dynamic scope


Note, this list is primarily RH's notes on Stu's patch.