Explicit this for methods

vit vit at vit.vit
Tue Jul 23 11:07:54 UTC 2024


Explicit `this` allow manipulating of `this` type without 
interacting with function attributes and without need to create 
template function or string mixin-s.

Syntax:
- explicit `this` must be first parameter of non-static method
- name is not identifier but keyword `this`.
- explicit `this` doesn't support all parameter attributes like 
`ref`, `out`, `in` and `lazy`, but attributes like `scope` and 
`return` can be supported.

Why?:
- Type qualifiers can be in position of function attributes when 
`this` type qualifier need to be specified. Conditional 
manipulation of function attributes at compile time is very hard 
but manipulating types is much easer.
- `this template parameter` can by replaced with explicit `this` 
+ normal template parameter.
- easer distinction between qualifiers/attributes for `this` and 
other function attributes like `pure` `nothrow` `@nogc` `ref`

examples:


```d
class C{


	//this 3 methods are same:
	abstract void test1();			//method with implicit this
	abstract void test1(this);		//method with explicit this with 
qualifier (mutable)
	abstract void test1(C this);	//method with explicit this with 
type (is(Unqual!T == C))
	
	//this 3 methods are same:
	abstract void test2()const pure;		//method with implicit const 
this
	abstract void test2(const this)pure;	//method with explicit this 
with qualifier
	abstract void test2(const C this)pure;	//method with explicit 
this with type (is(Unqual!T == C))
	
	//this 3 methods are same:
	void test3(this This)()const pure{}		//template method with 
implicit this with this template parameter
	void test3(this This)(const this)pure{}	//template method with 
this   template parameter and explicit this with qualifier
	void test3(This)(const This this)pure{}	//template method with 
normal template parameter and explicit this with type 
(is(Unqual!T : C))
	

	const{	//can not be conditionaly specified at compile time
		abstract void foo();
		abstract void foo(int i);
		abstract void foo(string str);
	}
	
	alias FooThis = const(C);	//can be conditionaly specified at 
compile time
	abstract void foo2(FooThis this);
	abstract void foo2(FooThis this, int i);
	abstract void foo2(FooThis this, string str);
}

struct S{

	//this 2 methods are same:
	ref S test2() @safe scope return pure{return this;}
	ref S test2(scope return this)@safe {return this;}
	//ref S test2(ref return this)@safe {return this;}

}

```
One problem is postblit constructor:
```d

class C{

	//this 3 ctors are same:
	this();				//constructor with implicit this
	this(this);			//AMBIGUOUS: conflict with postblit
	this(C this);		//constructor with explicit this with type 
(is(Unqual!T == C))
	
	//this 3 ctors are same:
	this()const;		//constructor with implicit const this
	this(const this);	//AMBIGUOUS: conflict with postblit
	this(const C this);	//constructor with explicit this with type 
(is(Unqual!T == C))
}

```
Explicit `this` is optional, non-static method without explicit 
`this` has still implicit `this`.

Explicit `this` can have other parameter attributes like:
- `scope`
- `return scope`
- `scope return`

In the future explicit `this` can allow making lvalue `this`:
```d
struct S{
	void test1(ref this)pure;	//callable only on lvalue?
}
```

What you think about this idea?



More information about the dip.ideas mailing list