unrepl

discussing specification of an edn-based repl and its implementations.
bozhidar 2018-01-04T18:52:41.000112Z

A small first step https://github.com/clojure-emacs/orchard šŸ™‚

šŸ‘ 4
bozhidar 2018-01-04T18:54:36.000520Z

Iā€™ve granted commit access to @volrath, @pesterhazy and @dominicm. Iā€™ll starting moving some logic out of cider-nrepl over the weekend (hopefully), but Iā€™d appreciate it if you join the effort to make something cross-tool compatible.

dominicm 2018-01-04T18:54:57.000505Z

Oh cool, would love to

pesterhazy 2018-01-04T19:25:49.000275Z

@bozhidar very nice. Also love the name

pesterhazy 2018-01-04T19:27:28.000500Z

one simple thing to contribute could be a fail-safe doc command: https://github.com/Unrepl/unravel/blob/0b7fe0e95912915d3144c79026778463702e3163/src/unravel/loop.cljs#L129

pesterhazy 2018-01-04T19:27:53.000038Z

background: (clojure.repl/doc a.b) throws an exception

richiardiandrea 2018-01-04T19:30:48.000454Z

@pesterhazy that's weird

richiardiandrea 2018-01-04T19:33:07.000296Z

@pesterhazy it must some problem related to something else, here is how inf-clojure does it: https://github.com/clojure-emacs/inf-clojure/blob/master/inf-clojure.el#L711

pesterhazy 2018-01-04T19:37:18.000357Z

Have you tried with a.b?

richiardiandrea 2018-01-04T19:43:36.000449Z

oh now let me try

richiardiandrea 2018-01-04T19:45:35.000491Z

@pesterhazy I get ClassNotFoundException of course šŸ˜‰

richiardiandrea 2018-01-04T19:47:07.000117Z

I mean is, should doc be failsafe? Or should be the client's responsibility to catch and show the error? In inf-clojure the latter has been chosen

cgrand 2018-01-04T19:49:15.000206Z

@pesterhazy doesnā€™t your need to have a failsafe doc comes from the fact that you automatically call doc on the current symbol?

pesterhazy 2018-01-04T19:50:05.000034Z

Yeah I could check if itā€™s a valid symbol

cgrand 2018-01-04T19:50:48.000507Z

@richiardiandrea try (doc java.lang.Object) for a different exception

pesterhazy 2018-01-04T19:50:51.000382Z

Although it should work for nss too so...

pesterhazy 2018-01-04T19:51:16.000353Z

Maybe best not to rely on doc

cgrand 2018-01-04T19:51:29.000050Z

@pesterhazy canā€™t you just handle the error?

richiardiandrea 2018-01-04T19:51:46.000497Z

@pesterhazy I think info is supposed to do something more than doc

pesterhazy 2018-01-04T19:52:08.000442Z

Sure Iā€™m doing that now, with the eval hack

richiardiandrea 2018-01-04T19:52:10.000579Z

@cgrand yep I am just saying that in inf-clojure we handle the error client side

richiardiandrea 2018-01-04T19:53:28.000651Z

but Paulus raised a good point, should this "middle layer" handle error handling and to which extent? Imho it shouldn't because different clients might need/want to do things differently

volrath 2018-01-04T20:14:38.000618Z

this is awesome! I was, in fact, wondering what to do next, and orchard was the top choice... I have lots of free time this month except for next week, so it's just a matter of coordinating with you guys so that I can get to work here. @bozhidar is this the type of files that we're expecting to have in orchard? https://github.com/Unrepl/spiral/blob/master/tools/src/spiral/tools/completion.clj -- basically same as cider-nrepl but replacing middlewares for plain functions? what other considerations do we have to be aware of while migrating?

volrath 2018-01-04T20:15:10.000174Z

actually, let me move this to the main thread...

bozhidar 2018-01-04T20:16:28.000549Z

Iā€™m guessing itā€™d be nice if there was a function that returned some more meaningful result when somethingā€™s not found. cider-nrepl for instances has to catch all exceptions in the middleware otherwise sync requests would time out.

volrath 2018-01-04T20:16:56.000166Z

> A small first step https://github.com/clojure-emacs/orchard šŸ™‚ this is awesome! I was, in fact, wondering what to do next, and orchard was the top choice... I have lots of free time this month except for next week, so it's just a matter of coordinating with you guys so that I can get to work here. @bozhidar is this the type of files that we're expecting to have in orchard? https://github.com/Unrepl/spiral/blob/master/tools/src/spiral/tools/completion.clj -- basically same as cider-nrepl but replacing middlewares for plain functions? what other considerations do we have to be aware of while migrating?

bozhidar 2018-01-04T20:17:07.000204Z

Not a big deal, of coruse, but a little annoying.

bozhidar 2018-01-04T20:19:47.000543Z

@volrath Yeah, exactly. Well itā€™d be nice if when migrating things you also replace what was extracted with references to orchard. > basically same as cider-nrepl but replacing middlewares for plain functions? Yes. > what other considerations do we have to be aware of while migrating? Just the standard ones - good names, some documentation and tests, reasonable APIs. šŸ™‚

bozhidar 2018-01-04T20:21:47.000384Z

Obviously we donā€™t have to get it right from the start. šŸ˜„

volrath 2018-01-04T20:22:38.000335Z

regarding exceptions and the doc thing.. I think this library should not shadow exceptions and clients should handled them on their own. In general, i think of orchard as just another library that can be extended by the client's own tooling. cider needs to do this by adding the nrepl wrappers, and I'm pretty sure spiral will need to have it's own clj code in some cases as well. I guess the key is to make it as generic as possible

volrath 2018-01-04T20:23:37.000408Z

so I agree with @richiardiandrea, clients should do their own "middle layer"

volrath 2018-01-04T20:24:00.000587Z

another thing that I wonder is how should we proceed regarding cljs

bozhidar 2018-01-04T20:24:54.000279Z

Iā€™m fine either way. My point was that if you had a function returning :orchard/symbol-not-found or something like this, itā€™s more or less the same level of abstraction, but a bit easier to handle in the tooling code.

dominicm 2018-01-04T20:25:24.000098Z

Exposing exceptions (and ergo implementation) stops you from categorizing so well.

dominicm 2018-01-04T20:26:28.000064Z

The more tightly we define the API, the simpler it is to use the library, as the inputs and outputs are defined.

bozhidar 2018-01-04T20:26:39.000343Z

> another thing that I wonder is how should we proceed regarding cljs cljs-tooling is tiny and was written before the era of cljc, so I guess we should integrate into orchard.

dominicm 2018-01-04T20:26:52.000566Z

I agree.

dominicm 2018-01-04T20:28:29.000144Z

We can always extend functions with new return values, and make it clear that functions may return new values in the future.

volrath 2018-01-04T20:32:26.000088Z

my fear is that exceptions provide meaningful information that can be used by clients in some cases, so shadowing them becomes tricky. In any case, a client could have its own clj code to catch exceptions and return an value that's easier to handle by the client's code

richiardiandrea 2018-01-04T20:32:56.000407Z

Yeah..if you think of cljs-lumo-planck then each and every of it throw different things...

dominicm 2018-01-04T20:33:35.000332Z

@volrath clients should expose that information via the api

dominicm 2018-01-04T20:33:42.000152Z

And give a PR

dominicm 2018-01-04T20:35:30.000356Z

I'd consider poking at those exceptions use of an "internal API", not something that's defined or guaranteed to continue working into the future.

volrath 2018-01-05T10:53:15.000148Z

so, I tried doc in lumo and it returns nil when the var doesn't exist, instead of throwing like clojure.repl/doc -- so now I think I'm closer to @dominicm's opinion on having the API handle certain errors. again, my fear is that I think this is a slippery slope towards having an inconsistent and, as @cgrand said, leaky abstraction. I mean inconsistent in terms of having to carefully decide whether an error is worth shadowing, since shadowing might mean loss of information

volrath 2018-01-05T10:53:26.000031Z

I like the idea of throwing with ex-info

dominicm 2018-01-05T10:57:16.000048Z

Loss of information isn't an argument I understand. If there's useful information to expose, it can be exposed (via a PR). Ex-info has a nice middle ground if you set the cause trace, as people can choose to poke at internals. The problem is if your contract marks a particular exception, you have no chance at changing the function, nor at general portability.

cgrand 2018-01-05T11:13:02.000080Z

@dominicm not sure I get what you mean by PR in this context

cgrand 2018-01-05T11:13:34.000157Z

Pull Request?

dominicm 2018-01-05T11:14:16.000098Z

@cgrand yeah. Nothing stops a user of the library exposing additional information as data.

cgrand 2018-01-05T11:20:12.000035Z

Iā€™m still not sure that I follow. Letā€™s say you have orchardā€™s doc which returns errors as data. Comes a user of orchard who is not satisfied by the data returned and needs more. You are suggesting that s/he should create a PR to have her/his change merged?

dominicm 2018-01-05T11:42:47.000329Z

Yes and/or create a local fork.

cgrand 2018-01-05T11:49:11.000052Z

Not lossing information allows the user to ship his own workaround right now and without having to fork. This doesnā€™t preclude him to at the same time discuss a change to the upstream lib. To me it has the following benefits: ā€¢ no fork (not having to understand the code and no extra build/deploy, not having to maintain the fork if the change never makes it upstream) ā€¢ ship right now without waiting on upstream patch ā€¢ (corollary of the previous point) less pressure on the maintainer of the lib, time to think about a proper fix or even to say no.

dominicm 2018-01-05T11:52:06.000312Z

I like those benefits, to the degree that they don't prevent improvements. My concern is about the workaround becoming part of general use. I actually think ex-info provides a nice middle ground in this. The ex-info exception is the API, the cause stack is the workaround. I want to ensure that orchard maintainers never feel compelled to prevent a change of code for the good, because other users might be relying on workarounds. Where those workarounds rely on implementation-specific exceptions.

volrath 2018-01-04T20:38:52.000350Z

@dominicm not sure if I follow that last bit

dominicm 2018-01-04T20:42:26.000338Z

@volrath exceptions are hard to make part of the API. They tend to shift. I'd think that any client using a random exception thrown by a function will break in a future version of the library. I tend to prefer that a function will use data, and clearly indicate what may go wrong. This gives more flexibility for the function to change, without breaking clients.

volrath 2018-01-04T20:49:13.000333Z

so you're saying that if a client needs an exception info/stacktrace, it should ask for it "post-mortem"? If so, I think this would be a pretty big commitment for a library targetting any type of clojure tooling. Another approach could be have the client ask to shadow certain well known possible errors (like doc when the var doesn't exist), so for example, the orchard/doc function could take an optional parameter indicating not to throw on this particular error.

richiardiandrea 2018-01-04T21:04:41.000525Z

In boot, as @dominicm might know, we serialize to string the stack traces so that it can be shared between tasks (from boot-cljs). That can be an option too

richiardiandrea 2018-01-04T21:15:09.000311Z

By serialize I mean maybe more normalize to a standard format

dominicm 2018-01-04T21:45:42.000160Z

Those details can be as minimal as required.

dominicm 2018-01-04T21:49:15.000260Z

My argument is more about expected cases, e.g. Non-existing var is something we expect can happen. I'm not sure it's a good idea to have clients build on exceptions which may not exist later. It gives friction to change. I guess I'm suggesting that the API should include some "error" cases which are expected (by some definition), and give a straightforward data description for each case.