Fork me on GitHub
#nrepl
<
2018-12-17
>
cgrand09:12:19

As I was reading Drawbridge, I stumbled on:

(if (find-ns 'clojure.tools.nrepl)
  (require
   '[clojure.tools.nrepl :as nrepl]
   '[clojure.tools.nrepl.server :as server]
   '[clojure.tools.nrepl.transport :as transport])
  (require
   '[nrepl.core :as nrepl]
   '[nrepl.server :as server]
   '[nrepl.transport :as transport]))
Wouldn’t it be more sensible to prefer nrepl.core over clojure.tools.nrepl?

cgrand09:12:11

@cfleming putting my thoughts together would take time and a small article. streaming pros: super simple model: 1 connection :: 1 repl :: 1 thread; can be taken over (powerful) streaming cons: tracking progress (see prepl and unrepl takes), mixed output streams (because of laziness, modern envs with more than 1 thread, err vs out etc.) (again unrepl and prepl both frame outputs, so their output is a stream of forms instead of a stream of characters); can be taken over (interfer with framing) RPC pros: 1 connection for everything; easy progress report (because framed input) RPC cons: thread management/serialization of evals; explicit lifecycle management; can not be taken over

cgrand09:12:56

summary reality is complex, RPC and streaming are ends of a continuum

bozhidar10:12:08

Excellent summary!

bozhidar10:12:16

> Wouldn’t it be more sensible to prefer nrepl.core over clojure.tools.nrepl?

bozhidar10:12:25

@cgrand Probably. I didn’t think much about this, as it was supposed to be a temporary measure and now that leiningen ships nREPL 0.5 we can remove all the compatibility code.

bozhidar10:12:05

Probably I’ll cut one more release of cider-nrepl that supports tools.nrepl and afterwards I’ll go over all the middleware/transport projects and drop this for simplicity’s sake.

👌 4
cgrand11:12:21

I’m happy to report that datafy/nav is now supported by rich (unrepl) printing: https://github.com/nrepl/nrepl/commit/26e51fbca0dfba5a9ee247605445df7e58e83269

aw_yeah 4
cgrand12:12:21

Obviously (as for elisions) it requires client-side ui. A datafiable value is represented as #unrepl/browsable [plain-value browsable-value] and to make this lazy the browsable-value is elided. For nav, it’s the same thing: if the datafied value is a map or a vector and is navigable then the map values becomes elided #unrepl/browsable whose elision triggers nav.

dominicm12:12:17

Does this affect existing clients? How?

cgrand12:12:37

unrepl printing is opt-in (set :printer to nrepl.elisions/printer on :eval)

eraserhd14:12:45

@cgrand I've been playing with the idea of not needing client side UI by binding variables to ..1 ..2 ..3 and so forth. Except I can't quite make the idea work.

cgrand14:12:04

for some simple elisions, it sort of work

cgrand14:12:34

I experimented with /1 /2 etc.

cgrand14:12:34

they are not readable so won’t clash with clojure code

cgrand14:12:26

..x are going to be tranformed by the compiler I think (because of the leading dot)

eraserhd14:12:41

Ahh, I wasn't to worried about that. I was worried about needing to keep the numbers forever.

cgrand14:12:53

(if they ccur in function position)

cgrand14:12:51

indeed if you use vars, they are interned and you can’t knwo when to GC

eraserhd14:12:54

you are right, hrmm

cgrand14:12:44

or you can choose to keep the last N vars

eraserhd14:12:00

right, and then you have unusable stuff in your history.

eraserhd14:12:17

but, I want it to work! :D

cgrand14:12:24

at some point GC pressure may cause collection of elisions anyway

cgrand14:12:31

click (or tab-navigate) to expand is a better ux if you can afford to

cgrand14:12:23

with datafy/nav, many values may be littered with small affordances hinting that an alternate view is available

eraserhd14:12:06

Anyway, I'm super excited to have this somehow baked in to my REPL. It solves quite a few problems for me, including 10,000 line exceptions in my primary app. So, thanks for working on it!

eraserhd17:12:48

Hey, that brings up a question about the nREPL client API. Why have a split between connection and client? It doesn't seem like multiple clients are possible per connection.

dominicm18:12:34

Why do you think they aren't?

cfleming19:12:20

@cgrand Thanks! I agree that the main benefit of streaming REPLs is that they’re composable, but that definitely comes at a cost.

eraserhd19:12:32

@dominicm I meant, to be clear, that it doesn't seem to add anything, AFAICT. There's not concept of client on the wire protocol, only session. And that's another layer of abstraction in the API.

dominicm19:12:56

@eraserhd I don't understand the point you're making. Can you give an example?

eraserhd19:12:10

I don't have a point, I want to understand abstracting clients from connections and sessions.

dominicm19:12:45

@eraserhd what's a client in this context?

eraserhd19:12:04

return of nrepl.core/client

dominicm19:12:56

But you would call that from a separate process, not necessarily even the same network