www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - does alias this work correctly?

reply "Zhenya" <zheny list.ru> writes:
Hi!
Is it all right with it:
struct Foo
{
	struct Bar
	{
		void opCall()
		{
			writeln("non-static");
		}
	}
	Bar bar;
	static struct Anotherbar
	{
		static void bar()
		{
			writeln("static");
		}
	}
	alias Anotherbar this;
}

void main()
{
	Foo f;
	f.bar();
	Foo.bar();//fils with message:type Bar is not an expression
         Foo.Bar b;
         b();//this works however
}
?
Jan 13 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Sunday, 13 January 2013 at 19:16:36 UTC, Zhenya wrote:
 Hi!
 Is it all right with it:
 struct Foo
 {
 	struct Bar
 	{
 		void opCall()
 		{
 			writeln("non-static");
 		}
 	}
 	Bar bar;
 	static struct Anotherbar
 	{
 		static void bar()
 		{
 			writeln("static");
 		}
 	}
 	alias Anotherbar this;
 }

 void main()
 {
 	Foo f;
 	f.bar();
 	Foo.bar();//fils with message:type Bar is not an expression
         Foo.Bar b;
         b();//this works however
 }
 ?
According to spec http://dlang.org/class.html#AliasThis undefined lookups are forwarded to AliasThis member. But in your case Foo struct has bar member, so no further resolution is performed. Rename the member and the code compiles. Note, this seems to come from neighbor thread http://forum.dlang.org/thread/uelmpwwckcveimpbdtdo forum.dlang.org. I think it is simpler to rename functions than create bunch of structs just to be able to have eponymous non-static and static functions.
Jan 13 2013
parent reply "Zhenya" <zheny list.ru> writes:
On Sunday, 13 January 2013 at 19:35:08 UTC, Maxim Fomin wrote:
 On Sunday, 13 January 2013 at 19:16:36 UTC, Zhenya wrote:
 Hi!
 Is it all right with it:
 struct Foo
 {
 	struct Bar
 	{
 		void opCall()
 		{
 			writeln("non-static");
 		}
 	}
 	Bar bar;
 	static struct Anotherbar
 	{
 		static void bar()
 		{
 			writeln("static");
 		}
 	}
 	alias Anotherbar this;
 }

 void main()
 {
 	Foo f;
 	f.bar();
 	Foo.bar();//fils with message:type Bar is not an expression
        Foo.Bar b;
        b();//this works however
 }
 ?
According to spec http://dlang.org/class.html#AliasThis undefined lookups are forwarded to AliasThis member. But in your case Foo struct has bar member, so no further resolution is performed. Rename the member and the code compiles. Note, this seems to come from neighbor thread http://forum.dlang.org/thread/uelmpwwckcveimpbdtdo forum.dlang.org. I think it is simpler to rename functions than create bunch of structs just to be able to have eponymous non-static and static functions.
I just want very much avoid renaming function,it's principle for me. So I would like to know is my sample right or no.
Jan 13 2013
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, January 13, 2013 20:41:48 Zhenya wrote:
 On Sunday, 13 January 2013 at 19:35:08 UTC, Maxim Fomin wrote:
 According to spec http://dlang.org/class.html#AliasThis
 undefined lookups are forwarded to AliasThis member. But in
 your case Foo struct has bar member, so no further resolution
 is performed. Rename the member and the code compiles.
 
 Note, this seems to come from neighbor thread
 http://forum.dlang.org/thread/uelmpwwckcveimpbdtdo forum.dlang.org.
 I think it is simpler to rename functions than create bunch of
 structs just to be able to have eponymous non-static and static
 functions.
I just want very much avoid renaming function,it's principle for me. So I would like to know is my sample right or no.
It functions exactly like it's supposed to. As Maxim said, undefined lookups go to the alias this member. If Foo already has a bar and you try and call it, it doesn't matter what Foo is aliased to, it's Foo's bar that's going to be used. - Jonathan M Davis
Jan 13 2013
next sibling parent "Zhenya" <zheny list.ru> writes:
On Sunday, 13 January 2013 at 22:36:03 UTC, Jonathan M Davis 
wrote:
 On Sunday, January 13, 2013 20:41:48 Zhenya wrote:
 On Sunday, 13 January 2013 at 19:35:08 UTC, Maxim Fomin wrote:
 According to spec http://dlang.org/class.html#AliasThis
 undefined lookups are forwarded to AliasThis member. But in
 your case Foo struct has bar member, so no further resolution
 is performed. Rename the member and the code compiles.
 
 Note, this seems to come from neighbor thread
 http://forum.dlang.org/thread/uelmpwwckcveimpbdtdo forum.dlang.org.
 I think it is simpler to rename functions than create bunch 
 of
 structs just to be able to have eponymous non-static and 
 static
 functions.
