Experience with Java taught me to loath ethe "do I/O
by composing lots of little wrappers" approach for
several reasons:
 - the fact that the commonest case was not the
   default case, so that simple obvious code was
   somewhere between disgracefully slow and wrong
 - the extra complexity needed to get it right
   (having to know a plethora of wrapper classes
   instead of just getting sensible defaults)
 - the poor performance.

In my own Smalltalk system I hewed to the ANSI
Smalltalk standard and if you do
    FileStream read: aFileName
or  FileStream write: aFileName
you get a text file using the encoding set by
your environment's locale, the native line ending
convention, Simple, easy, and leaves Java's
I/O performance in the dust.

Of course wrappers are available for the rare
cases when you need them, but you don't _have_
to use them.  One reason this matters is that
there are two ways to write a stream:

  s2 := WrapperClass on: s1
    -- closing s2 just closes s2, not s1.
  s2 := WrapperClass onOwn: s1
    -- closing s2 closes s1 as well

And yes, both of these *are* used.


On 24 June 2018 at 04:53, Sven Van Caekenberghe <s...@stfx.eu> wrote:

> Peter,
>
> > On 23 Jun 2018, at 15:39, Peter Uhnák <i.uh...@gmail.com> wrote:
> >
> > Hi,
> >
> > I'm starting to familiarize myself with new streams, and one thing I've
> noticed is the removal of #lineEndConvention (which I use all the time).
> >
> > So a statement like this
> >
> > aFile writeStreamDo: [ :stream |
> >       stream lineEndConvention: #lf.
> >       stream << '...'
> > ].
> >
> > has to be written like so
> >
> > aFile writeStreamDo: [ :rawStream | |stream|
> >       stream := (ZnNewLineWriterStream on: rawStream) forLf.
> >       stream << '...'
> > ].
> >
> > which feels very messy because I am mixing writing with the
> configuration. And I don't even take account for buffered/encoded
> decorators. Plus it increases the incidental complexity -- I need another
> variable, and I can accidentally write to the wrong stream, etc.
> >
> > Would a method like #writeStream:do: (or #writeStreamTransform:do:) make
> sense? E.g.
> >
> > aFile writeStreamTransform: [ :stream | (ZnNewLineWriterStream on:
> stream) ] do: [ :stream |
> >       stream << '...'
> > ]
> >
> > To separate the composition from the usage?
> >
> > Thanks,
> > Peter
>
> The goals of the 'new' (they have existed for quite a while) streams is to
> go from single big complex do all classes and replace that with a
> composition of much simpler single purpose classes. Another goal is to
> reduce the API so that it becomes easier to create new stream classes. Of
> course, a consequence is that you need composition to get the functionality
> you want. But I think you understand the tradeoff.
>
> If the mixing of configuration/setup with writing/reading bothers you,
> then I would suggest using two methods. One that does only the
> writing/reading assuming a limited API, and another that does the
> configuration/setup, using composition.
>
> Note that the streams that you get already are a composition (most often a
> BinaryFileStream wrapped in a Buffered stream wrapped in a
> Encoding/Decoding stream). EOL translation is not a standard part of that.
> But there is quite some system code that does uses EOL translation.
>
> Sven
>
>
>
>

Reply via email to