unrepl

discussing specification of an edn-based repl and its implementations.
2018-03-08T11:35:28.000109Z

Ah. Issue #36.

2018-03-08T11:38:31.000034Z

It keeps coming back to read tracking. 😿

cgrand 2018-03-08T11:42:18.000138Z

Don’t. Make. Cats. Cry.

cgrand 2018-03-08T11:44:23.000033Z

and I really want to remove unrepl/do

2018-03-08T11:51:11.000112Z

Yes. I see the problem now.

cgrand 2018-03-08T11:51:26.000104Z

Tell

cgrand 2018-03-08T11:58:04.000225Z

It’s good to hear people restating stuff, you get to see things under a different angle

2018-03-08T12:00:50.000389Z

I always forget about reading from stdin....

2018-03-08T12:01:31.000347Z

Like (read). Was happy to have it. Forgot about immediately. :face_palm:

2018-03-08T12:03:21.000414Z

Can we have a byte offset?

2018-03-08T12:04:30.000202Z

Scratch that.

cgrand 2018-03-08T12:04:47.000424Z

char offset not byte

2018-03-08T12:05:51.000350Z

Typing faster than thinking.

cgrand 2018-03-08T12:06:22.000135Z

with covering :readmessages it should be more frequent for the client to determine if nothing is “in flight”

2018-03-08T12:08:31.000249Z

Can I retrieve the exception from a repl? Without mocking with *1?

cgrand 2018-03-08T12:08:56.000346Z

heh?

2018-03-08T12:13:26.000112Z

At the moment I have to reimplement c.stacktrace. Because it expects a throwable. Also the stacktrace gets elided.

cgrand 2018-03-08T12:15:05.000030Z

Stop. Rewind. I need more context, I’m not following along at all

cgrand 2018-03-08T12:15:31.000138Z

Do you want the exception thrown by code evaluated in unrepl or something else?

2018-03-08T12:20:36.000287Z

I get an exception via unrepl. I want to pretty print it for human consumption. But I only get an #error with elided parts which doesn't read back in in the tooling connection.

2018-03-08T12:21:13.000404Z

So I need to translate things and have a modified pretty printer to understand the translated thing.

cgrand 2018-03-08T12:21:32.000228Z

It should read back. Can you reproduce it with just netcat?

2018-03-08T12:22:50.000328Z

I tried to read a (prn (Exception. ...)) in a plain repl. And it doesn't. Also the elision fails reading.

cgrand 2018-03-08T12:22:59.000180Z

Otherwise I do think that swapping some parts of unrepl to do most of the pretty printing server-side when the client-side is feeble is a good idea

cgrand 2018-03-08T12:23:13.000087Z

currently make-blob allows only actions to be customized

cgrand 2018-03-08T12:23:28.000118Z

but more hardcord customizations are possible

2018-03-08T12:27:47.000185Z

So you mean just to pretty print the EDN code?

cgrand 2018-03-08T12:38:06.000030Z

What’s the point of having machine-readable printings that your machine can’t print?

2018-03-08T12:39:23.000010Z

?

cgrand 2018-03-08T14:02:32.000163Z

If you can’t do stuff on the client side, modify the blob to have the server do most of it.

cgrand 2018-03-08T14:10:26.000367Z

reproduced with a more recent blob

2018-03-08T16:11:27.000358Z

Then how do I hook into things? Eg. Exception message emission?

cgrand 2018-03-08T16:12:44.000028Z

Let’s take a step back

cgrand 2018-03-08T16:13:02.000385Z

so full EDN is a bit too much for vim

cgrand 2018-03-08T16:15:18.000612Z

but doing all the pretty printing server side is too much too (at least for elisions)

cgrand 2018-03-08T16:16:24.000834Z

so why not emit some kind of markup?

2018-03-08T16:21:56.000474Z

Hi, is there some overview comparison between unrepl and nREPL? I haven't been able to figure it out from reading the readme and glancing over unrepl spec.

2018-03-08T16:23:40.000256Z

I like that unrepl wraps socket repl which makes it easy to plug in into CLJS environments. But if someone created a nREPL wrapper over socket repl would unrepl still have some other benefits?

2018-03-08T16:23:59.000443Z

???

2018-03-08T16:24:07.000014Z

I'm completely confused now.

2018-03-08T16:24:38.000037Z

I tried to keep vim jambowambo away from unrepl.

2018-03-08T16:24:51.000546Z

And indeed I think this would work perfectly well.

cgrand 2018-03-08T16:25:10.000362Z

can’t resolve “this”

2018-03-08T16:25:42.000500Z

this == "keep vim stuff away from unrepl"

2018-03-08T16:28:06.000524Z

My only grief at the moment is, that the provided representation of the exception cannot be easily machine-read back into clojure. At least not clojure 1.8.

cgrand 2018-03-08T16:28:35.000010Z

The goal of unrepl is to be transparent to the user: no configuration, no middleware. All you need is a repl (not even a socket one, I routinely test over stdin).

2018-03-08T16:28:54.000660Z

Also I somehow dislike elisions with exceptions.

cgrand 2018-03-08T16:29:26.000335Z

unrepl is meant to be an implementation detail for tools.

2018-03-08T16:31:03.000168Z

Also: I would only care for the user repls.

2018-03-08T16:31:23.000134Z

With the tooling I'm perfectly fine with #error.

2018-03-08T16:32:40.000113Z

Anyway, in the end it's a none problem. It works already. I just have to duplicate some of the pprint code from eg. c.stacktrace.

2018-03-08T16:33:47.000645Z

