July 25, 2018
On Wednesday, 25 July 2018 at 16:43:38 UTC, Paolo Invernizzi wrote:

> That's an opinion, naturally.

No I am expressing an argument not an opinion.

> "let's force the programmer to think about what he is doing, passing an rvalue by ref"
Nonsense, you have shown no evidence that they don't know what they are doing when making a automatic conversion. You might as well argue against the existence of var.

> At best, is "let's catch early some bugs (caused by other problems as Manu pointed out)".

He also pointed it is own class of problems, as it can be replicated without ref.

> Set of problems as automatic promotion or conversion, as decades of problems with unsigned/signed have proved...

False Equivalence. We are not discussing numeric overflows here.

> There's not a magic conversion between apples and oranges in a foreach loop... ref value apart.

https://dlang.org/spec/type.html#usual-arithmetic-conversions
You where saying?


-Alexander


July 25, 2018
On Wed, 25 Jul 2018 at 04:50, Jim Balter via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Wednesday, 25 July 2018 at 08:34:30 UTC, Manu wrote: [snip]
>
> > Meanwhile I think we have determined that the presumed
> > practical trouble
> > cases are even less that I suspected up front.
>
> That's surprising; I didn't realize that you suspected practical trouble cases.

My initial draft was written for 'ref const T ', and that was a conservative choice because I felt the same unsubstantiated fear. I think it's like this; there is a presumption that the feature was made that way for a reason... so it *must* be protecting us against something that it was designed to protect us against, right?

Others argued to remove the 'const' from my proposal, and then the more I thought on that, and followed various experiments through, I realised that my fears were unsubstantiated (I couldn't dream up legitimate problem cases), and that mutable ref brought significant additional value which actually strengthen the DIP substantially.

I still suspect it's possible to contrive a case where a bug may be caught by the existing mechanic, but what we have determined by following some of these cases presented here is that they're far less likely than even I initially _imagined_ (yes, still working from the same unsubstantiated fear), or that the bugs are actually unrelated issues which should be addressed separately.


For instance, I can imagine a DIP to address the property concern that we have identified here:

** Mutable-but-also-byval properties (ie, a property with a by-val
getter and also a setter) do not behave like a user expects when
supplied as ref arguments.
** Situation: a by-val getter passes an rval to a ref arg, which may
be mutated, and the results are lost.
** Propose: after the function call concludes, call the properties
setter, supplying the potentially mutated rval that the getter
returned.

This very simple semantic will cause non-ref properties to function
correctly even in the context of by-val getting and ref.
I actually think this is a very elegant solution to a wider class of
problem with properties.

...but this comment is dangerous. I REALLY don't want this point to
lead off on a tangent ;)
*considers deleting post... but clicks send anyway...*
July 25, 2018
On Wed, 25 Jul 2018 at 10:45, Atila Neves via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> > ...all that said, we understand that there is value in inhibiting calls with rvalues in some cases. We address this in a very nice way with @disable, which is also nicely symmetrical such that the limitation may by applied to rval or lval's.
>
> I like using @disable this way. It's unclear to me the impact on existing code that doesn't already have a @disable since it wasn't needed before.
>
> I'm not against the DIP - I think easier interop with C++ is a good thing and this would help it. I have to think a bit more about the points Jonathan has brought up, because it sounds like there's a possibility that bugs might be introduced if the DIP goes through, at least as-is. I'm not sure.

FWIW; I presented a further solution for the property case, which I
think is a good improvement for properties in general (it will address
other constructions of this same issue that aren't in conjunction with
ref).
It addresses the issue Jonathan raised in the domain where the problem
exists, and leaves unrelated problems outside of this DIP's problem
space.
July 25, 2018
On Wed, 25 Jul 2018 at 10:45, Atila Neves via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Saturday, 21 July 2018 at 08:59:39 UTC, Manu wrote:
> > [...]
> > 3. Scenario depends on introduction of a getter, but any getter
> > property that returns a member by-val is almost certainly a
> > primitive
> > type. A getter for a struct member would necessarily return a
> > ref, or
> > it would experience large copy semantics every time the get is
> > called!
>
> This is assuming anything that isn't a primitive is a large struct that is copied, which, in my experience, is rarely the case.

