unrepl

discussing specification of an edn-based repl and its implementations.
richiardiandrea 2018-01-01T00:14:49.000058Z

Happy New year to you all on that side then! Here I still need to wait a bit ๐Ÿ™‚

bozhidar 2018-01-01T05:43:53.000023Z

Happy New Year, everyone! :partywombat:

bozhidar 2018-01-01T05:44:17.000049Z

Itโ€™s almost 8 am at home and Iโ€™m just wrapping up the NY party here. ๐Ÿ˜„

cgrand 2018-01-01T13:16:00.000017Z

Happy New Year to you all!

pesterhazy 2018-01-01T13:44:03.000086Z

Happy New Year and happy new spiral Issue @volrath

volrath 2018-01-01T13:44:24.000024Z

๐ŸŽ‰

volrath 2018-01-01T13:44:33.000016Z

haha, looking at it

pesterhazy 2018-01-01T15:44:22.000002Z

holy moly, spiral's git repo is 102M big

volrath 2018-01-01T15:46:58.000003Z

the gifs...

pesterhazy 2018-01-01T15:49:30.000062Z

ahh lol!

volrath 2018-01-01T15:49:38.000013Z

they're about 50mb, plus the git ref objects, twice that size

pesterhazy 2018-01-01T15:50:32.000022Z

@volrath can't figure out to install spiral from master

pesterhazy 2018-01-01T15:50:42.000065Z

followed the instructions in the readme but

pesterhazy 2018-01-01T15:50:50.000030Z

