[ENH] Use of EndOfStream

Bill Schwab BSchwab at anest.ufl.edu
Tue Feb 17 21:24:07 UTC 2004


Boris,

=====================
thank you for reviewing this stuff. 
=====================

Thanks for _writing_ it!


=====================
First, it is a good start to check what Squeak 3.6 does when it reads past the end of a Stream. Please try this:

| st |
st := ReadStream on: #(1 2 3).
(1 to: 4) collect: [:x | st next]

=> #(1 2 3 nil)

This is a surprise, but we get the same results in VisualWork and in Smalltalk/X
=====================

No disrespect intended toward any interested parties, I think this behavior is incorrect.  
It made sense in 1980; in an age of structured exception handling, it does not make sense (IMHO).




=====================
To get something different, you have to write e.g.:
[examples snipped]
=====================

Interesting, but this requires the programmer to do extra work to get the benefit of structured exceptions.  The mechanism will be much less helpful as a result.



=====================
The first proposal protects every wingle call of next, whereas the second proposal protects the 'collect:'

It is not easy to see which is better - working with
exceptions is problematic.
=====================

It seems to me that one would protect #collect:, as there is overhead even to set up the #on:do:, and even more overhead when it "fires".



=====================
Your second observation:
>but #next: is still willing to truncate w/o complaining
is very interesting.
It refers to this example:
| st |
st := ReadStream on: #(1 2 3).
st next: 4

=> #(1 2 3) (in Squeak )
=> error notifaction in VW 3.0 and in Dolphin 2.1
=> #(1 2 3 nil) in Smalltalk/X

Smalltalk/X does not reimplement #next: in ReadStream and is therefore capable to exhibit consistent behavior.
=====================

In Dolphin, one would request/authorize the Squeak behavior by using #nextAvailable:.  Dolphin's #next: will not return a collection that is shorter than requested; doing so strikes me as hiding a problem that could be made obvious.  I have worked with Dolphin long enough to be convinced that its approach to stream exhaustion is correct.



=====================
The ANSI standard seemingly does not help much,
in an old draft, I found in sections 7.9.2.3, 7.9.2.4,
7.9.5.1, 7.10.2.1 that the result of next (resp. of next:) is *undefined* when the stream has no "future sequence value".

This 'undefined' gives room to a lot of surprising and incompatible solutions. I am not happy with it. 
=====================

I agree.


=====================
For now I think that
=> the defaultAction of EndOfStream should be ^nil
=> the implementations of next: should be discussed
and perhaps carefully improved.
=====================

This is one case where I think some XP would be in order.  If we have confidence in our unit tests, then I think we should do the consistent thing, which is:

* #next, #next: signal EndOfStream
* EndOfStream leads to a walkback, not a nil
  return value
* #nextAvailable: acts as #next: does now.

Regardless of the outcome, thanks for your efforts and the discussion!

Bill




Wilhelm K. Schwab, Ph.D.
University of Florida
Department of Anesthesiology
PO Box 100254
Gainesville, FL 32610-0254

Email: bills at anest4.anest.ufl.edu
Tel: (352) 846-1285
FAX: (352) 392-7029





More information about the Squeak-dev mailing list