I'm not sure I even want to hook into unrepl any more than the actions.

cgrand 2018-03-08T16:34:29.000864Z

why?

bozhidar 2018-03-08T16:34:37.000006Z

> But if someone created a nREPL wrapper over socket repl would unrepl still have some other benefits?

bozhidar 2018-03-08T16:36:05.000467Z

@kloud Why would do something like this? You’ll still need middleware, so you’d gain very little. What would be more impactful would be to just update the implementation to target Clojure 1.7 and support ClojureScript natively (something that was obviously not possible when nREPL was created).

2018-03-08T16:55:11.000788Z

So far I don't see the need to.

cgrand 2018-03-08T17:01:21.000504Z

regular expression of the message stream :unrepl/hello (:prompt :read (:started-eval (:eval | :exception))?)*

cgrand 2018-03-08T17:10:52.000821Z

previsouly was :unrepl/hello (:prompt (:read :started-eval (:eval | :exception))*)*

2018-03-08T17:18:00.000248Z

I get this: unrepl.repl$pkrTyzbcFcA3scs1I83X8tI0iM0.proxy$clojure.lang.LineNumberingPushbackReader$ILookup$ILocatedReader$ff3fd87c cannot be cast to clojure.lang.IFn

2018-03-08T17:18:10.000628Z

With the latest commit.

cgrand 2018-03-08T17:18:15.000478Z

grmf

cgrand 2018-03-08T17:18:25.000650Z

when doing what?

2018-03-08T17:18:34.000456Z

in set_file_line_col

ghadi 2018-03-08T17:18:41.000300Z

is that a bitcoin hash?

2018-03-08T17:18:41.000569Z

set source

cgrand 2018-03-08T17:18:46.000095Z

found

cgrand 2018-03-08T17:19:11.000166Z

@ghadi no it’s dependency sha1ding

🍎 1
1
2018-03-08T17:19:54.000350Z

It's used from vv-vZOFetlbOcKtaQ-vCp699gbSDFw.vimpire.nails

2018-03-08T17:20:04.000696Z

Notice the fangs.

2018-03-08T17:22:24.000006Z

@bozhidar I am working on a clojurescript shell and would like to create a backend so that it could be possible to use it with different readline frontends.

cgrand 2018-03-08T17:24:04.000648Z

what’s the 🍎 for? I would have expected rotten 🍅

2018-03-08T17:24:59.000100Z

For this one needs more strucuted protocal, so socket repl is not suitable. And there is no clojurescript implementation for nREPL. So I was wondering if unrepl can be utilized since it seems to have cljs support.

dominicm 2018-03-08T17:25:13.000686Z

I like the metaphors.

bozhidar 2018-03-08T17:34:41.000677Z

What’s wrong with using piggieback? That’s nREPL’s classic way to support ClojureScript. Unless you need support for a self-hosted repl, which is not an option right now.

2018-03-08T17:36:05.000440Z

Yeah, we are running self-hosted on top of lumo.

2018-03-08T17:45:35.000777Z

@cgrand Is it possible, that I don't get eval and friends for :set-source?

cgrand 2018-03-08T17:46:59.000702Z

that’s unrepl/do dark arts

2018-03-08T17:49:25.000503Z

Baron Samedi comes to haunt the voodoo priests who opened a tomb without his permission.

2018-03-08T17:51:44.000273Z

Let's hope your machine doesn't crash and take it into oblivion before you can push. 🙂

cgrand 2018-03-08T18:06:30.000153Z

also: since there are more prompts now, prompts will announce the next eval-id

2018-03-08T18:10:05.000165Z

What will trigger now a prompt?

cgrand 2018-03-08T18:17:59.000269Z

you get a prompt after ignored characters (possibly 0 soon, when interrupted from aux) or after evaluation

2018-03-08T20:37:11.000589Z

vimpire does now read tracking. That means commands are framed based on their submission. This is mostly interesting for the tooling repl.

2018-03-08T20:37:42.000014Z

For the repl buffer that means the prompt is only shown once at the end after all submitted commands are executed.

2018-03-08T20:38:11.000240Z

It also means that something like: user=> (read) (+ 1 2) will break the connection.

2018-03-08T20:38:51.000037Z

Is that a progress?

cgrand 2018-03-08T21:10:34.000455Z

@kotarak can you outline your algorithm?

2018-03-08T22:20:24.000507Z

The connection starts out in state prompt. Then input is sent. This happens in a queued context. Agent-like. A context may contain several forms. In particular the context also contains the length of input and callbacks for the events. This is important because vim channels are asynchronous. The conn is put into state evaling. The read event is used to reduce the remaining length. Eval checks whether there is input remaining. If so, the conn is kept in evaling state. The prompt handler sees the evaling state and does nothing. The next form is read. In particular are the proper callbacks still in place. Then we come back to eval eventually. Now assume, the input for the context is exhausted. Then the context is popped from the queue. And the connection is put into awaiting-prompt state. On the next prompt the handler recognises this. It switches the connection back to prompt state and triggers the execution of the next context in the queue (if any). And then things start over.

2018-03-08T22:24:06.000032Z

One special case: if the prompt handler sees the combination of evaling and exhausted input it assumes unrepl/do or whitespace only input and pops the context from the queue itself. The only way the prompt handler can see exhausted input is by skipping the eval handler.

2018-03-08T22:29:13.000348Z

The repl buffer is built on this. With some special handlers for output and exceptions. However, eg. a (read) does not generate read events. So "user=> (read) :foo" will break the connection state because the :foo will be consumed without the conn knowing about it. So it will wait forever for the "remaining" five chars to be read.