But my point is, that exact reasoning extends to the hypothetical ref
argument as the return value.
If a property function sees fit to return by-value (ie, struct is
small), then a function receiving that object will also receive the
argument by-value.

This will be the usual pattern. When a type becomes large enough to
want to pass it by ref, any property that returns one will also most
likely return by ref.
I'm trying to say that, a mismatch is naturally unlikely to occur. And
very unlikely occur *by accident*; it would be a design intent.

> I don't recall ever implementing a getter in D that returns by ref. I'd consider that a code smell in pretty much every language, allowing mutation from the outside.

Such a getter would likely return const ref, but discussions about proper use of 'const' are not on topic here.

> For context, I
> think that getters are a faint code smell and that setters always
> stink.

So, you're reducing the power of the properties argument in principle?

> All of this to say that I disagree that getters will usually return by ref unless the return type is a primitive. That's not how I write code and I don't remember encountering this in the wild.

Agreed. My above amendment should be a more accurate tendency, which is what I was trying to express, but in too-few words.

> > (`ref` is not the bug)
> >   - note, in all other constructions of this same 'bug',
> > existing
> > language semantics find it acceptable to silently accept the
> > accidental mutation of an expiring rvalue. Nobody is losing
> > sleep at
> > night.
>
> That's because T().mutate() is obviously not going to do
> anything. Nobody would expect it to.

Of course `T().mutate()` is obvious, but `s.member.mutate()` (where
member is property) might be misunderstood to do something. I don't
see how the exact set of arguments being applied to ref don't apply
here (and many other possible cases).

> > The same 'bug' expressed in a simpler and more likely way:
> >
> > // a struct that shall be the member
> > struct M {
> >   int x;
> >   void mutate() { ++x; }
> > }
> >
> > // the original (working) code
> > struct S {
> >   M member;
> > }
> > S s;
> > s.member.mutate();
>
> It'd take roughly 5s between me seeing this in code review and typing the words "Law of Demeter violation". To me that's TRWTF.

I don't understand what you're saying here?
I think this case is equally hard to spot as the
passing-property-as-ref-arg case.

Either way, the solution to this whole branch of discussion lies with property, not with ref (and I've given some ideas).
July 25, 2018
On Wednesday, 25 July 2018 at 17:52:00 UTC, 12345swordy wrote:
> On Wednesday, 25 July 2018 at 16:43:38 UTC, Paolo Invernizzi wrote:
>
>> That's an opinion, naturally.
>
> No I am expressing an argument not an opinion.

I don't know what vocabulary you are used to consult, but your 'pointless' it's a plain and simple opinion. To me it's not pointless at all.

>> "let's force the programmer to think about what he is doing, passing an rvalue by ref"

> Nonsense, you have shown no evidence that they don't know what they are doing when making a automatic conversion. You might as well argue against the existence of var.

Actually, by definition, every bug is made by a programmer that THINK to know what he is doing... no? Aren't you. going a little too far in  judging?

>> At best, is "let's catch early some bugs (caused by other problems as Manu pointed out)".
>
> He also pointed it is own class of problems, as it can be replicated without ref.

An so? Jonathan argumentation and mine is that are are. losing a way to catch such bugs earlier.

>> Set of problems as automatic promotion or conversion, as decades of problems with unsigned/signed have proved...
>
> False Equivalence. We are not discussing numeric overflows here.

It's not a false equivalence fallacy: all the discussion is about IMPLICIT conversion or rvalues to lvalues... your argumentation smell a little about strawmen (eheh)

>> There's not a magic conversion between apples and oranges in a foreach loop... ref value apart.
>
> https://dlang.org/spec/type.html#usual-arithmetic-conversions
> You where saying?

I'm saying that a foreach statement is easily lowered mentally in a for statement, and that implicitly converting between rvalue and lvalue is entirely another beast.

I will stop here... btw
July 25, 2018
On Wednesday, 25 July 2018 at 19:55:50 UTC, Paolo Invernizzi wrote:

> I don't know what vocabulary you are used to consult,
ad hominem attacks is not an argument

> Actually, by definition, every bug is made by a programmer that THINK to know what he is doing... no?

Avoiding burden of proof by shifting goal post.
> Aren't you. going a little too far in  judging?
loaded question

> An so?
He has explain the point in detail, go back and read his post.

> It's not a false equivalence fallacy: all the discussion is about IMPLICIT conversion or rvalues to lvalues.
Yes it is, the issues regarding rvalue/lvalue conversion is not the same issues regarding the unsigned/signed conversion.

Alexander
July 25, 2018
On Wed, 25 Jul 2018 at 13:55, 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> > It's not a false equivalence fallacy: all the discussion is about IMPLICIT conversion or rvalues to lvalues.
> Yes it is, the issues regarding rvalue/lvalue conversion is not the same issues regarding the unsigned/signed conversion.

I don't want to encourage this tangent, but I do want to say; there's
no proposal of rvalue -> lvalue *conversion*.
The proposal is "ref accepts rvalues". There's no 'conversion'
anywhere in sight. That's not on the menu.
July 25, 2018
On Wednesday, 25 July 2018 at 21:55:00 UTC, Manu wrote:
> On Wed, 25 Jul 2018 at 13:55, 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> > It's not a false equivalence fallacy: all the discussion is about IMPLICIT conversion or rvalues to lvalues.
>> Yes it is, the issues regarding rvalue/lvalue conversion is not the same issues regarding the unsigned/signed conversion.
>
> I don't want to encourage this tangent, but I do want to say; there's
> no proposal of rvalue -> lvalue *conversion*.
> The proposal is "ref accepts rvalues". There's no 'conversion'
> anywhere in sight. That's not on the menu.

Semantics? Call it a transformation. But it is an implicit changing of semantics.

Guess you encouraged it :p
July 26, 2018
On Wednesday, 25 July 2018 at 18:37:55 UTC, Manu wrote:
> On Wed, 25 Jul 2018 at 10:45, Atila Neves via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> On Saturday, 21 July 2018 at 08:59:39 UTC, Manu wrote:

> But my point is, that exact reasoning extends to the hypothetical ref
> argument as the return value.
> If a property function sees fit to return by-value (ie, struct is
> small), then a function receiving that object will also receive the
> argument by-value.

That's a good point. I mean, with code not under one's control it could happen otherwise, but most likely not.

> This will be the usual pattern. When a type becomes large enough to
> want to pass it by ref, any property that returns one will also most
> likely return by ref.

Yep.

>> For context, I
>> think that getters are a faint code smell and that setters always
>> stink.
>
> So, you're reducing the power of the properties argument in principle?

Yes, as long as it's code I write or review.


>> > S s;
>> > s.member.mutate();
>>
>> It'd take roughly 5s between me seeing this in code review and typing the words "Law of Demeter violation". To me that's TRWTF.
>
> I don't understand what you're saying here?
> I think this case is equally hard to spot as the
> passing-property-as-ref-arg case.

That unless it's a UFCS chain there shouldn't be more than one dot. One should attempt to not call functions on returned members. It should be `s.mutate()` where `member` is aliased this or has `mutate` manually forwarded.

That is: don't "reach in" to objects, it's bad design anyway and the bug doesn't exist if you don't.



November 08, 2018
On Wednesday, 25 July 2018 at 21:55:00 UTC, Manu wrote:
> On Wed, 25 Jul 2018 at 13:55, 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> > It's not a false equivalence fallacy: all the discussion is about IMPLICIT conversion or rvalues to lvalues.
>> Yes it is, the issues regarding rvalue/lvalue conversion is not the same issues regarding the unsigned/signed conversion.
>
> I don't want to encourage this tangent, but I do want to say; there's
> no proposal of rvalue -> lvalue *conversion*.
> The proposal is "ref accepts rvalues". There's no 'conversion'
> anywhere in sight. That's not on the menu.

I know this is kinda out of the blue, but I really like to use "in" and "out" to clarify my function interfaces.  "out" seems to imply "ref", but it also initializes the value to its .init value.

Personally I don't get much mileage out of "out" assigning the ".init" value.  The same keyword though could be used to satisfy both major use cases.

Maybe "ref" could accept rvalues as per the DIP, but "out ref" would not, allowing error checking for those who truly intend the argument to be used to store output (and this comes up a lot when a method needs to return multiple results).