It is good that you have a coherent idea of how << can work.
The question I was addressing is how << *DOES* work in Pharo.
Having simple things working, if they are kept consistent,
is indeed good.  The problem is that in Pharo 7 they are NOT
consistent, and << does NOT work consistently, because there
are occasions when << does ^something nextPutAll: something else
and nextPutAll: returns something else.

I am grateful for the link to the changes to Pharo 8.
That's a massive simplification and improvement.
There is some way to go yet.

The very first thing that should be done is to write down
what the *semantics* of #<< is supposed to be, and then to
ensure it is implemented that way.

Let's look at the chunk example.

exportTraitDefinitionOf: aClass on: aStream
  "Chunk format."
  aStream
    nextPutAll: 'Trait named: '; nextPutAll: aClass name; cr;
    tab; nextPutAll: 'package: '; print: aClass category; nextPutAll: '!!';
cr.
  aClass comment isEmpty ifFalse: [
    aStream
      nextPutAll: '!!'; print: aClass; nextPutAll: 'commentStamp!!'; cr;
      nextPutAll: aClass category withDelimiter: $!; nextPutAll: '!!'; cr].
  aStream cr.

With the exception of #nextPutAll:withDelimiter:, this is completely
standard and portable.  If I am willing to do something nonstandard,

  aStream format: 'Trait named: {s}{n}{t}package: {p}{n}'
    with: aClass name with: aClass category.
  aClass comment isEmpty ifFalse: [
    aStream format: '!!{p} commentStamp!!{n}{D$!}!!{n}'
      with: aClass with: aClass comment].
  aClass format: '{n}.

#write: really does not seem to be any improvement over #nextPutAll:.

For what it's worth, GNU Smalltalk also has #<<, which it defines
to be equivalent to #displayOn:, if memory serves me correctly.
It has never been clear to me what the use case for #write: is.
In Pharo 7, for streams it is the same as #putOn: except for the
result.  Neither of them is in any interesting way "higher
level" than #nextPut: or #nextPutAll:, merely less informative.

Reply via email to