www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Disappointing inflexibility of argument passing with "alias this"

reply Carl Sturtivant <sturtivant gmail.com> writes:
struct Test { int i; alias i this; }
auto testFunct( Test i){ }

void main() {
     Test t;
     t = 1;
     testFunct( 1);
}


The assignment is fine, but the call is rejected by dmd.

See also
http://forum.dlang.org/post/fqfonkcdcjuwbaacqshe forum.dlang.org
Feb 22 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 22 February 2016 at 17:22:51 UTC, Carl Sturtivant 
wrote:
 struct Test { int i; alias i this; }
 [...]
 The assignment is fine, but the call is rejected by dmd.
Test t = 1; is rejected too because alias this is not a constructor and a function call would be construction. I do think it would be very nice to have explicitly implicit constructors which would cover both these cases (then we can do user-defined types that accept the null literal in function calls too just like built in arrays!), but I don't think it has anything to do with alias this.
Feb 22 2016
parent reply rsw0x <anonymous anonymous.com> writes:
On Monday, 22 February 2016 at 17:29:40 UTC, Adam D. Ruppe wrote:
 On Monday, 22 February 2016 at 17:22:51 UTC, Carl Sturtivant 
 wrote:
 struct Test { int i; alias i this; }
 [...]
 The assignment is fine, but the call is rejected by dmd.
Test t = 1; is rejected too because alias this is not a constructor and a function call would be construction. I do think it would be very nice to have explicitly implicit constructors which would cover both these cases (then we can do user-defined types that accept the null literal in function calls too just like built in arrays!), but I don't think it has anything to do with alias this.
explicitly-implicit constructors are badly needed, I could write an essay on this
Feb 22 2016
parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Mon, Feb 22, 2016 at 06:07:26PM +0000, rsw0x via Digitalmars-d wrote:
 On Monday, 22 February 2016 at 17:29:40 UTC, Adam D. Ruppe wrote:
On Monday, 22 February 2016 at 17:22:51 UTC, Carl Sturtivant wrote:
struct Test { int i; alias i this; }
[...]
The assignment is fine, but the call is rejected by dmd.
Test t = 1; is rejected too because alias this is not a constructor and a function call would be construction. I do think it would be very nice to have explicitly implicit constructors which would cover both these cases (then we can do user-defined types that accept the null literal in function calls too just like built in arrays!), but I don't think it has anything to do with alias this.
explicitly-implicit constructors are badly needed, I could write an essay on this
AFAICT, implicit ctors are not supported by design. T -- Ruby is essentially Perl minus Wall.
Feb 22 2016
next sibling parent reply rsw0x <anonymous anonymous.com> writes:
On Monday, 22 February 2016 at 18:11:58 UTC, H. S. Teoh wrote:
 On Mon, Feb 22, 2016 at 06:07:26PM +0000, rsw0x via 
 Digitalmars-d wrote:
 On Monday, 22 February 2016 at 17:29:40 UTC, Adam D. Ruppe 
 wrote:
[...]
explicitly-implicit constructors are badly needed, I could write an essay on this
AFAICT, implicit ctors are not supported by design. T
It is a bad design.
Feb 22 2016
next sibling parent reply Dicebot <public dicebot.lv> writes:
On 02/22/2016 08:20 PM, rsw0x wrote:
 On Monday, 22 February 2016 at 18:11:58 UTC, H. S. Teoh wrote:
 On Mon, Feb 22, 2016 at 06:07:26PM +0000, rsw0x via Digitalmars-d wrote:
 On Monday, 22 February 2016 at 17:29:40 UTC, Adam D. Ruppe wrote:
[...]
explicitly-implicit constructors are badly needed, I could write an essay on this
AFAICT, implicit ctors are not supported by design. T
It is a bad design.
It is arguable opinion.
Feb 22 2016
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, 22 February 2016 at 18:28:04 UTC, Dicebot wrote:
 On 02/22/2016 08:20 PM, rsw0x wrote:
 On Monday, 22 February 2016 at 18:11:58 UTC, H. S. Teoh wrote:
 On Mon, Feb 22, 2016 at 06:07:26PM +0000, rsw0x via 
 Digitalmars-d wrote:
 On Monday, 22 February 2016 at 17:29:40 UTC, Adam D. Ruppe 
 wrote:
