Fork me on GitHub
#unrepl
<
2017-04-11
>
cgrand07:04:10

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

cgrand07:04:03

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

cgrand13:04:47

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

thheller13:04:39

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

thheller13:04:14

do not use it for any locals though

thheller13:04:05

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

cgrand13:04:26

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.

thheller13:04:00

oh its official then .. 🙂

cgrand13:04:31

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

thheller13:04:00

no thats reserved for namespace aliases

thheller13:04:08

which js is in some way, sort of reserved alias

thheller13:04:04

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

cgrand13:04:01

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

thheller13:04:29

js is treated very differently and for interop only

cgrand13:04:12

=> (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

pesterhazy13:04:29

be aware of the pitfalls of js/ though

pesterhazy13:04:32

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

pesterhazy13:04:36

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

cgrand14:04:26

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

pesterhazy14:04:53

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

cgrand14:04:42

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

pesterhazy14:04:39

just chilling

adamfrey14:04:41

hey so you might be able to help me with something

adamfrey14:04:31

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

pesterhazy14:04:02

hm interesting

pesterhazy14:04:17

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

pesterhazy14:04:38

how did you install node?

adamfrey14:04:45

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

adamfrey14:04:52

I don’t actually remember how I installed node

pesterhazy14:04:09

is this on macos?

pesterhazy14:04:04

it could be that your node installation is borked

adamfrey14:04:10

I don’t have nvm installed apparently

pesterhazy14:04:21

I don't use nvm either

pesterhazy14:04:51

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

adamfrey14:04:08

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

pesterhazy14:04:46

I usually just use brew install node

adamfrey15:04:43

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

adamfrey15:04:49

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?

dominicm15:04:46

@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)

adamfrey15:04:42

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

cgrand15:04:38

repl over http comes with its own bag of problems

adamfrey15:04:04

that’s very believable.

cgrand15:04:00

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 😉

adamfrey15:04:19

ha, sounds simple enough

cgrand15:04:55

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

pesterhazy15:04:25

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

cgrand15:04:00

generic and deployable on heroku as part of your app

cgrand15:04:02

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

pesterhazy15:04:07

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

adamfrey15:04:30

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

cgrand15:04:17

(for heroku, repl on websockets would be better)

adamfrey15:04:14

is there a library for repl over websockets?

dominicm15:04:28

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

dominicm15:04:45

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

richiardiandrea16:04:02

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

richiardiandrea16:04:00

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

richiardiandrea16:04:46

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

cgrand19:04:29

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

pesterhazy19:04:14

@cgrand how do you mean?

pesterhazy19:04:59

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

cgrand19:04:11

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

cgrand19:04:22

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

pesterhazy19:04:53

I saw it, sounds interesting

pesterhazy19:04:02

I think I'll start adding functionality to unrepl then

pesterhazy19:04:34

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

cgrand19:04:36

Start adding to the spec 😉

cgrand19:04:13

First what should they do? input & ouput

dominicm19:04:28

Should look at prior art in this area if we can

pesterhazy19:04:31

Sure, if you prefer

dominicm19:04:55

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

cgrand19:04:55

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

cgrand19:04:11

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.

anmonteiro19:04:48

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

anmonteiro19:04:01

just need to know exactly what that is 🙂

anmonteiro19:04:08

eval is already there, as I told you in DM

anmonteiro19:04:31

also feel free to open issues in the Lumo repo

dominicm19:04:26

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

anmonteiro20:04:06

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

anmonteiro20:04:50

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

mfikes20:04:12

@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)

thheller20:04:52

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

thheller20:04:16

the additional commands path is nREPL all over again I feel

cgrand20:04:13

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

mfikes20:04:07

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.

pesterhazy20:04:23

@thheller not sure what you're talking about

mfikes20:04:54

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

cgrand21:04:46

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

thheller20:04:07

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

thheller20:04:34

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.

thheller20:04:20

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

thheller20:04:24

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

thheller20:04:52

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

pesterhazy20:04:40

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

thheller20:04:19

it doesn't complicate the REPL protocol is one thing

pesterhazy20:04:24

Anyway this feels tangential to unrepl

thheller20:04:53

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

pesterhazy20:04:01

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

thheller20:04:39

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

thheller20:04:01

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

pesterhazy20:04:55

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

pesterhazy20:04:53

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

thheller21:04:02

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

pesterhazy21:04:43

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

pesterhazy21:04:49

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

thheller21:04:22

yes totally but not in a REPL.

thheller21:04:15

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

thheller21:04:33

guess how re-usable that would be

thheller21:04:30

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

thheller21:04:50

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

pesterhazy21:04:34

I'll have to continue this conversation another time

thheller21:04:42

perhaps better explained than I could

pesterhazy21:04:44

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)

cgrand21:04:39

> 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

cgrand21:04:55

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