Thread overview
does alias this work correctly?
Jan 13, 2013
Zhenya
Jan 13, 2013
Maxim Fomin
Jan 13, 2013
Zhenya
Jan 13, 2013
Jonathan M Davis
Jan 14, 2013
Zhenya
Jan 14, 2013
Zhenya
Jan 15, 2013
Jonathan M Davis
Jan 15, 2013
Zhenya
Jan 13, 2013
Andrey
Jan 14, 2013
Zhenya
January 13, 2013
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
}
?
January 13, 2013
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.
January 13, 2013
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.
January 13, 2013
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
January 13, 2013
> 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;
January 14, 2013
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.
January 14, 2013
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.
January 14, 2013
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.
January 15, 2013
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
January 15, 2013
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.