Let's please keep this discussion to the proposed feature and its suitability to various tasks. I don't want this to become a discussion about nREPL.
REPL stands for something - Read, Eval, Print, Loop.
It does not stand for - Eval RPC Server/Window.
It is not something I "feel" about. But I do think we should be precise about what we call REPLs.
While framing and RPC orientation might make things easier for someone who just wants to implement an eval window, it makes the resulting service strictly less powerful than a REPL.
Let's look at some of that power:
'read' is a protocol. It works on character streams, one of the most widely available transports. It uses delimiters (spaces, [], (), {} etc) to separate forms/messages. Readers implement this protocol and return data upon encountering complete forms. read is shipped with Clojure and multiple implementations are available. It is available for use in programs, including programs you invoke in a REPL. A substantial subset of evaluable+read-able forms are supported by edn, which has even wider support. The reader format is extensible. So, when you get read, you are getting a lot.
When embedded in a REPL, even more is implied by read. There must be some source (stream) of things read. That source is the same source that should be used should the code being evaluated call 'read'. If that source is a terminal with a human, they can continue their interaction *in place*.
'eval' implies the full power of Clojure. Take a form as data, evaluate it, return a result as data.
'print' takes the returned data and prints it on an output stream as characters. It is true that not all things might print read-ably, which can pose challenges for *programs* sitting on the other end of a REPL that would like to call 'read' on its output. But we have improved Clojure in this area - now the default print-method prints something that is read-able (with an appropriate tag handler installed). Another area where many REPLs presume a human consumer and print un-read-ably is when exceptions occur. This socket REPL will default to printing exceptions read-ably, but you can switch to a human oriented formatter of your choice.
Again, as with read, when embedded in a REPL, even more is implied by print. There must be a destination (stream) of things printed. That destination is the same destination that should be used should the code being evaluated call print. If that source is a terminal with a human, they can leave their reading focus *in place* and see all output targeted towards them.
'loop' - do it again. Note however that a REPL will not attempt to read/print while evaluating.
The stream binding and nestability is important. It means that you can, in the code you evaluate in your REPL, launch a nested interpreter, or Eliza-like thing, or a text-adventure etc, and those things will *get input from the same source and print to the same target*. This is what someone who knows what REPLs are expects and demands.
You can, if you desire, even launch an eval RPC server in a REPL, but not vice-versa.
REPLs work over the most primitive connections, terminals, and can be pipe, rerouted, etc with all tools. They accomplish a lot over a single connection, which will often be all you can get.
But, we now have nice editors/IDEs often running on the same machine, with the ability to use sockets. Multiplexing their needs with those of a human REPL consumer over the same connection is going to make things bad for one or both of them.
With the socket REPL, the recommendation is that tools will open more than one connection, and use a dedicated channel for most editor/IDE operations that might want to interact with the running process. With the improved read-ability of REPL output, I think an edn-based REPL makes a fine RPC server for program-to-program communication, especially since the set of 'verbs' supported is bounded only by what you can evaluate, and the types of things you might discover is open.
These are the intentions of this feature.
Thanks for the feedback,
Rich