nrepl

https://github.com/nrepl/nrepl || https://nrepl.org
2021-05-17T20:39:01.032700Z

Hi! @sakalli and I are creating a small middleware that listens to evaluation of code and keeps track of evaluation results. (This is part of an upcoming version of the Notespace project.) With :op "eval", this seems to work nicely. However, we are also interested in :op "load-file", since that is the kind of request when one evaluates a whole buffer in CIDER. Then, the nREPL response only tells about the evaluation result of the last top-level form. This kind of op directly calls clojure.lang.Compiler/load: https://github.com/clojure/tools.nrepl/blob/2263b6b/src/main/clojure/clojure/tools/nrepl/middleware/load_file.clj#L62 So, it seems that on whole-buffer evaluation, we will not be able to get the return values of intermediate top-level forms, but only of the last one. Any ideas about how to overcome that?

bozhidar 2021-05-17T20:42:17.033200Z

There's no way to circumvent this with load-file.

bozhidar 2021-05-17T20:43:16.034600Z

If you need to eval all top-level forms you'll need to walk over them and run eval for each. That won't be a problem if you eval in a single session as the evaluations will be serialized.

2021-05-17T20:48:31.037100Z

Thanks for the quick help, @bozhidar! We tried to evaluate a region with a few top-level forms (through :op "eval"), and it actually sent us multiple responses with all evaluation values. Is it surprising? Request (removed the bit :session member, so that it prints nicely):

{:transport
 #object[nrepl.middleware.caught$caught_transport$reify__915 0x5e5191a5 "nrepl.middleware.caught$caught_transport$reify__915@5e5191a5"],
 :ns "notespace.nrepl",
 :nrepl.middleware.print/print-fn
 #function[nrepl.middleware.print/wrap-print/fn--891/print--893],
 :file "/home/daslu/dev/scicloj/notespace/src/notespace/nrepl.clj",
 :load-tests? "true",
 :nrepl.middleware.print/quota 1048576,
 :nrepl.middleware.print/print "cider.nrepl.pprint/pr",
 :op "eval",
 :column 1,
 :line 50,
 :nrepl.middleware.caught/caught-fn
 #function[clojure.main/repl-caught],
 :id "132",
 :code "(+ 1 2)\n\n(+ 3 4)\n\n",
 :nrepl.middleware.print/stream? []}
Response messages:
{:id "132",
 :session "736cc68a-a5fe-44d5-8906-0ba56ca15dda",
 :ns "notespace.nrepl",
 :value 3,
 :nrepl.middleware.print/keys #{:value}}

{:id "132",
 :session "736cc68a-a5fe-44d5-8906-0ba56ca15dda",
 :ns "notespace.nrepl",
 :value 7,
 :nrepl.middleware.print/keys #{:value}}

{:id "132",
 :session "736cc68a-a5fe-44d5-8906-0ba56ca15dda",
 :status #{:done}}

2021-05-17T20:57:01.038100Z

If it seems interesting, I can share a self-contained example tomorrow. Anyway, your comment already helped wonderfully. 🙏

dpsutton 2021-05-17T20:58:28.038300Z

<https://ask.clojure.org/index.php/10624/should-load-file-use-the-repls-eval-function>

dpsutton 2021-05-17T20:58:51.038700Z

that is expected to me. evaluating a region can (and here does) have multiple effects

dpsutton 2021-05-17T20:59:01.039Z

load-file is a primitive offered by the clojure compiler

2021-05-17T20:59:40.039200Z

Thanks, @dpsutton!

pez 2021-05-17T21:08:45.039600Z

I don’t understand the answer…

pez 2021-05-17T21:12:42.041800Z

Also, eval a region and get back results for each top level form in it surprises me. I would expect the reader to get the text, eval each form and give me back the result of the last thing evaled.

dpsutton 2021-05-17T21:13:23.042500Z

that's just not what (def x 1)(def y 2) (def z 3) would ever do, and that's all evaling a region does, just send a region over to the repl

dpsutton 2021-05-17T21:14:05.042700Z

/tmp ❯❯❯ clj
Clojure 1.10.3
user=&gt; (def x 1)(def y 2)(def z 3)
#'user/x
#'user/y
#'user/z
user=&gt;

pez 2021-05-17T21:18:19.043400Z

I’m now realizing that Calva does not have a working eval region command.

dpsutton 2021-05-17T21:18:35.043800Z

it's probably quite infrequently used. i'd wait for a feature request to be honest

pez 2021-05-17T21:19:34.044700Z

Well, the command is actually named Evaluate current form (or selection) so we are breaking the promise…

pez 2021-05-17T21:20:20.045500Z

Noone has complained so far, and it must have been broken for quite a while. So you are probably right about infrequent.