digitalmars.D - Static attributes & immutability, static attributes seen from instances
- bearophile (15/15) Mar 05 2010 This was a discussion I've started in the digitalmars.D.learn newsgroup,...
- Walter Bright (3/18) Mar 05 2010 I think that's unworkable, as static variables cannot immutable in one
- bearophile (5/7) Mar 06 2010 If you want you can express your opinion about the second part of the po...
- Nick Sabalausky (5/30) Mar 05 2010 I've always felt that the ability to access static members through an
- Nick Sabalausky (13/26) Mar 05 2010 The one possible exception I can think of (and I'm not even sure if it's...
- Simen kjaeraas (7/14) Mar 06 2010 They can't. So the only reason for static members to be available from a...
- Lutger (3/6) Mar 06 2010 I agree, some compilers issue warnings in this case.
- Jonathan M Davis (6/14) Mar 06 2010 Warnings? Why allow it at all? I'm not aware of anything that you really...
- bearophile (5/9) Mar 06 2010 Walter has not commented about this topic yet.
- Michal Minich (22/26) Mar 06 2010 I think that calling static members through an instance should be
- Adam D. Ruppe (14/19) Mar 06 2010 I'd really like for opCall to be separated out, so you can initialize
- Michal Minich (4/23) Mar 06 2010 I never used opAssign, but doesn't it solves this problem? Considering
- Adam D. Ruppe (48/51) Mar 06 2010 opAssign only worked after the struct has been initialized.
- yigal chripun (12/45) Mar 08 2010 In dynamic languages like Ruby, instances carry a pointer to their class...
This was a discussion I've started in the digitalmars.D.learn newsgroup, but div0 has suggested to move it here for a more general public. This is a reduced version of a D2 program, written while I was trying to use/learn immutability. This program compiles: struct Foo { static int x; } void main() { immutable Foo f; Foo.x++; f.x++; } My idea was that immutable applied to a struct makes every thing in such struct namespace immutable. I was wrong, but what do you think about changing a little how D works here? A possible idea is: if one instance is 'const', then the static attribute x is seen as const from just that instance. If one instance is set to 'immutable' as here, then the static attributes become immutable in every instance of Foo. A bit later in the discussion div0 and Pelle M. have said/suggested that accessing static vars through an instance can be a bad thing, and it's better to allow the programmer to access them only through the class/struct name. Bye, bearophile
Mar 05 2010
bearophile wrote:This is a reduced version of a D2 program, written while I was trying to use/learn immutability. This program compiles: struct Foo { static int x; } void main() { immutable Foo f; Foo.x++; f.x++; } My idea was that immutable applied to a struct makes every thing in such struct namespace immutable. I was wrong, but what do you think about changing a little how D works here? A possible idea is: if one instance is 'const', then the static attribute x is seen as const from just that instance. If one instance is set to 'immutable' as here, then the static attributes become immutable in every instance of Foo.I think that's unworkable, as static variables cannot immutable in one instance and mutable in another.
Mar 05 2010
Walter Bright:I think that's unworkable, as static variables cannot immutable in one instance and mutable in another.If you want you can express your opinion about the second part of the post too. Some people (I think 4 so far) more or less want to disallow the access of static fields from an instance. Generally in my D/Python code I prefer to access static field using the class/struct name, to reduce possible confusion. Bye, bearophile
Mar 06 2010
"bearophile" <bearophileHUGS lycos.com> wrote in message news:hmrtbk$1aoi$1 digitalmars.com...This was a discussion I've started in the digitalmars.D.learn newsgroup, but div0 has suggested to move it here for a more general public. This is a reduced version of a D2 program, written while I was trying to use/learn immutability. This program compiles: struct Foo { static int x; } void main() { immutable Foo f; Foo.x++; f.x++; } My idea was that immutable applied to a struct makes every thing in such struct namespace immutable. I was wrong, but what do you think about changing a little how D works here? A possible idea is: if one instance is 'const', then the static attribute x is seen as const from just that instance. If one instance is set to 'immutable' as here, then the static attributes become immutable in every instance of Foo. A bit later in the discussion div0 and Pelle M. have said/suggested that accessing static vars through an instance can be a bad thing, and it's better to allow the programmer to access them only through the class/struct name. Bye, bearophileI've always felt that the ability to access static members through an instance was just a bad idea in general, and this seems to add another reason not to allow it.
Mar 05 2010
"Nick Sabalausky" <a a.a> wrote in message news:hmsqdk$9ud$1 digitalmars.com..."bearophile" <bearophileHUGS lycos.com> wrote in message news:hmrtbk$1aoi$1 digitalmars.com...The one possible exception I can think of (and I'm not even sure if it's applicable to D or not) is if you're passed an instance of something and want to call a static member of it polymorphically. Without polymorphism you can just do "typeof(instance).staticFunc()", but I'm not sure offhand whether or not there's a way to do that polymorphically (or if static members can even be polymorphic). However, I think that if people are calling static members through instances instead of types just to make the call polymorphic, then I'd consider that less of a reason to allow "instance.staticMember" and more of a reason to have some sort of polymorphic runtime equivilent to typeof() (Do we currently have such a thing that can suffice?).A bit later in the discussion div0 and Pelle M. have said/suggested that accessing static vars through an instance can be a bad thing, and it's better to allow the programmer to access them only through the class/struct name. Bye, bearophileI've always felt that the ability to access static members through an instance was just a bad idea in general, and this seems to add another reason not to allow it.
Mar 05 2010
On Sat, 06 Mar 2010 07:33:43 +0100, Nick Sabalausky <a a.a> wrote:The one possible exception I can think of (and I'm not even sure if it's applicable to D or not) is if you're passed an instance of something and want to call a static member of it polymorphically. Without polymorphism you can just do "typeof(instance).staticFunc()", but I'm not sure offhand whether or not there's a way to do that polymorphically (or if static members can even be polymorphic).They can't. So the only reason for static members to be available from an instance is to avoid typeof( T ). The presence of this feature does not bother me, but I feel the right thing would be to axe it. -- Simen
Mar 06 2010
Nick Sabalausky wrote: ...I've always felt that the ability to access static members through an instance was just a bad idea in general, and this seems to add another reason not to allow it.I agree, some compilers issue warnings in this case.
Mar 06 2010
Lutger wrote:Nick Sabalausky wrote: ...Warnings? Why allow it at all? I'm not aware of anything that you really gain by it. It's just confusing for no extra benefit. I have no idea why any language has ever allowed it. Sure, a warning is better than nothing, but it really should be disallowed entirely. - Jonathan M DavisI've always felt that the ability to access static members through an instance was just a bad idea in general, and this seems to add another reason not to allow it.I agree, some compilers issue warnings in this case.
Mar 06 2010
Jonathan M Davis:Warnings? Why allow it at all? I'm not aware of anything that you really gain by it. It's just confusing for no extra benefit. I have no idea why any language has ever allowed it. Sure, a warning is better than nothing, but it really should be disallowed entirely.Walter has not commented about this topic yet. If you want you can file a bug, trying to explain well all pros and cons of this idea (I moderately agree with it, I think it can make D a bit more tidy). Bye, bearophile
Mar 06 2010
On Fri, 05 Mar 2010 16:33:40 -0500, bearophile wrote:A bit later in the discussion div0 and Pelle M. have said/suggested that accessing static vars through an instance can be a bad thing, and it's better to allow the programmer to access them only through the class/struct name.I think that calling static members through an instance should be disallowed. In my opinion this is serious misfeature. It causes semantic un-clearness on usage - As you shown with the example with immutable static member. Here is one with mutable member: consider: struct S { static int s; int i } and usage in some other module: S s1, s2; s1.s += 1; s1.i += 1; now s2.s == 1, s2.i == 0. from usage is not apparent that 's' is a static member, in fact it seems it is instance member. This just makes program less clear. When one is presented with new code base and want to understand it, he must allays check if the member is not static - it should be apparent from usage and compiler should force it. This would allow an additional feature: two "namespaces" in the class/ struct - one for static names and one for instance names, giving ability to "overload" members - i.e. have two opCall in struct - one for type and one for instance. But I cannot think of any example use case of this feature right now.
Mar 06 2010
On Sat, Mar 06, 2010 at 11:33:02AM +0000, Michal Minich wrote:This would allow an additional feature: two "namespaces" in the class/ struct - one for static names and one for instance names, giving ability to "overload" members - i.e. have two opCall in struct - one for type and one for instance. But I cannot think of any example use case of this feature right now.I'd really like for opCall to be separated out, so you can initialize structs from various types and treat it like a function object without hassle. I've tried to do this now, but it keeps calling static opcall when I wanted the other one, and sometimes vice versa. In a perfect world, all three of these would be workable: Variant a = 10; Variant b = { writefln("Hello, world!"); }; b(); But, last time I tried, I could get line 2 or line 3 to work, but not both. Separating static from instance should do the trick. -- Adam D. Ruppe http://arsdnet.net
Mar 06 2010
On Sat, 06 Mar 2010 11:30:45 -0500, Adam D. Ruppe wrote:On Sat, Mar 06, 2010 at 11:33:02AM +0000, Michal Minich wrote:I never used opAssign, but doesn't it solves this problem? Considering that both opCall and opAssign work with "=" their interaction must be probably quite complex...This would allow an additional feature: two "namespaces" in the class/ struct - one for static names and one for instance names, giving ability to "overload" members - i.e. have two opCall in struct - one for type and one for instance. But I cannot think of any example use case of this feature right now.I'd really like for opCall to be separated out, so you can initialize structs from various types and treat it like a function object without hassle. I've tried to do this now, but it keeps calling static opcall when I wanted the other one, and sometimes vice versa. In a perfect world, all three of these would be workable: Variant a = 10; Variant b = { writefln("Hello, world!"); }; b(); But, last time I tried, I could get line 2 or line 3 to work, but not both. Separating static from instance should do the trick.
Mar 06 2010
On Sun, Mar 07, 2010 at 12:36:11AM +0000, Michal Minich wrote:I never used opAssign, but doesn't it solves this problem? Considering that both opCall and opAssign work with "=" their interaction must be probably quite complex...opAssign only worked after the struct has been initialized. === import std.stdio; struct S { /* static S opCall(int a) { S tmp; writefln("opCall(%d);", a); return tmp; } */ S* opAssign(int a) { writefln("opAssign(%d);", a); return &this; } } void main() { S a = 10; // Error: cannot implicitly convert expression (10) of type int to S a = 20; a(30); } === Uncomment the opCall, and it compiles, outputting: opCall(10); opAssign(20); opCall(30); If you add a second opCall that is not static, but otherwise identical, then it fails to compile either the first nor third lines, because: c.d(19): Error: function c.S.opCall called with argument types: ((int)) matches both: c.S.opCall(int a) and: c.S.opCall(int a) c.d(21): Error: function c.S.opCall called with argument types: ((int)) matches both: c.S.opCall(int a) and: c.S.opCall(int a) (one being the static opCall, and the other of course being the instance one). JavascriptObject struct right after opDispatch came out - emulating a delegate and accepting assignment at declaration were mutually incompatible. -- Adam D. Ruppe http://arsdnet.net
Mar 06 2010
Nick Sabalausky Wrote:"Nick Sabalausky" <a a.a> wrote in message news:hmsqdk$9ud$1 digitalmars.com...In dynamic languages like Ruby, instances carry a pointer to their class instance which contains the "static" variables. say we have: class Foo { static int bar = 42; //... } foo = new Foo(); foo.bar is resolved at runtime as e.g. foo.Class.bar where Class is the singelton instance that represents the Foo class itself. if foo is const then D style transitivity would mean that bar must be const as well. regarding immutability, this is imposaible since the Foo singleton is shared between all (mutable and immutable) instances. In this case foo mustn't contain a Class member at all and have no access to it's data in order to keep the transitivity. D has a different implementation but I think the above semantics is what people expect and the implementation differences shouldn't affect the semantics, they should be encapsulated. IMO, the entire const design is backwards and ties toghether two completely separate concerns (immutability for conccurency and const for interface definitions) but there's zero change any of it will ever be changed."bearophile" <bearophileHUGS lycos.com> wrote in message news:hmrtbk$1aoi$1 digitalmars.com...The one possible exception I can think of (and I'm not even sure if it's applicable to D or not) is if you're passed an instance of something and want to call a static member of it polymorphically. Without polymorphism you can just do "typeof(instance).staticFunc()", but I'm not sure offhand whether or not there's a way to do that polymorphically (or if static members can even be polymorphic). However, I think that if people are calling static members through instances instead of types just to make the call polymorphic, then I'd consider that less of a reason to allow "instance.staticMember" and more of a reason to have some sort of polymorphic runtime equivilent to typeof() (Do we currently have such a thing that can suffice?).A bit later in the discussion div0 and Pelle M. have said/suggested that accessing static vars through an instance can be a bad thing, and it's better to allow the programmer to access them only through the class/struct name. Bye, bearophileI've always felt that the ability to access static members through an instance was just a bad idea in general, and this seems to add another reason not to allow it.
Mar 08 2010