Skip to end of metadata
Go to start of metadata


The current ClojureScript REPL is tied heavily to the use of Java's embedded Rhino. We lack the set of abstractions and tools that would allow us to:

  • plug any JavaScript VM in as the "E" in our REPL, the advantages of which include:
    • faster development on alternate JSVMs
    • allowing the REPL to be used with evaluation environment specific code (browsers and node for example)
    • ease of comparing how the same ClojureScript evaluates on multiple JSVMs
      • the potential to evaluate the same code on multiple JSVMs simultaneously for compatibility testing
    • protocolization of the evaluation component's communication model, allowing for either in-process or remote evaluators
  • support multiple user interfaces: IDE, CLI; the "R" and "P"
    • for network REPLs, build nrepl server on top of what we provide
    • for in-process REPLs, build CLI on top of what we provide

Research, ideas

  • Right now, the REPL:
    • sets up and tears down the evaluator (Rhino)
    • changes compiler state when it sees in-ns
    • knows the value of *cljs-ns* for printing in prompt
    • knows about load-file, which uses the compiler
    • has the responsibility of knowing about *cljs-verbose* and printing intermediate compilation information
  • Vision for REPL:
    • An API that supports the idea of a purely presentational REPL
      • input: form
      • output: value, <exceptions, errors, compiler state as relevant to presentation, warnings>
    • When using a browser for evaluation all side-effects happen in the browser. This includes printing things. Printed values should go to the console.


  • Should we name the CrossPageChannel protocol CrossDomainChannel? Google thinks that is a better name but couldn't use it because it was already used. We are free use what is best for the protocol.

Multiple Evaluators

There are circumstances where having an implementation of IJavaScriptEval which evaluates code in multiple environments at the same time would be useful. One use case would be to run a browser-connected REPL which is connected to multiple browsers at the same time. This would be extremely helpful when working on code that is tricky to get right in multiple browsers. Another use case would be to allow for automated tests to be run in multiple environments at the same time. This implementation of IJavaScriptEval would be configured with any number of other IJavaScriptEvals. When a new JavaScript form is received for evaluation, this evaluator would send it to all of its child evaluators and wait to get a response form all of them. Once all of the responses are received, they will be compared and if all of them are the same, that single result will be returned. If any of the results are different, then the returned map will indicate that an exception has been thrown and additional keys will added to provide the results from each environment.

Status and TODO

  • Add a new protocol for IEvaluator which is used by a console to evaluate forms and return a map containing user feedback to be printed.
  • Extract console code from the current REPL and make it use the IEvaluator protocol.
  • Add a timeout in the REPL. This should only exist in the browser-connected REPL.
  • All of the old REPL code is still in cljs.compiler. This needs to be removed. Removing this code should solve some of the problems that users of OpenJDK have been having.
  • Figure out how to implement *1, *2 etc in a way that is useful when evaluating in a browser.
  • The REPL client code for the "inner page" of the CrossPageChannel doesn't work when compiled in advanced mode. Find out why. It is currently being compiled with simple optimizations.
    • The most likely cause is that service names are registered as strings which refer to functions which get minified.