[Pharo-dev] In-memory FileSystem write streams not being polymorphic

Chris Muller asqueaker at gmail.com
Wed Nov 13 17:13:47 EST 2013


These are really excellent arguments, Nicolas.  Good discussion.

On Wed, Nov 13, 2013 at 3:32 PM, Nicolas Cellier
<nicolas.cellier.aka.nice at gmail.com> wrote:
> Chris,
> I have to completely disagree.
> The idea of breaking a complex object into simpler parts is not just
> theories and extremism.
> Assigning several roles to an object is sometimes convenient for a start,
> but generally does scale very badly.
> It's a collective experience driven by pragmatic considerations in
> developping in all sort of languages.
> And it's my own experience too.
>
> A file is like the container, the stream is about reading/writing the
> contents.
> I think I remember the confusion was made at the beginning in st-80, because
> it was simple enough at that time.
> So it's rather an historical slag, not something that was added later for
> this special case.
> And it is something that should have been revised, because when we added
> pipes, sockets or other external streams, that ruined the idea of confusing
> the two things into a not well delimited blob without clear
> responsibilities.
> Though we kept the original implementation and started to distort the
> package by adding faked polymorphism like name ^'john doe'.
>
> Clearly, I need no stream on its contents to rename a file, query its
> permissions, or delete it, so why bother with internal states of a stream if
> I'm interested in handling the file?
> If I am interested about the contents, I don't need to ever know about the
> path of the file nor its name, or shall I change a $A read from it into a $B
> if the file is named 'turnAllAinB'?
>
> Where exactly are we going to need this encapsulated blob which pretend to
> be both a file and a stream? I would be happy to show that a rewrite is both
> simple and good looking at end application sites.
> Of course, inside the lava of multi year hacked stream hierarchy, it might
> be a bit less obvious to disentangle the spaghetti.
> Hence more radical solutions: table rase and complete rewrite.
>
>
>
>
>
> 2013/11/13 Chris Muller <asqueaker at gmail.com>
>>
>> On Wed, Nov 13, 2013 at 1:17 PM, Nicolas Cellier
>> <nicolas.cellier.aka.nice at gmail.com> wrote:
>> > Exactly, every specialized stream has its specialized API and/or
>> > specialized
>> > implementation.
>> > File streams don't even have a name, because they need not to.
>> > You can browse XTFileReadStream and XTFileWriteStream, you won't find
>> > such
>> > thing.
>> > The file has a name, the stream does not need any.
>> > Before adding anything to a stream, ask first, why am i going to need
>> > this?
>>
>> I agree with what Frank said, but not your suggestion that:
>>
>> > File streams don't even have a name, because they need not to.
>> > If it really need it, the application certainly can retrieve the name
>> > from a higher level object (a
>> > FIleReference, FileDirectory or whatever).
>>
>> because doing that means the FileStream is no longer
>> fully-encapsulated.  And now for the same method to support a
>> non-FileStream stream, what will be passed as the new FileReference
>> argument?  nil?  So the code went from stream-delegation to
>> case-logic.
>>
>> This is why organic growth happened in the original Stream hierarchy
>> -- because it was "needed", not random.  Not strict, yes, but not
>> "random" either.
>>
>> One final thing to consider about selector "uniformity" is how it can
>> negate the ability to effectively trace code (via senders and
>> implementors).  Wow, how many senders of #next...?
>>
>> Stream-composition is cool, though, and I understand that to be a
>> benefit of the stricter API.
>>
>>
>>
>> > 2013/11/13 Frank Shearar <frank.shearar at gmail.com>
>> >>
>> >> On 13 November 2013 16:48, Chris Muller <asqueaker at gmail.com> wrote:
>> >> > I know nothing about Xtreams but, IMO, this obsession with sterility
>> >> > borders on mental illness.
>> >> >
>> >> > "All sort of un-needed complexity?"  That's overstating it a bit,
>> >> > don't you think?
>> >> >
>> >> > So you must really feel stressed that ALL Object's, in fact, have a
>> >> > #name, huh?  I admit this seems to push the limits but...
>> >> >
>> >> > what's the point of having any kind of different streams at all then?
>> >> > It's the _differences_ between them that makes composing them useful.
>> >> > Compression, encryption, filtering, sockets, files, circular, etc.
>> >> > You think you'll be able to do all that and get away with all of them
>> >> > having exactly the same API?
>> >>
>> >> They don't have the same API. And they shouldn't. And that's Nicolas'
>> >> whole point. A Stream does not have a name (nor should it - what's the
>> >> name of the compressed output of an audio stream from your
>> >> microphone?). A FileStream can extend this API, and that's fine. But
>> >> keep that out of the Stream API.
>> >>
>> >> So Nicolas is arguing that _difference_ should be reflected in the
>> >> API. File streams have names, but generic streams do not.
>> >>
>> >> As it happens, Xtreams takes a very disciplined approach to this. Some
>> >> streams have positions, and so you can go back. Some can't. This is
>> >> reflected in the API. This is good.
>> >>
>> >> > IMHO working around that, passing extra objects around, sounds more
>> >> > stressful than letting a stream on a _file_ know its filename..
>> >>
>> >> Mu. Streams have no names. File streams have names.
>> >>
>> >> frank
>> >>
>> >> >> If it really need it, the application certainly can retrieve the
>> >> >> name
>> >> >> from a higher level object (a FIleReference, FileDirectory or
>> >> >> whatever).
>> >> >
>> >> > How does that solution allow uniformity in stream-using code?
>> >> >
>> >> > On Wed, Nov 13, 2013 at 9:58 AM, Nicolas Cellier
>> >> > <nicolas.cellier.aka.nice at gmail.com> wrote:
>> >> >> Yes, a Wrapper would provide the legacy API.
>> >> >>
>> >> >> And yes, the name of a stream should better not be part of the API.
>> >> >> Most stream don't have a name, and adding such API adds all sort of
>> >> >> un-needed complexity.
>> >> >> It's an internal detail that can eventually help for reporting error
>> >> >> if
>> >> >> accessible, but nothing more.
>> >> >>
>> >> >> If it really need it, the application certainly can retrieve the
>> >> >> name
>> >> >> from a
>> >> >> higher level object (a FIleReference, FileDirectory or whatever).
>> >> >>
>> >> >>
>> >> >> 2013/11/13 Chris Muller <asqueaker at gmail.com>
>> >> >>>
>> >> >>> On Tue, Nov 12, 2013 at 7:31 AM, Nicolas Cellier
>> >> >>> <nicolas.cellier.aka.nice at gmail.com> wrote:
>> >> >>> > It's just a matter of selecting a strategy. I've proposed two:
>> >> >>> > A) create a wrapper class for legacy Stream compatibility
>> >> >>> > selectors
>> >> >>> > B) create extensions for Legacy Stream compatibility selectors
>> >> >>> > My preference goes to A)
>> >> >>>
>> >> >>> By wrappers you mean the Xtreams are the innards doing the work and
>> >> >>> the wrappers providing the legacy API?
>> >> >>>
>> >> >>> This would be a great way to test Xtreams.
>> >> >>>
>> >> >>> > The legacy support MUST be minimal (next nextPut: nextPutAll:
>> >> >>> > peek
>> >> >>> > upTo:
>> >> >>> > ...), otherwise we will import all the cruft in Xtream and would
>> >> >>> > go
>> >> >>> > back
>> >> >>> > to
>> >> >>> > our starting point...
>> >> >>> > Once the minimal support written (a few hours should be enough),
>> >> >>> > we
>> >> >>> > should
>> >> >>> > gradually switch each every legacy Stream usage -> Xtream.
>> >> >>> >
>> >> >>> > An area which require more work is those Streams that have mixed
>> >> >>> > conventions
>> >> >>> > (one portion is interpreted as text, another as binary).
>> >> >>> > In theory that's easy, we just have two streams and they both
>> >> >>> > wrap
>> >> >>> > on a
>> >> >>> > low
>> >> >>> > level binary stream, but that means we have to be very cautious
>> >> >>> > with
>> >> >>> > buffers
>> >> >>> > and caches.
>> >> >>> >
>> >> >>> > Another area of work is usage of ugly selectors like name (we try
>> >> >>> > to
>> >> >>> > access
>> >> >>> > the file name from the Stream API, arghh). Those usages are bad
>> >> >>> > and
>> >> >>> > require
>> >> >>> > a rewrite.
>> >> >>>
>> >> >>> Are you saying a FileStream knowing its #name or #filename is bad?
>> >> >>>
>> >> >>
>> >> >
>> >>
>> >
>>
>




More information about the Pharo-dev mailing list