Personally I don't think there's anything wrong with lein, especially if it's used for a specific task like shading a library
@cgrand last night I started thinking/coding a way to interactively switch the REPL namespace to the one my current working buffer holds, i.e. my user conn REPL is in the user ns, and I'm looking at a file/buffer that's represented by foo.bar ns, I want to have an editor command to switch the user conn's ns to foo.bar, so this would have to go through the aux conn... I couldn't find an easy way to do that, any thoughts?
You don’t want to send (ns foo) over the userconn?
(where (ns foo) is the full ns form)
I could, but I'm avoiding it since I think this is more of a tooling thing.. it'd be an interactive editor command, don't know if I want that in the user repl history
If you want to read the repl log, knowing when you switch ns may be useful.
An aux command would also have to force reprompt on user otherwise there would be no feedback in the repl buffer
(ns foo) seems the natural thing to me as well
good point about the repl transcript too
I agree with that on premise, and I also had implemented a notification system so that the user sees when this happens... what I don't like as much is cluttering *1 *2 *3 with things that the user may not have wanted to evaluate
and what I mean by that, is that some times the editor may want to automatically switch to a namespace, without the user explicitly telling so
you mean this?
clojure.set=> (in-ns 'user)
#unrepl/ns user
user=> *1
#unrepl/ns useryes
here's the use case I have in mind
are you talking about spiral-eval-buffer?
I'm wondering now if spiral-eval-last-sexp will affect *1
the user repl is in user, and the user is looking at a foo.bar file. When the user tries to evaluate a form in foo.bar I want the REPL to automatically switch to foo.bar (this would be customizable of course), a notification will be seen so that the user know it happened and the form will be evaluated after the ns was switched
at this point, *1 would hold the evaluated form, but if I sent the (ns foo.bar) through the user conn, *2 will hold that as well
and do you revert to user after?
I'm meaning to make it customizable.. I might not
I might stay in foo.bar
do people actually use *2 ...? I mostly care about *1
it's kind of a tradeoff between truth and convenience
truth: we don't want to hide unnecessarily what gets sent to the repl
convenience: access to previous evaluations you actually care about
`(do (ns foo) (my expr))` ?
splicing do
nah won’t work is there are syntax quotes, aliases etc.
also you can't switch back like that
tbh, switching back is not something that I love
in nrepl what they do is pass a :ns key to their input messages
suppose I'm working in the repl buffer visiting 'user and running a test command repeatedly (foo.bar/quux)
so the REPL buffer can be in user, but the interactive buffer evaluations happen in the buffers ns (cider)
now I change quux - but that switches my ns in the repl buffer
(unrepl/do (ns foo))
I think this is a source of confusion
(unrepl/incognito (ns foo))
🙂
@cgrand that over the aux conn? I'm not entirely sure what unrepl/do does
unrepl/do only works at top level and works like top-level do except the return value is never printed and it doesn’t affect *1
it’s already in unrepl
oh! TIL!
and I was on the verge of removing it 😉
ok, let me try that then 🙂
unrepl/do saved by the bell?
(if (and (seq? r) (= (first r) 'unrepl/do))
(do
(flushing [*err* (tagging-writer :err id write)
*out* (scheduled-writer :out id write)]
(eval (cons 'do (next r))))
request-prompt)
r)
haha it took me a while to find that definitioncool, I'll try it out, I think it will work
^:unrepl/shhhh could be a better syntax
hahaha
unrepl/undo 🙂
gonna go grab something to eat first, then I'll try it
I like the metadata because it wouldn’t introduce a special
what would be the problem with a special form? just curious
(use of *1 notwithstanding) a transcript could be replayable in any repl (metadata would be ignored); unrepl/do would break
you mean ^:silently (in-ns 'foo.bar) ?
yeah
I'm not so sure — metadata usually doesn't apply to fn calls, right?
only to literals
no
hmmmm that's not true actually
you can type hint an expression
there’s the ^:once metadata on fn*
it's still a bit of an obscure feature
and it doesn’t apply to a fn call: it’s an annotation on an expression 😉
a "repl-special form" is easier to grok
dunno
yeah not sure either
@otfrom has joined the channel
@cgrand @pesterhazy alright I tried unrepl/do and it works but there are a couple of things that seem fishy somehow: 1. unrepl/do makes unrepl return a :read message with updated line-col positions, which is not a big deal to spiral, but to clients that use those values to keep sync with the input sent, it's problematic. 2. unrepl doesn't return an :eval message, which in this case is not a big deal cause I'm not interested in the result, but that may not always be the case
I'm not entirely sure about #2 though, it might be a problem on my side, I'll confirm in a few minutes
I don’t see what’s wrong with #1
no, you are right, that's not problematic...
#2 is happening though
I mean, there's no :eval back from unrepl/do
@otfrom welcome Bruce!
#2 is somehow by design
hmm I do not feel it would be too crazy to think that some client would want to do an unrepl/do expecting some result back. but I can ping back if I'm ever into that situation
👋
was intrigued after seeing spiral https://melpa.org/?utm_source=dlvr.it&utm_medium=twitter#/spiral
great! it's a work in progress, let me know if you try it out 🙂
I have the feeling we are over thinking here
A couple of observations:
1/ (ns foo.bar) in lumo doesn’t affect *1 and friends
it does in clj, but I wouldn't mind if unrepl would take the lumo approach
nope
in clj it basically deletes *1 *2 *3
not the asumption I had, let me check
user=> 1
1
user=> 2
2
user=> 3
3
user=> (ns foo.bar)
nil
foo.bar=> [*1 *2 *3]
[nil 3 2]so is doesn’t delete, it just shifts as usual
other.test=> 1
1
other.test=> 2
2
other.test=> 3
3
other.test=> (ns new.ns)
nil
new.ns=> *1 *2 *3
nil
nil
nil
new.ns=>
bah, nevermind
I see now
*3 *3 *3 would be better 🙂
side effects, we ❤️ you
haha yes ❤️
when you do (ns some.ns)
2/ what you really want atm is (ns buffer.ns) (expr-from-buffer) and we are complaining that *1 is messed up with while there’s little chance that expr-from-buffer would ref it, so (ns buffer.ns) (set! *1 *2) (set! *2 *3) (expr-from-buffer) would be safe
The fact that lumo doesn not behave like clj tells that it may be wise to consider a command since behaviour is going to vary amongst targets
I think ns is quite weird in cljs, so I'm not particularly surprised the behaviour is different.
lumo does its own handling of *1 *2 *3, from what I remember
true because handling of *1 etc is the repl job
yep, there's no such thing as clojure.main/repl in cljs
afaik
@volrath @pesterhazy how your clients handle a :prompt out of the blue?
mine just prints it, I'm not taking special precaution
so it could print a new prompt mid editing of the user?
it could
the user can only type when there's a prompt
so if for any reason a new prompt would appear without the user hitting enter, it would print the new prompt and copy/paste the user's input into the new one
cool
that's what's coded, but I haven't tested it cause I don't know how to reproduce that
you know what, I lied, I do take one precaution
so the scenario would be
1/ send command to aux
2/ wait for matching prompt on user
3/ send expr to user
I distinguish between interactive evals and repl evals.. if the new prompt is associated with a repl eval, I print it, if not, I ignore it
I don't understand that scenario 😕 when I send forms through aux I don't care about the prompts, I only care about user prompts
the :prompt appearing on user is the conformation that the ns had effectively been changed
it’s too complex
back to unrepl/do
I’m ok with it emitting an :eval
and renaming it
ah, I see what you mean... I mean, tbh, I wouldn't mind just adding an extra check: if the user :prompt comes out of nowhere and its namespace is different from the one before (I always keep reference of the current namespace in the client) -> print it out
but emitting :eval also works, an maybe it's better imo
I'm not sure
when you say "rename it" you mean emit another type of message different from :eval?
the whole scenario exposed above is brittle as you have to use two conns and wait etc.
re: “rename it”, no rename unrepl/do
got it
I’m event thinking about a :sneaky command (that would just be (unrepl/do #unrepl/param :expr))
I think an unexpected :prompt should cause the prompt to be reprinted in unravel (and the ns portion to be changed)
> so if we want to side load also AOT-id/Java, probably the best option would be to refactor mranderson and package it as boot library
Why so? Because unrepl is using boot?
No, unrepl uses Leiningen
I’m assuming it won’t be hard to make mranderson play well with boot.