<< Back to previous view

[NREPL-45] Laziness-forcing loses *out* bindings Created: 10/Dec/13  Updated: 12/Apr/14  Resolved: 25/Feb/14

Status: Resolved
Project: tools.nrepl
Component/s: None
Affects Version/s: 0.2.2
Fix Version/s: 0.2.4

Type: Defect Priority: Minor
Reporter: Colin Jones Assignee: Chas Emerick
Resolution: Completed Votes: 1
Labels: None

Attachments: File NREPL-45.diff     Text File nrepl-45.patch    

 Description   

This was reported in https://github.com/trptcolin/reply/issues/129

My current theory, outlined there, is that nREPL sets up session bindings for `out`, which since we're creating a lazy seq are lost before nREPL goes to print out the seq for transport back to the nREPL client (REPLy, vim-fireplace, etc.).

user=> (defn foo [] (println "a") (map (fn [x] (println "b") (throw (Exception. "oops"))) [1 2 3]))
#'user/foo
user=> (foo)
a

Exception oops  user/foo/fn--699 (NO_SOURCE_FILE:1)
user=> (doall (foo))
a
b

Exception oops  user/foo/fn--699 (NO_SOURCE_FILE:1)

Don't have time at the moment to dig in, but can do so later if nobody else gets to it first.



 Comments   
Comment by Colin Jones [ 21/Feb/14 5:19 PM ]

OK, more data: this is happening because of https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/middleware/pr_values.clj#L23, where the (with-out-str (pr v)) could be the first time a lazy sequence gets forced, so any side effects' printing gets thrown away.

The trick is distinguishing the actual side-effect printing from the printable value when the sequence is being forced. It seems like it comes down to this: we need to force lazy sequences in the same way that printing does, while keeping the value and the print output distinct. The attached patch does this (I opted to make a local instead of using the private #'clojure.core/pr-on).

I think this is good, but wouldn't mind a review before I push it.

Comment by Chas Emerick [ 25/Feb/14 4:28 AM ]

I'm going to reply on the reply ticket :-P, as I think the issue probably isn't nREPL.

As for the patch itself, I'm suspicious of printing values twice as a fix for anything. If output isn't being captured properly, then we should find the problem with how we're capturing output, not throw more output at the problem.

Comment by Chas Emerick [ 25/Feb/14 9:36 AM ]

Take a look at this, Colin. Your solution was correct, but can just drop into pr-values; with-out-str was too crude a hammer for what pr-values needs.

If you can, verify that this makes REPL-y (and any other tools you're interested in) work as expected. Feel free to commit it, or I can (you should have privs IIRC).

Comment by Colin Jones [ 25/Feb/14 11:56 AM ]

Yeah, I definitely like it better in pr-values, where the rest of the printing logic already lives. Committed as bbc5e02b665356e7dc33fe1d78346f17b3dec452.

Thanks!

Comment by Chas Emerick [ 25/Feb/14 12:04 PM ]

Nope, thank you. I'll get a release out sometime this week.

Generated at Thu Jul 24 09:39:02 CDT 2014 using JIRA 4.4#649-r158309.