Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-cmm.1059.mcz
==================== Summary ====================
Name: Collections-cmm.1059 Author: cmm Time: 18 February 2024, 5:19:05.159381 pm UUID: 982eb6aa-f237-4e79-a208-ae6b2f23cf1b Ancestors: Collections-mt.1058
- Let #peek: support a negative number of characters to peekBack:. - Let SharedQueue2 support #atEnd.
=============== Diff against Collections-mt.1058 ===============
Item was changed: ----- Method: PositionableStream>>peek: (in category 'accessing') ----- + peek: anInteger + ^ anInteger positive + ifTrue: [ self peekForward: anInteger ] + ifFalse: [ self peekBack: anInteger abs ]! - peek: anInteger - "Answer what would be returned if the message next: anInteger were sent to the receiver. If the receiver has less than anInteger more elements, only answer so many elements as available." - - | oldPosition result | - oldPosition := position. - result := self next: anInteger. - position := oldPosition. - ^ result!
Item was added: + ----- Method: PositionableStream>>peekBack: (in category 'accessing') ----- + peekBack: anInteger + "Answer anInteger characters previous to the current position, or all to the beginning, whichever is fewer." + ^ anInteger negative + ifTrue: [ self peek: anInteger negated ] + ifFalse: + [ | toSkip | toSkip := anInteger min: self position. + self + skip: toSkip negated ; + next: toSkip ]!
Item was added: + ----- Method: PositionableStream>>peekForward: (in category 'accessing') ----- + peekForward: anInteger + "Answer what would be returned if the message next: anInteger were sent to the receiver. If the receiver is at the end, answer an empty string." + | priorPos result | + priorPos := position. + result := self next: anInteger. + position := priorPos. + ^ result!
Item was added: + ----- Method: SharedQueue2>>atEnd (in category 'testing') ----- + atEnd + ^ monitor critical: [ items isEmpty ]!
Hi Chris,
In case of SharedQueue2, I think it's a Stream only by accident. I suggest changing the superclass of SharedQueue2 to Object, just like it's with SharedQueue, which SharedQueue2 was intended to replace. That would mean #atEnd is not required (as it wasn't implemented for almost two decades). And #isEmpty is already there with the same behavior.
As for #peek:, I would have used #negated instead of #abs to convert a negative number to positive.
Best, Levente
On 2024. 02. 18. 23:19, commits@source.squeak.org wrote:
Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-cmm.1059.mcz
==================== Summary ====================
Name: Collections-cmm.1059 Author: cmm Time: 18 February 2024, 5:19:05.159381 pm UUID: 982eb6aa-f237-4e79-a208-ae6b2f23cf1b Ancestors: Collections-mt.1058
- Let #peek: support a negative number of characters to peekBack:.
- Let SharedQueue2 support #atEnd.
=============== Diff against Collections-mt.1058 ===============
Item was changed: ----- Method: PositionableStream>>peek: (in category 'accessing') -----
- peek: anInteger
- ^ anInteger positive
ifTrue: [ self peekForward: anInteger ]
ifFalse: [ self peekBack: anInteger abs ]!
- peek: anInteger
- "Answer what would be returned if the message next: anInteger were sent to the receiver. If the receiver has less than anInteger more elements, only answer so many elements as available."
- | oldPosition result |
- oldPosition := position.
- result := self next: anInteger.
- position := oldPosition.
- ^ result!
Item was added:
- ----- Method: PositionableStream>>peekBack: (in category 'accessing') -----
- peekBack: anInteger
- "Answer anInteger characters previous to the current position, or all to the beginning, whichever is fewer."
- ^ anInteger negative
ifTrue: [ self peek: anInteger negated ]
ifFalse:
[ | toSkip | toSkip := anInteger min: self position.
self
skip: toSkip negated ;
next: toSkip ]!
Item was added:
- ----- Method: PositionableStream>>peekForward: (in category 'accessing') -----
- peekForward: anInteger
"Answer what would be returned if the message next: anInteger were sent to the receiver. If the receiver is at the end, answer an empty string."
| priorPos result |
priorPos := position.
result := self next: anInteger.
position := priorPos.
^ result!
Item was added:
- ----- Method: SharedQueue2>>atEnd (in category 'testing') -----
- atEnd
- ^ monitor critical: [ items isEmpty ]!
Hi Levente,
Should SharedQueue2 inherit from Object, or should SharedQueue inherit from Stream? Because, if it walks and quacks like a Stream, should it not be a Stream, able to inherit additional Stream behaviors?
Re: #peek:'s use of #abs vs. #negated, may I ask why you prefer #negated? For me,
- #abs ensures it's positive, whereas - #negated creates a dependency on the line above.
There's also the matter of unexpected behavior of "negative zero" which, I guess doesn't apply here since it can't accept Float's.
I'm not resisting your suggestions, just curious because I know you usually have good reasons for things which I often learn from.
Regards, Chris
On Thu, Feb 22, 2024 at 6:14 PM leves leves@caesar.elte.hu wrote:
Hi Chris,
In case of SharedQueue2, I think it's a Stream only by accident. I suggest changing the superclass of SharedQueue2 to Object, just like it's with SharedQueue, which SharedQueue2 was intended to replace. That would mean #atEnd is not required (as it wasn't implemented for almost two decades). And #isEmpty is already there with the same behavior.
As for #peek:, I would have used #negated instead of #abs to convert a negative number to positive.
Best, Levente
On 2024. 02. 18. 23:19, commits@source.squeak.org wrote:
Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-cmm.1059.mcz
==================== Summary ====================
Name: Collections-cmm.1059 Author: cmm Time: 18 February 2024, 5:19:05.159381 pm UUID: 982eb6aa-f237-4e79-a208-ae6b2f23cf1b Ancestors: Collections-mt.1058
- Let #peek: support a negative number of characters to peekBack:.
- Let SharedQueue2 support #atEnd.
=============== Diff against Collections-mt.1058 ===============
Item was changed: ----- Method: PositionableStream>>peek: (in category 'accessing')
- peek: anInteger
^ anInteger positive
ifTrue: [ self peekForward: anInteger ]
ifFalse: [ self peekBack: anInteger abs ]!
- peek: anInteger
"Answer what would be returned if the message next: anInteger were
sent to the receiver. If the receiver has less than anInteger more elements, only answer so many elements as available."
| oldPosition result |
oldPosition := position.
result := self next: anInteger.
position := oldPosition.
^ result!
Item was added:
- ----- Method: PositionableStream>>peekBack: (in category 'accessing')
- peekBack: anInteger
"Answer anInteger characters previous to the current position, or
all to the beginning, whichever is fewer."
^ anInteger negative
ifTrue: [ self peek: anInteger negated ]
ifFalse:
[ | toSkip | toSkip := anInteger min: self
position.
self
skip: toSkip negated ;
next: toSkip ]!
Item was added:
- ----- Method: PositionableStream>>peekForward: (in category
'accessing') -----
- peekForward: anInteger
"Answer what would be returned if the message next: anInteger were
sent to the receiver. If the receiver is at the end, answer an empty string."
| priorPos result |
priorPos := position.
result := self next: anInteger.
position := priorPos.
^ result!
Item was added:
- ----- Method: SharedQueue2>>atEnd (in category 'testing') -----
- atEnd
^ monitor critical: [ items isEmpty ]!
Hi Chris,
On 2024. 02. 24. 22:45, Chris Muller wrote:
Hi Levente,
Should SharedQueue2 inherit from Object, or should SharedQueue inherit from Stream? Because, if it walks and quacks like a Stream, should it not be a Stream, able to inherit additional Stream behaviors?
That's a very good question, and I think the answer is obvious. It did not walk and quack like a Stream until you added #atEnd. So, yeah, it's not a stream.
Re: #peek:'s use of #abs vs. #negated, may I ask why you prefer #negated? For me,
If you know that a number is negative and you want to make it non-negative, then #negated is the right message. #abs is for the case when you don't have any knowledge about the number's sign.
- #abs ensures it's positive, whereas - #negated creates a dependency on the line above.
You didn't have those concerns while using #negated in #peekBack: to create a non-negative number from a negative number.
Best, Levente
Hi Levente,
Should SharedQueue2 inherit from Object, or should SharedQueue inherit
from Stream? Because, if it walks and quacks like a Stream, should it not be a Stream, able to inherit additional Stream behaviors?
That's a very good question, and I think the answer is obvious. It did not walk and quack like a Stream until you added #atEnd. So, yeah, it's not a stream.
Shouldn't the question center around the nature of the behaviors themselves rather than the names. The four behaviors required of any Stream are:
#atEnd #contents #next #nextPut:
SharedQueue[2] already had two of them, and the other two make perfect sense for a Queue. #isEmpty could easily have been named #atEnd in the first place and be equally meaningful.
Does a "queue" not already seem like it "is-a" stream from a semantic sense? It seems like a lot of good behaviors could be inherited from it, why should those have to be copy-and-pasted?
Are there any good arguments _against_ inheriting from Stream?
Re: #peek:'s use of #abs vs. #negated, may I ask why you prefer
#negated? For me,
If you know that a number is negative and you want to make it non-negative, then #negated is the right message. #abs is for the case when you don't have any knowledge about the number's sign.
My thoughts were that not everyone reading the code would quickly know that a #negated means "* -1"; they might believe it means, "ensure it's negative, even if it's already negative". That's why I used #abs there.
- #abs ensures it's positive, whereas - #negated creates a dependency on the line above.
You didn't have those concerns while using #negated in #peekBack: to create a non-negative number from a negative number.
Only because there is no equivalent of #abs to force a number negative. #negated is only for toggling. If there were some #ensureNegative as #abs is like "ensurePositive", then I would've used it. I almost want to write "abs" and "abs negated".
I don't feel strongly about it, though. I can switch it to use #negated after we decide what to do with SharedQueue[2], which I do feel could benefit from inheriting from Stream. I wish I could understand why you're against that.
Regards, Chris
squeak-dev@lists.squeakfoundation.org