www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static class

reply "Michael" <pr m1xa.com> writes:
Why members of static class are not implicitly static?

static class Test
{
  void foo() {}
}

 Error: need 'this' for foo type void()
Feb 17 2013
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/17/13, Michael <pr m1xa.com> wrote:
 Why members of static class are not implicitly static?

 static class Test
 {
   void foo() {}
 }
That's not the meaning of static in that context. The above is useful in nested classes. Instead you can use: class Test { static: void foo() { } }
Feb 17 2013
parent reply "Michael" <pr m1xa.com> writes:
 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
 The above is useful in nested classes.
I just read it. Holy s.. cow.
 Instead you can use:

 class Test
 {
 static:
     void foo() { }
 }
So in mine case if I want purely static class I need to use: static Test { static void foo(); } right?
Feb 17 2013
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 17 Feb 2013 17:00:19 -0500, Michael <pr m1xa.com> wrote:

 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
Static in that position is a no-op. The compiler (infuriatingly sometimes) accepts attributes that have no meaning silently.
 So in mine case if I want purely static class I need to use:

 static Test
 {
    static void foo();
 }
A class that can't be instantiated has a private constructor. In addition, if you want to make all the functions static, in D you can either put them in a static scope, or use the colon: class Test { private this() {}; // will never be instantiatable static: // all members after this will be static. Could also use static { ... } void foo(); // a static function int x; // a static variable } -Steve
Feb 17 2013
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/17/13, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 A class that can't be instantiated has a private constructor.
An alternative to that is: final abstract class C { static: } You can't derive from it and you can't instantiate it.
Feb 17 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Feb 17, 2013 at 11:46:24PM +0100, Andrej Mitrovic wrote:
 On 2/17/13, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 A class that can't be instantiated has a private constructor.
An alternative to that is: final abstract class C { static: } You can't derive from it and you can't instantiate it.
Nice idiom! This could be D's equivalent to C++ namespaces. ;-) T -- Obviously, some things aren't very obvious.
Feb 17 2013
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, February 17, 2013 23:00:19 Michael wrote:
 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
