March 30, 2013
> No I highly appreciate it, that you are trying to solve the problem. The current state of the language on this is annoying and it needs to be fixed.
>
> I personally would like &A the question is if this is the "D-Way". Maybe we should add a new keyword like "vref" for "value reference".
>
> Kind Regards
> Benjamin Thaut

That's nice to hear. I was afraid I would be too intrusive on this.
And I've finally did it: A& works now. It was a bit tricky, but now it works nicely. Here a quick example:

void bar1(A& a) { } // OK
void bar2(A&* a) { } // Error: '&' can not be used in combination with '*'
void bar3(A*& a) { } // Error: '&' can not be used in combination with '*'
void bar4(const A& a) { } // OK
void bar5(ref A& a) { } // Error: conflicting storage class '&' and ref

and for templates:

void bar(T)(T& t) {
	writeln(t);
}

Thoughts?
March 30, 2013
On Saturday, 30 March 2013 at 13:07:44 UTC, Benjamin Thaut wrote:
> Am 30.03.2013 12:04, schrieb Namespace:
>>> I have to agree on that. My first impression was that ref& is equal to
>>> c++11 &&
>>>
>>> Kind Regards
>>> Benjamin Thaut
>>
>> Ok, it seems that I think differently.
>> And what is the general opinion of '&A' instead of 'ref &A'?
>> It has all the benefits that I described in my first post, but it may
>> not be so confusing.
>> If you like to ask "why not A&": That is more complex as it seems to be,
>> a opinion which is shared by Jonathan.
>> And I sincerely hope that no one is annoyed about my attempts to solve
>> this problem.
>
> No I highly appreciate it, that you are trying to solve the problem. The current state of the language on this is annoying and it needs to be fixed.
>
> I personally would like &A the question is if this is the "D-Way". Maybe we should add a new keyword like "vref" for "value reference".
>
> Kind Regards
> Benjamin Thaut

Although adding new keywords is not smiled upon at this point, it might actually be worth it in this case.
April 01, 2013
On Saturday, 30 March 2013 at 14:37:11 UTC, Namespace wrote:
> That's nice to hear. I was afraid I would be too intrusive on this.
> And I've finally did it: A& works now. It was a bit tricky, but now it works nicely. Here a quick example:
>
> void bar1(A& a) { } // OK
> void bar2(A&* a) { } // Error: '&' can not be used in combination with '*'
> void bar3(A*& a) { } // Error: '&' can not be used in combination with '*'
> void bar4(const A& a) { } // OK
> void bar5(ref A& a) { } // Error: conflicting storage class '&' and ref
>
> and for templates:
>
> void bar(T)(T& t) {
> 	writeln(t);
> }
>
> Thoughts?

It's esoteric, which is bad, but concise, which is good. I think perhaps the annoying aspect of this feature is how attractive it would be to just get the power of the feature implicitly without needing a new attribute or keyword. To get it implicitly, and only have an attribute for when you *don't want an rvalue, e.g.:

void foo(@lvalue ref T a) {}

...would break code, but is nonetheless less something to consider also.

April 01, 2013
On Saturday, 30 March 2013 at 09:17:17 UTC, Namespace wrote:
>> The major downside is that if you don't come from C++ it's hard to understand why 'ref &' means what you propose. The major upsides are, as you mention, it's very concise and perfectly intuitive if you DO come from C++. In the spirit of trying to come up with something for comparison, the best attribute I've thought of so far is '@val':
>>
>> void bar1(@val ref A a) { }
>>
>> The advantage is that it's consistent with my understanding of the general approach to adding things to D at this point. But that's also it's disadvantage: it's nothing more than a mundane attribute.
>
> Yes you're right. But I just think that a property does not make sense here, because we mix then two different things: storage classes and properties. This strikes me as wrong. When I implemented the pseudo-property @ref, I realized this. It seemed inconsistent compared to the rest of the D syntax.
> And since D, syntactically as well as linguistically (D provides direct access to C / C++), is a descendant of C++, I'd prefer to take a kind of hybrid: ref&.

Just a technical point, I believe your use of the term "property" should be replaced with the term "attribute". @ means attribute, of which there are two kinds, built-in and user defined. Built-in attributes themselves are little more than keywords which haven't acquired "tenure", so to speak - the confidence of the language designers that they merit the full status of a no-@ keyword.
April 01, 2013
On Monday, 1 April 2013 at 00:37:07 UTC, Zach the Mystic wrote:
> Just a technical point, I believe your use of the term "property" should be replaced with the term "attribute". @ means attribute, of which there are two kinds, built-in and user defined. Built-in attributes themselves are little more than keywords which haven't acquired "tenure", so to speak - the confidence of the language designers that they merit the full status of a no-@ keyword.

To be even more precise, some built-in attributes, such as 'ref', 'in', and 'out' function parameters, don't even require the @ and are indeed full-fledged keywords too.
April 01, 2013
> It's esoteric, which is bad, but concise, which is good. I think perhaps the annoying aspect of this feature is how attractive it would be to just get the power of the feature implicitly without needing a new attribute or keyword.
Maybe you're right. But I like the idea that, if you want strict lvalues, you use 'ref' and if you don't care, you use the C++ style. I think that would be the best idea.

But currently I have a problem with the implemenation of 'A&'. I do not know how to convey the fact that behind the type is a '&'. IMO the correct D way is to create a new type like TypePointer -> TypeRvRef. But my attempts failed so far to create such type.
Because of that I decided to declare a boolean flag 'isRvRef' inside of the basic Type struct which I set to TRUE if a '&' is behind the type. This works and don't break any code but I think that should be fixed by someone with more knowledge.
But I think also that this rvalue problem has a very low priority.
So if we want to resolve this issue, then we need to do it yourself.
If someone wants to help me, the code and the current solution is on github:
https://github.com/Dgame/dmd/tree/rvalueRef

> To get it implicitly, and only have an attribute for when you *don't want an rvalue, e.g.:
>
> void foo(@lvalue ref T a) {}
>
> ...would break code, but is nonetheless less something to consider also.

Walter hate to break code, so the introduction of that would be even much less likely.

And yes you're right, when I said 'property' I meant an attribute. ;)
April 01, 2013
> But currently I have a problem with the implemenation of 'A&'. I do not know how to convey the fact that behind the type is a '&'. IMO the correct D way is to create a new type like TypePointer -> TypeRvRef. But my attempts failed so far to create such type.
> Because of that I decided to declare a boolean flag 'isRvRef' inside of the basic Type struct which I set to TRUE if a '&' is behind the type. This works and don't break any code but I think that should be fixed by someone with more knowledge.
> But I think also that this rvalue problem has a very low priority.
> So if we want to resolve this issue, then we need to do it yourself.
> If someone wants to help me, the code and the current solution is on github:
> https://github.com/Dgame/dmd/tree/rvalueRef

I could finally fix the problem.
Now for rvalue references an extra type is created: TypeRvRef.
But this solution does not work with templates. I do not yet know how to solve this, but maybe someone knows advice.
Code: https://github.com/Dgame/dmd/tree/rvalueRef2
April 02, 2013
> I could finally fix the problem.
> Now for rvalue references an extra type is created: TypeRvRef.
> But this solution does not work with templates. I do not yet know how to solve this, but maybe someone knows advice.
> Code: https://github.com/Dgame/dmd/tree/rvalueRef2

Since I still have no idea how to solve the template problem (I tried it the last 6 hours - without success) I have one final alternative: final ref. This would be as easy to implement as my first solution, but of course does not look that nice and is much longer than the C++ style.
Any ideas? Opinions?
Suggestions or ideas to solve the template problem are also welcome. :)
April 02, 2013
On Saturday, 30 March 2013 at 12:00:32 UTC, Namespace wrote:
> As far as I studied the code, something like @ref isn't possible, because ref is already a keyword. Except as Pseudo-property. But this is a combination of '@' and 'ref' so that both, '@ref' and '@ ref' would be valid.
> I still like the idea of '&A'.

I have to disagree with me here.
Thanks to this thread (http://forum.dlang.org/thread/ohjdraaizvwiczifwrlk@forum.dlang.org) I know now that after the '@' can be an unlimited number of white spaces.
Hence my previous speculation that I would have implemented something wrong is wrong. So is something like '@ref' possible and already implemented, as you can see here: https://github.com/Dgame/dmd/tree/rvalue_property

I think this is probably the end result of my little journey. Any objections?

Quick example:

[code]
struct A {
public:
	ubyte id;
	
	this(ubyte id) {
		this.id = id;
	}
	
	this(this) {
		writeln("postblit of #", this.id);
	}
}

void foo(@ref A a) {
	writeln(":: id = ", a.id);
}

void foo1(@ref const A a) {
	writeln(":: id = ", a.id);
}

void foo2(@ref shared A a) {
	writeln(":: id = ", a.id);
}

void foo3(@ref immutable A a) {
	writeln(":: id = ", a.id);
}

// void foo4(@ref lazy A a) { /// Error: incompatible parameter storage classes
	// writeln(":: id = ", a.id);
// }

// void foo5(@ref ref A a) { /// Error: redundant storage class ref
	// writeln(":: id = ", a.id);
// }

// void foo6(@ref out A a) { /// Error: incompatible parameter storage classes
	// writeln(":: id = ", a.id);
// }

void bar(@ref int a) {
	writeln(a);
}

void quatz(T)(@ref T t) {
	static if (is(T == struct))
		writeln(t.id);
	else
		writeln(t);
}
[/code]
April 02, 2013
I think 'scope ref' is better.
'in' = 'const scope', then 'in ref' = 'const scope ref'.

bool opEquals(in ref T rhs) const { ... }

Kenji Hara
2013/03/30 21:06 "Namespace" <rswhite4@googlemail.com>:

> As far as I studied the code, something like @ref isn't possible, because
> ref is already a keyword. Except as Pseudo-property. But this is a
> combination of '@' and 'ref' so that both, '@ref' and '@ ref' would be
> valid.
> I still like the idea of '&A'.
>