Fork me on GitHub
#unrepl
<
2017-08-01
>
cgrand14:08:23

Pondering: 1/ should we worry about concurrent server implementations extension interop for the same platform? (forks) 2/ should we worry about extension interop between server impl for different platforms? (cljs, cljs, cljsjs, cljr...)

richiardiandrea14:08:26

Imho we need to start from somewhere, so I'd start from 1, still keeping 2 in the back of our head

cgrand14:08:22

edited my questions, do you maintain your position?

cgrand14:08:19

mine is “forget 1 and keep 2 in mind”

richiardiandrea14:08:05

put it this way, 1 seems to be a subcase of 2 (if done correctly)

richiardiandrea14:08:32

(if I understand correctly of course)

cgrand14:08:32

I didn’t considered it but yes

cgrand14:08:37

in cloiure it’s easy to start an extended repl by calling clojure.main/repl, why not follow this lead?

richiardiandrea14:08:41

I like the idea, yes, but also you don't want to call a function for everything you want to add to it...

cgrand14:08:51

the big cons to the clojure approach is that you don’t have access to the current extensions (eg if you just want to modifiy prompt), so it calls for some dynamic env

richiardiandrea14:08:14

so for completion you should not need a compliment.core/repl function

cgrand14:08:24

what do you mean by > call a function for everything you want to add to it

richiardiandrea14:08:23

But I think there is going to be a clojure.cljs/repl

cgrand14:08:01

what about (unrepl.repl/repl :action {:complete ...})?

richiardiandrea14:08:45

yes, so nRepl has descriptors, that would resemble it

richiardiandrea14:08:59

I declare which actions the repl would understand

cgrand14:08:11

the map would be merged with current one

cgrand14:08:42

extensions could then occur on the fly

richiardiandrea14:08:15

yep I like the idea, I think that part of nRepl was actually good, I guess you are more than familiar with it 😄

cgrand14:08:00

no or if I got involved I suffer from post-coding amnesia

cgrand14:08:41

or (alter-var-root! unrepl.repl/*actions* into {:complete ...})

richiardiandrea14:08:59

the latter is more dynamic, why not an atom?

cgrand14:08:06

middleware deps hell

cgrand14:08:24

because we want to keep it local to the session?

richiardiandrea14:08:46

yeah the problem of namespace munging comes back

cgrand14:08:24

on the jvm we can go nuclear and spawns a separate clojure in its own classloader

cgrand14:08:32

(not good for latency, hey boooot!)

richiardiandrea14:08:44

lol yes, pods in boot are superslow

richiardiandrea14:08:01

(to bootstrap I mean)

dominicm14:08:55

I thought we get to blame clojure for it being slow? 😉

richiardiandrea14:08:16

well if Clojure is slow than Clojure in Clojure (pods) what is it 🙂 ?

cgrand14:08:59

that’s why I never answer Chas emails anymore 😉

cgrand14:08:49

and I would rather blame clojure for making namespaces a mutability hell (Zach Tellmann has some name for that “clojure nasty mutability closet” or something)

richiardiandrea14:08:36

so in the above, what is the content of the :complete key? a simbol that points to the completion function?

cgrand14:08:36

munging: let’s assume we live in a hickeyic world where libs only ever accrete features?

richiardiandrea14:08:18

yes I liked the merkle tree for namespaces 😉

richiardiandrea14:08:32

maybe obvious here, I assume the client will not know about that

cgrand14:08:47

:complete would map to a message template

cgrand14:08:39

so it doesn’t say a thing about how namespaces are loaded. (the dreaded namespace talk)

richiardiandrea14:08:31

yeah well, at some point the munged namespace needs to go back to the client

cgrand14:08:56

Which munged namespace?

richiardiandrea14:08:09

or a mapping is done server side

richiardiandrea14:08:31

say the munged compliment.core

richiardiandrea14:08:01

server and client need to sync, either they speak unmunged or they speak munged (no?)

richiardiandrea14:08:00

(sorry corrections)

cgrand14:08:14

one approach could be [unrepl blob, including completion actions][munged compliment]

cgrand14:08:30

to me munging is static

cgrand14:08:02

btw what do you think of my content-based munging idea?

richiardiandrea14:08:35

it is super, also against tampering (if we wanted to)

cgrand14:08:00

so you munged compliment.core to compliment.core$sha1$djsfhbehsdbfhb

richiardiandrea14:08:52

is it a question? if so, not yet

cgrand14:08:08

(what’s the limit on classname length? well Spring existence proves we have ample room)

cgrand14:08:29

sorry it was an hypothesis

cgrand14:08:09

so you munged it statically and certainly also unrepl.complete which uses it while exposing a smaller api

cgrand14:08:48

[unrepl blob, with actions referring to unrepl.complete$sha1$.../xxx][munged compliment and complete]`

richiardiandrea14:08:58

if we had a :complete command action it would be different yep

richiardiandrea14:08:40

in that case the action would call the munged ns and send back stuff

richiardiandrea14:08:10

should work, I don't see big obstacles (right now)

cgrand14:08:12

actions make (I hope) lazy loading easier and interop between client and server easier. (edit: plus in case of doubt let’s have another level of indirection 😉)

richiardiandrea14:08:53

even better, clients can choose what to lazy load

richiardiandrea15:08:12

the action can be protected behind a delay

cgrand15:08:50

now the template could be (unrepl.repl/dyncall 'unrepl.complete$sha1$.... ..) with dyncall ensuring the namespace is loaded beforehand

cgrand15:08:38

[unrepl blob, with lazy activated actions, and side-loading]

cgrand15:08:19

ensuring which ns are preloaded would just be emitting a require

richiardiandrea15:08:47

it improves a lot of what nRepl at the moment does (but cider-nrepl folks will soon start adding delays)

richiardiandrea15:08:48

also, in this case the whole current nRepl middleware could be blobified and transformed in actions

richiardiandrea15:08:45

which is very appealing

richiardiandrea15:08:57

but wait...maybe I am missing something about munging

richiardiandrea15:08:19

if it is content based...would all the clients end up with the same sha1?

cgrand15:08:44

if all versions are aligned yes

cgrand15:08:22

so cavalier extensions of protocols or multimethods or usage of atoms may be problematic. (more than now?)

richiardiandrea15:08:18

atoms in the blob you mean? why?

cgrand15:08:23

if you have an atom in a lib and you modify it thinking you are the only user...

richiardiandrea15:08:58

uhm right, I had in the back of my head to have a session-based munging actually...

richiardiandrea15:08:26

you could put the atom in a session-based munged ns and that is only yours

cgrand15:08:43

I’m talking about atoms in random libs

cgrand15:08:54

not session state

cgrand15:08:25

at some point per-connection ns (with automatic removal) was considered for socket repl if memory serves me

richiardiandrea15:08:01

if we munged all the namespaces involving session, all those vars would effectively be available to the session only (even libs right?)...just throwing it there, haven't thought about implications

cgrand16:08:32

what are we trying to achieve? maximal protection against badly written code used by extensions?

cgrand16:08:03

if we are already protected from conflicting with application code, it’s a good enough protection for me

richiardiandrea16:08:27

no well, but your concern is valid, if a library is stateful, the state will be reflected to all the clients

richiardiandrea16:08:02

an example would be tools.namespace

cgrand16:08:31

What's the problem with it?

richiardiandrea16:08:48

not saying we cannot solve this, just putting it there...this is a pretty common thing that a user would want to do in a repl

cgrand17:08:38

@richiardiandrea true but it's not a class of problems that is made worse by unrepl.