On Wed, 29 Apr 2009 04:26:55 -0400, Denis Koroskin <[email protected]>
wrote:
On Tue, 28 Apr 2009 23:06:32 +0400, Robert Jacques <[email protected]>
┌───────┬──────────────┬────────────────────┬─────────────┐
│ 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.