April 24, 2013
On 24 April 2013 16:52, Walter Bright <newshound2@digitalmars.com> wrote:

> On 4/23/2013 8:32 PM, Manu wrote:
>
>> Is it actually complicated?
>>
>
> It's a lot more complicated than simply destructing them at the end of a function. You have to define what happens for conditionally executed expressions || && ?:, what happens at the end of a statement, what happens at a }, what happens to for statement initializers, etc., for each statement type.
>
>
>
>  Enclosing scope seems fine too. Can you suggest a case where it could
>> escalate
>> to an outer scope via a scope-ref argument?
>> So let's say then, that lifetime should be identical to a local declared
>> in the
>> same location. No change of any rules is required, it will work as
>> expected.
>>
>
> You cannot declare locals in conditionally compiled expressions. So it isn't as simple as that.
>

Okay, I understand the problem now. I'm sure it's possible to address these
issues, but I see the complexity in that case.
Is it worth doing so? Will it be taken seriously, or will another reason to
dismiss it appear?


April 24, 2013
On 4/24/2013 1:23 AM, Manu wrote:
> Okay, I understand the problem now. I'm sure it's possible to address these
> issues, but I see the complexity in that case.
> Is it worth doing so? Will it be taken seriously, or will another reason to
> dismiss it appear?

Yes, it's worth doing in whatever the final proposal will be.
April 24, 2013
On Wednesday, 24 April 2013 at 08:23:57 UTC, Manu wrote:
> Okay, I understand the problem now. I'm sure it's possible to address these
> issues, but I see the complexity in that case.
> Is it worth doing so? Will it be taken seriously, or will another reason to
> dismiss it appear?

I can't talk for Walter, but let me tell what I'd say if I was him.

