www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Renaming Flag!"" in API

reply FreeSlave <freeslave93 gmail.com> writes:
Let's say I use Flag type named 'myflagname' in API like this:

import std.typecons;

void func(Flag!"myflagname" flag)
{
//...
}

void main()
{
     func(Yes.myflagname);
}

Later I realize that 'myflagname' is a bad name and I want to 
change it to something else. But if I do so, I break the existing 
code using this API as Flag with different name will be a 
different type and Yes.myflagname and No.myflagname won't fit in. 
I can't use alias as Yes and No relies on string literal.
Can this issue overcome somehow? Looks like a fundamental flaw 
with std.typecons.Flag.
Oct 12 2020
next sibling parent user1234 <user1234 12.de> writes:
On Monday, 12 October 2020 at 10:24:44 UTC, FreeSlave wrote:
 Let's say I use Flag type named 'myflagname' in API like this:

 import std.typecons;

 void func(Flag!"myflagname" flag)
 {
 //...
 }

 void main()
 {
     func(Yes.myflagname);
 }

 Later I realize that 'myflagname' is a bad name and I want to 
 change it to something else. But if I do so, I break the 
 existing code using this API as Flag with different name will 
 be a different type and Yes.myflagname and No.myflagname won't 
 fit in. I can't use alias as Yes and No relies on string 
 literal.
 Can this issue overcome somehow? Looks like a fundamental flaw 
 with std.typecons.Flag.
Once encountered a similar situation. Flag was good but once you know your API, and as in my case I was the only user, I just replaced with a template param + constraint. In the worst case, let's say you forget a bit the API, a DDOC popup can help. example: --- import std.typecons; /* Params: T = anything convertible to bool t = indicates whether do this or do that */ void func(T)(T t) if (is(T : bool)){} void main() { enum yn { yes = true, no = false} // all good, all same semantic func(yn.yes); func(true); func(Yes.myflagname); } ---
Oct 12 2020
prev sibling next sibling parent aliak <something something.com> writes:
On Monday, 12 October 2020 at 10:24:44 UTC, FreeSlave wrote:
 Let's say I use Flag type named 'myflagname' in API like this:

 import std.typecons;

 void func(Flag!"myflagname" flag)
 {
 //...
 }

 void main()
 {
     func(Yes.myflagname);
 }

 Later I realize that 'myflagname' is a bad name and I want to 
 change it to something else. But if I do so, I break the 
 existing code using this API as Flag with different name will 
 be a different type and Yes.myflagname and No.myflagname won't 
 fit in. I can't use alias as Yes and No relies on string 
 literal.
 Can this issue overcome somehow? Looks like a fundamental flaw 
 with std.typecons.Flag.
One of the reason's Flag is there is because of what's known as the boolean trap [0]. If someone changes the name of a parameter, that can potentially mean the semantics have changed. Should Flag work then? And if it should, why not straight up bool? https://wiki.qt.io/API_Design_Principles#The_Boolean_Parameter_Trap
Oct 12 2020
prev sibling next sibling parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Monday, 12 October 2020 at 10:24:44 UTC, FreeSlave wrote:
 Can this issue overcome somehow?
Why not add a deprecated overload for your function which takes the old Flag value?
Oct 12 2020
next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/12/20 7:34 AM, Vladimir Panteleev wrote:
 On Monday, 12 October 2020 at 10:24:44 UTC, FreeSlave wrote:
 Can this issue overcome somehow?
Why not add a deprecated overload for your function which takes the old Flag value?
Or even not deprecated (if it still makes sense). -Steve
Oct 12 2020
prev sibling parent FreeSlave <freeslave93 gmail.com> writes:
On Monday, 12 October 2020 at 11:34:25 UTC, Vladimir Panteleev 
wrote:
 On Monday, 12 October 2020 at 10:24:44 UTC, FreeSlave wrote:
 Can this issue overcome somehow?
Why not add a deprecated overload for your function which takes the old Flag value?
I thought about overloading too. Templatizing the parameter is fitting too especially if the function is already templated. I think I'll go with the latter. Yet in general it would be a tedious work to add template constraints or overloads (and in case of overloads there's also a lot of copy-pasting included) to all functions that use this flag as parameter if there were too many of them. Some way to declare two flag types as implicitly convertable would be nice.
Oct 12 2020
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
It's amazing how things come together before each conference. Flag 
appears among my slides for an upcoming conference as well! :)

But I don't think there is any solution to your problem.

On 10/12/20 3:24 AM, FreeSlave wrote:

 Later I realize that 'myflagname' is a bad name and I want to change it
 to something else. But if I do so, I break the existing code using this
 API as Flag with different name will be a different type
This is essentially the same as one of the objections to named arguments. Ali
Oct 12 2020
parent FreeSlave <freeslave93 gmail.com> writes:
On Monday, 12 October 2020 at 16:44:52 UTC, Ali Çehreli wrote:
 It's amazing how things come together before each conference. 
 Flag appears among my slides for an upcoming conference as 
 well! :)

 But I don't think there is any solution to your problem.

 On 10/12/20 3:24 AM, FreeSlave wrote:

 Later I realize that 'myflagname' is a bad name and I want to
change it
 to something else. But if I do so, I break the existing code
using this
 API as Flag with different name will be a different type
This is essentially the same as one of the objections to named arguments. Ali
Huh, never thought about named arguments in this way. Yet some syntax for parameter name aliasing could be invented to refer to the same parameter by different names if D ever gets named arguments feature.
Oct 12 2020