On Sun, Mar 11, 2012 at 04:54:09PM -0700, Walter Bright wrote:
Consider the toHash() function for struct key types:
http://dlang.org/hash-map.html
And of course the others:
const hash_t toHash();
const bool opEquals(ref const KeyType s);
const int opCmp(ref const KeyType s);
They need to be, as well as const, pure nothrow @safe.
The problem is:
1. a lot of code must be retrofitted
2. it's just plain annoying to annotate them
Ah, I see the "just add a new attribute" thing is coming back to bite
you. ;-)
It's the same problem as for Object.toHash(). That was addressed by
making those attributes inheritable, but that won't work for struct
ones.
So I propose instead a bit of a hack. toHash, opEquals, and opCmp as
struct members be automatically annotated with pure, nothrow, and
@safe (if not already marked as @trusted).
I'm wary of the idea of automatically-imposed attributes on a "special"
set of functions... seems a bit arbitrary, and arbitrary things don't
tend to stand the test of time.
OTOH I can see the value of this. Forcing all toHash's to be pure
nothrow @safe makes is much easier to, for example, implement AA's
purely in object_.d (which I'm trying to do :-P). You don't have to
worry about somebody defining a toHash that does strange things. Same
thing with opEquals, etc.. It also lets you freely annotate stuff that
calls these functions as pure, nothrow, @safe, etc., without having to
dig through every function in druntime and phobos to mark all of them.
Here's an alternative (and perhaps totally insane) idea: what if,
instead of needing to mark functions as pure, nothrow, etc., etc., we
ASSUME all functions are pure, nothrow, and @safe unless they're
explicitly declared otherwise? IOW, let all D code be pure, nothrow, and
@safe by default, and if you want non-pure, or throwing code, or unsafe
code, then you annotate the function as impure, throwing, or @system. It
goes along with D's general philosophy of safe-by-default,
unsafe-if-you-want-to.