www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why doesn't std.variant.visit automatically call the provided

reply Nemanja Boric <4burgos gmail.com> writes:
```
import std.variant;
import std.stdio;
import std.exception;

void main()
{
     Algebraic!(int, string) variant;

     variant = 10;
     int x = 0;
     // Functions throws - uncomment and see
     //    variant.tryVisit!( (string s) => enforce(false),
     //                       (int i)    => enforce(false))();

     // This - does nothing
     variant.visit!(    (string s) => { enforce(false); x = 2; },
                        (int i)    => { enforce(false); x = 3; 
})();
     writeln("x = ", x);

     // This works as expected
     variant.visit!(    (string s) => { x = 2; }(),
                        (int i) =>    { x = 3; }())();

     writeln("x = ", x);
}
```
Nov 05 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 5 November 2016 at 08:27:49 UTC, Nemanja Boric wrote:
     // This - does nothing
     variant.visit!(    (string s) => { enforce(false); x = 2; },
It calls the function... which returns a delegate, which you never called. This is one of the most common mistakes people are making: {} in D is a delegate, and () => is a delegate, therefore () => {} is a delegate that returns a delegate... usually NOT what you want. What you wrote is equivalent to writing delegate() callback(string s) { return delegate() { enforce(false); x = 2; }; } Do not use the => syntax if there is more than one expression. You'll get what you want by simply leaving the => out:
     // This works as expected
     variant.visit!(    (string s) { x = 2; },
                        (int i)    { x = 3; });
Nov 05 2016
next sibling parent Nemanja Boric <4burgos gmail.com> writes:
On Saturday, 5 November 2016 at 10:09:55 UTC, Adam D. Ruppe wrote:
 On Saturday, 5 November 2016 at 08:27:49 UTC, Nemanja Boric 
 wrote:
 [...]
It calls the function... which returns a delegate, which you never called. This is one of the most common mistakes people are making: {} in D is a delegate, and () => is a delegate, therefore () => {} is a delegate that returns a delegate... usually NOT what you want. What you wrote is equivalent to writing delegate() callback(string s) { return delegate() { enforce(false); x = 2; }; } Do not use the => syntax if there is more than one expression. You'll get what you want by simply leaving the => out:
                        [...]
Oh, God. Thanks, Adam, all clear! Thanks!
Nov 05 2016
prev sibling parent reply Kapps <opantm2+spam gmail.com> writes:
On Saturday, 5 November 2016 at 10:09:55 UTC, Adam D. Ruppe wrote:
 On Saturday, 5 November 2016 at 08:27:49 UTC, Nemanja Boric 
 wrote:
     // This - does nothing
     variant.visit!(    (string s) => { enforce(false); x = 2; 
 },
It calls the function... which returns a delegate, which you never called. This is one of the most common mistakes people are making: {} in D is a delegate, and () => is a delegate, therefore () => {} is a delegate that returns a delegate... usually NOT what you want. What you wrote is equivalent to writing delegate() callback(string s) { return delegate() { enforce(false); x = 2; }; } Do not use the => syntax if there is more than one expression. You'll get what you want by simply leaving the => out:
     // This works as expected
     variant.visit!(    (string s) { x = 2; },
                        (int i)    { x = 3; });
That's really confusing. I've used D for quite a while, and didn't know that. Admittedly I doubt I've ever tried () => { }, from(?), that behaviour is very unexpected. That feels like it should be a compiler warning.
Nov 05 2016
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Saturday, 5 November 2016 at 20:15:14 UTC, Kapps wrote:
 That feels like it should be a compiler warning.
I'm now of the opinion that the {} delegates should be deprecated (instead use () {} delegates)... this comes up a lot and there's a few other places too where it is a pain... and it isn't that worth keeping imo.
Nov 05 2016
next sibling parent ixid <nuaccount gmail.com> writes:
On Saturday, 5 November 2016 at 20:22:13 UTC, Adam D. Ruppe wrote:
 On Saturday, 5 November 2016 at 20:15:14 UTC, Kapps wrote:
 That feels like it should be a compiler warning.
I'm now of the opinion that the {} delegates should be deprecated (instead use () {} delegates)... this comes up a lot and there's a few other places too where it is a pain... and it isn't that worth keeping imo.
Have you discussed this with Andrei or Walter? It would be a good change.
Nov 05 2016
prev sibling next sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 11/05/2016 04:22 PM, Adam D. Ruppe wrote:
 On Saturday, 5 November 2016 at 20:15:14 UTC, Kapps wrote:
 That feels like it should be a compiler warning.
I'm now of the opinion that the {} delegates should be deprecated (instead use () {} delegates)... this comes up a lot and there's a few other places too where it is a pain... and it isn't that worth keeping imo.
I didn't even know you could create a delegate with just {} and no parens. Kinda confusing since, normally, {} by itself creates a scope, not a delegate.
Nov 08 2016
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/8/16 11:31 AM, Nick Sabalausky wrote:
 On 11/05/2016 04:22 PM, Adam D. Ruppe wrote:
 On Saturday, 5 November 2016 at 20:15:14 UTC, Kapps wrote:
 That feels like it should be a compiler warning.
I'm now of the opinion that the {} delegates should be deprecated (instead use () {} delegates)... this comes up a lot and there's a few other places too where it is a pain... and it isn't that worth keeping imo.
I didn't even know you could create a delegate with just {} and no parens. Kinda confusing since, normally, {} by itself creates a scope, not a delegate.
Indeed: {int x = foo; return x;} // scope auto dg = {int x = foo; return x;} // delegate The requirements seem to be that you have to use the {} syntax as an expression instead of a block. omitting the initial parentheses seems like a really low benefit to having such confusing ambiguity. And of course, it leads to the horrible examples shown by OP. -Steve
Nov 08 2016
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/5/16 4:22 PM, Adam D. Ruppe wrote:
 On Saturday, 5 November 2016 at 20:15:14 UTC, Kapps wrote:
 That feels like it should be a compiler warning.
I'm now of the opinion that the {} delegates should be deprecated (instead use () {} delegates)... this comes up a lot and there's a few other places too where it is a pain... and it isn't that worth keeping imo.
I created an enhancement request, as I didn't see any in the issue tracker already. https://issues.dlang.org/show_bug.cgi?id=16672 -Steve
Nov 08 2016
prev sibling next sibling parent reply Chris Wright <dhasenan gmail.com> writes:
On Sat, 05 Nov 2016 20:15:14 +0000, Kapps wrote:
 Admittedly I doubt I've ever tried () => { }, but given languages

Otherwise it would likely have followed suit.
Nov 05 2016
parent Jesse Phillips <jesse.k.phillips+D gmail.com> writes:
On Sunday, 6 November 2016 at 00:19:57 UTC, Chris Wright wrote:
 On Sat, 05 Nov 2016 20:15:14 +0000, Kapps wrote:
 Admittedly I doubt I've ever tried () => { }, but given 
 languages

delegates. Otherwise it would likely have followed suit.
than 2 years ago.
Nov 06 2016
prev sibling parent Nemanja Boric <4burgos gmail.com> writes:
On Saturday, 5 November 2016 at 20:15:14 UTC, Kapps wrote:
 That's really confusing. I've used D for quite a while, and 
 didn't know that. Admittedly I doubt I've ever tried () => { }, 

 taken from(?), that behaviour is very unexpected. That feels 
 like it should be a compiler warning.
I was just going to say that after a weekend my mind on this is that this behavior is no different than C's: if (x = 5) { } issue. It deserves at least warning (if you make a delegate that returns delegate that can't be called).
Nov 07 2016