Point lambdafications in java.io

Joe Bowbeer joe.bowbeer at gmail.com
Wed Jun 19 12:47:30 PDT 2013


My position is: We should do it right if we do it.

Where "right" is well above the low-bar set by finalizer.

I'm interested in seeing a more detailed proposal.

I also think there is some room to explore other options for the File case.

URL is another place where this use case may surface, and is also a place
where "Stream" has another meaning, for example: URL.openStream() and
URLStreamHandler

--Joe


On Wed, Jun 19, 2013 at 7:12 AM, Brian Goetz <brian.goetz at oracle.com> wrote:

> Right, and that's just one problem.  The current implementation of
> CloseableStream is pretty much broken; not only do the methods do not
> return CloseableStream, but close()ing the CS does not have any effect on
> the stream.  So, I think the current CS is just too weak and at the same
> time consumes too much API surface area.  And creating a separate
> bulletproof CS abstraction is more than we can do now.  (And I never really
> liked having any FooableStream interfaces, because they invariably
> proliferate, and you end up in situations where you can you get a
> FooableStream or a BarableStream but you really want a
> FooableBarableStream.  Better not to go there at all.)
>
> But, we can bring AutoCloseable into Stream itself with relatively litle
> pain if we don't demand absolute perfection.  It is fairly easy to
> implement AC in Stream and have close() actually be reflected in the
> behavior of other stream methods with little intrusion and no additional
> runtime performance overhead (we can piggyback on an existing stream reuse
> check.)
>
> Your example about concat() is a good one, but I think it points the other
> way.  My first attempt at incorporating AutoCloseable into Stream missed
> that case.  But if all streams are Closeable, it is possible to hit that
> case in the second round.  With a separate CloseableStream abstraction, it
> will be impractical to ever hit that case.
>
> So I think we have two choices.
>
>  - No close support whatsoever.  Kill existing CloseableStream.  That
> means no use of TWR on IO-backed streams, and no way to release the
> resources except maybe after successful exhaustion of the input.
>
>  - Some reasonable best-effort attempt at "all streams are Closeable",
> like the one I've outlined.
>
> It sounds like your position is "if we can't do it perfectly, don't try?"
>
>
>
> On 6/19/2013 6:50 AM, Joe Bowbeer wrote:
>
>> Update:
>>
>> Some of my comments were based on the assumption that all streams would
>> be Closeable, the way all IO streams are closeable.
>>
>> The problem with adding closeable stream separately is that none of the
>> closeable streams' stream methods return closeable streams. That, and
>> also that there are no closeable primitive streams.
>>
>> On Jun 19, 2013 3:36 AM, "Joe Bowbeer" <joe.bowbeer at gmail.com
>> <mailto:joe.bowbeer at gmail.com>**> wrote:
>>
>>     I'm not in favor. As an implementer of custom IO streams, I'm aware
>>     of the burden that proper close() implementation adds, as well as
>>     the lack of any uses in many contexts. You can't(*) add close and
>>     expect best effort to be acceptable. There are unit tests, and close
>>     is expected to propagate (right?), e.g., in concat'd and zipped and
>>     merged and filtered streams.
>>
>>     As Remi points out, this would also require diluting the static
>>     analysis checks and editor warnings that are in place to ensure
>>     proper use of Closeables. From the programmer's point of view, every
>>     Stream would have to be treated as if it were an IO stream.
>>
>>     Joe
>>
>>     On Jun 18, 2013 6:48 PM, "Brian Goetz" <brian.goetz at oracle.com
>>     <mailto:brian.goetz at oracle.com**>> wrote:
>>
>>         I did a quick look at the code, this would be very easy to
>>         implement by piggybacking on top of the existing checking for
>>         stream re-use.  Just as
>>
>>            Stream s = ...
>>            s.forEach(...)
>>            s.forEach(...) // throws ISE
>>
>>         fails because the stream is being "reused", we can have future
>>         stream operations fail with ISE if they are initiated after the
>>         stream is closed.  For the example behavior you suggest,
>>         probably anything could happen.  But we can make a good-faith
>>         effort to prevent future stream operations from proceeding
>>         (which, Mike noted, is more than a lot of the existing
>>         Autocloseable IO classes do.)
>>
>>         On 6/18/2013 12:30 PM, Sam Pullara wrote:
>>
>>             I am very much in favor of a way to signal to the stream to
>>             relinquish resources so that you don't have to exhaust it to
>>             ensure that it is cleaned up. That said, without things like
>>             takeWhile() I'm not sure that there are many cases where you
>>             can close the stream unless you are in an exception state.
>>             What would be the semantics of something like this:
>>
>>             Stream stream = list.stream();
>>             stream.forEach(o -> stream.close());
>>
>>             Sam
>>
>>             On Jun 18, 2013, at 9:05 AM, Brian Goetz
>>             <brian.goetz at oracle.com <mailto:brian.goetz at oracle.com**>>
>> wrote:
>>
>>                 The libraries team added the following methods to
>>                 java.io <http://java.io> and java.nio, with discussion
>>
>>                 on corelibs-dev:
>>
>>                 In java.io.BufferedReader:
>>                    Stream<String> lines()
>>
>>                 In java.nio.Files, static methods for:
>>
>>                    CloseableStream<Path> list(Path dir) throws
>> IOException;
>>
>>                    CloseableStream<Path> walk(Path start, int maxDepth,
>>                 FileVisitOption... options) throws IOException
>>
>>                    CloseableStream<Path> walk(Path start,
>>                 FileVisitOption... options) throws IOException
>>
>>                    CloseableStream<Path> find(Path start,
>>                                             int maxDepth,
>>                                             BiPredicate<Path,
>>                 BasicFileAttributes> matcher,
>>                                             FileVisitOption... options)
>>                          throws IOException
>>
>>                    CloseableStream<String> lines(Path path, Charset cs)
>>                 throws IOException
>>
>>
>>                 CloseableStream simply extends Stream and AutoCloseable,
>>                 making it suitable for use with try-with-resources:
>>
>>                 public interface CloseableStream<T> extends Stream<T>,
>>                 AutoCloseable {
>>                      void close();
>>                 }
>>
>>                 Should we consider moving AutoCloseable up to Stream and
>>                 friends, and get rid of CloseableStream?
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/attachments/20130619/c1452cf1/attachment.html 


More information about the lambda-libs-spec-experts mailing list