Recently I've been going through SLIME and SLY looking for features we still lack, and their REPL "presentations" caught my attention: clickable result objects you can inspect, tap, or feed back into the REPL by reference. It seems relatively doable. The Emacs/UI side is tracked in clojure-emacs/cider#4015; this issue is the server piece it needs.
The idea is to make eval results addressable, so the client can act on the live object instead of re-parsing printed text or leaning on *1.
Design
- A bounded, per-session result ring (default ~100 entries) holding the actual result objects keyed by a monotonic integer id. Bounded so it can't leak; oldest entries drop out. A size of 0 disables retention for the memory-conscious.
- The eval middleware stores each value in the ring and adds a
presentation-id to the eval response, alongside the existing value. No change to how value itself is printed.
- A
lookup-presentation op (or an extension of the existing inspect/eval ops) that takes an id and operates on the live object (inspect, tap, etc.), so the inspector can target an id rather than re-evaluating *1.
- Reader support for backreferences: a
#cider/ref N tagged literal resolved from the ring to the live object. Tagged literals survive the reader cleanly, which is nicer than a custom reader macro.
Some of this (the ring plus lookup) may fit better in orchard than in cider-nrepl; open to that.
Open questions
- Ring scope: per-session vs per-connection.
- Whether to keep
*1 and presentation ids independent (leaning yes: *N stays the Clojure last-3, #cider/ref is the addressable ring).
- Eviction policy and default size.
Graceful degradation
Everything keys off presentation-id being present in the response, so older middleware and raw nREPL sessions just fall back to text results, the same pattern we already use for content-types.
Recently I've been going through SLIME and SLY looking for features we still lack, and their REPL "presentations" caught my attention: clickable result objects you can inspect, tap, or feed back into the REPL by reference. It seems relatively doable. The Emacs/UI side is tracked in clojure-emacs/cider#4015; this issue is the server piece it needs.
The idea is to make eval results addressable, so the client can act on the live object instead of re-parsing printed text or leaning on
*1.Design
presentation-idto the eval response, alongside the existingvalue. No change to howvalueitself is printed.lookup-presentationop (or an extension of the existing inspect/eval ops) that takes an id and operates on the live object (inspect, tap, etc.), so the inspector can target an id rather than re-evaluating*1.#cider/ref Ntagged literal resolved from the ring to the live object. Tagged literals survive the reader cleanly, which is nicer than a custom reader macro.Some of this (the ring plus lookup) may fit better in orchard than in cider-nrepl; open to that.
Open questions
*1and presentation ids independent (leaning yes:*Nstays the Clojure last-3,#cider/refis the addressable ring).Graceful degradation
Everything keys off
presentation-idbeing present in the response, so older middleware and raw nREPL sessions just fall back to text results, the same pattern we already use for content-types.