Thread overview
Renaming Flag!"" in API
Oct 12, 2020
FreeSlave
Oct 12, 2020
user1234
Oct 12, 2020
aliak
Oct 12, 2020
Vladimir Panteleev
Oct 12, 2020
FreeSlave
Oct 12, 2020
Ali Çehreli
Oct 12, 2020
FreeSlave
October 12, 2020
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.
October 12, 2020
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);
}
---
October 12, 2020
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
October 12, 2020
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?
October 12, 2020
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
October 12, 2020
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.
October 12, 2020
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

October 12, 2020
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.