As the original author of the function that eventually became 
clojure.java.io/reader, it was one of those unfortunate decisions that 
seemed like a good idea at the time and cannot be changed without breaking 
backwards compatibility.

Long before EDN existed, I wrote clojure.contrib.io 
https://github.com/clojure/clojure-contrib/blob/1.2.x/src/main/clojure/clojure/contrib/io.clj

This included a function `reader` that returned a java.io.BufferedReader: 
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html

BufferedReader was a convenient type to return because it supports 
.readLine, which is used by clojure.core/line-seq: 
https://github.com/clojure/clojure/blob/1.1.x/src/clj/clojure/core.clj#L1954-L1960

However, clojure.core/read and later clojure.edn/read were written in terms 
of java.io.PushbackReader, because they need the ability to look ahead one 
character in the stream while parsing it:
http://docs.oracle.com/javase/7/docs/api/java/io/PushbackReader.html

java.io.PushbackReader and java.io.BufferedReader are both subclasses of 
java.io.Reader, but there is no class in the JDK which combines the 
features of both PushbackReader and BufferedReader. Java does not permit 
multiple inheritance of concrete classes.

In Java it is common to have several layers of Reader sub-classes wrapped 
around each other, so that's what we do.

We cannot change clojure.java.io/reader to return a different type without 
breaking a lot of existing code that expects it to return a BufferedReader.

This was reported as an issue in 2009 and discussed on the mailing list:
https://groups.google.com/forum/#!topic/clojure/_tuypjr2M_A
http://dev.clojure.org/jira/browse/CLJ-82

It turns out there are some subtle issues which can cause incorrect 
behavior were clojure.core/read to blindly wrap a PushbackReader around its 
argument:
https://groups.google.com/d/msg/clojure/_tuypjr2M_A/W1EcEbMUg_cJ

In conclusion, this is a minor nuisance, well-known to Clojure developers, 
for which no good solution has been identified.

–S


On Sunday, December 7, 2014 11:27:05 PM UTC-5, Fluid Dynamics wrote:
>
> => (with-open [in (io/reader (io/resource "foo"))] (edn/read in))
> ClassCastException java.io.BufferedReader cannot be cast to 
> java.io.PushbackReader  clojure.edn/read (edn.clj:35)
>
> Er, what? Aren't these things supposed to just plug into each other and 
> work OOTB? Do I need to muck about with interop to use edn with any input 
> source other than strings, then?
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to