Hi Nicolas, On 4 April 2018 at 12:36, Nicolas Cellier <nicolas.cellier.aka.n...@gmail.com> wrote: > > > 2018-04-04 12:18 GMT+02:00 Alistair Grant <akgrant0...@gmail.com>: >> >> Hi Sven, >> >> On Wed, Apr 04, 2018 at 11:32:02AM +0200, Sven Van Caekenberghe wrote: >> > Somehow, somewhere there was a change to the implementation of the >> > primitive called by some streams' #atEnd. >> >> That's a proposed change by me, but it hasn't been integrated yet. So >> the discussion below should apply to the current stable vm (from August >> last year). >> >> >> > IIRC, someone said it is implemented as 'remaining size being zero' >> > and some virtual unix files like /dev/random are zero sized. >> >> Currently, for files other than sdio (stdout, stderr, stdin) it is >> effectively defined as: >> >> atEnd := stream position >= stream size >> >> >> And, as you say, plenty of virtual unix files report size 0. >> >> >> >> > Now, all kinds of changes are being done image size to work around this. >> >> I would phrase this slightly differently :-) >> >> Some code does the right thing, while other code doesn't. E.g.: >> >> MultiByteFileStream>>upToEnd is good, while >> FileStream>>contents is incorrect >> >> >> > I am a strong believer in simple, real (i.e. infinite) streams, but I >> > am not sure we are doing the right thing here. >> > >> > Point is, I am not sure #next returning nil is official and universal. >> > >> > Consider the comments: >> > >> > Stream>>#next >> > "Answer the next object accessible by the receiver." >> > >> > ReadStream>>#next >> > "Primitive. Answer the next object in the Stream represented by the >> > receiver. Fail if the collection of this stream is not an Array or a >> > String. >> > Fail if the stream is positioned at its end, or if the position is out >> > of >> > bounds in the collection. Optional. See Object documentation >> > whatIsAPrimitive." >> > >> > Note how there is no talk about returning nil ! >> > >> > I think we should discuss about this first. >> > >> > Was the low level change really correct and the right thing to do ? >> >> The primitive change proposed doesn't affect this discussion. It will >> mean that #atEnd returns false (correctly) sometimes, while currently it >> returns true (incorrectly). The end result is still incorrect, e.g. >> #contents returns an empty string for /proc/cpuinfo. >> >> You're correct about no mention of nil, but we have: >> >> FileStream>>next >> >> (position >= readLimit and: [self atEnd]) >> ifTrue: [^nil] >> ifFalse: [^collection at: (position := position + 1)] >> >> >> which has been around for a long time (I suspect, before Pharo existed). >> >> Having said that, I think that raising an exception is a better >> solution, but it is a much, much bigger change than the one I proposed >> in https://github.com/pharo-project/pharo/pull/1180. >> >> >> Cheers, >> Alistair >> > > Hi, > yes, if you are after universal behavior englobing Unix streams, the > Exception might be the best way. > Because on special stream you can't allways say in advance, you have to try. > That's the solution adopted by authors of Xtreams. > But there is a runtime penalty associated to it. > > The penalty once was so high that my proposal to generalize EndOfStream > usage was rejected a few years ago by AndreaRaab. > http://forum.world.st/EndOfStream-unused-td68806.html
Thanks for this, I'll definitely take a look. Do you have a sense of how Denis' suggestion of using an EndOfStream object would compare? It would keep the same coding style, but avoid the problems with nil. Thanks, Alistair > I have regularly benched Xtreams, but stopped a few years ago. > Maybe i can excavate and pass on newer VM. > > In the mean time, i had experimented a programmable end of stream behavior > (via a block, or any other valuable) > http://www.squeaksource.com/XTream.htm > so as to reconcile performance and universality, but it was a source of > complexification at implementation side. > > Nicolas > >> >> >> > Note also that a Guille introduced something new, #closed which is >> > related to the difference between having no more elements (maybe right now, >> > like an open network stream) and never ever being able to produce more >> > data. >> > >> > Sven >> > >> > >> > >> >