Skip to content

A result ring for REPL presentations (addressable result objects) #988

Description

@bbatsov

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions