unrepl

discussing specification of an edn-based repl and its implementations.
cgrand 2017-04-11T07:32:10.764933Z

To wrap yesterday lesson, here is the canonical source on closure behavior https://developers.google.com/closure/compiler/docs/api-tutorial3?csw=1#propnames

cgrand 2017-04-11T07:33:03.775347Z

What’s fun is that most of my aset/`aget` should have been plain property accessors.

cgrand 2017-04-11T13:19:47.566799Z

I saw some cljs like (js/console.log ...) is it another case that it works by accident and should be avoided?

thheller 2017-04-11T13:30:39.792265Z

@cgrand you can use (js/<anything-global>.foo.bar.baz)

thheller 2017-04-11T13:31:14.804513Z

do not use it for any locals though

thheller 2017-04-11T13:33:05.844413Z

its fine and used commonly .. so probably not going away. many people rely on it

cgrand 2017-04-11T13:34:26.874182Z

dnolen (in the link above): > It’s perfectly fine to write js/console.log this is supported and never going to change. This tends to occur in interop situations anyhow so it’s non-portable anyway.

thheller 2017-04-11T13:35:00.886797Z

oh its official then .. 🙂

cgrand 2017-04-11T13:35:31.898192Z

@thheller what about (<whatever>/foo.bar.baz ...)?

thheller 2017-04-11T13:36:00.909562Z

no thats reserved for namespace aliases

thheller 2017-04-11T13:36:08.912136Z

which js is in some way, sort of reserved alias

thheller 2017-04-11T13:37:04.933356Z

and foo.bar.baz is not a valid var name

cgrand 2017-04-11T13:38:01.954017Z

hmmm it’s bizarre to bless it only for js (it works with any ns or alias)

thheller 2017-04-11T13:38:29.964302Z

js is treated very differently and for interop only

cgrand 2017-04-11T13:40:12.002281Z

=> (ns a)
nil
WARNING: a is a single segment namespace at line 1
a=> (def foo #js {:bar 42})
#’a/foo
a=> (ns b)
nil
WARNING: b is a single segment namespace at line 1
b=> a/foo.bar
42

pesterhazy 2017-04-11T13:52:29.279998Z

be aware of the pitfalls of js/ though

pesterhazy 2017-04-11T13:52:32.280806Z

cljs.user=> (let [window :foo] (prn js/window))
:foo

pesterhazy 2017-04-11T13:53:36.305080Z

js/ isn't really a namespace, I see it more like custom syntax

cgrand 2017-04-11T14:06:26.611990Z

@pesterhazy ouch and there’s no way to avoid that short of checking that you don’t shadow global names?

pesterhazy 2017-04-11T14:07:08.628333Z

Correct

pesterhazy 2017-04-11T14:07:53.646098Z

It hasn't caused problems for me but it's something to be aware of

cgrand 2017-04-11T14:13:42.780665Z

Ok so updated version of the reader, any cljs newb error? https://gist.github.com/cgrand/d99afba8ce7ae9a13931184a58bbffc8

pesterhazy 2017-04-11T14:52:54.744630Z

welcome @adamfrey 🙂

adamfrey 2017-04-11T14:53:07.750293Z

what’s up @pesterhazy 😛

pesterhazy 2017-04-11T14:53:39.764118Z

just chilling

adamfrey 2017-04-11T14:53:41.764973Z

hey so you might be able to help me with something

adamfrey 2017-04-11T14:54:31.786409Z

I’m about to check out unravel, and when I run sudo npm install -g lumo-cljs, I get

shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
sh: /usr/local/bin/node: Permission denied
This might be some basic npm thing I don’t understand

pesterhazy 2017-04-11T14:56:02.826149Z

hm interesting

pesterhazy 2017-04-11T14:56:17.832025Z

can you run ls -l /usr/local/bin/node ?

pesterhazy 2017-04-11T14:56:38.841539Z

how did you install node?

adamfrey 2017-04-11T14:56:45.844713Z

-rwx------ 1 adam admin 27568300 Feb 19 23:22 /usr/local/bin/node

adamfrey 2017-04-11T14:56:52.847758Z

I don’t actually remember how I installed node

pesterhazy 2017-04-11T14:57:09.854911Z

is this on macos?

adamfrey 2017-04-11T14:57:15.857341Z

yes

pesterhazy 2017-04-11T14:58:04.879062Z

it could be that your node installation is borked

adamfrey 2017-04-11T14:58:10.880994Z

I don’t have nvm installed apparently

pesterhazy 2017-04-11T14:58:21.885978Z

I don't use nvm either

pesterhazy 2017-04-11T14:58:51.899384Z

if nothing important depends on it, I'd just install a current version of node

adamfrey 2017-04-11T14:59:08.906327Z

I’m going to clear out my node installation and try again

pesterhazy 2017-04-11T14:59:46.923166Z

I usually just use brew install node

adamfrey 2017-04-11T15:26:43.612172Z

ok, after nuking my node installation I have unravel working @pesterhazy. It looks so good.

2
adamfrey 2017-04-11T15:27:49.639802Z

I’m new to this arena, but is there a state of the art for embedding a something like unrepl into a live application? Possibly also an equivalent to cemerick’s drawbridge?

dominicm 2017-04-11T15:31:46.740766Z

@adamfrey if you put unrepl on your cp, you can upgrade a socket repl with it (so depend on it for your uberjar for example)

adamfrey 2017-04-11T15:33:42.789005Z

I ask about drawbridge, because my deployment environment is heroku, so I can’t ssh into the instance to connect to a normal socket repl

cgrand 2017-04-11T15:34:38.812632Z

repl over http comes with its own bag of problems

adamfrey 2017-04-11T15:35:04.823310Z

that’s very believable.

cgrand 2017-04-11T15:37:00.872063Z

however I have on the todo list a nrepl-to-repl adapter, so you would be able to do: application->nrepl->drawbridge-server->drawbridge-client->nrepl-to-repl->unrepl->unravel 😉

adamfrey 2017-04-11T15:37:19.879858Z

ha, sounds simple enough

cgrand 2017-04-11T15:37:55.894464Z

or in other words: would work just fine if you already have nrepl working

pesterhazy 2017-04-11T15:37:56.895244Z

haha

pesterhazy 2017-04-11T15:38:25.905439Z

isn't there a generic TCP-over-HTTP server?

cgrand 2017-04-11T15:39:00.921255Z

generic and deployable on heroku as part of your app

cgrand 2017-04-11T15:40:02.945935Z

and with sticky sessions to avoid landing on a different server process at each packet

pesterhazy 2017-04-11T15:40:07.947862Z

(why do you want to repl into your production instances? I've never found this particularly useful)

adamfrey 2017-04-11T15:41:30.982693Z

It’s an event scheduler, so there’s going to be a list of yet-to-run jobs that I would like to query. There are obviously other ways of getting that info

cgrand 2017-04-11T15:42:17.001912Z

(for heroku, repl on websockets would be better)

adamfrey 2017-04-11T15:45:14.073581Z

is there a library for repl over websockets?

dominicm 2017-04-11T15:48:28.153422Z

SSE would be better for REPL over, because then auth would work.

dominicm 2017-04-11T15:48:45.160157Z

nrepl was always intended to have multiple backends. I've rarely seen anyone use anything except the default though.

richiardiandrea 2017-04-11T16:07:02.609861Z

I was thinking that it would be awesome to expose repl capabilities like apropos, fold/expansion, doc, from an nrepl endpoint. And maybe a command template to trigger it

richiardiandrea 2017-04-11T16:08:00.632505Z

So if that an "editor" at this point only has to query what is the command for something andcache it and use it when the user wants to

richiardiandrea 2017-04-11T16:10:46.696194Z

For instance in inf-clojure now I have a different (arepl.namespace/doc %s) template for each repl type

cgrand 2017-04-11T19:05:29.600858Z

@richiardiandrea yeah, that’s one lesson I learnt by looking at unravel completion code: more facilities must be enumerated by unrepl.

pesterhazy 2017-04-11T19:13:14.758913Z

@cgrand how do you mean?

pesterhazy 2017-04-11T19:13:59.774159Z

Should we move completion/doc code to unrepl? I'd be all for that

cgrand 2017-04-11T19:27:11.042558Z

Yes I mean listing such actions in :unrepl/hello so that the client doesn’t have to hardwire them.

cgrand 2017-04-11T19:28:22.067423Z

Btw join #planck where I’m trying to explain what is missing to get planck and lumo to be upgradable.

pesterhazy 2017-04-11T19:28:53.078339Z

I saw it, sounds interesting

pesterhazy 2017-04-11T19:30:02.102068Z

I think I'll start adding functionality to unrepl then

pesterhazy 2017-04-11T19:31:34.133780Z

Should stuff like doc, complete and apropos go in another namespace?

cgrand 2017-04-11T19:31:36.134323Z

Start adding to the spec 😉

cgrand 2017-04-11T19:32:13.146542Z

First what should they do? input & ouput

dominicm 2017-04-11T19:32:28.152323Z

Should look at prior art in this area if we can

pesterhazy 2017-04-11T19:32:31.153373Z

Sure, if you prefer

dominicm 2017-04-11T19:32:55.161178Z

If you want completion that tooling can use generally (e.g. editors in a text editing) then you'll need a context option

cgrand 2017-04-11T19:40:55.323988Z

and maybe a basic :completion command with unspecified algorithm. And more specific names for specific completion algorithms.

cgrand 2017-04-11T19:41:23.333751Z

hi @anmonteiro

anmonteiro 2017-04-11T19:41:30.336099Z

🙂

cgrand 2017-04-11T19:45:11.410051Z

So unrepl is an effort to empower toolsmithes without requiring repl (server) to be changed or deps added. For this to be true for selfhosted cljs, the repls need to be upgradeable, and this is done by exposing their 3 components.

anmonteiro 2017-04-11T19:46:48.443127Z

@cgrand I’m happy to add whatever you need to Lumo to make the REPL upgradable

anmonteiro 2017-04-11T19:47:01.447732Z

just need to know exactly what that is 🙂

anmonteiro 2017-04-11T19:47:08.449962Z

eval is already there, as I told you in DM

anmonteiro 2017-04-11T19:47:31.457904Z

also feel free to open issues in the Lumo repo

dominicm 2017-04-11T19:49:26.496669Z

@cgrand There's also the idea that completion belongs to Language Server Protocol, and that a REPL client could talk to that LSP?

cgrand 2017-04-11T20:05:41.837823Z

@anmonteiro where is eval?

anmonteiro 2017-04-11T20:06:06.846266Z

I’m thinking of lumo.repl/execute. let me know if that doesn’t serve your needs

anmonteiro 2017-04-11T20:18:50.099195Z

I can probably create a lumo.repl/eval just like Planck has

mfikes 2017-04-11T20:22:12.166995Z

@anmonteiro Yeah, I think it is safe to add eval to Lumo, in the sense that I haven't regretted having it in Planck (it has been pretty much problem free since introduction; it has survived being available for a little more than a year now)

thheller 2017-04-11T20:32:52.385643Z

@cgrand I though we were past adding additional commands to the unrepl and instead using a new connection with its own protocol?

thheller 2017-04-11T20:33:16.393423Z

the additional commands path is nREPL all over again I feel

cgrand 2017-04-11T20:34:13.412787Z

Interesting: what are the reasons/fears against exposing eval?

mfikes 2017-04-11T20:46:07.653209Z

Oh, for me with Planck, the fear that I may not have sorted out all of the corner cases, but yet, once added you kind-of need to stick with it.

pesterhazy 2017-04-11T20:46:23.658587Z

@thheller not sure what you're talking about

mfikes 2017-04-11T20:46:54.669216Z

With Planck's eval, there were some funky cases discussed at the end of this post: http://blog.fikesfarm.com/posts/2016-01-22-clojurescript-eval.html

thheller 2017-04-11T20:48:07.693155Z

@pesterhazy my pitch is that tooling concerns should use a different protocol as they are not a REPL.

thheller 2017-04-11T20:48:34.702474Z

something like https://github.com/Microsoft/language-server-protocol is better suited for this task. its a dedicated protocol that could be initiated over a REPL.

thheller 2017-04-11T20:49:20.717765Z

since most tool things are RPC, so instead of multiplexing everything over one connection

thheller 2017-04-11T20:50:24.739605Z

you keep your REPL connection and open another tool connection (which may start as a REPL connection but gets upgraded)

thheller 2017-04-11T20:50:52.748798Z

the tool connection does not need to worry about read eval or print

pesterhazy 2017-04-11T20:52:40.785015Z

Using a separate connection is useful, but I don't see what using yet another new rpc protocol buys you

thheller 2017-04-11T20:53:19.798180Z

it doesn't complicate the REPL protocol is one thing

pesterhazy 2017-04-11T20:53:24.799859Z

Anyway this feels tangential to unrepl

thheller 2017-04-11T20:53:53.809539Z

well if additional commands are added to unrepl that is where they are going to stay

pesterhazy 2017-04-11T20:55:01.832291Z

Well "adding commands" just means making functions available, and perhaps advertising them on startup

thheller 2017-04-11T20:55:39.845550Z

not exactly. you also need to provide a way to register those functions with unrepl.

thheller 2017-04-11T20:57:01.873515Z

looking at this :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]} makes me cringe

pesterhazy 2017-04-11T20:58:55.912407Z

We're taking one step before the next; it sounds like you're getting ahead of yourself

pesterhazy 2017-04-11T20:59:53.932Z

As I see it we're exploring the practical possibilities of a common interface for repls and tooling

👍 1
thheller 2017-04-11T21:00:02.935022Z

I saw talk of :completions command coming up which we went through a few times already

pesterhazy 2017-04-11T21:00:43.950272Z

Have you looked at the code in unravel? It's very simple so far

pesterhazy 2017-04-11T21:01:49.973139Z

Similar completer code could be shared by multiple tools, so this looks like it makes sense to move this to a common place

thheller 2017-04-11T21:02:22.984533Z

yes totally but not in a REPL.

thheller 2017-04-11T21:03:15.002690Z

pretend you had a HTTP interface to GET /completions?prefix=foo&line=3&column=1 that returned JSON/EDN

thheller 2017-04-11T21:03:33.009433Z

guess how re-usable that would be

thheller 2017-04-11T21:04:30.028325Z

not saying that HTTP is a good protocol to chose, just using it as an example since its a generally understood protocol

thheller 2017-04-11T21:04:50.035029Z

point is if you free up all this work from the REPL it gets much simpler

pesterhazy 2017-04-11T21:05:34.049900Z

I'll have to continue this conversation another time

thheller 2017-04-11T21:06:42.071567Z

perhaps better explained than I could

pesterhazy 2017-04-11T21:08:44.109846Z

For the record, I'm not convinced that using a repl connection as a basis for tooling is not a good simple pragmatic choice (hence why I'm trying this approach in unravel)

pesterhazy 2017-04-11T21:09:12.117925Z

TTYL

cgrand 2017-04-11T21:26:46.430738Z

I remember Rich talking me out of using this kind of trick (`(eval (list inc 0))`)

cgrand 2017-04-11T21:29:39.479719Z

> Multiplexing their needs with those of a human REPL consumer over the same connection is going to make things bad for one or both of them. doesn’t preclude having separate repl connections, 1 for the human, N for the services

cgrand 2017-04-11T21:30:55.502151Z

I have no definitive answer, I try to find the sweet spot so my opinion swings back and forth like a pendulum