www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Feature idea: .userinit property (or trait) to retrieve the

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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?
Jul 17 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Wednesday, 17 July 2013 at 11:28:18 UTC, Andrej Mitrovic wrote:
 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);
 }
 -----
I think this is not a fair comparison. Your S s could be S s = S(2) and you cannot retrieve S(2) just like in case with int value = 5. I see no difference between basic type variables and user-defined variables here. Also, this reminds me replacing typedef by alias with loosing one nice feature - you could do typedef MyInt int = 5; but not with alias.
 One workaround is to factor out the initializer to a manifest
 constant, for example:
Other approach is to use UDA, it may be better then enum, but one still need extra typing. Having new trait seems to be a good idea but it needs to be figured out how it behaves in different contexts.
Jul 17 2013
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 7/17/13, Maxim Fomin <maxim maxim-fomin.ru> wrote:
 I think this is not a fair comparison. Your S s could be S s =
 S(2) and you cannot retrieve S(2) just like in case with int
 value = 5. I see no difference between basic type variables and
 user-defined variables here.
It wasn't meant to be a comparison, but a showcase that we already have /some/ form of retrieving the initializer, but I want to expand this for all variables and not just fields of aggregates.
Jul 17 2013
prev sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Wednesday, 17 July 2013 at 11:28:18 UTC, Andrej Mitrovic wrote:
 Anyway, I think the feature should be fairly easy to implement, 
 but
 would anyone else have a use for this?
At least once I wanted to reset a variable to its default value (which wasn't in a manifest constant). Would it make sense to [ab]use the "default" keyword for this, to avoid introducing a new property which might collide with existing code?
Jul 17 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Jul 18, 2013 at 12:33:20AM +0200, Vladimir Panteleev wrote:
 On Wednesday, 17 July 2013 at 11:28:18 UTC, Andrej Mitrovic wrote:
Anyway, I think the feature should be fairly easy to implement, but
would anyone else have a use for this?
At least once I wanted to reset a variable to its default value (which wasn't in a manifest constant). Would it make sense to [ab]use the "default" keyword for this, to avoid introducing a new property which might collide with existing code?
How would you handle this case: int x = funcWithSideEffects(); x = 123; x = x.default; // what is the value of x now? ? T -- Two wrongs don't make a right; but three rights do make a left...
Jul 17 2013