Skip to end of metadata
Go to start of metadata

There are various situations you get into in Clojure where the easy way out is "just restart the REPL." This is unfortunate, because

  • startup time is slow
  • often REPLs have a ton of useful context built up

I believe these problems could be entirely solved in a contrib library of helper functions for REPL development. This a significantly better than making changes to Clojure, which must pass a high bar and be carefully assessed for possible affects on exiting code. It is also consistent with Rich's desire to more clearly delineate development vs. production functionality.

Some of problems to be solved (please add to these):

  • reloading of multimethods
  • reloading of records/types that implement a protocol
  • removal of "dead" vars
  • destroying/recreating stateful objects (threads, sockets, files, etc.)
  • Adding new dependencies to my Leiningen project. Solved by pomegranate ? Visible enough ? (added by Laurent Petit)

  • Infinite (or approaching infinite) loops
  • Protocol :impls leaks types when extending to a re-defined type

Possible Contributions to this Effort

  • tools.namespace contrib library 
    • Handles reloading at the namespace level
    • Needs to reach in and modify the private Var clojure.core/*loaded-libs* in order to truly "unload" a library
    • Ensures correct reload order by statically examining namespace dependencies
    • Also removes "dead" Vars that have been deleted from source files.
  • Pomegranate
    • Clojure interface to the Aether library, a general-purpose Jave API to Maven repositories and dependency resolution
  • Stuart's clojure workflow is a useful path to minimize the pain of restarts
Labels:
  1. Sep 06, 2012

    Having defprotocol check to see if any signatures have changed before generating a new Interface would possibly relieve some of the pain around recompiling namespaces that define protocols (assuming they are often recompiled for reasons other than a protocol change).

  2. Sep 06, 2012

    the big one is adding deps. if we can assume everyone has pomegranate and a project.clj you should be able to watch and reload

    1. Sep 06, 2012

      If you're ok with shelling out to lein in order to calculate a new classpath, you might not even need pomegranate on the classpath, just classlojure.

      1. Nov 21, 2012

        is there a benefit to "just" having classlojure on the classpath over pomegranate?

        1. Nov 21, 2012

          The only disadvantage to pomegranate is that it pulls in aether, and other transitive dependencies. I now have this working in ritz, which uses pomegranate to resolve dependencies, but uses classlojure to manage the classloaders, since there is more than one. It takes some care to create a new clojure runtime if any existing dependency has been removed or replaced, but otherwise creates a child classloader of the current classloader. The nrepl-project sub-project in ritz contains the start of a general project management middleware for nrepl.

          Ritz has it a little easier, since pomegranate can run in the debugger jvm instance, and doesn't have to go into the user's jvm. With a single jvm, you would probably want to run pomegranate in a separate classloader to avoid dependency conflicts, etc.