Feature idea: .userinit property (or trait) to retrieve the initializer of a variable

Andrej Mitrovic andrej.mitrovich at gmail.com
Wed Jul 17 04:28:02 PDT 2013


I often need to re-initialize a variable back to its user-defined
initializer. For variables that have no user-defined initializer, you
can simply use .init. For fields of structs or classes you can
actually use A.init.field, where A is the aggregate type. For example:

-----
struct S
{
    int value = 5;
}

void main()
{
    S s;
    s.value += 1;
    s.value = S.init.value;
    assert(s.value == 5);  // ok
}
-----

But there's no equivalent for variables which do not belong to any aggregate:

-----
void main()
{
    int value = 5;
    value += 1;
    // value = ??
    assert(value == 5);
}
-----

One workaround is to factor out the initializer to a manifest
constant, for example:

-----
void main()
{
    enum valueInit = 5;
    int value = valueInit;
    value += 1;
    value = valueInit;
    assert(value == 5);
}
-----

It's a workable solution, but I think we can do better. I'd like us to
introduce either a .userinit property, or a compiler trait. For
example:

-----
template userinit(alias symbol)
{
    enum userinit = __traits(getSymbolInitializer, symbol);
}

void main()
{
    int value = 5;
    value += 1;
    value = userinit!value;
    assert(value == 5);
}
-----

The trait version is less intrusive to the language than a .userinit
property, although the latter would avoid having to instantiate a
template:

-----
void main()
{
    int value = 5;
    value += 1;
    value = value.userinit;
    assert(value == 5);
}
-----

Anyway, I think the feature should be fairly easy to implement, but
would anyone else have a use for this?


More information about the Digitalmars-d mailing list