Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

Phase Next

These are much less well considered! The primary reason for documenting them now is merely to make sure that nothing in Phase One blocks future development.

What's the Problem?

  • Exception throwers have the details and the context, and high level handlers have the policy. The right information is all available, but not all at the same time and place:
    • Throwers have to anticipate what handlers might need.
    • Handlers miss the time window to recover from the problem as it happens--the stack is already unwound.
  • Programmatic response to errors based on types is inflexible
    • Inheritance hierarchy baked in
    • Have to manufacture new types to drive dispatch 

Condition System

  • adopt matchure as general purpose matching strategy
    • update implementation to use protocols instead of multimethods
    • matching will work with class of plain Java exceptions
    • and also work with maplikeness of Clojure exceptions
  • How to prevent people from writing handlers that rely on debug-build information?
    • yes: warn users through documentation
    • no: parse matching forms and reject
    • no: give locals and bindings ugly "debug" names
  • possible approach
    • extend try/catch/finally with handle
    • handle takes two args: error and context
    • match on error to grab exceptions unwinding
    • then walk stack of registered handlers, matching on context
      • note that context is arbitrary object
      • it could be, or include, the error!
    • handler is fn of two args (error, context)
      • if not a fn, could be literal value for simple case
    • tools would be able to allow interactive restart, a la CL
    • note that this approach puts more responsibility on top and less on middle (when compared to CL)
Code Block
;; simple degenerate example
;; error matcher is IOException (could be arbitrary match)
;; context is :io (could be arbitrary match)
;; handler is "<NO DATA>" (could be arbitrary fn)
(defn top []
  (with-handler :io "<NO DATA>"
    (middle)))

(defn middle []
  (try*
   (bottom)
   (handle IOException :io)))

(defn bottom []
  (slurp "file-does-not-exist"))

Better Java Unification

  • ISnapshot protocol identifies Java objects that can be "immutable data-ized"
    • protocol extends to throwable
    • other possible cool uses
      • dynamic codegen of nonreflective code a la clojure.core/bean
  • extend condition system to call through ISnapshot where available
    • get power of matching with plain ol' Java exceptions!
  • simplify REPL and reporting code
    • all exceptions can now be treated as data, from Java or from Clojure
  • would snaphsot need to be memoized ??
    • probably
    • simple LRU might be good enough
    • or could use a weak map keyed by base object
      • do exceptions consume any native resources?
  • if unification with Java was good enough, could we drop the Clojure-specific exceptions?
    • unlikely – bottom needs to be separable
    • if IMeta or IPersistentMap were protocols...