[ENH] Use of EndOfStream (sm)

Boris Gaertner Boris.Gaertner at gmx.net
Tue Feb 17 20:21:10 UTC 2004


From: "Bill Schwab" <BSchwab at anest.ufl.edu> wrote:

>Hello all,

>On 29 Dec, Boris posted a change set to attempt to make Squeak signal
>EndOfStream when the corresponding condition occurs.  I just tried it in
>3.7a and noted that EndOfStream>>defaultAction took the teeth out of it.
This is a beautiful way to say it  :-)  and it is absolutely correct!

>Reverting to Error>>defaultAction gets #next to signal an error, but #next:
>is still willing to truncate w/o complaining (something that I would leave
>to #nextAvailable:).

Hi Bill,

thank you for reviewing this stuff. I had to think for a while about
your findings. The end-of-stream handling is not a very clean
thing. Here is now what I feel I should write:

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

When you install my proposed change, the defaultAction
answers  nil and you get the same result that you got
without exception handling. This is desireable, because
I do not want to install hidden pitfalls.

To get something different, you have to write e.g.:

 | st |
  st := ReadStream on: #(1 2 3).
  (1 to: 5) collect:
                 [:x | [st next]
                         on: EndOfStream
                         do: [:ex | ex return: #eof]
                 ]
 =>  #(1 2 3 #eof #eof)

To get a notifier window, you can write:

 | st |
  st := ReadStream on: #(1 2 3).
  (1 to: 5) collect:
                 [:x | [st next]
                         on: EndOfStream
                         do: [:ex | ex resignalAs: (Halt new messageText:
'read past end of stream')]
                 ].

or:

 | st |
  st := ReadStream on: #(1 2 3).
  [(1 to: 5) collect: [:x | st next]
]
    on: EndOfStream
    do: [:ex | ex resignalAs:
              (Halt new messageText: 'read past end of stream')]


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.

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.

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. For now I think that
=>  the defaultAction of EndOfStream should be  ^nil
=>  the implementations of  next:  should be discussed
    and perhaps carefully improved.

More opinions are welcome!

Greetings,
Boris





More information about the Squeak-dev mailing list