July 21, 2018
On Saturday, 21 July 2018 at 08:55:59 UTC, Paolo Invernizzi wrote:

> Frankly speaking, my feeling is that D is becoming a horrible mess for the programmer...

> /Paolo
How!? Please Explain. You need to demonstrate evidence instead of appeal to emotional fallacy by resorting to "feels".

-Alexander
July 21, 2018
I was for this back when it was only for 'const ref' but that somehow changed to just ref. Which I think is a mistake. Yes D's const is broken and useless, but I don't think that's a reason to introduce difficult to locate bugs with the addition of this feature. There's not a simple way to locate where code might be breaking if a temporary value is being passed to a ref function when it wasn't intended. Right now this is a compiler error, even in C++. But with this proposed change it might take a lengthy amount of time in the debugger trying to understand what is happening.

Yes I want rvalue refs, just not like this.
July 21, 2018
On Sat., 21 Jul. 2018, 12:30 pm Johnatune via Digitalmars-d, < digitalmars-d@puremagic.com> wrote:

> I was for this back when it was only for 'const ref' but that somehow changed to just ref. Which I think is a mistake. Yes D's const is broken and useless, but I don't think that's a reason to introduce difficult to locate bugs with the addition of this feature. There's not a simple way to locate where code might be breaking if a temporary value is being passed to a ref function when it wasn't intended. Right now this is a compiler error, even in C++. But with this proposed change it might take a lengthy amount of time in the debugger trying to understand what is happening.
>
> Yes I want rvalue refs, just not like this.
>

It's like you didn't read the DIP.

I was initially very hesitant as you, but I was motivated to remove the
const restriction when I realised that usefulness of the pattern far
exceeds what you're familiar with in C++.
While interacting with interfaces similar to C++ is one motivating use case
(particularly for myself), I realised that pipeline programming and 'return
ref' change the game.
They are distinctly "D" coding styles, and this issue is a cause of
friction with respect to one of D's greatest success stories.
Such use with pipelines and 'return ref' imply that mutable ref also
supported.

There is indeed also the restrictive-const issue, and the current recommendation is to not over-use const. From that perspecetive, this DIP is in-line with current recommendations regarding const; it is obviously naturally supported, but not mandated.

Finally, I have really thought about the problem case that everyone is so terrified about, and I am still trying to visualise real-world situations where that could arise. Please read the replies to Jonathan's sub-thread... that has all the detail on that.

TLDR:
  - The fear in question relates to a general class of problem and not
specifically related to 'ref' - that's just one of very many ways to expose
the 'accidentally modified an rvalue' issue.
  - I don't believe it's within 'ref's responsibility domain to fight that
class of problem, particularly at the expense of the other advantages we're
inhibiting (proposed in thie DIP).
  - We're still trying to identify probably real-world examples.
  - Your fear is mostly invalid. And even if it's not, the DIP proposes a
very nice and principled mechanism to retain "lval-only please" API design.

>


July 22, 2018
On Saturday, 21 July 2018 at 08:59:39 UTC, Manu wrote:
> 4. A struct-type getter that returns by-val exhibits this gotcha in a
> variety of ways; you 'get' the member (a by-val copy), then mutate a
> member in any way, (ie, call a method), and you've accidentally
> modified the copy, not the source value! (`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.

This argument kind of convinced me. I also just realized, there is another such situation which is very similar to functions taking ref parameters, where references to rvalues are actually allowed: foreach loops. The following code is actually valid, which kind of surprised me:

foreach(ref e; iota(0, 10))
{
    e += 1;
}

So DIP 1016 actually seems to make the language more consistent in that regard.

I also carefully reread the DIP and found some minor issues:

- "It has been noted that is it possible to perceive the current usage of":
it should be "[...] it is [...]

- Somebody already mentioned this, but this sections sounds confusing, please find a better wording: "An example may be some meta that reflects or receives a function by alias." Also you seem to be using "meta" as a noun many times. I'm not totally sure, but I don't think it actually is a noun and for the least, It is very uncommon as a noun which makes understanding the corresponding sections much harder. For example I don't understand what is actually meant by "brittle meta" in a later section.


July 22, 2018
On Sun, 22 Jul 2018 at 01:00, Johannes Loher via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Saturday, 21 July 2018 at 08:59:39 UTC, Manu wrote:
> > 4. A struct-type getter that returns by-val exhibits this
> > gotcha in a
> > variety of ways; you 'get' the member (a by-val copy), then
> > mutate a
> > member in any way, (ie, call a method), and you've accidentally
> > modified the copy, not the source value! (`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.
>
> This argument kind of convinced me. I also just realized, there is another such situation which is very similar to functions taking ref parameters, where references to rvalues are actually allowed: foreach loops. The following code is actually valid, which kind of surprised me:
>
> foreach(ref e; iota(0, 10))
> {
>      e += 1;
> }
>
> So DIP 1016 actually seems to make the language more consistent in that regard.

Hooray! Perhaps my cause is not so hopeless after all these years :)

