| Thread overview | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
October 10, 2012 std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
And replace them with global reset function:
void reset(T)(ref T digest)
if (isDigest!T)
{
digest = T.init;
}
Current usage:
SHA1 sha1;
sha1.start();
... calculate hash
sha1.start(); // start again
... calculate hash
New usage:
SHA1 sha1;
... calculate hash
sha1.reset(); // start egain
... calculate hash
| ||||
October 10, 2012 Re: std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Piotr Szturmaj | Am Wed, 10 Oct 2012 12:55:59 +0200 schrieb Piotr Szturmaj <bncrbme@jadamspam.pl>: > And replace them with global reset function: > > void reset(T)(ref T digest) > if (isDigest!T) > { > digest = T.init; > } > > Current usage: > > SHA1 sha1; > sha1.start(); > ... calculate hash > sha1.start(); // start again > ... calculate hash > > New usage: > > SHA1 sha1; > ... calculate hash > sha1.reset(); // start egain > ... calculate hash Unlike classes, structs don't mandate a ctor call, so in general you need to disguise the constructor as 'start()' 'Create()' or similar, where T.init is not sufficient. If on the other hand, you use a ".isInitialized = false" field instead of start(), then you'd have to unnecessarily check that every time data is added to the digest, instead of doing it once. (That might be personal taste though :) ) I think the constraints are: * no start() method ever takes arguments * no digest needs to allocate to start * no digest depends on global/static variables -- Marco | |||
October 10, 2012 Re: std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | Marco Leise wrote: > Unlike classes, structs don't mandate a ctor call, so in > general you need to disguise the constructor as 'start()' > 'Create()' or similar, where T.init is not sufficient. I know, but in case of digests their init data is always known at compile time, hence no special "constructor" is needed. > I think the constraints are: > * no start() method ever takes arguments > * no digest needs to allocate to start > * no digest depends on global/static variables Yes, these constraints do not prevent digest structs to be correctly initialized after declaration. | |||
October 10, 2012 Re: std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | Am Wed, 10 Oct 2012 15:02:40 +0200 schrieb Marco Leise <Marco.Leise@gmx.de>: > Am Wed, 10 Oct 2012 12:55:59 +0200 > schrieb Piotr Szturmaj <bncrbme@jadamspam.pl>: > > > And replace them with global reset function: > > > > void reset(T)(ref T digest) > > if (isDigest!T) > > { > > digest = T.init; > > } > > > > Current usage: > > > > SHA1 sha1; > > sha1.start(); > > ... calculate hash > > sha1.start(); // start again > > ... calculate hash > > There's makeDigest which calls start for you, so you can write code like this: auto sha1 = makeDigest!SHA1(); //calculate hash sha1.start(); //start again //calculate hash... But the digests still have to implement a start method, even if it's only a "this = typeof(this).init;". Maybe we could avoid the start method by introducing a fallback UFCS start method... > Unlike classes, structs don't mandate a ctor call, so in > general you need to disguise the constructor as 'start()' > 'Create()' or similar, where T.init is not sufficient. If on > the other hand, you use a ".isInitialized = false" field > instead of start(), then you'd have to unnecessarily check > that every time data is added to the digest, instead of doing > it once. (That might be personal taste though :) ) > > I think the constraints are: > * no start() method ever takes arguments > * no digest needs to allocate to start > * no digest depends on global/static variables > Yes, that's the main reason why we have 'start', but it also must work as a reset function. The difficult question is whether there actually is a hash algorithm (or whether there will be one in the future) which needs such a complex start method. No-allocation often means no C wrapper (although a C API could allow to use stack objects, but often they just provide opaque structs), so this is a little controversial. But if we allowed allocation we'd have to worry about deallocation as well and then things get tricky. Reference counting is probably still the easiest solution for those cases. | |||
October 10, 2012 Re: std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | Am Wed, 10 Oct 2012 16:28:36 +0200 schrieb Johannes Pfau <nospam@example.com>: > There's makeDigest which calls start for you, so you can write code like this: > > auto sha1 = makeDigest!SHA1(); > //calculate hash > sha1.start(); //start again > //calculate hash... Just this point, I think it adds mental bloat. It is still easier to remember and shorter to use: SHA1 sha1; sha1.start(); //calculate hash sha1.start(); //calculate hash... -- Marco | |||
October 10, 2012 Re: std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | On Wed, Oct 10, 2012 at 05:16:38PM +0200, Marco Leise wrote: > Am Wed, 10 Oct 2012 16:28:36 +0200 > schrieb Johannes Pfau <nospam@example.com>: > > > There's makeDigest which calls start for you, so you can write code like this: > > > > auto sha1 = makeDigest!SHA1(); > > //calculate hash > > sha1.start(); //start again > > //calculate hash... > > Just this point, I think it adds mental bloat. It is > still easier to remember and shorter to use: > > SHA1 sha1; > sha1.start(); > //calculate hash > sha1.start(); > //calculate hash... [...] What makes it so difficult that we cannot do this: struct MyHash { bool is_init = false; ... void init() { ... is_init = true; } void computeHash(...) { if (!is_init) init(); // Continue as usual ... } } Then you could just write: SHA1 sha1; // calculate hash sha1 = SHA1.init; // calculate hash ... Fits in better with the language, and no need to remember to call start(), which adds mental load 'cos you have to remember it's called "start" and not something else, and it's also is error-prone 'cos people will forget to do it. T -- Famous last words: I wonder what will happen if I do *this*... | |||
October 10, 2012 Re: std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | H. S. Teoh wrote:
> Then you could just write:
>
> SHA1 sha1;
> // calculate hash
> sha1 = SHA1.init;
> // calculate hash
> ...
>
In my proposal reset() does exactly the same.
| |||
October 10, 2012 Re: std.digest: can we get rid of start() functions? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Piotr Szturmaj | On Wed, Oct 10, 2012 at 06:21:10PM +0200, Piotr Szturmaj wrote: > H. S. Teoh wrote: > >Then you could just write: > > > > SHA1 sha1; > > // calculate hash > > sha1 = SHA1.init; > > // calculate hash > > ... > > > > In my proposal reset() does exactly the same. My point was that there's no need to remember that there's a method called "start" or "reset", etc., when we can just use .init which is common to all types in D. It reduces cognitive load. T -- EMACS = Extremely Massive And Cumbersome System | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply