Jump to page: 1 2
Thread overview
using this instead of typeof(this)
Feb 26, 2013
Ivan Kazmenko
Feb 26, 2013
bearophile
Feb 26, 2013
monarch_dodra
Feb 26, 2013
Maxim Fomin
Feb 26, 2013
Ivan Kazmenko
Feb 26, 2013
Maxim Fomin
Feb 26, 2013
Kenji Hara
Feb 26, 2013
monarch_dodra
Feb 26, 2013
bearophile
Feb 26, 2013
Ben Davis
Feb 26, 2013
bearophile
Feb 26, 2013
Maxim Fomin
Feb 26, 2013
Ivan Kazmenko
February 26, 2013
Hi!

I have recently experimented with ways to express the exact instantiated type of a generic struct, and found that I can in some cases use "this" as that type.

Here is a sample program (DMD 2.062) demonstrating various uses of "this" as a type:

-----
import std.stdio;

struct S
{
	int x = 1;
	int y = 0;

	void f ()
	{
		y = 1;
	}

	this (this) // postblit constructor
	{
		x = 10;
	}

	this (ref this) // not a postblit constructor
	{
		x = 100;
	}

	this (ref this, this f, typeof (this), this, ref this g)
	{
		x = 1000 + _param_0.x + f.x + _param_2.x + _param_3.x + g.x;
	}
}

void main ()
{
	S a;
	a.f ();
	S b = a;
	S c = S (a);
	S d = S (a, a, a, a, a);
	writefln ("%s %s", a.x, a.y); // 1 1
	writefln ("%s %s", b.x, b.y); // 10 1 (copied b.y = a.y)
	writefln ("%s %s", c.x, c.y); // 100 0 (did not copy)
	writefln ("%s %s", d.x, d.y); // 1032 0 (refs add 1, non-refs add 10)
}
-----

And so I wonder:

(1) Should I refrain from using this as a type, is it a bug?

(2) A matter of style: what is the idiomatic way to take the exact type of a templated struct? For example, which method signature to return a typeof(this) value is "better" in which way if all have the same effect:
-----
struct S (A, B, C)
{
...
	auto method () {...}
	S method () {...}
	S !(theA, theB, theC) method () {...}
	typeof (this) method () {...}
}
-----
Note that S, theA, theB and theC can get lengthy.

(3) Is the usage of unnamed parameters and _param_### a language feature or an implementation-specific detail I should not ever use?

-----
Ivan Kazmenko.
February 26, 2013
Ivan Kazmenko:

> (1) Should I refrain from using this as a type, is it a bug?

Using typeof(this) is OK, and makes code more DRY.


> (2) A matter of style: what is the idiomatic way to take the exact type of a templated struct? For example, which method signature to return a typeof(this) value is "better" in which way if all have the same effect:
> -----
> struct S (A, B, C)
> {
> ...
> 	auto method () {...}
> 	S method () {...}
> 	S !(theA, theB, theC) method () {...}
> 	typeof (this) method () {...}
> }

I think there is no common idiom here. Generally being DRY is good. typeof(this) is more explicit than auto, so I prefer that.

Bye,
bearophile
February 26, 2013
On Tuesday, 26 February 2013 at 16:28:59 UTC, Ivan Kazmenko wrote:
> Hi!
>
> I have recently experimented with ways to express the exact instantiated type of a generic struct, and found that I can in some cases use "this" as that type.
>
> -----
> 	this (ref this) // not a postblit constructor
> 	this (ref this, this f, typeof (this), this, ref this g)
> -----
> Ivan Kazmenko.

