something I noticed the other day, when evaluating a form in CIDER vs Cursive CIDER:
{:op "eval"
:code "(foo)"
:file "bla.clj"}
Cursive
{:op "eval"
:code "^{:clojure.core/eval-file "bla.clj" :line 1 :column 1} (foo)"}
We have some internal middleware that sniffs the file extension to dispatch to different evaluation logic, so this was quite surprising... Not sure what the conclusion is, maybe we should document more explicitly that a "file" field is optional but recommended? The spec (https://spec.nrepl.org/) has one example of a "file" field on "eval", but the accompanying explanation only talks about "ns"... I'm not sure if Cursive's behaviour is even really intentional, or if the metadata just comes from the reader it happens to use. cc @cflemingThat was intentional, but I can't remember the details right now sorry, it was a while back. I think this behaviour switches on the version of Clojure since at some point Clojure added support for meta on eval'ed forms. I'll dig around tomorrow and see if I can jog my memory.
It kinda already is optional but recommended. Can't make it required – some forms are evaluated outside of any file. Otherwise, if there is a file, it better be put on the map. https://nrepl.org/nrepl/ops.html#eval
I looked through the history of this. Cursive used to always use load-file to evaluate forms from editors, by padding the forms so that the line numbers were correct. This is probably more important in Cursive than in other editors because the line numbers are important for debugging. But I received an issue that for systems which display evaluated forms (REBL in the case of the issue, but probably others as well) this looked really weird. In Clojure 1.10 the metadata option was added, so Cursive still uses load-file when working with older versions of Clojure, and uses the metadata with eval on more recent versions. Cursive has never sent :file with eval as far as I can tell.
I remember this padding workarounds from the days of old, but if memory serves these changes in eval 11 years ago made the workaround redundant https://github.com/nrepl/nrepl/commit/e03670d2c14ef854e5c2410e640a49bc0e8f8f86
Limitations like this one were the reason I got interested in contributing to nREPL in the first place. 😂
I can't remember all the details, but I think that that was not sufficient for some reason.
There was something special about load-file which did something that didn't happen with eval.
Btw, the spec is still in its very early days, so there are plenty of blanks to fill there.
I'm surprised that the CIDER eval doesn't pass location metadata, though, as this was added to nREPL initially to implement this feature in CIDER. 😄
no it seems it does, looking at nrepl-messages. my point is mainly that cursive doesn't send "file"
Ah, my bad - I thought it was that CIDER wasn't sending "line" and "column". facepalm
Generally our reasoning lately has been that now that eval is smarter, probably we can eventually retire load-file completely. I'm not sure whether it was introduced originally to circumvent the limitations around source code metadata or there was more to it. (e.g. more efficient way to load/eval an entire file)
But overall it doesn't seem like some essential to the protocol or the Clojure implementation for that matter.
they do seem to behave differently in CIDER, when I load-file, I get annotations for reflection/boxed-math warnings. When I eval a single form I generally don't
That's exactly what the metadata is designed to solve IIRC, without that the forms are compiled with incorrect line data in the byte code, which is why you're probably not seeing annotations in your code. Before support for the meta was added to Clojure, Cursive used to use load-file even for simple forms evals, and would essentially create a dummy file with blank lines at the start so the line numbers in the byte code were correct. This affects things like exception stack traces etc too.
And there have been some recent improvements to this area like https://github.com/nrepl/nrepl/pull/391 and https://github.com/nrepl/nrepl/pull/385