Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
October 15, 2020 Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
std.typecons.Flag and its friends Yes and No are so trivial that I copy them here (and reformat for my liking): template Flag(string name) { enum Flag : bool { no = false, yes = true } } struct Yes { template opDispatch(string name) { enum opDispatch = Flag!name.yes; } } struct No { template opDispatch(string name) { enum opDispatch = Flag!name.no; } } void main() { auto a = Flag!"foo".no; // Fine auto b = No.foo; // Fine // Error: cannot implicitly convert expression `true` of type `bool` to `Flag`: auto c = Flag!"foo"(true); } I think that is a wrong limitation because clearly I am being "explicit" there with a bool value. (I understand the issue but it exposes a limitation of the implementation.) I have to use the ternary operator e.g. after parsing a bool from program arguments: bool someFlag; // ... foo(someFlag ? Yes.someFlag : No.someFlag); Spoiler alert: I will show the following function template during my DConf Online presentation as a workaround (or "solution"): auto asFlag(alias variable)() { enum name = variable.stringof; enum expr = "return variable ? Yes." ~ name ~ " : No." ~ name ~ ";"; mixin (expr); } That allows the following cleaner and "explicit" syntax: bool someFlag; // ... foo(asFlag!someFlag); (I actually called it flagFromBool in existing code.) However: 1) I think the standard library should already have something like that to remove the need for that ternary operator. 2) (This feels like something that must have been requested already.) While we're on the topic of removing unnecessary limitations, it would be nice to be able to use "not necessarily quoted string template arguments" just like opDispatch empowers us with. void foo(Foo!"myFlag" myFlag) { // <-- Ugly } void foo(Foo!myFlag myFlag) { // <-- Better } Maybe there would be a parsing issue with the syntax but then opDispatch seems to be happy with it. Perhaps we should add opDispatch to templates? (Because I tried but failed to achieve the "better" syntax above with opDispatch inside (a struct inside) a template.) If it requires a special template parameter syntax we can always abuse 'static' further: :o) template Flag(static string name) { // ... } Ali |
October 15, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Thursday, 15 October 2020 at 21:33:32 UTC, Ali Çehreli wrote: > void main() { > auto a = Flag!"foo".no; // Fine > auto b = No.foo; // Fine > > // Error: cannot implicitly convert expression `true` of type `bool` to `Flag`: > auto c = Flag!"foo"(true); > } > > I think that is a wrong limitation because clearly I am being "explicit" there with a bool value. (I understand the issue but it exposes a limitation of the implementation.) I have to use the ternary operator e.g. after parsing a bool from program arguments: > > bool someFlag; > // ... > foo(someFlag ? Yes.someFlag : No.someFlag); An easier way is to use a cast: bool someFlag; // ... foo(cast(Flag!"someFlag") someFlag); std.conv.to also knows how to handle this conversion: foo(someFlag.to!(Flag!"someFlag")); |
October 15, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On 10/15/20 4:25 PM, Paul Backus wrote: > On Thursday, 15 October 2020 at 21:33:32 UTC, Ali Çehreli wrote: >> bool someFlag; >> // ... >> foo(someFlag ? Yes.someFlag : No.someFlag); > > An easier way is to use a cast: > > bool someFlag; > // ... > foo(cast(Flag!"someFlag") someFlag); > > std.conv.to also knows how to handle this conversion: > > foo(someFlag.to!(Flag!"someFlag")); I still like the ternary operator more partly because it uses features that are explained in the documentation. :) Both of your methods rely on the fact that the implementation is a bool-based enum. Are the users expected to know that? If yes, then the library can't change the implementation. Ali |
October 15, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 10/15/2020 2:33 PM, Ali Çehreli wrote:
> [...]
Named parameters takes care of this.
|
October 16, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Friday, 16 October 2020 at 06:50:49 UTC, Walter Bright wrote:
> On 10/15/2020 2:33 PM, Ali Çehreli wrote:
>> [...]
>
> Named parameters takes care of this.
Has anyone started to work on an implementation?
|
October 16, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 10/15/20 11:50 PM, Walter Bright wrote:
> On 10/15/2020 2:33 PM, Ali Çehreli wrote:
>> [...]
>
> Named parameters takes care of this.
Maybe for some people, yes. (Assuming calling with named parameters is optional.) But I would still be uncomfortable defining a function with naked bools like this:
void foo(bool shouldDoThis, bool shouldDoThat) {
// ...
}
The possibility of calling it wrong is still there. Is that purely the caller's fault? What do others think?
Ali
|
October 17, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 17/10/2020 4:20 AM, Ali Çehreli wrote:
> The possibility of calling it wrong is still there. Is that purely the caller's fault? What do others think?
I have never been convinced of the arguments against using bool for flags in params.
But I do think that having named parameters rather than named arguments would have removed this as an issue. The name should be required.
|
October 16, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Friday, 16 October 2020 at 15:46:54 UTC, rikki cattermole wrote:
> On 17/10/2020 4:20 AM, Ali Çehreli wrote:
>> The possibility of calling it wrong is still there. Is that purely the caller's fault? What do others think?
>
> I have never been convinced of the arguments against using bool for flags in params.
>
> But I do think that having named parameters rather than named arguments would have removed this as an issue. The name should be required.
It's always possible to add named parameters *in addition* to named arguments. The two are not mutually incompatible.
|
October 16, 2020 Re: Cannot implicitly convert expression `true` of type `bool` to `Flag` | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 10/16/2020 2:44 AM, Andrej Mitrovic wrote:
> On Friday, 16 October 2020 at 06:50:49 UTC, Walter Bright wrote:
>> On 10/15/2020 2:33 PM, Ali Çehreli wrote:
>>> [...]
>>
>> Named parameters takes care of this.
>
> Has anyone started to work on an implementation?
Not myself, anyway. I'm currently buried.
|
Copyright © 1999-2021 by the D Language Foundation