digitalmars.D - "The last feature": scope structs
- Andrei Alexandrescu (29/29) Feb 07 2010 Following work on typechecking synchronized methods, Walter and I were
- Lars T. Kyllingstad (17/51) Feb 08 2010 Though the feature seems useful, I worry about the asymmetry with scope
- Walter Bright (4/7) Feb 08 2010 I agree, except I more and more think that scope classes were a mistake....
- Jacob Carlborg (6/14) Feb 08 2010 Scope class seems like a workaround in D1 because it doesn't got structs...
- Kagamin (2/10) Feb 08 2010 stack allocs will be quite a hack...
- Andrei Alexandrescu (3/33) Feb 08 2010 Scope classes will be eliminated from the language.
- bearophile (4/5) Feb 08 2010 Isn't it better to remove scope classes after a good escape analysis is ...
- Walter Bright (3/8) Feb 13 2010 Escape analysis can still be used to put class instantiations on the
- Leandro Lucarella (8/18) Feb 13 2010 LDC already have some heuristics for that:
- dsimcha (8/16) Feb 13 2010 But the compiler has to be relatively conservative about this, whereas t...
- bearophile (4/5) Feb 14 2010 How can this be done? Is it possible to take any class and instantiate i...
- dsimcha (39/44) Feb 14 2010 placement new inside another class instance? I'd like to see a bit of th...
- bearophile (5/7) Feb 14 2010 Thank you for your code, I'll try it.
- Michel Fortin (31/65) Feb 08 2010 Are you saying by "you can take addresses of its member" that it's up
- Ary Borenszweig (2/38) Feb 08 2010 Why is this useful?
- Walter Bright (6/7) Feb 13 2010 Many optimizations are possible if it can be unambiguously determined
Following work on typechecking synchronized methods, Walter and I were discussing about managing escaping references to objects that wouldn't actually agree to escaping. The problem is that today a value has no idea that its address is being taken, so it has no saying in that. To compensate for that, my idea was to allow disable on opUnary!"&". Walter suggested allowing "scope" as a property of a struct: scope struct Transitory { ... } A scope struct cannot have its address taken. You can take addresses of its members (access permitting), but you can't take the address of any other struct that has at least one scope struct as a direct member. For example: struct A { int x; Transitory tr; } A will also be scope. So scope has this funny way of propagating outwards, as opposed to qualifiers, which propagate inwards. This is as much as we have in terms of a design right now, so definitely it stands some more fleshing out. If gotten right, scope should allow defining a number of useful idioms, such as pass-down values, unique/lent objects, and the such. Working against escapes has long been a problem, and with scope we're hoping to strike a balance between useful and simple. Please share any thoughts you might have. Andrei
Feb 07 2010
Andrei Alexandrescu wrote:Following work on typechecking synchronized methods, Walter and I were discussing about managing escaping references to objects that wouldn't actually agree to escaping. The problem is that today a value has no idea that its address is being taken, so it has no saying in that. To compensate for that, my idea was to allow disable on opUnary!"&". Walter suggested allowing "scope" as a property of a struct: scope struct Transitory { ... } A scope struct cannot have its address taken. You can take addresses of its members (access permitting), but you can't take the address of any other struct that has at least one scope struct as a direct member. For example: struct A { int x; Transitory tr; } A will also be scope. So scope has this funny way of propagating outwards, as opposed to qualifiers, which propagate inwards.Though the feature seems useful, I worry about the asymmetry with scope classes. I think it will be very confusing to new D programmers that a scope class and a scope struct have very little to do with each other. - You can't have globals, statics, fields, or enums that are scope classes, but it seems they can be scope structs. (Hence, there can be no outward propagation of the scope class qualifier either.) - You can't take the address of a scope struct, but you can take the address of a scope class reference. - A scope class variable must be declared with scope, but your example indicates that that's not the idea for scope structs.This is as much as we have in terms of a design right now, so definitely it stands some more fleshing out. If gotten right, scope should allow defining a number of useful idioms, such as pass-down values, unique/lent objects, and the such.What are pass-down values? (Yes, I've tried searching for it.)Working against escapes has long been a problem, and with scope we're hoping to strike a balance between useful and simple. Please share any thoughts you might have.In brief: I like the idea, but I like the ' disable opUnary!"&"' suggestion better than 'scope struct'. -Lars
Feb 08 2010
Lars T. Kyllingstad wrote:Though the feature seems useful, I worry about the asymmetry with scope classes. I think it will be very confusing to new D programmers that a scope class and a scope struct have very little to do with each other.I agree, except I more and more think that scope classes were a mistake. Structs with destructors are a much better solution, and wrapping a class inside a struct would give it RAII semantics.
Feb 08 2010
On 2/8/10 11:05, Walter Bright wrote:Lars T. Kyllingstad wrote:Scope class seems like a workaround in D1 because it doesn't got structs with constructors and destructors. If scope classes are up for removal shouldn't struct constructors be fixed to allow to do the same as class constructors? For example, allow empty parameter lists. /Jacob CarlborgThough the feature seems useful, I worry about the asymmetry with scope classes. I think it will be very confusing to new D programmers that a scope class and a scope struct have very little to do with each other.I agree, except I more and more think that scope classes were a mistake. Structs with destructors are a much better solution, and wrapping a class inside a struct would give it RAII semantics.
Feb 08 2010
Walter Bright Wrote:Lars T. Kyllingstad wrote:stack allocs will be quite a hack...Though the feature seems useful, I worry about the asymmetry with scope classes. I think it will be very confusing to new D programmers that a scope class and a scope struct have very little to do with each other.I agree, except I more and more think that scope classes were a mistake. Structs with destructors are a much better solution, and wrapping a class inside a struct would give it RAII semantics.
Feb 08 2010
Lars T. Kyllingstad wrote:Andrei Alexandrescu wrote:Scope classes will be eliminated from the language. AndreiFollowing work on typechecking synchronized methods, Walter and I were discussing about managing escaping references to objects that wouldn't actually agree to escaping. The problem is that today a value has no idea that its address is being taken, so it has no saying in that. To compensate for that, my idea was to allow disable on opUnary!"&". Walter suggested allowing "scope" as a property of a struct: scope struct Transitory { ... } A scope struct cannot have its address taken. You can take addresses of its members (access permitting), but you can't take the address of any other struct that has at least one scope struct as a direct member. For example: struct A { int x; Transitory tr; } A will also be scope. So scope has this funny way of propagating outwards, as opposed to qualifiers, which propagate inwards.Though the feature seems useful, I worry about the asymmetry with scope classes.
Feb 08 2010
Andrei Alexandrescu:Scope classes will be eliminated from the language.Isn't it better to remove scope classes after a good escape analysis is implemented in the front-end? Bye, bearophile
Feb 08 2010
bearophile wrote:Andrei Alexandrescu:Escape analysis can still be used to put class instantiations on the stack - it's just that that will be a compiler optimization, not a user one.Scope classes will be eliminated from the language.Isn't it better to remove scope classes after a good escape analysis is implemented in the front-end?
Feb 13 2010
Walter Bright, el 13 de febrero a las 19:13 me escribiste:bearophile wrote:LDC already have some heuristics for that: http://www.dsource.org/projects/ldc/browser/gen/passes/GarbageCollect2Stack.cpp -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ ---------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ----------------------------------------------------------------------Andrei Alexandrescu:Escape analysis can still be used to put class instantiations on the stack - it's just that that will be a compiler optimization, not a user one.Scope classes will be eliminated from the language.Isn't it better to remove scope classes after a good escape analysis is implemented in the front-end?
Feb 13 2010
== Quote from Walter Bright (newshound1 digitalmars.com)'s articlebearophile wrote:But the compiler has to be relatively conservative about this, whereas the user can take advantage of knowing how his/her program works at a high level. That said, I'm in favor of removing scope classes from the core language because their RAII purpose has been taken over by structs and their optimization purpose should be fulfilled via an uglier, more dangerous looking and more general library construct. Such a library construct should also allow strong class instances inline in other class instances.Andrei Alexandrescu:Escape analysis can still be used to put class instantiations on the stack - it's just that that will be a compiler optimization, not a user one.Scope classes will be eliminated from the language.Isn't it better to remove scope classes after a good escape analysis is implemented in the front-end?
Feb 13 2010
dsimcha:Such a library construct should also allow strong class instances inline in other class instances.<How can this be done? Is it possible to take any class and instantiate it with a placement new inside another class instance? I'd like to see a bit of the implementation code. Thank you, bye, bearophile
Feb 14 2010
== Quote from bearophile (bearophileHUGS lycos.com)'s articledsimcha:other class instances.<Such a library construct should also allow strong class instances inline inHow can this be done? Is it possible to take any class and instantiate it with aplacement new inside another class instance? I'd like to see a bit of the implementation code.Thank you, bye, bearophileHere's a quick and dirty implementation. I haven't thought about how to work out all the details yet: 1. If the class contains immutable members, this implementation allows for overwriting immutable data. 2. I don't know how to give the struct proper type information so that the GC won't scan it if it doesn't contain any pointers. Right now I'm using void[], which needs to always be conservatively scanned. 3. The way I handled c'tors isn't going to work with ref parameters, etc. import std.stdio; struct InlineClass(C) { enum instanceSize = __traits(classInstanceSize, C); void[instanceSize] space = void; this(T...)(T args) { space[] = typeid(C).init[]; instance.__ctor(args); } C instance() { return cast(C) cast(void*) &this; } alias instance this; } class Foo { uint n; this(uint startVal) { n = startVal; } void printN() { writeln("Called printN for the ", n++, "th time."); } } void main() { auto foo = InlineClass!Foo(5); foo.printN(); foo.printN(); }
Feb 14 2010
dsimcha:Here's a quick and dirty implementation. I haven't thought about how to work out all the details yet:Thank you for your code, I'll try it. If some of the problems you talk about can't be currently solved, then I think D2 has to be improved/modified to allow all those problems to be fully solved :-) I think it's important to create a flexible language. That's why I have asked for some code here. If the language can't be modified enough to solve all those problems, then it's better to not remove (yet) the scope classes from D2 (the same is true for foreach_reverse). Bye, bearophile
Feb 14 2010
On 2010-02-08 00:27:29 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Following work on typechecking synchronized methods, Walter and I were discussing about managing escaping references to objects that wouldn't actually agree to escaping. The problem is that today a value has no idea that its address is being taken, so it has no saying in that. To compensate for that, my idea was to allow disable on opUnary!"&". Walter suggested allowing "scope" as a property of a struct: scope struct Transitory { ... } A scope struct cannot have its address taken. You can take addresses of its members (access permitting), but you can't take the address of any other struct that has at least one scope struct as a direct member. For example:Are you saying by "you can take addresses of its member" that it's up to the struct implementation to not leak the address of a member? (by making members private and propagating access only through proxy scope structs?) I'd say that it looks useful, but it can't do much by itself. That's just one piece of the puzzle and without other pieces it won't go very far. Consider this: scope struct Transitory(O) { private O o; this(string s) { o = new O(s); } string toString() { return o.toString(); } } Transitory!MyObject t = Transitory!MyObject("hello"); t.toString(); This code has two issues: 1. MyObject's constructor could leak a reference. 2. MyObject's toString could leak a reference. Do we need a "scope class" for this to work?A scope struct cannot have its address taken. You can take addresses of its members (access permitting), but you can't take the address of any other struct that has at least one scope struct as a direct member. For example: struct A { int x; Transitory tr; } A will also be scope. So scope has this funny way of propagating outwards, as opposed to qualifiers, which propagate inwards.I'm not sure why you need that. If Transitory is scope, then you can't take tr's address. Taking the address of A doesn't give you the address of tr (in reality it might be the same address, but it'll be typed as A and won't allow you to get the address of tr anyway). So why does A need to be scope?This is as much as we have in terms of a design right now, so definitely it stands some more fleshing out. If gotten right, scope should allow defining a number of useful idioms, such as pass-down values, unique/lent objects, and the such.That'd be really great. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 08 2010
Andrei Alexandrescu wrote:Following work on typechecking synchronized methods, Walter and I were discussing about managing escaping references to objects that wouldn't actually agree to escaping. The problem is that today a value has no idea that its address is being taken, so it has no saying in that. To compensate for that, my idea was to allow disable on opUnary!"&". Walter suggested allowing "scope" as a property of a struct: scope struct Transitory { ... } A scope struct cannot have its address taken. You can take addresses of its members (access permitting), but you can't take the address of any other struct that has at least one scope struct as a direct member. For example: struct A { int x; Transitory tr; } A will also be scope. So scope has this funny way of propagating outwards, as opposed to qualifiers, which propagate inwards. This is as much as we have in terms of a design right now, so definitely it stands some more fleshing out. If gotten right, scope should allow defining a number of useful idioms, such as pass-down values, unique/lent objects, and the such. Working against escapes has long been a problem, and with scope we're hoping to strike a balance between useful and simple. Please share any thoughts you might have.Why is this useful?
Feb 08 2010
Ary Borenszweig wrote:Why is this useful?Many optimizations are possible if it can be unambiguously determined that an object's lifetime cannot exceed the lifetime of the function it is instantiated in. By preventing taking the address of it, there's no way to escape a reference to it.
Feb 13 2010