I have no idea how you came to that conclusion. That's not what it means for a class to be static at all. The only place that static has any effect on classes is for nested classes. A static, nested class is like any other class except that it's inside another class, which affects its path. e.g. module b; class C { static class W { } } W is therefore b.C.W, whereas if it were not nested inside of C but next to it within the same module, then it would be b.W. However, non-static nested classes are associated with an instance of the outer class, and therefore only one can exist per class instance. However, it also has access to that outer class instance through the property outer. e.g. class C { class R { void func() { //Sets the variable in the instance of //C that it's associated with. outer.i = 7; } } int i; } - Jonathan M Davis
Feb 17 2013
next sibling parent reply Ben Davis <entheh cantab.net> writes:
On 17/02/2013 22:25, Jonathan M Davis wrote:
 On Sunday, February 17, 2013 23:00:19 Michael wrote:
 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
I have no idea how you came to that conclusion.
In fairness, it is the natural guess you'd make if you haven't actively used nested instance classes and understood how the outer instance pointer is stored. We use Java at work (same mechanism as D), and hardly anyone actually knows to write 'static' when they create a nested class that they intend to be POD. :)
 That's not what it means for a
 class to be static at all. The only place that static has any effect on classes
 is for nested classes. A static, nested class is like any other class except
 that it's inside another class, which affects its path. e.g.

 module b;

 class C
 {
      static class W
     {
     }
 }

 W is therefore b.C.W, whereas if it were not nested inside of C but next to it
 within the same module, then it would be b.W.

 However, non-static nested classes are associated with an instance of the
 outer class, and therefore only one can exist per class instance.
That's not true, is it? You can make as many nested instances as you like. It's just that there must be some outer instance available at the time of construction (which can be a new one each time or the same one every time or anything in between).
 However, it
 also has access to that outer class instance through the property outer. e.g.

 class C
 {
      class R
      {
          void func()
          {
              //Sets the variable in the instance of
              //C that it's associated with.
              outer.i = 7;
          }
      }

      int i;
 }
Is it possible to write someInstanceOfR.outer? I've occasionally wanted Java to have that feature, and ended up storing the 'outer' reference manually. Though this probably means I was writing bad code; I can't remember. :D
Feb 17 2013
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, February 17, 2013 23:26:37 Ben Davis wrote:
 On 17/02/2013 22:25, Jonathan M Davis wrote:
 However, non-static nested classes are associated with an instance of the
 outer class, and therefore only one can exist per class instance.
That's not true, is it? You can make as many nested instances as you like. It's just that there must be some outer instance available at the time of construction (which can be a new one each time or the same one every time or anything in between).
I stand corrected (I just looked it up again in TDPL). I don't think that I've ever used a non-static inner class in D. I think that used them in Java all of once, but that was quite some time ago, so I don't remember for certain. It's not exactly the most useful feature ever. So, clearly I misremembered.
 Is it possible to write someInstanceOfR.outer? I've occasionally wanted
 Java to have that feature, and ended up storing the 'outer' reference
 manually. Though this probably means I was writing bad code; I can't
 remember. :D
Probably. I don't know. It's not a feature that I ever use. - Jonathan M Davis
Feb 17 2013
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 17 Feb 2013 18:26:37 -0500, Ben Davis <entheh cantab.net> wrote:

 On 17/02/2013 22:25, Jonathan M Davis wrote:
 On Sunday, February 17, 2013 23:00:19 Michael wrote:
 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
I have no idea how you came to that conclusion.
In fairness, it is the natural guess you'd make if you haven't actively used nested instance classes and understood how the outer instance pointer is stored. We use Java at work (same mechanism as D), and hardly anyone actually knows to write 'static' when they create a nested class that they intend to be POD. :)
static class at module level means nothing. It's a noop. static class inside a class means, this class instance does not contain a pointer to it's outer class instance, nor does it have access to the outer class instance's variables (naturally). so: module X; static class A {} is exactly equivalent to class A {}
 You can make as many nested instances as you like.
Yes, as Jonathan indicated, this is possible.
 Is it possible to write someInstanceOfR.outer? I've occasionally wanted  
 Java to have that feature, and ended up storing the 'outer' reference  
 manually. Though this probably means I was writing bad code; I can't  
 remember. :D
I don't know if outer is public or private. Quick test... Yep, you can access it. But I don't know if that is the correct way to do it, or if that is intended. The spec does not consider that possibility. I will note, one VERY annoying thing about outer, is that outer by itself doesn't work inside an inner class' function unless you qualify it with this: class A { int x; class B { void foo() { // outer.x = 5; // Error: undefined identifier outer this.outer.x = 5; // ok } } } -Steve
Feb 17 2013
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Sunday, 17 February 2013 at 22:26:16 UTC, Jonathan M Davis 
wrote:
 On Sunday, February 17, 2013 23:00:19 Michael wrote:
 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
I have no idea how you came to that conclusion. That's not what it means for a class to be static at all. The only place that static has any effect on classes is for nested classes. A static, nested class is like any other class except that it's inside another class, which affects its path. e.g. - Jonathan M Davis
That's not a surprise because dmd allows nonsense attributes. It's also not a surprise that somebody can hit in a such situation and deduce some sence from erroneous syntax construction. I often meet following: public class Foo { public int x; .... } can think that's correct for considerable amount of time because this is what expected based on experience with other languages.
Feb 18 2013
prev sibling next sibling parent Ary Borenszweig <ary esperanto.org.ar> writes:
On 2/17/13 7:25 PM, Jonathan M Davis wrote:
 On Sunday, February 17, 2013 23:00:19 Michael wrote:
 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
I have no idea how you came to that conclusion.
Probably because of this: http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
Feb 18 2013
prev sibling next sibling parent dennis luehring <dl.soluz gmx.net> writes:
Am 17.02.2013 23:25, schrieb Jonathan M Davis:
 On Sunday, February 17, 2013 23:00:19 Michael wrote:
 That's not the meaning of static in that context.
As I understand a static class can't be instantiated.
I have no idea how you came to that conclusion. That's not what it means for a class to be static at all. The only place that static has any effect on classes is for nested classes. A static, nested class is like any other class except that it's inside another class, which affects its path. e.g.
Feb 18 2013
prev sibling parent reply "Michael" <pr m1xa.com> writes:


So, there is no static for classes at module level. Good to have 
a msg for it at compile-time.

import std.stdio;

public final abstract class Test
{
    static this() { writeln("in static ctor"); }
    static :
        void foo() { writeln("in static method"); }
}

void main()
{
    Test.foo();
}
public - adds a little bit of verbosity (ref http://wiki.dlang.org/Access_specifiers_and_visibility). For now is noop. final - adds a no inheritance. abstract - disables non-static ctors. right?
Feb 18 2013
parent reply Ben Davis <entheh cantab.net> writes:
On 18/02/2013 21:25, Michael wrote:


 So, there is no static for classes at module level. Good to have a msg
 for it at compile-time.

 import std.stdio;

 public final abstract class Test
 {
    static this() { writeln("in static ctor"); }
    static :
        void foo() { writeln("in static method"); }
 }

 void main()
 {
    Test.foo();
 }
public - adds a little bit of verbosity (ref http://wiki.dlang.org/Access_specifiers_and_visibility). For now is noop. final - adds a no inheritance. abstract - disables non-static ctors. right?
Technically 'abstract' doesn't disable the ctors; they would still be called by super() if you had a subclass (if you didn't use 'final'). What 'abstract' does is insist that all instances must be of some subtype, not of the class itself. I'm sure you knew that and it's just a wording thing :) Fun fact: in Java, it's an error to combine 'final' and 'abstract'.
Feb 20 2013
parent reply "Michael" <pr m1xa.com> writes:
 I'm sure you knew that and it's just a wording thing :)

 Fun fact: in Java, it's an error to combine 'final' and 
 'abstract'.
Yes. As I understand, in D the "abstract" keyword is some alternative to disable in that case.
Feb 21 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, February 21, 2013 19:52:39 Michael wrote:
 I'm sure you knew that and it's just a wording thing :)
 
 Fun fact: in Java, it's an error to combine 'final' and
 'abstract'.
Yes. As I understand, in D the "abstract" keyword is some alternative to disable in that case.
More like D just doesn't care about mixing abstract and final. They're perfectly compatible on a technical level. abstract means that you can't instantiate it, because some of the function's have been declared but not defined, whereas final means that you can't derive from it (if it's a class), or you can't override it (if it's a function). Those attributes aren't in and of themselves contradictory. They just result in a fairly useless object (aside from whatever static functions you throw on it, in which case, you're basically making a namespace, though it still incurs some overhead, since the class definition still exists). Apparently Java gives you an error if you mix abstract and final, but that's only because it checks for that. D doesn't bother to check, so you get the natural consequence of mixing them. I'm quite sure that the fact that it works that way is an accident. It was never intentially made to be allowed or disallowed. It's just allowed, because there's nothing intrinsic about either of the attributes which makes it illegal, and no effort was made to do prevent it (it probably didn't even occur to Walter that anyone would do it). I'd expect it to continue to work though, since it doesn't really harm anything, and it would break code if it were disallowed. - Jonathan M Davis
Feb 21 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 D doesn't
 bother to check, so you get the natural consequence of mixing 
 them. I'm quite
 sure that the fact that it works that way is an accident. It 
 was never
 intentially made to be allowed or disallowed. It's just 
 allowed, because
 there's nothing intrinsic about either of the attributes which 
 makes it
 illegal, and no effort was made to do prevent it (it probably 
 didn't even occur
 to Walter that anyone would do it). I'd expect it to continue 
 to work though,
 since it doesn't really harm anything,
