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 [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
