August 08, 2012
On 8/8/2012 9:47 AM, Johannes Pfau wrote:
> Am Wed, 8 Aug 2012 17:50:33 +0200
> schrieb Johannes Pfau <nospam@example.com>:
>
>> However, I do agree digest!Hash, md5Of, sha1Of should have an
>> additional overload which takes a InputRange. It would be implemented
>> with copy and be a nice convenience function.
>
> I implemented the function, it's actually quite simple:
> ----
> digestType!Hash digestRange(Hash, Range)(Range data) if(isDigest!Hash &&
>      isInputRange!Range && __traits(compiles,
>      digest!Hash(ElementType!(Range).init)))
> {
>      Hash hash;
>      hash.start();
>      copy(data, hash);
>      return hash.finish();
> }
> ----

The finish() should be implicit when the range ends.

>
> but I don't know how make it an overload. See thread "overloading a
> function taking a void[][]" in D.learn for details.
>

I don't know what you mean, it takes a range, not a void[][] as input.


August 08, 2012
Am Wed, 08 Aug 2012 14:36:32 -0400
schrieb "Jonathan M Davis" <jmdavisProg@gmx.com>:

> What's wrong with the *endianToNative and nativeTo*Endian functions? They work just fine as far as I know. swapEndian works too if you want it to use that, but there should be nothing wrong with the endian-specific ones.
> 
> - Jonathan M Davis

in CTFE?
http://dpaste.dzfl.pl/0503b8af

According to Don reinterpret casts (even if done through unions) won't be supported in CTFE. So you can't convert from uint-->ubyte[4]
August 08, 2012
Am Wed, 08 Aug 2012 11:47:38 -0700
schrieb Walter Bright <newshound2@digitalmars.com>:

> On 8/8/2012 9:47 AM, Johannes Pfau wrote:
> > Am Wed, 8 Aug 2012 17:50:33 +0200
> > schrieb Johannes Pfau <nospam@example.com>:
> >
> >> However, I do agree digest!Hash, md5Of, sha1Of should have an additional overload which takes a InputRange. It would be implemented with copy and be a nice convenience function.
> >
> > I implemented the function, it's actually quite simple:
> > ----
> > digestType!Hash digestRange(Hash, Range)(Range data)
> > if(isDigest!Hash && isInputRange!Range && __traits(compiles,
> >      digest!Hash(ElementType!(Range).init)))
> > {
> >      Hash hash;
> >      hash.start();
> >      copy(data, hash);
> >      return hash.finish();
> > }
> > ----
> 
> The finish() should be implicit when the range ends.
> 
> >
> > but I don't know how make it an overload. See thread "overloading a function taking a void[][]" in D.learn for details.
> >
> 
> I don't know what you mean, it takes a range, not a void[][] as input.
> 
> 

So the post in D.learn for a detailed description. Yes the code I posted takes a range, but digest (as it is now) takes void[][] to accept all kind of types _without_ template bloat. The difficulty is to combine those two overloads without causing unnecessary template bloat.
August 08, 2012
Am Wed, 08 Aug 2012 11:40:10 -0700
schrieb Walter Bright <newshound2@digitalmars.com>:

> 
> Take a look at the reduce function in http://dlang.org/phobos/std_algorithm.html#reduce
> 
> It has provision for an initial state that can be the current running total.
> 

This can only work if the final state is valid as an initial state. This is just not true for some hash algorithms.

---
auto sum = reduce!("a + b")(0, range);
auto sum2 = reduce!("a + b")(sum, range2);
---

---
MD5 hash;
hash.start();

auto sum = copy(range, hash);
auto sum2 = copy(range2, sum);

auto result = hash.finish();
---

No where's the difference, except that for hashes the context ('hash') has to be setup and finished manually?
August 08, 2012
--------
Hash hash;

void onData(void[] data)
{
    hash.put(data);
}

void main()
{
    hash.start();
    auto stream = new EventTcpStream("localhost", 80);
    stream.onData = &onData;
    hash.finish();
}
--------

> Have the callback supply a range interface to call the hash with.

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.
August 08, 2012
On 8/8/2012 12:08 PM, Johannes Pfau wrote:
> No where's the difference, except that for hashes the context ('hash')
> has to be setup and finished manually?


The idea is to have hash act like a component - not with special added code the user has to write.

In this case, it needs to work like a reduce algorithm, because it is a reduce algorithm. Need to find a way to make this work.

August 08, 2012
On 8/8/2012 12:05 PM, Johannes Pfau wrote:
> So the post in D.learn for a detailed description. Yes the code I
> posted takes a range, but digest (as it is now) takes void[][] to
> accept all kind of types _without_ template bloat. The difficulty is to
> combine those two overloads without causing unnecessary template bloat.

Have the templated version with overloads simply call the single version (with a different name) with void[][].


August 08, 2012
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().

August 08, 2012
On Wednesday, August 08, 2012 18:47:34 Johannes Pfau wrote:
> Am Wed, 8 Aug 2012 14:16:40 +0000 (UTC)
> 
> schrieb travert@phare.normalesup.org (Christophe Travert):
> > If it where me, I would have the presently reviewed module std.hash.hash be called std.hash.digest, and leave room here for regular hash functions. In any case, I think regular hash HAVE to be in a std.hash module or package, because people looking for a regular hash function will look here first.
> 
> std.hash.digest doesn't sound too bad. We could have std.hash.func (or a better named module ;-) for general hash functions later.

I say just keep at simple and leave it at std.hash. It's plenty clear IMHO.

- Jonathan M Davis
August 08, 2012
On Wednesday, August 08, 2012 20:55:19 Johannes Pfau wrote:
> Am Wed, 08 Aug 2012 14:36:32 -0400
> 
> schrieb "Jonathan M Davis" <jmdavisProg@gmx.com>:
> > What's wrong with the *endianToNative and nativeTo*Endian functions? They work just fine as far as I know. swapEndian works too if you want it to use that, but there should be nothing wrong with the endian-specific ones.
> > 
> > - Jonathan M Davis
> 
> in CTFE?
> http://dpaste.dzfl.pl/0503b8af
> 
> According to Don reinterpret casts (even if done through unions) won't be supported in CTFE. So you can't convert from uint-->ubyte[4]

No. It wouldn't work in CTFE, because it uses a union. But what it's trying to doesn't really make sense in CTFE in most cases anyway, because the endianness of the target machine may not be the same endianness as the machine doing the compilation. Any computations which cared about endianness must be in a state where they don't care about endianness anymore once CTFE has completed, or you're going to have bugs.

Though if the issue is std.hash being CTFEable, I don't know why anyone would even care. It's cool if it's CTFEable, but the sorts of things that you hash pretty much always require user or file input of some kind (which you can't do with CTFE). You'd have to have a use case where something within the program itself needed to be hashed for some reason for it to matter whether std.hash was CTFEable or not, and it wouldn't surprise me at all if it were typical in hash functions to do stuff that isn't CTFEable anyway.

- Jonathan M Davis