According the way my brain works, sometimes I find the D compiler unnervingly sloppy.
 and it would break code if it were disallowed.
Uhmm. Bye, bearophile
Feb 21 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, February 22, 2013 00:06:26 bearophile wrote:
 Jonathan M Davis:
 D doesn't
 bother to check, so you get the natural consequence of mixing
 them. I'm quite
 sure that the fact that it works that way is an accident. It
 was never
 intentially made to be allowed or disallowed. It's just
 allowed, because
 there's nothing intrinsic about either of the attributes which
 makes it
 illegal, and no effort was made to do prevent it (it probably
 didn't even occur
 to Walter that anyone would do it). I'd expect it to continue
 to work though,
 since it doesn't really harm anything,
According the way my brain works, sometimes I find the D compiler unnervingly sloppy.
True enough, but in this case, I don't think that it's a problem. The way these parts work together is the logical conclusion of how they work separately. It's the stuff like outright ignoring invalid attributes which tends to be problematic.
 and it would break code if it were disallowed.
Uhmm.
What's the confusion? People have been using the idiom of marking classes as both abstract and final in order to effectively create namespaces. Any code that does that would break if marking a class as both abstract and final were made illegal. IIRC, even a couple parts of Phobos do it (though Andrei and Walter are both generally against the idiom, preferring that free functions be used rather than trying to create namespaces out of other features when namespaces were never meant to be a feature of D). - Jonathan M Davis
Feb 21 2013
parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
On 2/21/13 8:34 PM, Jonathan M Davis wrote:
 On Friday, February 22, 2013 00:06:26 bearophile wrote:
 Jonathan M Davis:
 D doesn't
 bother to check, so you get the natural consequence of mixing
 them. I'm quite
 sure that the fact that it works that way is an accident. It
 was never
 intentially made to be allowed or disallowed. It's just
 allowed, because
 there's nothing intrinsic about either of the attributes which
 makes it
 illegal, and no effort was made to do prevent it (it probably
 didn't even occur
 to Walter that anyone would do it). I'd expect it to continue
 to work though,
 since it doesn't really harm anything,
