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:


        (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.


> 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