On 10. 9. 2019 15:20, Sven Van Caekenberghe wrote:
Development happens in Pharo 8 first, with possible back ports if really 
necessary.

The last relevant change was the following:

https://github.com/pharo-project/pharo/pull/2698

That's a very nice change, indeed. Thank you.

But there's still one catch. I looked, and in Pharo 8 branch, this is still the active implementation:

WriteStream >> << anObject [
        "Write anObject to the receiver, dispatching using #putOn:
This is a shortcut for both nextPut: and nextPutAll: since anObject can be both
        the element type of the receiver as well as a collection of those 
elements.
        No further conversions of anObject are applied.
        This is an optimisation.
        Return self to accomodate chaining."

        anObject class == collection class
                ifTrue: [ self nextPutAll: anObject ]
                ifFalse: [ anObject putOn: self ]
]

It is wrong to shortcut putOn: double dispatch based on anObject class == collection class. I strongly believe this test should pass:

testPutDiverseNestedSequences

  | array otherSequenceable higherOrderArray higherOrderSequenceable |

  array := Array with: 1 with: 2 with: 3.
  otherSequenceable := OrderedCollection with: 1 with: 2 with: 3.
  higherOrderArray := Array with: array with: otherSequenceable.
higherOrderSequenceable := OrderedCollection with: array with: otherSequenceable.

  result := Array streamContents: [ :s | s
    << array << otherSequenceable
    << higherOrderArray << higherOrderSequenceable ].

  self assert: result equals: #(
    1 2 3 1 2 3
    1 2 3 1 2 3
    1 2 3 1 2 3 )

If I guess correctly, based on mere implemetation detail of which class holds the 1 2 3, some of them are not unnested.

I understand how that optimization is needed in case a string is put on character stream, double dispatching every character is insane. But so is shortcutting Array is Array-based stream.

Maybe the optimization should have additional anObject isString test (in case of string, the counterexample cannot be created, because they cannot be nested). Or there should be additional double dispatch via nextPutString:, if string-based streams have their hierarchy. You know the codebase better.

Unless it is already solved by some other twist.

Thanks, Herby

Reply via email to