Sven Van Caekenberghe wrote on 3. 7. 2018 11:36:
On 3 Jul 2018, at 11:28, Herbert Vojčík <he...@mailbox.sk> wrote:
Herbert Vojčík wrote on 3. 7. 2018 11:21:
Sven Van Caekenberghe wrote on 3. 7. 2018 10:55:
On 3 Jul 2018, at 10:08, Herbert Vojčík <he...@mailbox.sk> wrote:
Sven Van Caekenberghe wrote on 2. 7. 2018 16:00:
On 25 Jun 2018, at 12:56, Herbert Vojčík <he...@mailbox.sk> wrote:
Peter Uhnák wrote on 23. 6. 2018 15:39:
Hi,
I'm starting to familiarize myself with new streams, and one thing I've noticed
is the removal of #lineEndConvention (which I use all the time).
So a statement like this
aFile writeStreamDo: [ :stream |
stream lineEndConvention: #lf.
stream << '...'> ].
has to be written like so
aFile writeStreamDo: [ :rawStream | |stream|
stream := (ZnNewLineWriterStream on: rawStream) forLf.
stream << '...'
].
which feels very messy because I am mixing writing with the configuration. And
I don't even take account for buffered/encoded decorators. Plus it increases
the incidental complexity -- I need another variable, and I can accidentally
write to the wrong stream, etc.
Would a method like #writeStream:do: (or #writeStreamTransform:do:) make sense?
E.g.
aFile writeStreamTransform: [ :stream | (ZnNewLineWriterStream on: stream) ]
do: [ :stream |
stream << '...'
]
aFile writeStreamDo: [ :rawStream |
(ZnNewLineWriterStream on: rawStream) in: [ :stream |
stream << '...' ] ].
As for transformation, I'd go for some more generic (functional?) approach like:
aFile writeStreamDo: ([:x | ZnNewLineWriterStream on: x] pipe: [ :stream |
stream << '...' ]).
I like the first version with the (little known, but still standard and clear)
#in: selector.
I can't see how the second is 'better', as it looks equally 'complex' but adds
a new selector, #pipe:
All this, IMHO.
It's a bit more focused on the task, that being transform incoming argument. Cf.
#asString pipe: [ :aString | ... ]
instead of:
[ :anObject | anObject asString in: [ :aString | ... ] ]
IOW, scope of anObject is limited (and if using #selector you don't even need
to come up with a name, like the rawStream in examples before).
OK, maybe, what is your definition for #pipe: then ?
Basically something like this:
(BlockClosure | Symbol) >> pipe: aBlock
^ [ :arg | aBlock value: (self value: arg) ]
Now that I think of, it is basically nothing more than function composition, so
it could have binary selector instead. That would save parentheses, so the
example would look like:
aFile writeStreamDo:
[ :x | ZnNewLineWriterStream on: x ] ++
[ :stream | stream << '...' ].
Interesting ;-)
Why not even #, then ? (It is used to compose Exceptions into an ExceptionSet
too, why not blocks into blocks).
Doesn't fit in my PoV. The spirit of #, is to produce some
collection-like thing. The function composition is not a collection,
it's not a BlockSet, it's a single block, welded together from parts,
but those are not important any more.
IMNSHO.
An 'issue' that I see is that your #pipe: definition only works for single
argument blocks, something that is probably unavoidable. IIRC this can be done
in CommonLisp, but I am not 100% sure.
Most probably this idea of functional composition has been discussed before ...
Herby
To separate the composition from the usage?
Thanks,
Peter