The issue is worth considering. However, clearly in a 2 step process :
 - Ensuring lifetime safety.
 - In a second step, ensuring rvalue ref binding when it is safe (this include many consideration about temporary lifetime that aren't trivial as you can see).

I'd give priority to #1 as it seems like a major hole in D right now. But #2, even if truly important, solve a problem that isn't as fundamental, and incurs a fair amount of complexity, so I'd delay it until some core recurring problems are sorted out.
April 24, 2013
> r-values can NEVER be accepted by a ref argument, they don't 'exist', we're
> talking about implicitly generated temporaries (which also addresses the
> issues with receiving _explicit_ temp's).
They may be temporary but why should that mean they don't exist. (wow that's disturbingly close to a harry potter quote)

Currently temporaries exist as long as they are required to exist, and their lifetime never exceeds one statement.

> If I were to start arguing upon the basis of your proposal, I would then
> start arguing that auto-ref in this context is pointless, and automatic
> creation of a temp to hold any r-value should be the universal/default
> behaviour.

I believe with the exception of literals (which are probably implemented as global immutable variables) temporaries are already whenever an rvalue is used...

>> Why does the temporary need to exist any longer than the current
>> statement? (the current lifetime of temporaries are the statement or
>> expression). Surely any longer is just wasting stack space.
> 
> scope ref a(scope ref int x) { return x; }
> void b(scope ref int x);
> 
> b(a(10));
> 
> The temp produced from '10' needs to last longer than a(), because it can
> be returned to b(). Ie, the temp needs the life of any normal local
> declared within that scope.
> 
> How do you describe 'wasting' stack space? Does D attempt to recycle stack
> space from previous short-lived locals within a single function?

I said "Why does the temporary need to exist any longer than the current statement?". In your example the temporary does not exist longer than the current statement, (the current statement in this example being "b(a(10))" since that is the context in which the temporary would be created)

I would hope that D reuses the stack space it uses for temporaries, certainly any decent C++ compiler would...

> The important distinction is that with scope ref, a temps life can be
> prolonged and cascaded via return values.
That's simply not true, even if you allow passing rvalues as normal "ref", as long as DIP25A is implemented. The longest a temp ever needs to exist is until the end of the statement, with or without rvalue references. This means there is no issue with conditionals.

Anyway, it seems in general that everyone thinks DIP25A should be implemented, or am I mistaken?
April 24, 2013
On 4/24/13 6:27 AM, Diggory wrote:
> Anyway, it seems in general that everyone thinks DIP25A should be
> implemented, or am I mistaken?

I'd like to work a bit more on it before a formal review.

Andrei
April 24, 2013
On 04/24/2013 04:56 AM, Jonathan M Davis wrote:
>...
> However, the problem with simply making auto ref do this for non-templated
> functions is that then it functions fundamentally differently for templated and
> non-templated functions. ...

http://forum.dlang.org/thread/ylebrhjnrrcajnvtthtt@forum.dlang.org?page=12#post-kl8m2e:24i7g:241:40digitalmars.com

April 24, 2013
On Wednesday, 24 April 2013 at 12:38:19 UTC, Andrei Alexandrescu wrote:
> On 4/24/13 6:27 AM, Diggory wrote:
>> Anyway, it seems in general that everyone thinks DIP25A should be
>> implemented, or am I mistaken?
>
> I'd like to work a bit more on it before a formal review.
>
> Andrei

If you find the time one day, please revisit the "Taking address" section.

I'm convinced that the goal of DIP25 could be fully realized even with some of the restrictions relaxed/lifted, with less code-breakage as result.

In particular:
Allowing '&' for non-ref parameters and "Stack-allocated locals" in @system.

It encourages bad programming style where heap is preferred over stack, just to silence the compiler. Yes '&' is dangerous but it's a separate issue, why conflate  a "Sealed references" DIP with restrictions on normal "non ref" C-style systems programming?

Thanks for reading this far...
April 24, 2013
On 4/24/13 3:08 PM, Tove wrote:
> On Wednesday, 24 April 2013 at 12:38:19 UTC, Andrei Alexandrescu wrote:
>> On 4/24/13 6:27 AM, Diggory wrote:
>>> Anyway, it seems in general that everyone thinks DIP25A should be
>>> implemented, or am I mistaken?
>>
>> I'd like to work a bit more on it before a formal review.
>>
>> Andrei
>
> If you find the time one day, please revisit the "Taking address" section.
>
> I'm convinced that the goal of DIP25 could be fully realized even with
> some of the restrictions relaxed/lifted, with less code-breakage as result.
>
> In particular:
> Allowing '&' for non-ref parameters and "Stack-allocated locals" in
> @system.
>
> It encourages bad programming style where heap is preferred over stack,
> just to silence the compiler. Yes '&' is dangerous but it's a separate
> issue, why conflate a "Sealed references" DIP with restrictions on
> normal "non ref" C-style systems programming?
>
> Thanks for reading this far...

I agree. At any rate, DIP25 is on the aggressive side right now. I think we should first implement the noncontroversial parts and defer discussion on the breakages.

Andrei
April 25, 2013
What I ask me for some time:
Would it not be possible that a method such as
----
void foo (auto ref A a) {}
----
In such a call:
----
foo (A (42));
----
move the argument, and in a case like this
----
A a = 42;
/ / ...
foo (a);
----
gets the argument by ref? And that without to double the function 2^n times?
Purely out of interest. Because that would actually (as far as I can see) the optimal solution.
April 25, 2013
On Wednesday, April 24, 2013 08:54:09 Zach the Mystic wrote:
> On Wednesday, 24 April 2013 at 02:56:42 UTC, Jonathan M Davis
> 
> wrote:
> > So, probably the best route at this point is to come up with a
> > new attribute
> > which is replace with ref in the function definition and
> 
> When you say "replace with ref", does that mean 'ref' won't appear in the common case?
> 
> ref T fc(scope int a) {}
> 
> The problem would be that 'scope' would behave differently, implying 'ref' with a value type, from with a reference type, in which it shouldn't imply 'ref'. I don't know if it makes sense to automatically promote the meaning of 'scope' to include 'ref' for value types while leaving it alone for reference types. This was objected to by others, but if it were provably harmless to allow, it would be an appearance improvement.

You misunderstand me (possibly because I didn't proofread what I wrote). What I mean is that the way that auto ref should work with non-templated functions is that

auto foo(auto ref T param) {...}

becomes

auto foo(ref T param) {...}

underneath the hood. Then when you pass an rvalue to it - e.g. foo(T(5)) - that gets translated to something like

T __temp = T(5);
foo(__temp);

Then auto ref works with both lvalues and rvalues with only one function definition, and ref is unchanged in how it works (it still only accepts lvalues).

The problem is that that's not how auto ref works with templated functions, and we need the way that it currently works with templated functions (as it improves D's forwarding capabilities), but we also really should have the ability to do auto ref with templated functions like I just described for non- templated ones, since the templated approach results in a combinatorial explosion of template instantiations as you add more auto ref parameters. And obviously auto ref can't mean both for, so if we're going to have both, one of the two ends up needing a new attribute. So, either

1. auto ref on templates continues as-is (and is never implemented for non- templated functions), and @newattr does what I just described for both templated and non-templated functions, or

2. auto ref is changed to mean what I just described, and @newattr is used to do the forwarding trick that auto ref is often currently used for with templated functions.

Nowhere in here am I suggesting that ref itself be treated differently, and nothing I'm describing really has anything to do with scope.

- Jonathan M Davis