Yes, there are countless possible constructions of this 'issue'.
Here's my personal favourite:
  T().mutate();

;)

It's not 'ref's job to address this issue.

> I also carefully reread the DIP and found some minor issues:
>
> - "It has been noted that is it possible to perceive the current
> usage of":
> it should be "[...] it is [...]

There's a PR that nobody has merged that fixes some bugs.

> - Somebody already mentioned this, but this sections sounds confusing, please find a better wording: "An example may be some meta that reflects or receives a function by alias." Also you seem to be using "meta" as a noun many times. I'm not totally sure, but I don't think it actually is a noun and for the least, It is very uncommon as a noun which makes understanding the corresponding sections much harder. For example I don't understand what is actually meant by "brittle meta" in a later section.

I use the term 'meta' (as in meta-programming) to refer to
compile-time constructions.
I don't tend to say "a template", because many problematic
constructions are compositions, and then consider mixin; not
'template's.
I feel like 'meta' is the simplest accepted term for "compile time
machinery". I'm happy to change my language if it's so confusing. What
should I write?
July 22, 2018
On Sunday, 22 July 2018 at 08:53:53 UTC, Manu wrote:
> On Sun, 22 Jul 2018 at 01:00, Johannes Loher via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> - Somebody already mentioned this, but this sections sounds confusing, please find a better wording: "An example may be some meta that reflects or receives a function by alias." Also you seem to be using "meta" as a noun many times. I'm not totally sure, but I don't think it actually is a noun and for the least, It is very uncommon as a noun which makes understanding the corresponding sections much harder. For example I don't understand what is actually meant by "brittle meta" in a later section.
>
> I use the term 'meta' (as in meta-programming) to refer to
> compile-time constructions.
> I don't tend to say "a template", because many problematic
> constructions are compositions, and then consider mixin; not
> 'template's.
> I feel like 'meta' is the simplest accepted term for "compile time
> machinery". I'm happy to change my language if it's so confusing. What
> should I write?

Both these terms (CT [construction|machinery]) I find more descriptive than just “meta”. If you want to use “meta” then I’d suggest “meta code” to differentiate it from meta data, meta key or meta proposal (which is this: a proposal on a proposal) :-)

-Bastiaan
July 22, 2018
On Sunday, July 22, 2018 01:53:53 Manu via Digitalmars-d wrote:
> I use the term 'meta' (as in meta-programming) to refer to
> compile-time constructions.
> I don't tend to say "a template", because many problematic
> constructions are compositions, and then consider mixin; not
> 'template's.
> I feel like 'meta' is the simplest accepted term for "compile time
> machinery". I'm happy to change my language if it's so confusing. What
> should I write?

Then say meta-programming, not just meta. What you mean by meta can certainly be inferred by the context, but I don't think that it's generally accepted that meta by itself necesarily means meta-programming when discussing D. Even then, I think that it's more common to say template meta-programming than meta-programming by itself, but meta-programming by itself is much more descriptive than just meta.

- Jonathan M Davis

July 22, 2018
Am Fri, 20 Jul 2018 10:33:56 -0600
schrieb Jonathan M Davis <newsgroup.d@jmdavisprog.com>:

> On Friday, July 20, 2018 15:50:29 meppl via Digitalmars-d wrote:
> > On Friday, 20 July 2018 at 13:21:11 UTC, Jonathan M Davis wrote:
> > > On Friday, July 20, 2018 05:16:53 Mike Parker via Digitalmars-d
> > >
> > > wrote:
> > >> ...
> > >
> > > ...
> > > Allowing ref to accept rvalues goes completely against the idea
> > > that ref is for passing an object so that it can be mutated and
> > > have its result affect the caller. With this DIP, we'd likely
> > > start seeing folks using ref all over the place even when it
> > > has nothing to do with having the function mutating its
> > > arguments, and that's not only error-prone, but it obfuscates
> > > what ref was originally intended for.
> > > ...
> >
> > So, if `immutable` would be the default in D, you would be okay with "DIP 1016"?  Because then people would have to write `ref mutable` for mutation
> 
> No. I don't see why that would help at all.
> 
> Honestly, if D had immutable by default, I'd probably quit D, because it would make the language hell to use. Some things make sense as immutable but most don't. If I wanted that kind of strait jacket, I'd use a language like Haskell.
> 
> But regardless, even if I could put up with a such a default, it wouldn't help, because the use case that Manu is trying to solve would be using ref mutable just like the use cases that ref is normally used for now. There needs to be a distinction between the case where ref is used because the intent is to mutate the object and the case where the intent is to avoid having to copy lvalues and mutation is acceptable but not the goal. C++ solves this by using const, since once const is used, mutation is no longer an issue, so the refness is clearly to avoid copying, but with how restrictive const is in D, it probably wouldn't solve much, because many use cases couldn't use const. We really do need a mutable equivalent to C++'s const&. But Manu's solution unnecesarily destroys the dinstinction between ref being used as means to mutate the argument and ref being used to avoid copying the argument. Since we can't use const for that, we really need a new attribute.
> 
> - Jonathan M Davis

I understand the distinction you make, but I don't feel strongly about it. Vector math can use const in D just fine as there are no indirections involved, so my functions would have `ref const` arguments all over the place to discriminate between "for performance" and "for mutation". That said, I'm not opposed to some other keyword or @tribute either.

-- 
Marco

July 22, 2018
On 7/20/18 3:36 PM, Jonathan M Davis wrote:
> 
> The reality of the matter is that it's always going to be up to the API
> author on some level - e.g. even if the proposed changes were implemented,
> there's still the question of whether a function's parameter should be
> marked with ref or not, and arguably, in general, it really shouldn't be,
> because it destroys the compiler's ability to move. Yes, by either allowing
> ref to accept rvalues or by adding an attribute like @rvalue to make ref
> accept rvalues, it's then up to the caller as to whether they pass an lvalue
> or rvalue, but it's still up to the API designer to decide how values are
> passed, and in some cases, it really does matter whether rvalues are
> accepted or not.

This has been accepted, pretty much always:

struct S
{
    int x;
    void opOpAssign(string op : "+")(int val) { x += val; }
}

struct Y
{
    S s;
    S foo() { return s; }
}

void main()
{
    import std.stdio;
    Y y;
    y.s += 5;
    writeln(y.s.x); // 5
    y.foo += 5;
    writeln(y.foo.x); // still 5
}

Yet, there has been no major catastrophe, no falling of the sky, no errors that I can ever think of that weren't caught because it obviously didn't do what it was supposed to. Note also, THERE IS NO WAY TO DISABLE IT! If you define operators on a type, you can call them on rvalues. Always.

This is one of the 2 reasons I think that this DIP is OK -- experience shows us that the allowance of binding `this` to rvalues hasn't caused problems.

The other reason is to avoid having to do acrobatics with static if in order to properly accept both rvalues and lvalues. Yes, you can use auto ref, but there are many cases where it's not desirable to use templates. Those are pretty well outlined in the DIP.

-Steve
July 25, 2018
Am Sat, 21 Jul 2018 19:22:05 +0000
schrieb 12345swordy <alexanderheistermann@gmail.com>:

> On Saturday, 21 July 2018 at 08:55:59 UTC, Paolo Invernizzi wrote:
> 
> > Frankly speaking, my feeling is that D is becoming a horrible mess for the programmer...
> 
> > /Paolo
> How!? Please Explain. You need to demonstrate evidence instead of appeal to emotional fallacy by resorting to "feels".
> 
> -Alexander

The DIP increases consistency recalling that rvalues are accepted:

- for the implicit 'this' parameter in methods
- in foreach loop variables declared as ref

No more special rules: rvalues are implicitly promoted to
lvalues where needed. The feeling probably comes from the
inevitable realization that the community is pluralistic and
Dlang acquired a lot of features that go towards someone else's
vision for a good PL. Some want a relaxed stance towards
breaking change, some want C++ or ObjC compatibility, some
want to know what assembly a piece of code compiles to or have
soft realtime constraints that don't work with a system
language's mark&sweep GC. Is D2 messier than D1? Sure it is,
and it caters to more use cases, too. As soon as you
substantiate what exact feature is adding to the horrible
mess, someone (often a group) will jump to defend it, because
they have a good use case or two.
It is kind of ironic that in order to do better than C++ you
have to support most of what modern C++ compilers offer and end
up having tons of unrelated features that make the language
just as bloated as C++ after a decade of community feedback.
It is a system PL. I think it needs to be this way and is a
lot cleaner with basic data types and more expressive still,
lacking a lot of C++'s legacy.

-- 
Marco