finish function for output ranges
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Sat Aug 11 16:29:53 PDT 2012
N.B. I haven't yet reviewed the proposal.
There's been a lot of discussion about the behavior of hash
accumulators, and I've just have a chat with Walter about such.
There are two angles in the discussion:
1. One is, the hash accumulator should work as an operand in an
accumulation expression. Then the reduce() algorithm can be used as follows:
HashAccumulator ha;
reduce!((a, b) => a + b)(ha, [1, 2, 3]);
writeln(ha.finish());
This assumes the hash overloads operator +.
2. The other is, the hash accumulator is an output range - a sink! -
that supports put() for a lot of stuff. Then the code would go:
HashAccumulator ha;
copy([1, 2, 3], ha);
writeln(ha.finish());
I think (2) is a much more fertile view than (1) because the notion of
"reduce" emphasizes the accumulation operation (such as "+"), and that
is a forced notion for hashes (we're not really adding stuff there). In
contrast, the notion that the hash accumulator is a sink is very
natural: you just dump a lot of stuff into the accumulator, and then you
call finish and you get its digest.
So, where does this leave us?
I think we should reify the notion of finish() as an optional method for
output ranges. We define in std.range a free finish(r) function that
does nothing if r does not define a finish() method, and invokes the
method if r does define it.
Then people can call r.finish() for all output ranges no problem.
For files, finish() should close the file (or at least flush it -
unclear on that). I also wonder whether there exists a better name than
finish(), and how to handle cases in which e.g. you finish() an output
range and then you put more stuff into it, or you finish() a range
several times, etc.
Destroy!
Andrei
More information about the Digitalmars-d
mailing list