hola @volrath
hallo @pesterhazy !
@richiardiandrea hmm find-ns
happens to trigger an interesting shadowing bug, opened https://dev.clojure.org/jira/browse/CLJS-2088
Identifying a repl:
(cond
(find-ns '<http://clojure.java.io|clojure.java.io>) :clj
(find-ns '<http://clojure.clr.io|clojure.clr.io>) :cljr
(find-ns 'lumo.repl$macros) :lumo
(find-ns 'planck.repl$macros) :planck
(find-ns 'cljs.core$macros) :cljs-js
(find-ns 'cljs.core) :cljs-jvm
:else :unknown)
@cgrand find-ns
is bootstrap only
for repl sniffing it works enough in non-bootstrap
says so in the docs at least
don’t use that in a lib though (advanced compilation...)
hmm you are right, actually works in normal as well
but sending that before every interaction would suck
why not once per connection?
rlwrap nc localhost 8201
shadow-cljs - REPL - see (help), :repl/quit to exit
[13:0]~shadow.user=> (shadow/node-repl)
[13:1]~cljs.user=> :repl/quit
:repl/quit
[13:0]~shadow.user=>
@pesterhazy starts out as CLJ, then becomes CLJS, then CLJ again
if only there was a protocol which clearly tells when an upgrade occurs 😇
I know right? 🙂
any ideas how to do the upgrade process properly for cljs yet?
not self-hosted that is
still not totally on-board with unrepl yet but thats mostly due to tool support
guess I can’t get around nrepl for now
Some ideas start to click together. The current cljs repl infrastructure is not ok but it can be remixed (that is: reuse environments and so on but recreate an upgradable infrastructure to replace https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/repl.cljc)
shadow-cljs doesn’t use any of that, maybe its simpler to integrate there
is there an unrepl client I could test this with?
I dunno, ask @pesterhazy or @richiardiandrea
my current idea is to consider the loop on the js-side as its own repl
it starts as a framed JS repl but is upgradable
this is the loop for the CLJS REPL at the moment
it reads off *in*
and prints to *out*
the actual JS eval is RPC
@thheller I'd test with netcat first
so it should be really simple to add the upgrade
once you have a working protocol, you can try unravel
this is where the blob is concatenated at the moment: https://github.com/pesterhazy/unravel/blob/b687edb188aaab58b9ac0ce7a143172dc3e256a6/src/unravel/loop.cljs#L115
it's not updated yet to use the "official" unrepl blob
and the blob is only for clj
bootstrap soon
of course the blob would have to be completely replaced
yeah still not sold on the blob idea
I’m fine with just having a dependency in the server
@thheller how do you handle the print part in shadow repl?
the client decides how to print
currently it just does pr-str
but I could make that configurable
it does not send a wrapped form over the wire
so if you eval (js/alert "foo")
the client actually just evals alert("foo")
nothing else
not the wrapped stuff the normal CLJS REPL sends
@cgrand, I did a presentation on unrepl/unravel here in Berlin yesterday. Here are the slides: http://pesterhazy.karmafish.net/unravel-your-repl.pdf
How was it received?
pretty well. I had a few people express interest in contributing after the talk, which is awesome
^ yes, pretty well 🙂
great! welcome @volrath
> Rich capabilities, frugal dependencies I like this wording!
bonus points for using “transclusion”
heheh
[15:1]~cljs.user=> [1 2 3]
(] 3 2 1 [)
[15:1]~cljs.user=> (set! shadow.cljs.devtools.client.env/repl-print-fn #(reverse (pr-str %))
)
(] " }
; ) ) _ P R A H S _ 5 2 6 5 4 _ _ 1 p , l l u n ( l l a c . r t s _ r p . e r o c . s j l c , l l u n ( l l a c . e s r e v e r . e r o c . s j l c n r u t e r
{ ) _ P R A H S _ 5 2 6 5 4 _ _ 1 p ( n o i t c n u f " n o i t c n u F [ t c e j b o #)
[15:1]~cljs.user=> [1 2 3]
(] 3 2 1 [)
not the result I had in mind but fun 😛
@cgrand, yup, I've learned a new word 🙂
[15:1]~cljs.user=> (set! shadow.cljs.devtools.client.env/repl-print-fn #(clojure.string/upper-case (pr-str %)))
#OBJECT[FUNCTION "FUNCTION (P1__45626_SHARP_){
RETURN CLOJURE.STRING.UPPER_CASE.CALL(NULL,CLJS.CORE.PR_STR.CALL(NULL,P1__45626_SHARP_));
}"]
[15:1]~cljs.user=> [:hello :world]
[:HELLO :WORLD]
cgrand: thanks! I really like the whole idea. I told @pesterhazy yesterday that I went through the documentation two nights ago, to prepare for the talk, and I think I can contribute a very small PR with some minor fixes to the README (commas, and a couple typos) and then maybe I can help with documenting more stuff (missing tags like :started-eval
, and so on)
that would help with my understanding of the protocol as well
if that's ok with you
that’s more than totally ok
is there a CLJS impl for the unrepl print style yet?
Don’t hesitate pinging me (in private or on the channel)
thank you! will do
yes there is, @plexus made one https://github.com/plexus/unrepl/blob/lumo_support/src/unrepl/print.cljc
I plan to merge it when I got time
hmm
[15:1]~cljs.user=> (load-file "/Users/zilence/code/shadow-cljs/src/dev/unrepl/print.cljc")
[:result {:type :repl/error, :message "cond-splice not in list", :data {:type :reader-exception, :line 15, :column 5, :file "unrepl/print.cljc"}, :causes []}]
indeed, remove the @
and add a do
another one at 170
ok got it
reader discrpencies: LispReader is ok with that, tools.reader not
I guess @plexus tested it against cljs-js-repl on lumo
print.cljc is completely untested. I got as far as making sure the forms evaluated without errors on Lumo. That's it. It almost certainly is incomplete, it's just a first pass addressing the most obvious differences.
async-reader should be fine too
hmm heeh
tools.reader issue?
it cannot print itself
[18:0]~shadow.user=> (shadow/dev :browser)
[18:1]~cljs.user=> (require 'unrepl.print)
[18:1]~cljs.user=> (set! shadow.cljs.devtools.client.env/repl-print-fn unrepl.print/edn-str)
nil
[18:1]~cljs.user=> {:foo "bar"}
{:foo "bar"}
TypeError: Cannot read property 'cljs$core$IFn$_invoke$arity$1' of undefined
at cljs.core.MultiFn.cljs$core$IFn$_invoke$arity$1 (cljs.core.cljs:10295)
at Function.unrepl.print.ednize.cljs$core$IFn$_invoke$arity$3 (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:457:119)
at Function.unrepl.print.ednize.cljs$core$IFn$_invoke$arity$2 (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:425:28)
at Object.unrepl$print$print_on [as print_on] (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:610:33)
doesn’t seem to work really
I haven’t had time to test it, I was doing some preliminary work on the upgradable cljs repl
(range 0 10000)
also fails
TypeError: Cannot read property 'cljs$core$IFn$_invoke$arity$1' of undefined
at cljs.core.MultiFn.cljs$core$IFn$_invoke$arity$1 (cljs.core.cljs:10295)
at Function.unrepl.print.ednize.cljs$core$IFn$_invoke$arity$3 (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:457:119)
at Function.unrepl.print.ednize.cljs$core$IFn$_invoke$arity$2 (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:425:28)
at unrepl$print$print_on (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:610:33)
at Function.unrepl.print.print_vs.cljs$core$IFn$_invoke$arity$5 (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:571:113)
at Function.unrepl.print.print_vs.cljs$core$IFn$_invoke$arity$3 (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:516:30)
at Object.unrepl$print$print_on [as print_on] (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:653:23)
at unrepl$print$edn_str (eval at shadow$cljs$devtools$client$browser$do_js_load (shadow.cljs.devtools.client.browser.cljs:48), <anonymous>:698:18)
damn js stack traces are ugly
ah wait I have a debugger for that 😉
i may have an idea, in the clojure version you need to set some dynvars around it
(keep calm it’s synchronous so plain binding
is ok)
it would explain the undefined
*ednize*
seems unbound
(defmulti default-ednize-fn class)
<- no class
in cljs
why isn’t that a protocol?
trying to remember — I dislike multimethods so there must be a reason
Error: No method in multimethod 'unrepl.print/default-ednize-fn' for dispatch value: function Function() { [native code] }
just changed it to type
uhm (try try try try try try try try try try #unrepl/... nil)
😛
almost?
[20:1]~cljs.user=> (range 0 1000)
(try try try try try try try try try try #unrepl/... nil)
🙂
where does the try come from? 😛
re: protocol, really I don’t see why anymore, maybe to have the opportunity to prefer impls in case of conflicts?
there are only two “try” one in the expansion of a macro, I think it’s the one
ok .. I gotta do some other stuff .. will try again later
on line 234 blame-seq
which is a macro is called like a function (because cljs) and then its head (`try`) is used for v
[20:1]~cljs.user=> (range 0 1000)
(0 1 2 3 4 5 6 7 8 9 #unrepl/... nil
indeed
#?(:cljs (:require-macros [unrepl.print :refer (blame-seq)]))
in ns
#?(:clj
(defmacro ^:private blame-seq [& body]
`(try (seq ~@body)
(catch Throwable t#
(list (tagged-literal 'unrepl/lazy-error t#))))))
oh noes, you just broke it for self-hosted
hihi
macrovich to the rescue!
heh?
(btw David applied my patch)
“was wondering why $macros
should it find either way” ?
cgrand: lol let me rephrase
Why did you switch to detecting core$macros
instead of core
because in self-hosted cljs, (find-ns 'lumo.repl)
cripples access to this ns macros (open lumo, enter this find-ns
and after that try to use doc
)
Oh gotcha temporary fix before your patch is officially in
and until non-patched cljs are rare enough