There was a discussion about this recently (wasn't it with you?) and I believe the conclusion basically boiled down to "bug: accepts-wrong".

Neither of those two signatures should compile. The fact that they do is a bug.

If they do compile, it's undefined behavior. From there, you can't rely on anything.

I think there was a bugzilla entry for it, but I'll have to look for it.
February 26, 2013
On Tuesday, 26 February 2013 at 16:57:50 UTC, monarch_dodra wrote:
> On Tuesday, 26 February 2013 at 16:28:59 UTC, Ivan Kazmenko wrote:
>> Hi!
>>
>> I have recently experimented with ways to express the exact instantiated type of a generic struct, and found that I can in some cases use "this" as that type.
>>
>> -----
>> 	this (ref this) // not a postblit constructor
>> 	this (ref this, this f, typeof (this), this, ref this g)
>> -----
>> Ivan Kazmenko.
>
> There was a discussion about this recently (wasn't it with you?) and I believe the conclusion basically boiled down to "bug: accepts-wrong".

That would be significant change in the language, where it is?

> Neither of those two signatures should compile. The fact that they do is a bug.
>
> If they do compile, it's undefined behavior. From there, you can't rely on anything.

Certainly this is not undefined behavior because those rely on 2 language rules.

> I think there was a bugzilla entry for it, but I'll have to look for it.

February 26, 2013
>> -----
>> 	this (ref this) // not a postblit constructor
>> 	this (ref this, this f, typeof (this), this, ref this g)
>> -----
>
> There was a discussion about this recently (wasn't it with you?) and I believe the conclusion basically boiled down to "bug: accepts-wrong".

Yeah, and the curiosity on "how does one call that this(ref this) constructor?" was what triggered me to try it further here.  But that thread resulted in another issue in Bugzilla (#9513), the "this(ref this)" case was just barely touched.  The thread: http://forum.dlang.org/thread/qhlsrpqajuwstvlspimf@forum.dlang.org?page=2#post-op.wsh3o4nqeav7ka:40stevens-macbook-pro.local

> Neither of those two signatures should compile. The fact that they do is a bug.
>
> If they do compile, it's undefined behavior. From there, you can't rely on anything.
>
> I think there was a bugzilla entry for it, but I'll have to look for it.

After a quick search, I didn't find anything related to this(ref this) in Bugzilla.  Should I create an issue now?
February 26, 2013
On Tuesday, 26 February 2013 at 16:28:59 UTC, Ivan Kazmenko wrote:
> Hi!
>
> I have recently experimented with ways to express the exact instantiated type of a generic struct, and found that I can in some cases use "this" as that type.
>

1) D allows omitting parameter names in function definitions which are replaced by implicitly created _param_XXX.

2) This as a type in parameter list replaces type of this.

What you observe is consequence of combination of this rules. The most unintuitive is that applying attribute to postblit declaration makes it a regular constructor which takes argument of that struct type.

>
> And so I wonder:
>
> (1) Should I refrain from using this as a type, is it a bug?

Better to avoid such usage.

> (2) A matter of style: what is the idiomatic way to take the exact type of a templated struct? For example, which method signature to return a typeof(this) value is "better" in which way if all have the same effect:
> -----
> struct S (A, B, C)
> {
> ...
> 	auto method () {...}
> 	S method () {...}
> 	S !(theA, theB, theC) method () {...}
> 	typeof (this) method () {...}
> }
> -----
> Note that S, theA, theB and theC can get lengthy.

You can use template this parameter in templates and avoid in non-templates.

> (3) Is the usage of unnamed parameters and _param_### a language feature or an implementation-specific detail I should not ever use?
>
> -----
> Ivan Kazmenko.

It is implementation-specific detail.
February 26, 2013
On Tuesday, 26 February 2013 at 16:28:59 UTC, Ivan Kazmenko wrote:
> Hi!
>
> I have recently experimented with ways to express the exact instantiated type of a generic struct, and found that I can in some cases use "this" as that type.
>
> Here is a sample program (DMD 2.062) demonstrating various uses of "this" as a type:
>
> -----
> import std.stdio;
>
> struct S
> {
> 	int x = 1;
> 	int y = 0;
>
> 	void f ()
> 	{
> 		y = 1;
> 	}
>
> 	this (this) // postblit constructor
> 	{
> 		x = 10;
> 	}
>
> 	this (ref this) // not a postblit constructor
> 	{
> 		x = 100;
> 	}
>
> 	this (ref this, this f, typeof (this), this, ref this g)
> 	{
> 		x = 1000 + _param_0.x + f.x + _param_2.x + _param_3.x + g.x;
> 	}
> }
>
> void main ()
> {
> 	S a;
> 	a.f ();
> 	S b = a;
> 	S c = S (a);
> 	S d = S (a, a, a, a, a);
> 	writefln ("%s %s", a.x, a.y); // 1 1
> 	writefln ("%s %s", b.x, b.y); // 10 1 (copied b.y = a.y)
> 	writefln ("%s %s", c.x, c.y); // 100 0 (did not copy)
> 	writefln ("%s %s", d.x, d.y); // 1032 0 (refs add 1, non-refs add 10)
> }
> -----
>
> And so I wonder:
>
> (1) Should I refrain from using this as a type, is it a bug?

It is definitely a bug. I cannot believe that such horrible bug is still there.
If you have a time, could you please file it in bugzilla?

http://d.puremagic.com/issues/

> (2) A matter of style: what is the idiomatic way to take the exact type of a templated struct? For example, which method signature to return a typeof(this) value is "better" in which way if all have the same effect:
> -----
> struct S (A, B, C)
> {
> ...
> 	auto method () {...}
> 	S method () {...}
> 	S !(theA, theB, theC) method () {...}
> 	typeof (this) method () {...}
> }
> -----
> Note that S, theA, theB and theC can get lengthy.

Returning S, S!(...), and typeof(this) are identical. You can use them as you favorite.
auto return is a little different with others. To infer return type, the method body is aggressively analyzed in compilation. If the method has mutual call with another auto return function, it will cause 'forward reference error'.

> (3) Is the usage of unnamed parameters and _param_### a language feature or an implementation-specific detail I should not ever use?

It is implementation specific. You must not rely on that.

Kenji Hara
February 26, 2013
On Tuesday, 26 February 2013 at 18:22:03 UTC, Kenji Hara wrote:
> Returning S, S!(...), and typeof(this) are identical...
> Kenji Hara

Just note that if the function is const or immutable, then "typeof(this)" will be "immutable S!(...)", where as if you use an actual "S!(...)" as your return value, you'll get a mutable return.

This can make a difference depending on if or if not you can strip constness by copy, for functions such as:

R!T save() const;
vs
typeof(this) save() const;

Just wanted to note it. It's a subtle difference that's often forgotten.
February 26, 2013
Kenji Hara:

> auto return is a little different with others. To infer return type, the method body is aggressively analyzed in compilation.

So that usage of "auto" sounds like something to avoid if you want D compiler to compile quickly a lot of code.

Bye,
bearophile
February 26, 2013
On Tuesday, 26 February 2013 at 18:22:03 UTC, Kenji Hara wrote:
> It is definitely a bug. I cannot believe that such horrible bug is still there.
> If you have a time, could you please file it in bugzilla?
>
> http://d.puremagic.com/issues/
> Kenji Hara

I can't believe you are not aware of that. By the way, I posted similar case to bugzilla and received WONTFIX, but I don't remember the #.




« First   ‹ Prev
1 2