I came across this problem debugging a funny result in porting the SUnit
Browser model. The following code, when evaluated in a workspace, answers true. I think it should answer false: =================================== | testStream | testStream := ReadWriteStream on: String new. testStream nextPut: $A. testStream isEmpty =================================== jlo |
Jeffrey,
> I came across this problem debugging a funny result in porting the SUnit > Browser model. > > The following code, when evaluated in a workspace, answers true. I think > it should answer false: ReadWriteStream is a strange amalgamation of it's more "normal" superclasses and doesn't always behave as expected. I believe that some Smalltalk implementations work in the way you suggest but if you look at ANSI then the picture is slightly muddier. 1) ANSI defines #with: as the only constructor for ReadWriteStream (and WriteStream), #on is not mentioned. However changing your example to use #with has, in Dolphin anyway, the same effect as you describe. 2) #with: is defined as creating a Stream whose "past sequence values" consist of the objects in the argument collection (an empty String in your example) and which initially has no "future sequence values" 3) #nextPut: adds it's argument to the end of the receiver Stream's "past sequence values". In your example the "future sequence values" collection is therefore still empty. 4) #atEnd answers true if the receiver's Stream has no "future sequence values" which, as noted in (3), is the condition your example stream is in. 5) Although #on: does work with Dolphin ReadWriteStream, in the sense that it doesn't raise an error, it's behaviour is probably not what you would expect anyway (see (7)). testStream := ReadWriteStream on: 'hello'. testStream nextPut: $A. testStream contents --> answers 'A' but testStream := ReadWriteStream with: 'hello'. testStream nextPut: $A. testStream contents --> answers 'helloA' 6) A rule of thumb that I try to use is that ReadWriteStream's are not normally necessary, I've found very few occasions when a ReadStream or WriteStream is not easier to use, but when I do use one I try to think of it as a WriteStream that can be read rather than a ReadStream that can be written, IYSWIM. This basically means that every time I read from one I make sure that I know where the read is going to occur, using either #reset or #position:. 7) I once got into a long e-conversation about Streams and finally understood that it is an unwritten law of nature that everybody has a different interpretation on how they work and how they _should_ work. Bearing that in mind, please feel free to completely ignore points 1 to 6 <g> Ian |
Ian, Jeffrey,
> 7) I once got into a long e-conversation about Streams and finally > understood that it is an unwritten law of nature that everybody has a > different interpretation on how they work and how they _should_ work. <grin> In this case, though, ANSI had an opinion (and a correct one too -- in my opinion ;-), which is that <sequencedStream>#isEmpty Returns true if both the set of past and future sequence values of the receiver are empty. Otherwise returns false. So I think the behaviour Jeffrey's seeing is wrong (and probably a bug). BTW, (in case anyone at OA's reading) what's the rational behind PositionableStream>>peekFor: ? The way it works in Dolphin is inconsistent with the ANSI definition (which, as I read it, requires that the stream "position" be unchanged whether or not the desired element is found). Is that for consistency with other Smalltalk implementations, or was the ANSI def too pointless to swallow ? -- chris |
Chris,
> So I think the behaviour Jeffrey's seeing is wrong (and probably a bug). Doh, you're quite right as usual. At some stage in my reply I started thinking that #atEnd rather than #isEmpty was the problem that Jeffrey was talking about and never noticed my mistake. Sorry all. Ian |
That explains why I kept rereading your post but not quite getting it at the
end. The bulk of the post is very useful however, so I appreciate the long and thoughtful answer. I'll await an OA response on this one - it does seem incorrect. jlo "Ian Bartholomew" <[hidden email]> wrote in message news:CZw77.101636$[hidden email]... > Chris, > > > So I think the behaviour Jeffrey's seeing is wrong (and probably a bug). > > Doh, you're quite right as usual. At some stage in my reply I started > thinking that #atEnd rather than #isEmpty was the problem that Jeffrey was > talking about and never noticed my mistake. Sorry all. > > Ian > > |
In reply to this post by Ian Bartholomew-4
> 7) I once got into a long e-conversation about Streams and finally
> understood that it is an unwritten law of nature that everybody has a > different interpretation on how they work and how they _should_ work. > Bearing that in mind, please feel free to completely ignore points 1 to 6 > <g> <G> Streams should be considered harmful, and consequently outlawed, exactly for that reason. Well, there are some occasions where the Stream concept is really the most useful and appropriate, but my feeling is that a Cursor would help you better (get you clearer code, and easier to write) in the majority of situations where Streams are used in practice. Part of my understanding of the Stream concept is that you are only guaranteed navigability in one direction (i.e., forward), and that there also is no guarantee of a meaningful #position attribute. In many practical situations these limitations do not apply (because we have random access), and the concept of a Cursor on a (possibly virtual) collection would be more natural. Anyway, that's just my feeling, and I have never tried to actually implement a Cursor class :-). Regards, Peter van Rooijen > > Ian > > |
In reply to this post by Chris Uppal-3
Chris, Ian, Jeffrey
"Chris Uppal" <[hidden email]> wrote in message news:[hidden email]... > Ian, Jeffrey, > > > 7) I once got into a long e-conversation about Streams and finally > > understood that it is an unwritten law of nature that everybody has a > > different interpretation on how they work and how they _should_ work. > > <grin> > > In this case, though, ANSI had an opinion (and a correct one too -- in my > opinion ;-), which is that <sequencedStream>#isEmpty > > Returns true if both the set of past and future sequence values > of the receiver are empty. Otherwise returns false. > > So I think the behaviour Jeffrey's seeing is wrong (and probably a bug). Yes, I agree. Defect # 302, to be fixed in a future release, hopefully the next one. > BTW, (in case anyone at OA's reading) what's the rational behind > PositionableStream>>peekFor: ? The way it works in Dolphin is inconsistent > with the ANSI definition (which, as I read it, requires that the stream > "position" be unchanged whether or not the desired element is found). Is > that for consistency with other Smalltalk implementations, or was the ANSI > def too pointless to swallow ? I would say that ANSI definition is wrong - it's inconsistent with the long established behaviour of #peekFor:, and for no good reason since not advancing the position when the peeked for element is found rather defeats its purpose. Regards Blair |
"Blair McGlashan" <[hidden email]> wrote in message
news:[hidden email]... > > Yes, I agree. Defect # 302, to be fixed in a future release, hopefully the > next one. > Sorry, let me correct that: Already recorded as defect no. 183. Regards Blair |
Free forum by Nabble | Edit this page |