January 30
On Wednesday, 30 January 2019 at 13:58:38 UTC, 12345swordy wrote:
> I do not accept gut feeling as a valid objection here. The current workarounds is shown to be painful as shown in the dip and in the discussions that it currently link. That *the* motivation here.

Like I said previously I am on the reviews side and that's it.

By the way I don't like your tone when you say: "I do not accept gut feeling as a valid objection here".

I don't think you would like if I say that your opinion is biased because you know the author either, so don't go that way, because it's not only me against this DIP.

> I am familiar with the author here, he is very involved with the C++<->D compatibility side of things. He knows the pain from first hand experience.

Alright we're talking about a change that have been on hold for almost 10 years, if it was simple it would already been done.

In this thread we saw some other concerns been emerged.

Finally I only know the author by his postings in this forum, and I don't have anything personally against him.

Donald.
January 30
On Tue., 29 Jan. 2019, 10:25 pm Walter Bright via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com wrote:

> On 1/29/2019 3:45 AM, Andrei Alexandrescu wrote:
> > I am talking about this:
> >
> > int[] a = cast(int[]) alloc.allocate(100 * int.sizeof);
> > if (alloc.reallocate(a, 200 * int.sizeof)
> > {
> >      assert(a.length == 200);
> > }
>
> Even simpler:
>
>    void func(ref void* p) {
>      free(p);                     // frees (1)
>      p = malloc(100);              // (2)
>    }
>
>    int* p = cast(int*)malloc(16);  // (1)
>    func(p);                        // p copied to temp for conversion to
> void*
>    free(p);                        // frees (1) again
>                                    // (2) is left dangling
>
> It's a memory corruption issue, with no way to detect it.
>

Why are you so stuck on this case? The DIP is about accepting rvalues, not
lvalues...
Calling with 'p', an lvalue, is not subject to this DIP.

>


January 30
On Wed, 30 Jan 2019 09:15:36 -0800, Manu wrote:
> Why are you so stuck on this case? The DIP is about accepting rvalues,
> not lvalues...
> Calling with 'p', an lvalue, is not subject to this DIP.

The result of a CastExpression is an rvalue. An implicit cast is a compiler-inserted CastExpression. Therefore all lvalues with a potential implicit cast are rvalues.
January 30
On Wed, Jan 30, 2019 at 9:20 AM Neia Neutuladh via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
>
> On Wed, 30 Jan 2019 09:15:36 -0800, Manu wrote:
> > Why are you so stuck on this case? The DIP is about accepting rvalues,
> > not lvalues...
> > Calling with 'p', an lvalue, is not subject to this DIP.
>
> The result of a CastExpression is an rvalue. An implicit cast is a compiler-inserted CastExpression. Therefore all lvalues with a potential implicit cast are rvalues.

But there's no existing language rule that attempts to perform an
implicit cast where an lvalue is supplied to a ref arg...?
Why is the cast being attempted? 'p' is an lvalue, and whatever that
does should remain exactly as is (ie, emits a compile error).

We could perhaps allow this for `const` args, but that feels like separate follow-up work to me, and substantially lesser value. This DIP doesn't want to change anything about lvalues.
January 30
On Wednesday, 30 January 2019 at 16:47:48 UTC, Don wrote:
> On Wednesday, 30 January 2019 at 13:58:38 UTC, 12345swordy wrote:
>> I do not accept gut feeling as a valid objection here. The current workarounds is shown to be painful as shown in the dip and in the discussions that it currently link. That *the* motivation here.
>
> Like I said previously I am on the reviews side and that's it.

In terms of what exactly?
Walter had stated they do not rejected the dip in principle.
You apparently *do* rejected it in principle, from judging your posts here.

> By the way I don't like your tone when you say: "I do not accept gut feeling as a valid objection here".

If you stated that you think it a bad/good idea without explaining why you think it. That is what I call "gut feeling"

> Alright we're talking about a change that have been on hold for almost 10 years, if it was simple it would already been done.

The current dip system didn't exist 10 years prior. I wouldn't say that things are already done due to them being simple, as there are quite number of "simple" features that wasn't implemented already (Looking at you tuples).

-Alex


January 30
On Wednesday, 30 January 2019 at 18:29:37 UTC, Manu wrote:
> On Wed, Jan 30, 2019 at 9:20 AM Neia Neutuladh via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
>>
>> On Wed, 30 Jan 2019 09:15:36 -0800, Manu wrote:
>> > Why are you so stuck on this case? The DIP is about accepting rvalues,
>> > not lvalues...
>> > Calling with 'p', an lvalue, is not subject to this DIP.
>>
>> The result of a CastExpression is an rvalue. An implicit cast is a compiler-inserted CastExpression. Therefore all lvalues with a potential implicit cast are rvalues.
>
> But there's no existing language rule that attempts to perform an
> implicit cast where an lvalue is supplied to a ref arg...?
> Why is the cast being attempted?
Because of the rewrite that your proposed in your dip.

void fun(ref int x);

fun(10);

{
  T __temp0 = void;
  fun(__temp0 := 10);
}

lets replace 10 with a short variable named: S

void fun(ref int x);

fun(S)
{
  T __temp0 = void;
  fun(__temp0 := S);
}
fun(__temp0 := S) This is where the cast is being attempted. As __temp0 is an                            integer type and S is a short type
January 30
On 1/30/19 1:29 PM, Manu wrote:
> On Wed, Jan 30, 2019 at 9:20 AM Neia Neutuladh via
> Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
>>
>> On Wed, 30 Jan 2019 09:15:36 -0800, Manu wrote:
>>> Why are you so stuck on this case? The DIP is about accepting rvalues,
>>> not lvalues...
>>> Calling with 'p', an lvalue, is not subject to this DIP.
>>
>> The result of a CastExpression is an rvalue. An implicit cast is a
>> compiler-inserted CastExpression. Therefore all lvalues with a potential
>> implicit cast are rvalues.
> 
> But there's no existing language rule that attempts to perform an
> implicit cast where an lvalue is supplied to a ref arg...?

That's exactly what lowerings are for: to precisely specify what should happen when the proposed construct is used. DIP 1016 proposes a lowering of the form:

{
  T __temp0 = expr;
  fun(__temp0);
}

In the first step, an implicit conversion of an lvalue may take place.

> Why is the cast being attempted? 'p' is an lvalue, and whatever that
> does should remain exactly as is (ie, emits a compile error).

Not according to DIP 1016. Here is an example pasted from it:

========
This inconvenience extends broadly to every manner of rvalue passed to functions, including:
...
fun(my_short); // implicit type conversions (ie, short->int promotion)
========

Presumably my_short is a variable of type short. Is that correct?

Again (this is not a rhetorical or sarcastic question): are you sure DIP 1016 expresses what you are trying to accomplish?

> We could perhaps allow this for `const` args, but that feels like
> separate follow-up work to me, and substantially lesser value. This
> DIP doesn't want to change anything about lvalues.

What we have here is:

* DIP 1016 proposes a hole in the language one could drive a truck through.

* The problem goes undetected in community review.

* Its own author seems to not have an understanding of what the DIP proposes.


Andrei
January 30
On Monday, 28 January 2019 at 19:58:24 UTC, Andrei Alexandrescu wrote:
> On 1/28/19 1:00 PM, Andrei Alexandrescu wrote:
>> It seems to me that a proposal adding the "@rvalue" attribute in function signatures to each parameter that would accept either an rvalue or an lvalue would be easy to argue.
>> 
>> - No exposing existing APIs to wrong uses
>> - The function's writer makes the decision ("I'm fine with this function taking an rvalue")
>> - Appears in the function's documentation
>> - Syntax is light and localized where it belongs
>> - Scales well with number of parameters
>> - Transparent to callers

The inverse, the @norval attribute, would feature all but the first advantages, at least once people get used to normal ref allowing (some) rvalues too. I can't think of many good reasons for a callee to disallow rvalues (with matching type at least); your example wrt. interlockedIncrement() is a good one, as synchronization overhead clearly isn't required for an rvalue. But my usages of (mutable) ref are >99% of the time something like:

Header readHeader(ref Stream stream)
{
    // read from & advance stream, return parsed header
}

where I'd like to be able put everything into one line if trivial (stream not required later on):

readHeader(Stream("file")).doSomething();

(And const ref is mostly used for performance with bigger structs, where rvalues are absolutely fine).

TLDR: I'd guess that I'd need to type `@rvalue` about 1000 times as often as `@norval`. I'm not kidding.

> TL;DR: it could be argued that the only dangerous conversions are lvalue -> temp rvalue -> ref, so only disable those. The conversion rvalue -> temp rvalue -> ref is not dangerous because the starting value on the caller side could not be inspected after the call anyway.

I agree that the DIP needs to be clearer wrt. rvalues resulting from implicit conversions. I also agree with the above point. I'm just not sure we need to allow implicit conversions from rvalue argument expressions at all. To minimize the changes for overload resolution, it might be enough to allow rvalue argument expressions of matching type only, i.e., the types which are allowed for current ref semantics. After all, I don't plan to use the proposed ref semantics for primitive types where that might come in handy (something silly like `modf(x, 123.456)` if the second param is a `ref real`), and explicit casts would IMO be an acceptable price to pay for safety and visibility in the remaining cases.
January 30
On Wed, Jan 30, 2019 at 12:40 PM 12345swordy via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
>
> On Wednesday, 30 January 2019 at 18:29:37 UTC, Manu wrote:
> > On Wed, Jan 30, 2019 at 9:20 AM Neia Neutuladh via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
> >>
> >> On Wed, 30 Jan 2019 09:15:36 -0800, Manu wrote:
> >> > Why are you so stuck on this case? The DIP is about
> >> > accepting rvalues,
> >> > not lvalues...
> >> > Calling with 'p', an lvalue, is not subject to this DIP.
> >>
> >> The result of a CastExpression is an rvalue. An implicit cast is a compiler-inserted CastExpression. Therefore all lvalues with a potential implicit cast are rvalues.
> >
> > But there's no existing language rule that attempts to perform
> > an
> > implicit cast where an lvalue is supplied to a ref arg...?
> > Why is the cast being attempted?
> Because of the rewrite that your proposed in your dip.
>
> void fun(ref int x);
>
> fun(10);
>
> {
>    T __temp0 = void;
>    fun(__temp0 := 10);
> }
>
> lets replace 10 with a short variable named: S

"a short variable named: S" is an lvalue, so why would the rewrite be attempted? S must be an rvalue for any rewrite to occur. We're talking about rvalues here.
January 30
On Wed, Jan 30, 2019 at 1:05 PM Andrei Alexandrescu via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
>
> On 1/30/19 1:29 PM, Manu wrote:
> > On Wed, Jan 30, 2019 at 9:20 AM Neia Neutuladh via Digitalmars-d-announce <digitalmars-d-announce@puremagic.com> wrote:
> >>
> >> On Wed, 30 Jan 2019 09:15:36 -0800, Manu wrote:
> >>> Why are you so stuck on this case? The DIP is about accepting rvalues,
> >>> not lvalues...
> >>> Calling with 'p', an lvalue, is not subject to this DIP.
> >>
> >> The result of a CastExpression is an rvalue. An implicit cast is a compiler-inserted CastExpression. Therefore all lvalues with a potential implicit cast are rvalues.
> >
> > But there's no existing language rule that attempts to perform an implicit cast where an lvalue is supplied to a ref arg...?
>
> That's exactly what lowerings are for: to precisely specify what should happen when the proposed construct is used. DIP 1016 proposes a lowering of the form:
>
> {
>    T __temp0 = expr;
>    fun(__temp0);
> }
>
> In the first step, an implicit conversion of an lvalue may take place.

What? `expr` must be an rvalue... if it's not, then none of this applies.


> > Why is the cast being attempted? 'p' is an lvalue, and whatever that does should remain exactly as is (ie, emits a compile error).
>
> Not according to DIP 1016. Here is an example pasted from it:
>
> ========
> This inconvenience extends broadly to every manner of rvalue passed to
> functions, including:
> ...
> fun(my_short); // implicit type conversions (ie, short->int promotion)
> ========

Oh I see.

> fun(short(10)); // implicit type conversions (ie, short->int promotion)

I did not intend for this DIP to apply to anything other than rvalues.
I can totally see how that's not clear. `my_short` should be an rvalue
of some form, like the rest.
Is that the only such line?

> Presumably my_short is a variable of type short. Is that correct?

It is not. It should be an rvalue like everything else. Perhaps it's an enum... but I should write `short(10)`, that would be clear.

> Again (this is not a rhetorical or sarcastic question): are you sure DIP 1016 expresses what you are trying to accomplish?

Fairly certain.

> > We could perhaps allow this for `const` args, but that feels like separate follow-up work to me, and substantially lesser value. This DIP doesn't want to change anything about lvalues.
>
> What we have here is:
>
> * DIP 1016 proposes a hole in the language one could drive a truck through.

I still can't see a truck-sized hole.

> * The problem goes undetected in community review.

I don't know how I could have influenced this outcome.

> * Its own author seems to not have an understanding of what the DIP proposes.

More classy comments. I can't get enough of the way you belittle people.

I made a 1-word error, where I should have written `short(10)` to be clear.
1-word error feels amendment-worthy, and not a call for "let's start
over from scratch".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15