According the way my brain works, sometimes I find the D compiler unnervingly sloppy.
True enough, but in this case, I don't think that it's a problem.
If the compiler gave you an error if you put "static" on a top-level class definition, this whole thread wouldn't exist. Don't you see that as a problem? People loosing their time answering this questions over and over again instead of the compiler giving you the answer.
Feb 21 2013
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, February 22, 2013 00:59:45 Ary Borenszweig wrote:
 On 2/21/13 8:34 PM, Jonathan M Davis wrote:
 On Friday, February 22, 2013 00:06:26 bearophile wrote:
 Jonathan M Davis:
 D doesn't
 bother to check, so you get the natural consequence of mixing
 them. I'm quite
 sure that the fact that it works that way is an accident. It
 was never
 intentially made to be allowed or disallowed. It's just
 allowed, because
 there's nothing intrinsic about either of the attributes which
 makes it
 illegal, and no effort was made to do prevent it (it probably
 didn't even occur
 to Walter that anyone would do it). I'd expect it to continue
 to work though,
 since it doesn't really harm anything,
According the way my brain works, sometimes I find the D compiler unnervingly sloppy.
True enough, but in this case, I don't think that it's a problem.
If the compiler gave you an error if you put "static" on a top-level class definition, this whole thread wouldn't exist. Don't you see that as a problem? People loosing their time answering this questions over and over again instead of the compiler giving you the answer.
I'm not talking about static. I'm talking about the fact that putting both final and abstract on a class isn't a problem. In general, I do agree that the fact that the compiler doesn't complain about inapplicable attributes is a problem. There are some good arguments with regards to generic programming which make it so that having the compiler complain could be problematic, but I'm not completely convinced that we can't have the compiler complain at least _some_ of the time. And as for static in particular, I doubt that it ever makes sense for it not to be complained about if it's used where it doesn't apply. But Walter doesn't see it as a problem. I suspect that a detailed analysis (possibly even a DIP) would be required to show where it would make sense to make inapplicable attributes illegal and where it wouldn't. Certainly, just complaining about it won't convince Walter. - Jonathan M Davis
Feb 21 2013
parent reply "Michael" <pr m1xa.com> writes:
On Friday, 22 February 2013 at 04:06:09 UTC, Jonathan M Davis 
wrote:
I'm not talking about static. I'm talking about the fact that 
putting both final and abstract on a class isn't a problem.
 - Jonathan M Davis
