December 12, 2014
On Friday, 12 December 2014 at 22:05:21 UTC, Walter Bright wrote:
>> > forms can work, too.
>> No, unless we wrap every single indirection (pointer, slice, classes, delegates)
>> into a wrapper. That is not going to fly very far.
>
> The beauty of GC is that you don't have to do any of this. To have safe other methods of allocation, there has to be annotation everywhere or use a wrapped type in the same places.

The whole point of scope is to reduce that cost, both in term of
runtime (as copy can be elided) but also on the user.
December 12, 2014
On 12/12/2014 4:19 AM, Manu via Digitalmars-d wrote:
>> I simply do not understand why distinguishing beteen ref and not-ref is a
>> cornerstone of everything you do.
>
> I've said so many times, it's the single greatest regular frustration
> I encounter, by far.
> That is of course a relative measure. It's not the 'cornerstone of
> everything I do'; I don't start discussions about things that are not
> broken and otherwise painless.
> It is the thing that is *the most broken*, and leads to the most edge
> cases, general bloat, and text mixins.
> It comes up the most frequently, and by that metric alone, I consider
> it highest priority on my list.
>
> I've also said many times before, it possibly stems from the fact that
> one of the key cornerstones of almost everything I do in D is interact
> with other languages.
> This is a practical reality, I can't write all my code in D, and have
> mountains of existing code to interact with.
> Boilerplate is the result. D has powerful systems to automate
> boilerplate, like a carrot dangling right in front of my face, but
> it's almost always thwarted by ref, and almost exclusively so.
>
> My recent work updating LuaD to support all the features I required
> wasted about 80% of my time dealing with ref issues.
> In my past C++ bindings solutions, much code, which was otherwise
> simple, readable, and elegant, turned into a mess of text mixins,
> almost exclusively because ref is broken.

You've said this before, many times, but what is lacking is an explanation of WHY. What is the pattern, and why do you need that pattern? You say you don't like auto ref because it doesn't give you exact control, but what are the cases where auto ref is wrong?


>> Consider a ref counted type, RC!T. If scope were transitive, then you could
>> not have, say, a tree where the edges were RC!T. I.e., the payload of an RC
>> type should not be forced to be scope.
>
> I'm not sure I quite visualise this correctly...

struct Tree {
   RefCount!(Tree*) left;
   RefCount!(Tree*) right;
   ...
}


> So you're saying that a pointer itself shouldn't be able to escape a
> call tree, but the thing it points to should be able to escape just
> fine?

Yes.


> It feels like that kinda defeats the purpose...

You're arguing that a data structure with only one access point is the only kind of data structure in use. With transitive scope, such a data structure would be the only one possible!


> I guess you're seeing a situation where 'scope' is almost exclusively
> useful as a mechanism to tell the RC that it doesn't need to worry
> about ref-fiddling, and the thing we're passing isn't interested in
> scope restrictions at any level other than that RC optimisation?
> I guess I can see your angle... but my reaction is if that's all you
> are concerned about, maybe scope is the wrong tool for eliding ref
> fiddling in that case :/

'scope' is a way to say that this use of a pointer does not escape this scope. That is incredibly useful.

Recall my statements that pervasive refcounting is a terrible performance problem because of all the inc/dec? Knowing that references cannot escape means an inc/dec pair can be elided.

December 12, 2014
On 12/12/2014 4:20 AM, Manu via Digitalmars-d wrote:
> On 12 December 2014 at 08:53, John Colvin via Digitalmars-d
>> Because he requires control over function ABIs for both inter-language
>> communication and performance.
>>
>> In binding D to IDL (Interactive Data, not Interface Description) I found
>> ref often required special casing.
>
> Thank you. I feel like I'm just repeating myself over and over again.


Example, please.
December 12, 2014
On 12/12/2014 2:09 PM, deadalnix wrote:
> On Friday, 12 December 2014 at 22:05:21 UTC, Walter Bright wrote:
>>> > forms can work, too.
>>> No, unless we wrap every single indirection (pointer, slice, classes, delegates)
>>> into a wrapper. That is not going to fly very far.
>>
>> The beauty of GC is that you don't have to do any of this. To have safe other
>> methods of allocation, there has to be annotation everywhere or use a wrapped
>> type in the same places.
>
> The whole point of scope is to reduce that cost, both in term of
> runtime (as copy can be elided) but also on the user.

Yes, I do understand that :-) but currently doing a safe refcounted type is impossible in D. This proposal fixes that.
December 12, 2014
On Friday, 12 December 2014 at 22:34:27 UTC, Walter Bright wrote:
> On 12/12/2014 2:09 PM, deadalnix wrote:
> Yes, I do understand that :-) but currently doing a safe refcounted type is impossible in D. This proposal fixes that.

