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