I just want very much avoid renaming function,it's principle for me. So I would like to know is my sample right or no.
It functions exactly like it's supposed to. As Maxim said, undefined lookups go to the alias this member. If Foo already has a bar and you try and call it, it doesn't matter what Foo is aliased to, it's Foo's bar that's going to be used. - Jonathan M Davis
Now it's clear for me,thank you.
Jan 14 2013
prev sibling parent reply "Zhenya" <zheny list.ru> writes:
On Sunday, 13 January 2013 at 22:36:03 UTC, Jonathan M Davis 
wrote:
 On Sunday, January 13, 2013 20:41:48 Zhenya wrote:
 On Sunday, 13 January 2013 at 19:35:08 UTC, Maxim Fomin wrote:
 According to spec http://dlang.org/class.html#AliasThis
 undefined lookups are forwarded to AliasThis member. But in
 your case Foo struct has bar member, so no further resolution
 is performed. Rename the member and the code compiles.
 
 Note, this seems to come from neighbor thread
 http://forum.dlang.org/thread/uelmpwwckcveimpbdtdo forum.dlang.org.
 I think it is simpler to rename functions than create bunch 
 of
 structs just to be able to have eponymous non-static and 
 static
 functions.
I just want very much avoid renaming function,it's principle for me. So I would like to know is my sample right or no.
It functions exactly like it's supposed to. As Maxim said, undefined lookups go to the alias this member. If Foo already has a bar and you try and call it, it doesn't matter what Foo is aliased to, it's Foo's bar that's going to be used. - Jonathan M Davis
import std.stdio; struct Bar { void opDispatch(string op)() if(op == "bar") { if(this !is m_init) writeln("non-static"); else writeln("maybe static"); } static property Bar m_init() { return Bar.init; } alias m_init this; } void main() { Bar b; Bar.bar(); readln; } If I understood you correctly, it must be compiled since there isn't some 'bar' that is going to be used, right? But it doesn't compile.
Jan 14 2013
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, January 14, 2013 17:57:03 Zhenya wrote:
 import std.stdio;
 
 struct Bar
 {
 	void opDispatch(string op)()
 		if(op == "bar")
 		{
 			if(this !is m_init)
 				writeln("non-static");
 			else
 				writeln("maybe static");
 		}
 	static  property Bar m_init()
 	{
 		return Bar.init;
 	}
 	alias m_init this;
 }
 
 void main()
 {
 	Bar b;
 	Bar.bar();
 	readln;
 }
 
 If I understood you correctly, it must be compiled since there
 isn't some 'bar' that is going to be used, right?
 But it doesn't compile.
I honestly have no idea how opDispatch and alias this are supposed to interact. They're both used as fallbacks when the type doesn't directly define a function. That being said The reason that your code doesn't work here is the fact that you'r ecalling bar is if it were a static function, but your opDispatch isn't static. opDispatch would have to be static for it to be used as a static function (it can't be both static and non-static), and in that case, the if condition that you have in it wouldn't compile. - Jonathan M Davis
Jan 14 2013
parent "Zhenya" <zheny list.ru> writes:
On Tuesday, 15 January 2013 at 00:04:15 UTC, Jonathan M Davis 
wrote:
 On Monday, January 14, 2013 17:57:03 Zhenya wrote:
 import std.stdio;
 
 struct Bar
 {
 	void opDispatch(string op)()
 		if(op == "bar")
 		{
 			if(this !is m_init)
 				writeln("non-static");
 			else
 				writeln("maybe static");
 		}
 	static  property Bar m_init()
 	{
 		return Bar.init;
 	}
 	alias m_init this;
 }
 
 void main()
 {
 	Bar b;
 	Bar.bar();
 	readln;
 }
 
 If I understood you correctly, it must be compiled since there
 isn't some 'bar' that is going to be used, right?
 But it doesn't compile.
I honestly have no idea how opDispatch and alias this are supposed to interact. They're both used as fallbacks when the type doesn't directly define a function. That being said The reason that your code doesn't work here is the fact that you'r ecalling bar is if it were a static function, but your opDispatch isn't static. opDispatch would have to be static for it to be used as a static function (it can't be both static and non-static), and in that case, the if condition that you have in it wouldn't compile. - Jonathan M Davis
:( If compiler tried alias this before opDispatch all would be OK. Maybe I'm going to give up. Thank you for comprehensive explanation.
Jan 14 2013
prev sibling parent reply "Andrey" <andr-sar yandex.ru> writes:
 I just want very much avoid renaming function,it's principle 
 for me.
 So I would like to know is my sample right or no.
I think that the main overall principle here is that is it impossible to have two functions which differ only by static attribute. I even do not imagine the use case of this. Well, here is the most natural way to achieve similar effect, I suppose: struct MyStruct { struct Static { static void myfun() { writeln("static myfun"); } } void myfun() { writeln("myfun"); } static Static opCall() { return Static(); } } MyStruct obj; obj.myfun(); //dynamic; MyStruct().myfun(); //static;
Jan 13 2013
parent "Zhenya" <zheny list.ru> writes:
On Sunday, 13 January 2013 at 23:21:20 UTC, Andrey wrote:
 I just want very much avoid renaming function,it's principle 
 for me.
 So I would like to know is my sample right or no.
I think that the main overall principle here is that is it impossible to have two functions which differ only by static attribute. I even do not imagine the use case of this. Well, here is the most natural way to achieve similar effect, I suppose: struct MyStruct { struct Static { static void myfun() { writeln("static myfun"); } } void myfun() { writeln("myfun"); } static Static opCall() { return Static(); } } MyStruct obj; obj.myfun(); //dynamic; MyStruct().myfun(); //static;
I do not agree with you, static attribute is not a small detail. this reference is the same argument, like all the others. And despite the fact that function signatures are the same, the actual list of arguments are different.
Jan 14 2013