[...]
explicitly-implicit constructors are badly needed, I could write an essay on this
AFAICT, implicit ctors are not supported by design. T
It is a bad design.
It is arguable opinion.
Yeah. Sometimes having implicit conversions is great. Other times, it creates tons of problems. C++ allows a lot of implicit stuff, and it becomes really easy to have unexpected conversions going on, and it can be difficult to figure out exactly what code is being called. For the most part, D doesn't have any of those problems, but it arguably loses some usability as a result. So, it's highly debatable. Personally, I think that the big place that implicit conversions are a disaster is generic code. It makes it really easy to have stuff pass template constraints due to implicit conversions and then have the wrong behavior inside the templated code, because the conversion is never forced, and it doesn't act the same way as it would if the conversion had been forced and possibly even ends up being converted for some of expressions in the function and not converted in others. For non-templated code, it's a lot more debatable, but when it comes to templated code, I really wish that alias this didn't exist. - Jonathan M Davis
Feb 22 2016
parent reply Kagamin <spam here.lot> writes:
On Tuesday, 23 February 2016 at 01:02:21 UTC, Jonathan M Davis 
wrote:
 Yeah. Sometimes having implicit conversions is great. Other 
 times, it creates tons of problems. C++ allows a lot of 
 implicit stuff, and it becomes really easy to have unexpected 
 conversions going on, and it can be difficult to figure out 
 exactly what code is being called. For the most part, D doesn't 
 have any of those problems, but it arguably loses some 
 usability as a result.
Don't we already have implicit conversions with alias this, so what's the deal? struct A { int i; alias i this; } void f(int i){} void f(string s){} void g(A a){ f(a); } //what's called?
Feb 23 2016
parent reply NX <nightmarex1337 hotmail.com> writes:
On Tuesday, 23 February 2016 at 12:43:42 UTC, Kagamin wrote:
 Don't we already have implicit conversions with alias this, so 
 what's the deal?
The deal is you can't have implicit construction like: A a = 5; // Error a = 5 // okay
 struct A { int i; alias i this; }
 void f(int i){}
 void f(string s){}
 void g(A a){ f(a); } //what's called?
f(int) will be called. But problem here is the opposite: try calling g() with an int argument (like 5) and compiler won't let you. import std.stdio; struct A { int i; alias i this;} void f(int i){writeln("int");} void f(A a){writeln("A");} void g(A a){ f(a); } void main() { g(A()); } Above code prints "A". I would expect it to be an ambiguity error. Not sure if I should file a bug report?
Feb 23 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 23 February 2016 at 14:29:27 UTC, NX wrote:
 The deal is you can't have implicit construction like:
 A a = 5; // Error
That is *explicit* construction and it is perfectly legal in D. It is just done with constructors, not alias this. Alias this has absolutely nothing to do with construction, it plays zero role. All alias this does is forward to a member object when you try to use it as a case where the outer type doesn't work but the inner type does. The object must already exist for this to happen, so it can't work on constructors.
 import std.stdio;

 struct A { int i; alias i this;}
 void f(int i){writeln("int");}
 void f(A a){writeln("A");}

 void g(A a){ f(a); }

 void main()
 {
     g(A());
 }

 Above code prints "A". I would expect it to be an ambiguity 
 error. Not sure if I should file a bug report?
There's no ambiguity there and no bug; it is working as defined. alias this is only ever invoked if the outer type doesn't fit. It does fit here, A is A, so no need to check alias this at all.
Feb 23 2016
parent reply NX <nightmarex1337 hotmail.com> writes:
On Tuesday, 23 February 2016 at 14:35:35 UTC, Adam D. Ruppe wrote:
 There's no ambiguity there and no bug; it is working as 
 defined. alias this is only ever invoked if the outer type 
 doesn't fit. It does fit here, A is A, so no need to check 
 alias this at all.
It's arguably the right design. Conservativeness can prevent a lot of stupidity. I don't have a an example at hand though...
Feb 23 2016
parent NX <nightmarex1337 hotmail.com> writes:
On Tuesday, 23 February 2016 at 15:07:08 UTC, NX wrote:
 It's arguably the right design.
When I say arguably I don't mean arguably :D "It's not the right design in my opinion"
Feb 23 2016
prev sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Mon, Feb 22, 2016 at 06:20:09PM +0000, rsw0x via Digitalmars-d wrote:
 On Monday, 22 February 2016 at 18:11:58 UTC, H. S. Teoh wrote:
On Mon, Feb 22, 2016 at 06:07:26PM +0000, rsw0x via Digitalmars-d wrote:
On Monday, 22 February 2016 at 17:29:40 UTC, Adam D. Ruppe wrote:
[...]
explicitly-implicit constructors are badly needed, I could write an essay on this
AFAICT, implicit ctors are not supported by design. T
It is a bad design.
Don't shoot the messenger. Take it up with Walter / Andrei. T -- Never ascribe to malice that which is adequately explained by incompetence. -- Napoleon Bonaparte
Feb 22 2016
prev sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 22 February 2016 at 18:11:58 UTC, H. S. Teoh wrote:
 AFAICT, implicit ctors are not supported by design.
I agree with them that implicitly implicit ctors are a bad design, but explicitly implicit ctors I think are a different issue because then it is clear that the designer intended it and we can ask if it is sane to use or not. Explicitly implicit ctors are like: struct Foo { implicit this(int a) {} } since it has the attribute, the compiler will allow it to be used when calling a function that expects a Foo using an int (unless some other thing matches better). Calling that explicitly is already allowed: Foo a = 1; // works with that now
Feb 22 2016