Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 10, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
On Thu, Jul 10, 2014 at 01:56:39PM +0200, Jacob Carlborg via Digitalmars-d wrote: > On 10/07/14 01:57, H. S. Teoh via Digitalmars-d wrote: > > >[...] > >I'm sure there are plenty of holes in this proposal, so destroy away. > >;-) > > You should post this in a new thread. Done. > I'm wondering if a lot more data can be statically allocated. Then passed by reference to functions taking scope parameters. This should be safe since the parameter is guaranteed to outlive the function call. Yep. In whatever shape or form we finally implement 'scope', it would allow us to address such issues. On Thu, Jul 10, 2014 at 01:26:54PM +0000, Wyatt via Digitalmars-d wrote: > On Wednesday, 9 July 2014 at 23:58:39 UTC, H. S. Teoh via Digitalmars-d wrote: > > > >So here's a first stab at refining (and extending) what 'scope' > >should be: > > > In general, I like it, but can scopedness be inferred? The impression I get from this is we're supposed to manually annotate every scoped everything, which IMO kind of moots the benefits in a broad sense. I think in some cases it can be inferred. For example, taking the address of a local variable should return an appropriately-scoped pointer type, so that the type system can statically verify that it doesn't leak past the variable's lifetime: int* myFunc(int* q) { int x; auto ptr = &x; // typeof(ptr) == scoped(int*) with lifetime == x.lifetime if (cond) return q; // OK, q has infinite lifetime else return ptr; // compile error: cannot convert scoped(int*) to int* } There is an interesting subtlety here, in that local variables themselves are not necessarily scoped, for example: class C {} C createObj() { auto obj = new C; // obj is a local variable return obj; // but its lifetime can be extended outside the function } Yet addresses of local variables are scoped: class C {} C* createObj() { auto obj = new C; return &obj; // INVALID: this would allow the caller // to access a local variable that's // gone out of scope } This leads to some further complications, for example: class C { C* getRef() { return &this; } } C* func(scope C obj) { // In here, obj's lifetime is the body of func // But this violates obj's lifetime: return obj.getRef(); } The problem is, how do we statically prevent this sort of abuse? since the definition of C.getRef may not know anything about func, and so can't possibly return a type whose lifetime is restricted to func, yet that's what's needed to prevent the invalid return of obj.getRef's value outside func. > If it _cannot_ be inferred (even if imperfectly), then I wonder if it doesn't make more sense to invert the proposed default and require annotation when scope restrictions need to be eased. The way I see it, scope is really a way for a function to state that it won't keep a persistent reference to the scoped parameter, and so it's OK to pass in, say, a reference to a temporary that will disappear after the function returns. Defaulting to scope will cause far too much breakage, I think, esp. given that code like the following is probably common in the wild: class C {} C myFunc(C obj) { obj.doSomething(); return obj; // will be rejected if parameters are scoped by default } T -- One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie. -- The Silicon Valley Tarot |
July 11, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 10/07/14 20:15, H. S. Teoh via Digitalmars-d wrote: > class C {} > C myFunc(C obj) { > obj.doSomething(); > return obj; // will be rejected if parameters are scoped by default > } Hmm, why wouldn't that work? The scope where you called "myFunc" is guaranteed to outlive "myFunc". -- /Jacob Carlborg |
July 11, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Fri, Jul 11, 2014 at 08:56:10AM +0200, Jacob Carlborg via Digitalmars-d wrote: > On 10/07/14 20:15, H. S. Teoh via Digitalmars-d wrote: > > > class C {} > > C myFunc(C obj) { > > obj.doSomething(); > > return obj; // will be rejected if parameters are scoped by default > > } > > Hmm, why wouldn't that work? The scope where you called "myFunc" is guaranteed to outlive "myFunc". [...] Because the scope of the parameter 'obj' is defined to be the scope of myFunc only, according to the current proposal. T -- What are you when you run out of Monet? Baroque. |
July 13, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2014-07-11 16:29, H. S. Teoh via Digitalmars-d wrote: > Because the scope of the parameter 'obj' is defined to be the scope of > myFunc only, according to the current proposal. Wouldn't it be possible to define the scope of a parameter to the caller's scope? -- /Jacob Carlborg |
July 13, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Sun, Jul 13, 2014 at 12:07:58PM +0200, Jacob Carlborg via Digitalmars-d wrote: > On 2014-07-11 16:29, H. S. Teoh via Digitalmars-d wrote: > > >Because the scope of the parameter 'obj' is defined to be the scope of myFunc only, according to the current proposal. > > Wouldn't it be possible to define the scope of a parameter to the caller's scope? [...] We could, but how would that help static analysis within the function's body, since the caller's scope is unknown? T -- Truth, Sir, is a cow which will give [skeptics] no more milk, and so they are gone to milk the bull. -- Sam. Johnson |
July 14, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 13/07/14 16:37, H. S. Teoh via Digitalmars-d wrote: > We could, but how would that help static analysis within the function's > body, since the caller's scope is unknown? Won't the caller's scope always outlive the callee's? -- /Jacob Carlborg |
July 14, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Mon, Jul 14, 2014 at 10:41:10AM +0200, Jacob Carlborg via Digitalmars-d wrote: > On 13/07/14 16:37, H. S. Teoh via Digitalmars-d wrote: > > >We could, but how would that help static analysis within the function's body, since the caller's scope is unknown? > > Won't the caller's scope always outlive the callee's? [...] Yes, but since the extent of this scope is unknown from inside the function body, it doesn't easily lend itself nicely to check things like this: int* ptr; void func(scope int* arg) { ptr = arg; // should this be allowed? } If we only know that 'arg' has a longer lifetime than func, but we don't know how long it is, then we don't know if it has the same lifetime as 'ptr', or less. So it doesn't really let us do useful checks. T -- "I suspect the best way to deal with procrastination is to put off the procrastination itself until later. I've been meaning to try this, but haven't gotten around to it yet. " -- swr |
July 15, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 15/07/14 01:48, H. S. Teoh via Digitalmars-d wrote: > Yes, but since the extent of this scope is unknown from inside the > function body, it doesn't easily lend itself nicely to check things like > this: > > int* ptr; > void func(scope int* arg) { > ptr = arg; // should this be allowed? > } > > If we only know that 'arg' has a longer lifetime than func, but we don't > know how long it is, then we don't know if it has the same lifetime as > 'ptr', or less. So it doesn't really let us do useful checks. I was thinking that "arg" would have at least the same lifetime as the caller, i.e. the same as "ptr". -- /Jacob Carlborg |
July 15, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Tue, Jul 15, 2014 at 09:19:34AM +0200, Jacob Carlborg via Digitalmars-d wrote: > On 15/07/14 01:48, H. S. Teoh via Digitalmars-d wrote: > > >Yes, but since the extent of this scope is unknown from inside the function body, it doesn't easily lend itself nicely to check things like this: > > > > int* ptr; > > void func(scope int* arg) { > > ptr = arg; // should this be allowed? > > } > > > >If we only know that 'arg' has a longer lifetime than func, but we don't know how long it is, then we don't know if it has the same lifetime as 'ptr', or less. So it doesn't really let us do useful checks. > > I was thinking that "arg" would have at least the same lifetime as the caller, i.e. the same as "ptr". [...] But what if 'ptr' is declared in a private binary-only module, and only the signature of 'func' is known? Then what should 'scope' mean to the compiler when 'func' is being called from another module? T -- ASCII stupid question, getty stupid ANSI. |
July 15, 2014 Re: Proposal for design of 'scope' (Was: Re: Opportunities for D) | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2014-07-15 16:58, H. S. Teoh via Digitalmars-d wrote: > But what if 'ptr' is declared in a private binary-only module, and only > the signature of 'func' is known? Then what should 'scope' mean to the > compiler when 'func' is being called from another module? Hmm, I didn't think of that :( -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation