December 31, 2014
On 12/30/14 7:32 PM, Manu via Digitalmars-d wrote:
> void mayEscape(ref int x); // <-- may escape this ref arg
>
> void t()
> {
>    int onStack = 1;
>    mayEscape(onStack); // <- perfectly legal, and equally unsafe
> }

DIP25 puts this code in illegality. I don't think the proposal has been explicit about that, will fix. Thanks! -- Andrei

December 31, 2014
On 12/30/14 7:32 PM, Manu via Digitalmars-d wrote:
> While that code is legal, the rejection of rvalue->ref is absolutely arbitrary.
> The 'workaround' for not allowing rvalue->ref is to simply assign it
> to a stack local with a stupid name (eg: t1, t2, etc) on the preceding
> line.
> That workaround appears in*every*  instance that rvalue->ref would be
> used, making code messy and more difficult to maintain.

The alternate hypothesis is "ref" is being misused. "ref" is for propagating changes into the arguments. It should be rare that code does not actually care for that. Unlike in C++, ref is seldom needed for optimizing copies away. -- Andrei

December 31, 2014
On Tue, 30 Dec 2014 21:28:32 -0800
Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com>
wrote:

> The alternate hypothesis is "ref" is being misused. "ref" is for propagating changes into the arguments. It should be rare that code does not actually care for that. Unlike in C++, ref is seldom needed for optimizing copies away. -- Andrei
slightly derailing comment: the small annoyance of `ref` is that it hides the fact that i'm passing argument by reference. i still can't fully convince myself that i should use `ref` instead of explicit pointer, 'cause:

  void foo (ref int a);
  void bar (int a);

  // and the following calls looks all the same T_T
  int a;
  foo(a);
  bar(a);

but:

  void foo (int* a);
  void bar (int a);

  // wow, we don't even need to look at the signatures to find
  // that `foo` wants a reference and that it therefore can
  // modify `a`!
  int a;
  foo(&a);
  bar(a);

another "cosmetic issue" that bugs me alot.

p.s. and with pointers it's easy to write something like this:

  auto parseNumber (string s, bool* error=null);

yes, i know about exceptions... which blocks `@nogc`. not yummy.


December 31, 2014
On 31 December 2014 at 15:28, Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 12/30/14 7:32 PM, Manu via Digitalmars-d wrote:
>>
>> While that code is legal, the rejection of rvalue->ref is absolutely
>> arbitrary.
>> The 'workaround' for not allowing rvalue->ref is to simply assign it
>> to a stack local with a stupid name (eg: t1, t2, etc) on the preceding
>> line.
>> That workaround appears in*every*  instance that rvalue->ref would be
>> used, making code messy and more difficult to maintain.
>
>
> The alternate hypothesis is "ref" is being misused. "ref" is for propagating changes into the arguments. It should be rare that code does not actually care for that. Unlike in C++, ref is seldom needed for optimizing copies away. -- Andrei

Exactly like C++, ref it equally needed for optimising copies away. If
you use separate compilation, or binary libs (normal practise outside
OSS), then you still need it.
Also, when binding to external code; C++ api's have ref, so D bindings
have ref. I interact with C code more than I interact with other D
code.

Your view on ref only stands true in an 'everything is D' world, which we are clearly not in, and I don't see any risk of that happening any time soon. I'm suspect it may never happen.
December 31, 2014
On 31 December 2014 at 16:12, Manu <turkeyman@gmail.com> wrote:
>
> Your view on ref only stands true in an 'everything is D' world, which we are clearly not in, and I don't see any risk of that happening any time soon. I'm suspect it may never happen.

And even then, passing by value in not something you would do! Why
would you ever pass some big struct by value? Are you relying on the
inliner? Inliners only inline tiny functions.
What about unoptimised/debug performance?
December 31, 2014
On Wednesday, 31 December 2014 at 06:04:41 UTC, ketmar via
Digitalmars-d wrote:
>   void foo (ref int a);
>   void bar (int a);
>
>   // and the following calls looks all the same T_T
>   int a;
>   foo(a);
>   bar(a);
>
> but:
>
>   void foo (int* a);
>   void bar (int a);
>
>   // wow, we don't even need to look at the signatures to find
>   // that `foo` wants a reference and that it therefore can
>   // modify `a`!
>   int a;
>   foo(&a);
>   bar(a);

To require ref at the callside was proposed long ago. Dunno if
this would
make Manu's task harder. I agree, that this might have been
better in
the long run.

> another "cosmetic issue" that bugs me alot.
>
> p.s. and with pointers it's easy to write something like this:
>
>   auto parseNumber (string s, bool* error=null);
>
> yes, i know about exceptions... which blocks `@nogc`. not yummy.

