On 8/9/2012 2:48 AM, Johannes Pfau wrote:
Am Wed, 08 Aug 2012 12:31:29 -0700
schrieb Walter Bright <newshou...@digitalmars.com>:
On 8/8/2012 12:14 PM, Martin Nowak wrote:
That hardly works for event based programming without using
coroutines. It's the classical inversion-of-control dilemma of
event based programming that forces you to save/restore your state
with every event.
See the discussion on using reduce().
I just don't understand it. Let's take the example by Martin Nowak and
port it to reduce: (The code added as comments is the same code for
hashes, working with the current API)
int state; //Hash state;
void onData(void[] data)
{
state = reduce(state, data); //copy(data, state);
//state = copy(data, state); //also valid, but not necessary
//state.put(data); //simple way, doesn't work for ranges
}
void main()
{
state = 0; //state.start();
auto stream = new EventTcpStream("localhost", 80);
stream.onData = &onData;
//auto result = hash.finish();
}
There are only 2 differences:
1:
the order of the arguments passed to copy and reduce is swapped. This
kinda makes sense (if copy is interpreted as copyTo). Solution: Provide
a method copyInto with swapped arguments if consistency is really so
important.
Consistency is important so that disparate components can fit together.
2:
We need an additional call to finish. I can't say it often enough, I
don't see a sane way to avoid it. Hashes work on blocks, if you didn't
pass enough data finish will have to fill the rest of the block with
zeros before you can get the hash value. This operation can't be
undone. To get a valid result with every call to copy, you'd have to
always call finish. This is
* inefficient, you calculate intermediate values you don't need at all
* you have to copy the hashes state, as you can't continue hashing
after finish has been called
and both, the state and the result would have to fit into the one value
(called seed for reduce). But then it's still not 100% consistent, as
reduce will return a single value, not some struct including internal
state.
That isn't a problem, the internal state can be private data for the struct, and
the "finish value" can be the result of overloading operator() on that struct.
I'm not sure if that would work, but it's worth investigating.