February 18, 2013
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
February 18, 2013
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;
   ....
}

Public is redundant, but code works, and one coming from C++/C# can think that's correct for considerable amount of time because this is what expected based on experience with other languages.
February 18, 2013
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

February 18, 2013
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.

i think hes refering to c# static class
February 18, 2013
Yes, it's comes from C#.

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?
February 20, 2013
On 18/02/2013 21:25, Michael wrote:
> Yes, it's comes from C#.
>
> 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'.
February 21, 2013
> 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.
February 21, 2013
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
February 21, 2013
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
February 21, 2013
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