www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - implicit break of scope / scope-by-default

Hi, wouldn't it make sense to forbid the implicit conversion of
scoped types to non-scoped ?
For example "scope MyClass" should not implicitly be converted to
"MyClass".

------------------------------------------------------------------------
import std.stdio;

class Foo {
	int x,y;
	this(int i, int j) { x = i; y = j; }
}

Foo createFoo(int i, int j) {
	scope Foo foo = new Foo(i, j);
	Foo foo2 = foo;
	return foo2;
}

void main() {
	Foo foo = createFoo(1, 2);
	Foo foo2 = createFoo(3, 4);
	writefln(foo.x, " ", foo.y);
}
------------------------------------------------------------------------
createFoo returns a reference to a destructed instance of type Foo 
(which was the instance, foo was refering to within the function's body).
Output is undefined (ok it's "3 4" but that's luck)
"1 2" would be expected of course.


"Foo foo2 = foo;"
This implicitly breaks the scope type.

typeof(foo) should be "scope Foo" and then
it should give an error:
implicit conversion of type "scope Foo" (foo) to type "Foo" (foo2) not 
allowed


If I try to "return foo" within createFoo, I get (as expected and wanted):
Error: escaping reference to auto local foo

If I use auto foo2 = foo; I would like foo2 to be of type "scope Foo".
When I then would try to return foo2, it should issue the same Error as 
above.



We had the discussion about const by default for parameter types.
Now another -by-default suggestion:
What about making all objects declared within the body of a function 
scope-by-default.
And use a keyword like "global" for objects, from which you intend to 
pass the reference outside of the function's body.
So global means the instance, the object is refering to, will be passed 
to and needed outside of this scope.
"global" removes the "scope" in the typeid for objects within func body.

Example:

Foo createFoo(int i, int j) {
	global Foo foo = new Foo(i, j);
//	Foo foo2 = foo; //Error: can't implicitly convert "Foo" -> "scope Foo"
// what foo refers to can be passed to outside.


//	return foo2; //Error: escaping reference to scope foo
	return foo; //Ok, reference of foo is marked global
}


string appender(in string s, in string what) {
	global string result;
//it's immediately clear, that result will be passed to outside
	result = s ~ what;
	return result;
}
appender("foo", "bla") returns reference to global string "foobla"


void appender(ref string s, in string what) {
//already clear, that the result will be passed into s
	string result;
//don't need global here, because s is in this scope, too.
	result = s ~ what;
	s = result;
//s is like a local scope variable, so both are type "scope string"
}


void* allocate(in size_t nbytes) {
	global void* ptr;
//what ptr points to, will be passed to and needed outside of the func
	ptr = malloc(nbytes);
	return ptr;
}

With scope-by-default, it's clear that no reference/ptr to data created
within the scope is hold outside of it, unless explicitly declared with
global.


I'm interested in your opinions about this.

Daniel
Jul 05 2007