D2 Multithreading Architecture
Robert Jacques
sandford at jhu.edu
Wed Apr 29 08:34:23 PDT 2009
On Wed, 29 Apr 2009 04:26:55 -0400, Denis Koroskin <2korden at gmail.com>
wrote:
> On Tue, 28 Apr 2009 23:06:32 +0400, Robert Jacques <sandford at jhu.edu>
>> ┌───────┬──────────────┬────────────────────┬─────────────┐
>> │ scope │ Common Super │ Unknown Allocation │ Transitive† │
>> └───────┴──────────────┴────────────────────┴─────────────┘
>> Use of the scope keyword for the common ownership-type is based upon
>> Walter’s original escape analysis blog. However, this design is based
>> upon using the type system restrictions as opposed to full escape
>> analysis to prevent object escape. Full escape analysis would alleviate
>> the restrictions in rule 6.
>> Basic Rules:
>> 1) Refers to scope definitions inside a function body.
>> 2) May only be assigned at declaration
>> scope Node!(int) n;
>> n.next = new Node!(int)(); // Error: Possible escape
>> n = n.next; // Error: see relaxation of this
>> rule below
>
> What's Node? Is it a class or a struct?
Opps. Class. I've updated the wiki4D page with
scope Node!(int) n = mySharedNode;
> I believe you should have put Node's definition, first, and explained
> and implicit ctor call, if one takes place.
Okay.
>> 3) Applies to references taken from scope types
>> scope int* value = &(n.value);
>
> So, scope T and scope T* have different meaning?
>
> scope T means that T is constructed on stack, but scope T* is
> essentially "a pointer to scope variable". If that's the case, it is
> *very* confusing, because one could expect scope T to be the same no
> matter T is a class, a struct or a primitive type like int or ptr.
No, your confusion stems from Walter's choice to reuse the scope keyword,
yet again.
Logically,
scope T -> scope(T)
scope T* -> scope(T*)
As scope is transitive.
> It would be better to write
>
> scope(int)* value = &(n.value);
>
> Now it's more clear that value is a pointer to a data of type int which
> is stored on stack. I believe that's what intended in your example.
Though this is also correct. (Wiki code example updated)
>> 4) Implicit conversion is always fully transitive.
>> Foo[] y;
>> scope Foo[] x = y;
>
> I don't understand what this example does.
>> 5) Mixed implicit conversion is illegal.
>> scope(Foo)[] z = y; // Error: cannot implicitly convert...
Rule 4 and 5 have to do with the ways arrays can create loopholes in the
type system (Bug 2095, http://d.puremagic.com/issues/show_bug.cgi?id=2095)
Adding a link in the wiki.
>> 4) Objects and structs use the local interface
>> f.push(5); // Error: push is not part of
>> the scope interface
>> temp.push(5); // Okay, push is part of the
>> local interface
>>
>
> I don't understand this example. What's the difference between temp and
> f? They all said to be the same (see example 1).
> What's a difinition of push, anyway? *Please*, provide class difinition,
> first.
Opps. My example is completly wrong. *Sigh* How's this.
auto sf = new auto(Stack!(Foo))(); // declared as class Stack(T) {},
stack interface defaults
auto f1 = new Foo();
auto f2 = new auto(Foo)();
sf.push(f1); // Okay, push(local Foo) is defined
sf.push(f2); // Error: push(stack Foo) is is not
defined, use a scope class declaration instead
And I need to work on clearer examples...
>> Note that this catches all of Walter’s examples from the Escape
>> Analysis blog via rule 3:
>> int* foo()
>> {
>> int x = 3;
>> return &x; // Error: can not convert type
>> auto(int)* to int*
>> }
>>
>> int* bar(int* p) { return p; }
>> int* foo()
>> {
>> int x = 3;
>> return bar(&x); // Error: ditto
>> }
>>
>> void abc(int x, int** p) { *p = &x; } // Error: ditto
>>
>
> I don't see *any* difference between scope and stack variables. Besides,
> both using the same keyword, scope, and essentially are the same. It's
> very confusing because I got no idea about the difference between them,
> aside from scope object being created automagically and stack object
> need to be constructed explicitly:
>
> scope Node!(int) n; // scope
> scope Foo foo = new Foo(); // stack
>
> All I can say, wtf?
Honestly, I seriously though of using final instead of scope to avoid just
this confusion. But I decided to follow Walter's choice. (Besides it's
more intuitive).
scope Foo foo = new Foo(); // Foo is a of type scope and has been
allocated on the stack. (see rule 1)
auto Foo f2 = new scope(Foo)(); // Foo is a of type stack and has been
allocated on the stack. (see rule 1)
I think scope Foo foo = new Foo(); should be probably be deprecated.
(which I hinted at in the class definition section)
> The proposal sound reasonable, but it's hard to follow. I really can't
> comment on it because I didn't fully understand it.
>
> Many of my coworkers are preparing for an upcoming Game Developers
> Conference (КРИ, Russia) and we listen to the their talks everyday, spot
> errors, make some suggestions etc. And almost everyone does the same
> mistake: they explain solution without explaining a problem. It is very
> important but *really* hard to understand *why* you do something when
> you don't know what's a problem is.
>
> I believe your proposal suffers from it, too. For example, when reading
> an introduction, I see this:
>
>> ┌──────────────┐
>> │ Overview │
>> ├──────────────┼─────────────────┬─────────────┬──────────────┐
>> │ Hierarchy │ Description │ Ownership │ Transitivity │
>> ├──────────────┼─────────────────┼─────────────┼──────────────┤
>> │ scope │ super-interface │ unknown │ deep† │
>> │ ││└─stack │ current scope │ stack │ implicit │
>> │ │└──local │ object default │ local-heap │ deep† │
>> │ ├───shared │ thread safe │ shared-heap │ deep† │
>> │ └───mobile │ unique objects │ shared-heap │ shallow │
>> └──────────────┴─────────────────┴─────────────┴──────────────┘
>
> You tell that you introduce 5 different qualifiers but you don't explain
> why are they needed. Why not 4, not 3? What problem each of them solve?
> All I can do is guess and be proven wrong, that's the most frustrating.
> Next, you tell about issues:
>
>> •scope(T) in a function body conflicts with scope guard statements.
>> This is a general problem with Walter’s choice of using the scope
>> keyword for this concept. A clean solution is to mandate the use of {}
>> in scope guard statements. Others include using an alternative
>> keyword(auto, final, scope!(exit)), let the ambiguity stand, add a
>> keyword, etc.
>
> Great! You never told that "scope" keyword is used by your proposal.
> Without showing any line of code, it's absolutely worthless to mention
> keyword conflict. Issues belongs to "pros and cons" section at the end
> of your proposal, just before a conclusion.
>
> I also didn't understand a difference between scope and stack - that's
> pretty much all you explained! You gave no example of shared or mobile
> object, how they are used, how ownership passing occurs etc. I expected
> to see a rationale of these qualifiers, but there is no one.
>
> cents += 2;
>
Thanks a lot for the comments. They a really appreciated. I see I need to
go back and do some rewriting.
More information about the Digitalmars-d
mailing list