To wrap yesterday lesson, here is the canonical source on closure behavior https://developers.google.com/closure/compiler/docs/api-tutorial3?csw=1#propnames
What’s fun is that most of my aset
/`aget` should have been plain property accessors.
I saw some cljs like (js/console.log ...)
is it another case that it works by accident and should be avoided?
ok found http://stackoverflow.com/questions/24239144/js-console-log-in-clojurescript#comment52543608_24240669
@cgrand you can use (js/<anything-global>.foo.bar.baz)
do not use it for any locals though
its fine and used commonly .. so probably not going away. many people rely on it
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.
oh its official then .. 🙂
@thheller what about (<whatever>/foo.bar.baz ...)
?
no thats reserved for namespace aliases
which js
is in some way, sort of reserved alias
and foo.bar.baz
is not a valid var name
hmmm it’s bizarre to bless it only for js
(it works with any ns or alias)
js
is treated very differently and for interop only
=> (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
be aware of the pitfalls of js/
though
cljs.user=> (let [window :foo] (prn js/window))
:foo
js/
isn't really a namespace, I see it more like custom syntax
@pesterhazy ouch and there’s no way to avoid that short of checking that you don’t shadow global names?
Correct
It hasn't caused problems for me but it's something to be aware of
Ok so updated version of the reader, any cljs newb error? https://gist.github.com/cgrand/d99afba8ce7ae9a13931184a58bbffc8
welcome @adamfrey 🙂
what’s up @pesterhazy 😛
just chilling
hey so you might be able to help me with something
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 understandhm interesting
can you run ls -l /usr/local/bin/node
?
how did you install node?
-rwx------ 1 adam admin 27568300 Feb 19 23:22 /usr/local/bin/node
I don’t actually remember how I installed node
is this on macos?
yes
it could be that your node installation is borked
I don’t have nvm
installed apparently
I don't use nvm either
if nothing important depends on it, I'd just install a current version of node
I’m going to clear out my node installation and try again
I usually just use brew install node
ok, after nuking my node installation I have unravel working @pesterhazy. It looks so good.
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?
@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)
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
repl over http comes with its own bag of problems
that’s very believable.
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 😉
ha, sounds simple enough
or in other words: would work just fine if you already have nrepl working
haha
isn't there a generic TCP-over-HTTP server?
generic and deployable on heroku as part of your app
and with sticky sessions to avoid landing on a different server process at each packet
(why do you want to repl into your production instances? I've never found this particularly useful)
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
(for heroku, repl on websockets would be better)
is there a library for repl over websockets?
SSE would be better for REPL over, because then auth would work.
nrepl was always intended to have multiple backends. I've rarely seen anyone use anything except the default though.
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
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
For instance in inf-clojure now I have a different (arepl.namespace/doc %s)
template for each repl type
@richiardiandrea yeah, that’s one lesson I learnt by looking at unravel completion code: more facilities must be enumerated by unrepl.
@cgrand how do you mean?
Should we move completion/doc code to unrepl? I'd be all for that
Yes I mean listing such actions in :unrepl/hello
so that the client doesn’t have to hardwire them.
Btw join #planck where I’m trying to explain what is missing to get planck and lumo to be upgradable.
I saw it, sounds interesting
I think I'll start adding functionality to unrepl then
Should stuff like doc, complete and apropos go in another namespace?
Start adding to the spec 😉
First what should they do? input & ouput
Should look at prior art in this area if we can
Sure, if you prefer
If you want completion that tooling can use generally (e.g. editors in a text editing) then you'll need a context option
and maybe a basic :completion
command with unspecified algorithm. And more specific names for specific completion algorithms.
hi @anmonteiro
🙂
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.
@cgrand I’m happy to add whatever you need to Lumo to make the REPL upgradable
just need to know exactly what that is 🙂
eval
is already there, as I told you in DM
also feel free to open issues in the Lumo repo
@cgrand There's also the idea that completion belongs to Language Server Protocol, and that a REPL client could talk to that LSP?
@anmonteiro where is eval?
I’m thinking of lumo.repl/execute
. let me know if that doesn’t serve your needs
I can probably create a lumo.repl/eval
just like Planck has
@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)
@cgrand I though we were past adding additional commands to the unrepl and instead using a new connection with its own protocol?
the additional commands path is nREPL all over again I feel
Interesting: what are the reasons/fears against exposing eval?
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.
@thheller not sure what you're talking about
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
@pesterhazy my pitch is that tooling concerns should use a different protocol as they are not a REPL.
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.
since most tool things are RPC, so instead of multiplexing everything over one connection
you keep your REPL connection and open another tool connection (which may start as a REPL connection but gets upgraded)
the tool connection does not need to worry about read
eval
or print
Using a separate connection is useful, but I don't see what using yet another new rpc protocol buys you
it doesn't complicate the REPL protocol is one thing
Anyway this feels tangential to unrepl
well if additional commands are added to unrepl that is where they are going to stay
Well "adding commands" just means making functions available, and perhaps advertising them on startup
not exactly. you also need to provide a way to register those functions with unrepl.
looking at this :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
makes me cringe
We're taking one step before the next; it sounds like you're getting ahead of yourself
As I see it we're exploring the practical possibilities of a common interface for repls and tooling
I saw talk of :completions
command coming up which we went through a few times already
Have you looked at the code in unravel? It's very simple so far
Similar completer code could be shared by multiple tools, so this looks like it makes sense to move this to a common place
yes totally but not in a REPL.
pretend you had a HTTP interface to GET /completions?prefix=foo&line=3&column=1
that returned JSON/EDN
guess how re-usable that would be
not saying that HTTP is a good protocol to chose, just using it as an example since its a generally understood protocol
point is if you free up all this work from the REPL it gets much simpler
I'll have to continue this conversation another time
https://groups.google.com/d/msg/clojure-dev/Dl3Stw5iRVA/IHoVWiJz5UIJ
perhaps better explained than I could
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)
TTYL
I remember Rich talking me out of using this kind of trick (`(eval (list inc 0))`)
> 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
I have no definitive answer, I try to find the sweet spot so my opinion swings back and forth like a pendulum