Debugger entered--Lisp error: (file-error "Cannot open load file" "No such file or directory" "a")
  require(a)
  eval-buffer(#<buffer  *load*-613561> nil "/Users/pe/prg/spiral/parseclj/parseclj-parser.el" nil t)  ; Reading at buffer position 1146
  load-with-code-conversion("/Users/pe/prg/spiral/parseclj/parseclj-parser.el" "/Users/pe/prg/spiral/parseclj/parseclj-parser.el" nil t)
  require(parseclj-parser)
  eval-buffer(#<buffer  *load*-630384> nil "/Users/pe/prg/spiral/parseclj/parseclj.el" nil t)  ; Reading at buffer position 1113
  load-with-code-conversion("/Users/pe/prg/spiral/parseclj/parseclj.el" "/Users/pe/prg/spiral/parseclj/parseclj.el" nil t)
  require(parseclj)
  eval-buffer(#<buffer  *load*-294663> nil "/Users/pe/prg/spiral/spiral-loop.el" nil t)  ; Reading at buffer position 1277
  load-with-code-conversion("/Users/pe/prg/spiral/spiral-loop.el" "/Users/pe/prg/spiral/spiral-loop.el" nil t)
  require(spiral-loop)
  eval-buffer(#<buffer  *load*> nil "/Users/pe/prg/spiral/spiral.el" nil t)  ; Reading at buffer position 1491
  load-with-code-conversion("/Users/pe/prg/spiral/spiral.el" "/Users/pe/prg/spiral/spiral.el" nil t)
  require(spiral)
  (let ((spiral-dir "/Users/pe/prg/spiral")) (add-to-list (quote load-path) spiral-dir) (add-to-list (quote load-path) (expand-file-name "parseclj" spiral-dir)) (require (quote spiral)))
  eval((let ((spiral-dir "/Users/pe/prg/spiral")) (add-to-list (quote load-path) spiral-dir) (add-to-list (quote load-path) (expand-file-name "parseclj" spiral-dir)) (require (quote spiral))) nil)
  elisp--eval-last-sexp(nil)
  #[257 "\204\303!\207	\303!\n)B\211A	=\204\211A\211@\207" [eval-expression-debug-on-error elisp--eval-last-sexp-fake-value debug-on-error elisp--eval-last-sexp] 4 2269455 "P"](nil)
  ad-Advice-eval-last-sexp(#[257 "\204\303!\207	\303!\n)B\211A	=\204\211A\211@\207" [eval-expression-debug-on-error elisp--eval-last-sexp-fake-value debug-on-error elisp--eval-last-sexp] 4 2269455 "P"] nil)
  apply(ad-Advice-eval-last-sexp #[257 "\204\303!\207	\303!\n)B\211A	=\204\211A\211@\207" [eval-expression-debug-on-error elisp--eval-last-sexp-fake-value debug-on-error elisp--eval-last-sexp] 4 2269455 "P"] nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

volrath 2018-01-01T15:51:15.000026Z

did you package-install a?

pesterhazy 2018-01-01T15:51:16.000048Z

(by the way why are emacs stacktraces so ugly??)

volrath 2018-01-01T15:51:26.000073Z

they are the worst!

pesterhazy 2018-01-01T15:51:29.000057Z

there's a package called a???

volrath 2018-01-01T15:51:42.000065Z

yep, is Arne's

pesterhazy 2018-01-01T15:51:48.000009Z

whoever came up with that should be ... oops ๐Ÿ™‚

volrath 2018-01-01T15:51:56.000068Z

it's a dependency of parseclj

volrath 2018-01-01T15:51:57.000051Z

haha

pesterhazy 2018-01-01T15:52:12.000049Z

very hard to figure that out from the stacktrace

volrath 2018-01-01T15:52:12.000065Z

a as in Associative data structures for elisp

volrath 2018-01-01T15:52:58.000034Z

you need a, clojure-mode (which you have already) and treepy

pesterhazy 2018-01-01T15:53:15.000053Z

looks like I didn't actually read the readme

pesterhazy 2018-01-01T15:53:18.000082Z

serves me right ๐Ÿ™‚

pesterhazy 2018-01-01T15:54:18.000050Z

usually I try to follow a readme roughly and then let myself be guided by the errors

volrath 2018-01-01T15:56:51.000024Z

spiral master installation is not so straight forward because of the parseclj submodule/dependency

pesterhazy 2018-01-01T15:57:24.000028Z

yeah I totally get that

volrath 2018-01-01T15:57:25.000049Z

but cool that you got it to work, melpa is updating really slow lately, the fix will be there sometime today, I guess

pesterhazy 2018-01-01T15:57:29.000033Z

the instructions are great

volrath 2018-01-01T16:03:56.000029Z

btw, I've been thinking into implementing more tooling, particularly getting information about symbols, for documentation or any other purposes. This type of tooling is not only relevant to spiral, but to any unrepl client, so I was thinking we should start considering creating a repo for it

volrath 2018-01-01T16:04:25.000102Z

things that can be reused between unravel and spiral, that may not fit in unrepl itself

volrath 2018-01-01T16:05:33.000009Z

another way to go would be to look into cider-nrepl and try to split that into library / nrepl stuff, and make it generic enough so that it's useful for unrepl clients

pesterhazy 2018-01-01T16:17:15.000020Z

@volrath you mean clojure code like https://github.com/unrepl/unravel/blob/throwable/src/unravel/loop.cljs#L120 ?

pesterhazy 2018-01-01T16:17:27.000047Z

as a simple example

pesterhazy 2018-01-01T16:18:08.000070Z

that could be a library actually that we include in the unrepl blob (or add as a second blob)

volrath 2018-01-01T16:18:11.000055Z

correct

volrath 2018-01-01T16:18:32.000045Z

or as a sideloded jar ๐Ÿ™‚

pesterhazy 2018-01-01T16:18:33.000050Z

@volrath do you have a pointer to the corresponding code in CIDER?

volrath 2018-01-01T16:18:40.000001Z

yes, sec

volrath 2018-01-01T16:21:27.000065Z

@pesterhazy for example, this function will give you information about any symbol, if it's a special form, a function, macro, or java class/member, its arglist if any, docstring, etc.. https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/middleware/info.clj#L87

pesterhazy 2018-01-01T16:22:09.000010Z

ah right so in CIDER it's part of the nrepl middleware

pesterhazy 2018-01-01T16:22:39.000063Z

I think spinning that off as a (reusable?) library would be great

volrath 2018-01-01T16:22:42.000023Z

another example on cider-nrepl is this: https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/middleware/complete.clj which I basically copied the only interesting part that I needed here: https://github.com/Unrepl/spiral/blob/master/tools/src/spiral/tools/completion.clj

pesterhazy 2018-01-01T16:22:49.000043Z

ideally 0 calories (no deps)

volrath 2018-01-01T16:23:01.000050Z

yeah exactly

volrath 2018-01-01T16:23:46.000034Z

so cider-nrepl has the two things coupled, and even though we could use it and only refer to the functions that we need, it's far from 0 calories

volrath 2018-01-01T16:25:00.000023Z

but what I think we should start thinking is have a unified place where to create these helpers that all clients might benefit from... I was going to start building my own version of info in spiral, but then I thought maybe we share them and reuse them

pesterhazy 2018-01-01T16:25:32.000055Z

definitely, unravel needs those just as much

pesterhazy 2018-01-01T16:25:43.000021Z

same with all future clients

volrath 2018-01-01T16:25:48.000017Z

right

pesterhazy 2018-01-01T16:26:06.000064Z

I'm getting a bit worried that we're spawning too many repos

pesterhazy 2018-01-01T16:26:35.000004Z

it makes integration more complicated because you need submodules or some other means of coordination

pesterhazy 2018-01-01T16:27:14.000044Z

otoh I don't know what alternative is better (monorepo for all things unrepl?)

pesterhazy 2018-01-01T16:27:57.000089Z

I know that React uses a monorepo for all their projects, even if they're disparate as modules (react, react-dom, react-server, ...)

pesterhazy 2018-01-01T16:28:49.000002Z

what do you think?

volrath 2018-01-01T16:29:52.000083Z

for this, I'm thinking maybe just a separate repo, and clients would include a jar file... submodules would still be an option for client authors that might wanna hack on the tooling library and release their own versions of it

volrath 2018-01-01T16:30:17.000015Z

the jar file can be sideloaded the same way as a submodule folder

pesterhazy 2018-01-01T16:30:53.000017Z

right

volrath 2018-01-01T16:31:17.000045Z

tbh, I'm not sure how to make mono repo work, I'm not being able to picture it

pesterhazy 2018-01-01T16:31:37.000035Z

the missing piece is "shading' (to echo @dominicm) the namespaces

volrath 2018-01-01T16:31:52.000021Z

yes....

volrath 2018-01-01T16:32:02.000046Z

that's a big deal

pesterhazy 2018-01-01T16:32:25.000032Z

I don't want to leave too much perf on the table by unpacking a jar, regex the hell out of the ns declarations, than re-assembling it, all at runtime

volrath 2018-01-01T16:32:27.000019Z

cider-nrepl uses mranderson and it works fine

pesterhazy 2018-01-01T16:32:41.000020Z

is that done at runtime?

dominicm 2018-01-01T16:32:45.000018Z

No

volrath 2018-01-01T16:32:46.000047Z

they do it at build time, I think....

pesterhazy 2018-01-01T16:33:26.000076Z

I guess you might as well reuse the NS if it's the same exact version

volrath 2018-01-01T16:33:38.000038Z

yes

pesterhazy 2018-01-01T16:34:20.000025Z

so we'd just bundle a shaded "clojure-tooling.jar"

pesterhazy 2018-01-01T16:34:29.000041Z

sounds good to me

volrath 2018-01-01T16:36:25.000010Z

cool, I'm going to create an issue in unrepl, as I'm sure @cgrand will have interesting thoughts on this

๐Ÿ‘ 1
richiardiandrea 2018-01-01T17:15:46.000035Z

@volrath Does spiral already support the classic apropos, doc, ... I would start from those as they are a must in any lisp (see geiser) the build up. Also wanted to ask what you guys think about REPL types (cljs, lumo, Planck..). I am asking not to port things right now but to take into consideration while hooking up things, like in inf-clojure, a simple defcustom might be the solution.

pesterhazy 2018-01-01T17:18:28.000021Z

@richiardiandrea I don't understand. Cider, spiral and inf-clojure use vastly different methods if interacting with the repl. How could that be just a matter of a defcustom?

richiardiandrea 2018-01-01T17:20:50.000040Z

@pesterhazy are they? In any case not maybe a matter of just a defcustom, just asking if you folks considered the multiple REPL type thing or it is out of scope for now

pesterhazy 2018-01-01T17:23:50.000044Z

I'd say they're pretty different. Sure there could be a layer of abstraction, but that would be a lot of effort โ€” essentially merging multiple project. Or am I misunderstanding?

richiardiandrea 2018-01-01T17:27:00.000039Z

@pesterhazy maybe I am oversimplifying ๐Ÿ˜„

richiardiandrea 2018-01-01T17:35:21.000033Z

@pesterhazy @volrath thinking a bit more about this, in inf-clojure each operation is dispatched based on the REPL type: https://github.com/clojure-emacs/inf-clojure/blob/master/inf-clojure.el#L808

richiardiandrea 2018-01-01T17:35:55.000084Z

Then each op is defined by a defcustom: https://github.com/clojure-emacs/inf-clojure/blob/master/inf-clojure.el#L837

richiardiandrea 2018-01-01T17:36:13.000039Z

This can be expanded by adding the connection type

richiardiandrea 2018-01-01T17:36:54.000056Z

So that the dispatch now is on [conn-type op]

pesterhazy 2018-01-01T17:36:55.000079Z

@volrath as requested, in master you can now run arbitrary unravel sessions in "dual pane debug" view, e.g.

scripts/dual bin/unravel --debug --method clojure

โž• 1
volrath 2018-01-01T17:40:02.000032Z

@richiardiandrea > Does spiral already support the classic apropos, doc, ... I would start from those as they are a must in any lisp (see geiser) the build up. My initial intention is to start with eldoc, then I was going to decide between apropos or just something that would resolve symbols to its fully qualified name so that we could integrate tools like grimoire

volrath 2018-01-01T17:43:49.000019Z

about dispatching on the type of repl, I think we'll need to do something similar... the idea is that unrepl as a protocol would be a common ground to communicate to any type of repl, but definitely tooling would vary depending on the underlying actual repl. For that, I think there might be 2 options: 1. use the custom session actions that @cgrand added to unrepl, so that client authors could specify actions for completing on the jvm or on lumo or whatever, for example, 2. let the tooling library decide how to do it, which i think it would be best

volrath 2018-01-01T17:44:32.000029Z

so that client authors only have one way to call for completion, and the tooling library decides how to do it.. the only thing is that I'm not sure if this approach is generic enough to cover things beside completion

richiardiandrea 2018-01-01T17:49:12.000061Z

@volrath Some actions (ok I found the common term now) cannot be shared for, say, text repls and I think this is partly why there is a "manifest" in the unrepl initial :hello to advertise capabilities. Having said that I was more thinking in terms of UI. I would really like to see your UI applied to inf-clojure simple and not bloated REPL.

richiardiandrea 2018-01-01T17:50:43.000019Z

The dispatch on connection type + repl type + op is a simple layer on top I could take care of (already done that in inf-clojure)

richiardiandrea 2018-01-01T17:52:31.000001Z

The only thing I am asking is if there is interest in this now, never or later. I see value, but maybe I am the only one ๐Ÿ˜ƒ

richiardiandrea 2018-01-01T17:54:06.000008Z

Maybe I can propose it in the next hack day ๐Ÿ˜บ

volrath 2018-01-01T17:54:53.000040Z

I think I'm a bit lost ๐Ÿ˜ณ do you mean if there's a need of dispatching depending on connection type (clj, cljs, self-hosted cljs) in spiral? or in any unrepl client?

richiardiandrea 2018-01-01T17:56:17.000012Z

I am talking about spiral only yes. Do you mean you would like to push the dispatching at the tooling library level?

volrath 2018-01-01T17:57:25.000079Z

hopefully yes. the thing is that unrepl only works in clojure so far, so there's no way to connect to cljs, or lumo/plank/... as in inf-clojure

volrath 2018-01-01T17:57:37.000059Z

that's why i only did completion for the jvm only

volrath 2018-01-01T17:58:05.000004Z

but once there's support for (self hosted)cljs, we definitely will want to port all the tooling

richiardiandrea 2018-01-01T17:58:24.000109Z

All the other repls have socket, I am not even thinking stdin/out

volrath 2018-01-01T17:58:51.000037Z

the thing I'm wondering is if we could push all of this to the tooling library, as you say, so that clients can just dispatch the same session actions

volrath 2018-01-01T17:59:14.000004Z

there are some initial efforts to bring support for unrepl in lumo, check this out

volrath 2018-01-01T17:59:33.000017Z

https://github.com/cgrand/lumo/tree/suspension

volrath 2018-01-01T18:00:22.000227Z

that branch let's you have a suspension in lumo's socket repl, so that you can upgrade it to unrepl

richiardiandrea 2018-01-01T18:00:32.000039Z

Uhm, I feel that would bring us to the brittleness of the current cider-nrepl. I liked the idea of clients deciding that actually

richiardiandrea 2018-01-01T18:01:01.000040Z

Yep I am very aware of that

volrath 2018-01-01T18:01:56.000107Z

alright, so you think it'd be better to have different session actions for, say, completing, depending on the host? that could also be an option

richiardiandrea 2018-01-01T18:03:15.000023Z

I'll be back, breakfast time with family

volrath 2018-01-01T18:07:03.000031Z

either way, I think this is something that not only concerns spiral but all the family of unrepl clients, because we definitely should want to have a standarized way to handle this. Maybe we could also discuss this in unrepl#30. If we go with having host-dependent actions, then spiral would certainly need something similar to what inf-clojure does ๐Ÿ™‚ but instead of defcustoms, it would be session actions that are declared in :hello

richiardiandrea 2018-01-01T18:22:55.000002Z

On the other end it would be pretty trivial for inf-clojure to support the basics of the unrepl protocol. Ok ok going ๐Ÿ›ฉ๏ธ

bozhidar 2018-01-01T19:08:15.000014Z

> Uhm, I feel that would bring us to the brittleness of the current cider-nrepl. I liked the idea of clients deciding that actually

bozhidar 2018-01-01T19:08:19.000051Z

What brittleness?

bozhidar 2018-01-01T19:09:04.000018Z

> so cider-nrepl has the two things coupled, and even though we could use it and only refer to the functions that we need, itโ€™s far from 0 calories

bozhidar 2018-01-01T19:09:35.000006Z

Iโ€™m not sure if you understand what this middleware does - it simple calls two completion functions from two different libraries.

bozhidar 2018-01-01T19:09:53.000041Z

Obviously thereโ€™s no way to use the libraries without depending on them. ๐Ÿ™‚

bozhidar 2018-01-01T19:11:38.000098Z

All of the middleware is really easy to reorganize into something generic - the nREPL handlers call just a single function generating the desired result and thatโ€™s it. Nothingโ€™s really coupled between nREPL and utility logic. There was just no real need to have different namespaces when there was just a single user of this code.

bozhidar 2018-01-01T19:23:03.000046Z

Itโ€™s similar for info - thereโ€™s one implementation for Clojure thatโ€™s in cider-nrepl itself and another for cljs in cljs-tooling.

bozhidar 2018-01-01T19:23:45.000048Z

> they do it at build time, I think....

bozhidar 2018-01-01T19:23:48.000045Z

Yeah, thatโ€™s true.

bozhidar 2018-01-01T19:24:20.000020Z

We just deploy artefacts that have been processed with mranderson.

๐Ÿ‘ 1
dominicm 2018-01-01T19:57:03.000017Z

I'm getting close to a point where I might take a shot at doing the cider-nrepl port work.

dominicm 2018-01-01T19:59:27.000043Z

I've just got a full build system shoe-horned into clj command line tool, and I'm aware of a frustration (with myself) with having to provide support for tooling baked-in. So I'm keen to reach a point where I can tell people to sideload their own damn dev tools and leave me alone ๐Ÿ˜„. Once I add support for unrepl to replant (unreplant?) I'll probably say that it's time for people to move over ๐Ÿ˜„

dominicm 2018-01-01T19:59:35.000002Z

(of course, I can say that to my team, as long as emacs has a good story)

bozhidar 2018-01-01T20:48:18.000007Z

๐Ÿ™‚

bozhidar 2018-01-01T20:49:01.000009Z

> Iโ€™m getting close to a point where I might take a shot at doing the cider-nrepl port work. Iโ€™ll also try to do something on the subject in the next couple of weeks.

bozhidar 2018-01-01T20:49:57.000106Z

Might be fun to write a bit of pure Clojure for a change. ๐Ÿ˜„

pesterhazy 2018-01-01T21:04:01.000060Z

nice!

richiardiandrea 2018-01-01T23:12:07.000009Z

Maybe brittleness in not the right word here, but the reason I switched to inf-Clojure was to avoid errors due to the middleware libraries and have shorter stack traces.