[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
|