Initial question for me was how to get something like:
They only contain static members.
They cannot be instantiated.
They are sealed.
They cannot contain Instance Constructors
But topic shows that not only for me and top-level static have unclear state. This topic (and others) will pop-upped many times by newcomers.
Feb 22 2013
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, February 22, 2013 20:39:01 Michael wrote:
 On Friday, 22 February 2013 at 04:06:09 UTC, Jonathan M Davis
 
 wrote:
I'm not talking about static. I'm talking about the fact that
putting both final and abstract on a class isn't a problem.

 - Jonathan M Davis
Initial question for me was how to get something like:
Yes, but Bearophile was commenting on the fact that the compiler doesn't complain when you mark a class as both abstract and final, and that's what I was responding to in that post.
They only contain static members.
They cannot be instantiated.
They are sealed.
They cannot contain Instance Constructors
Marking a class as both abstract and final is the closest that you're going to get.
 But topic shows that not only for me and top-level static have
 unclear state.
Top-level static means nothing on anything. It's a no-op. The fact that inapplicable attributes are frequently ignored does cause some confusion, but there's nothing special about static in that regard.
 This topic (and others) will pop-upped many times by newcomers.
forced to create classes to hold them. D has no such restrictions, making classes like that almost useless. The only value that they really give you is to be able to force a function to be called with its outer "namespace." If you namespace stuff with modules (as is expected in D), then you can call a function without its full import path and therefore without any namespacing (e.g. find instead of std.algorithm.find), whereas if it's on a class, then you can't (e.g. you use Clock.currTime for std.datetime.Clock.currTime and not just currTime), because the class isn't part of the import path. There are a couple of places in Phobos where a class is used like this, but it's generally complained about, and the practice is almost universally shunned. - Jonathan M Davis
Feb 22 2013
parent reply "Michael" <pr m1xa.com> writes:
In D a module can be statically imported and then I can use full 
names.

But question: is it possible to force a static import?
Feb 22 2013
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, February 22, 2013 22:12:44 Michael wrote:
 In D a module can be statically imported and then I can use full
 names.
 
 But question: is it possible to force a static import?
No. - Jonathan M Davis
Feb 22 2013
prev sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/22/13, Ary Borenszweig <ary esperanto.org.ar> wrote:
 Don't you see that as a problem? People loosing their time answering
 this questions over and over again instead of the compiler giving you
 the answer.
They're losing their time if they expect D to act as another language. Anyway an annoying compiler complaining about static is worse than having the occasional question being asked in the newsgroups.
Feb 22 2013
parent "Michael" <pr m1xa.com> writes:
It's natural and would be good if something will be stated in 
documentation about static at top-level.

"static" is well known feature. Yes it can act differently in 
diff languages.

 They're losing their time if they expect D to act as another 
 language.
With this point of view to user, only D will lose.
Feb 22 2013
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, February 17, 2013 14:47:12 H. S. Teoh wrote:
 On Sun, Feb 17, 2013 at 11:46:24PM +0100, Andrej Mitrovic wrote:
 On 2/17/13, Steven Schveighoffer <schveiguy yahoo.com> wrote:
 A class that can't be instantiated has a private constructor.
An alternative to that is: final abstract class C { static: } You can't derive from it and you can't instantiate it.
Nice idiom! This could be D's equivalent to C++ namespaces. ;-)
It's the closest that we've got, and Phobos uses it in a couple of places (like std.datetime.Clock), but it gets complained about quite a bit every time it comes up (particularly with regards to std.datetime.Clock). So, while it's useful upon occasion and some people like it, it's generally shunned. For the most part, it's considered better to just declare a free function and be done with it. - Jonathan M Davis
Feb 17 2013