You could preallocate the exception or use an out parameter.


December 31, 2014
On Wednesday, 31 December 2014 at 03:25:24 UTC, Manu via Digitalmars-d wrote:
>> On the other hand, power just because we can add it is not always a good
>> thing. C macros are very powerful, but experience has shown it is the wrong
>> kind of power. Also, programmers do not really want a complex annotation
>> system. They want to just write code in the most obvious manner and have it
>> work correctly. Having a powerful (but complex) system is not very
>> attractive.
>
> His point is similar to my other point elsewhere though. I don't think
> he's talking about 'power' in the sense you describe, what he's really
> talking about is consistency or uniformity. His original scope
> proposal wasn't 'powerful' (even though it was effectively more
> powerful), it was holistic, and without the edges that seem to have
> been introduced to try and 'contain the concept into a smaller space',
> if that makes sense.
>
> In this particular case, I think practical 'complexity' is being
> expressed in the form of awkward edge cases, and the reason that
> happened I suspect, is precisely what Andrei asked me to do; talk
> about the specific problem case, not the general problem that's
> recurring in numerous problem cases.
> I feel like the current proposals are to effectively add yet more
> edges to address specific cases, rather than removing the edges that
> are already present causing the problems in the first place.
> Address the problem, don't add layers of patches to round off rough edges.

Thank you, I know what I wrote was kind of abstract, this describes my thoughts quite well.
December 31, 2014
On Wednesday, 31 December 2014 at 00:09:15 UTC, Walter Bright wrote:
> On 12/30/2014 1:27 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>> In general, I get the impression from both DIP25 and DIP69 that both are
>> motivated by minimizing the change to the existing language, instead of looking
>> for the most powerful solution (that may have other use-cases besides the ones
>> under consideration). I.e., instead of asking which concepts are behind the
>> problem in question, how these concepts could be expressed in an ideal world,
>> and then making compromises to fit them into D, it seems like we're starting
>> with some premises (as few changes as possible, no type modifiers), and then
>> look for a solution that needs to sacrifice the smallest number of use cases to
>> stay within the constraints. This is particularly bad if our premises are going
>> against the nature of the problem we want to solve, because then we are
>> guaranteed to get a bad solution.
>
> On the other hand, power just because we can add it is not always a good thing. C macros are very powerful, but experience has shown it is the wrong kind of power.

So... how does this apply to our problem concretely? Do you believe a full blown ownership/lifetime system is "the wrong kind of power"? Remember, we're talking about an ideal world at first. If after thorough discussion it turns out that it can't be integrated into D, at least we know that it's probably not possible. But I haven't seen any indications that this is the case; in fact, it's not even been discussed.

> Also, programmers do not really want a complex annotation system. They want to just write code in the most obvious manner and have it work correctly. Having a powerful (but complex) system is not very attractive.

But a powerful system doesn't need to be complicated. In fact, a system with a handful of general and orthogonal features is likely easier to understand and handle in practice than one with lots of (even trivial) edge cases and exceptions.
December 31, 2014
On 12/31/14, Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 12/30/14 7:32 PM, Manu via Digitalmars-d wrote:
>> void mayEscape(ref int x); // <-- may escape this ref arg
>>
>> void t()
>> {
>>    int onStack = 1;
>>    mayEscape(onStack); // <- perfectly legal, and equally unsafe
>> }
>
> DIP25 puts this code in illegality. I don't think the proposal has been explicit about that, will fix. Thanks! -- Andrei

Wait, what? Passing stack variables by ref will be disallowed?
December 31, 2014
On Wednesday, 31 December 2014 at 05:28:31 UTC, Andrei Alexandrescu wrote:
> The alternate hypothesis is "ref" is being misused. "ref" is for propagating changes into the arguments. It should be rare that code does not actually care for that. Unlike in C++, ref is seldom needed for optimizing copies away. -- Andrei

Could you elaborate on that? Say I've got some big, expensive struct I want to pass into a function efficiently. In C++ I'd do this by const reference (or reference if I'm making changes).

What does D do that would make the ref unnecessary for efficiency? I can't imagine the compiler doing any sort of copy (even the efficient blig) being as fast as just passing in a reference. There is also a problem if the struct has disabled postblit. If the compiler silently turned something passed by value into a secret reference then it would open the door for problems during multithreading.

It is a shame that there is a conflation between an optimization and a tool for more flexible code structure. It makes it hard to express your intention when you use ref.

With DIP25 it seems like passing in an rvalue by ref would be safer and thus open it to being allowed.