Hmm. One problem with nesting REPLs that way is that your evaluation->return ends up offset by one unless upon starting the nested REPL fires out a fake :ret
in order to pretend it's completed.
Ah, but :form
lets you relate them somewhat. Interesting.
Would it make sense for REPLs to bind *file*
, etc. to a thread local so that clients can do something like:
(set! *file* "/tmp/foo.clj") (set! *line-number* 84)
(defn foo [])
Or maybe just *in*
so that tools can rebind that with a pushback reader that has the line numbers set.but there is also a way to convey file/line information with form metadata
^{:clojure.core/eval-file "a/b/foo.clj", :line 100, :column 1} (hi 1)
So it does, that's way simpler!
user=> ^{:clojure.core/eval-file "foo.clj" :line 20 :column 3} 1
Syntax error reading source at (REPL:9:0).
Metadata can only be applied to IMetas
It does require you to pre-read to know whether you can apply meta or not :thinking_face:yeah, that's true. probably just need to look at first 2 characters though
That seems like it wouldn't necessarily be reliable.
Good example of that is that I could extend IMeta to work on numbers (if I was a madman or something), and then parsing wouldn't work.
heh, you could just detect the exception and correct for it
(if (and i-have-messed-with-the-source? (= :read-source (:clojure.error/phase (ex-data *e))))
(do (restore *e old*e) (send-original))
(display-error *e)
Alternatively, read
/LispReader could take an opt for ignoring invalid metadata on things, or something like that.
Or maybe some metadata to allow on anything (eval-file/line/column)
that's just not possible
https://github.com/clojure/clojure/blob/28b87d53909774af28f9f9ba6dfa2d4b94194a57/src/jvm/clojure/lang/LispReader.java#L963 couldn't this line make that decision?
elseif (opts.dropLocationMeta && onlyHasLocationMeta(meta)){ return o }
Something like that?
That works pretty well for tooling, because it would still support chained meta ^{:line 10} ^:foo o
would either blow up or not, dependent on whether it should.
Oh, I should clarify what I meant by "allow on anything" I meant to ignore on anything!
ah ok :)