Playing a bit devil's advocate, the idea is that, in general, 

[ stream atEnd] whileFalse: [ stream next. "..." ].

is no longer allowed ? And you want to replace it with

[ stream next ifNil: [ false ] ifNotNil: [ :x | "..." true ] whileTrue.

That is a pretty big change, no ?

I think/feel like a proper EOF exception would be better, more correct.

[ [ stream next. "..." true ] on: EOF do: [ false ] ] whileTrue.

Will we throw away #atEnd then ? Do we need it if we cannot use it ?

> On 4 Apr 2018, at 12:41, Alistair Grant <akgrant0...@gmail.com> wrote:
> 
> 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


Reply via email to