Actually, no it doesn't. It allow to ensure that this is safe,
module the RC system is the only owner.

This proposal allow for easy to use and fast RC, but certainly do
not make it safe.
December 13, 2014
On 12/12/2014 2:48 PM, deadalnix wrote:
> On Friday, 12 December 2014 at 22:34:27 UTC, Walter Bright wrote:
>> On 12/12/2014 2:09 PM, deadalnix wrote:
>> Yes, I do understand that :-) but currently doing a safe refcounted type is
>> impossible in D. This proposal fixes that.
>
> Actually, no it doesn't. It allow to ensure that this is safe,
> module the RC system is the only owner.
>
> This proposal allow for easy to use and fast RC, but certainly do
> not make it safe.

How not?
December 13, 2014
On Saturday, 13 December 2014 at 00:06:18 UTC, Walter Bright wrote:
> How not?

scope a = new Stuff();
scope b = a;

auto rc1 = RC(a);
auto rc2 = RC(b);

// Enjoy the free when it comes !
December 13, 2014
On 12/11/2014 10:10 PM, Dicebot wrote:
> So far I tend to agree, unfortunately. Considering all provided answers and
> explanations suggested semantics are simply not powerful enough to be useful
> even for relatively simple idiomatic D code and with no clear way of backward
> compatible improvements this DIP does not pull own weight.
> "Those are not scopes you are looking for"

The proposal provides escape proof passing of arguments. This is necessary in order to make rc safe, for example.

What are you looking for?
December 13, 2014
On 12/11/2014 4:13 PM, deadalnix wrote:
> On Thursday, 11 December 2014 at 13:55:55 UTC, Marc Schütz wrote:
>> On Thursday, 11 December 2014 at 12:48:05 UTC, Manu via Digitalmars-d wrote:
>>> On 8 December 2014 at 07:29, Walter Bright via Digitalmars-d
>>> <digitalmars-d@puremagic.com> wrote:
>>>> On 12/7/2014 6:12 AM, Dicebot wrote:
>>>>>
>>>>> But from existing cases it doesn't seem working good enough. For example,
>>>>> not
>>>>> being able to represent idiom of `scope ref int foo(scope ref int x) {
>>>>> return x;
>>>>> }` seems very limiting.
>>>>
>>>>
>>>>  scope ref int foo(ref int x);
>>>>
>>>> will do it.
>>>
>>> Will it? It looks like foo can't be called with scope data?
>>
>> This is a point that most people don't seem to understand yet, and which
>> wasn't obvious for me either, at the beginning:
>>
>> * A `ref` parameter means that it cannot escape the function, _except_ by return.
>> * A `scope ref` parameter means that it cannot escape the function  _ever_,
>> not even by return.
>> * A `scope ref` return means that it cannot leave the current statement.
>>
>> Therefore, a `scope ref` return value can be passed on to the next function as
>> a `ref` argument. If that function again returns a reference (even if not
>> explicitly designated as `scope`), the compiler will treat it as if it were
>> `scope ref`.
>>
>
> No, it understood. It is simply not useful.

The use case is described in the DIP under the 'Scope Ref' heading.


>> I agree, this is important. In my proposal, this works without transitivity.
>> The wrapper stores the pointer as a `scope` member, then by copying the
>> wrapper, the pointer gets copied implicitly, to which the normal scope
>> restrictions apply (`scope` on members means "will not outlive the
>> aggregate"). If it stored it as normal non-scope pointer, it couldn't get
>> assigned in the first place.
>
> Wut ? You cante store anything with grear lifetime, including non scope things
> (as they'll have infinite lifetime). Meaning the only thing you know, is that
> thing are possibly scoped.
>
> Meaning you have to assume infinite lifetime with every indirection, which make
> this proposal useless.

It means you'll have to wrap the next level of indirection in a ref counting (or equivalent) manner.

The great thing about GC is you can leave everything to the GC. But when explicitly managing memory, you have to decide for EVERY pointer who owns it, when it can be released, etc. Having a transitive scope is NOT going to resolve that for you, it isn't even going to help.

December 13, 2014
On 12/12/2014 4:07 PM, deadalnix wrote:
> On Saturday, 13 December 2014 at 00:06:18 UTC, Walter Bright wrote:
>> How not?
>
> scope a = new Stuff();
> scope b = a;
>
> auto rc1 = RC(a);
> auto rc2 = RC(b);
>
> // Enjoy the free when it comes !

RC needs to take a type as a parameter, not a symbol.