www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D could really use a true inner-class

reply "Kris" <fu bar.com> writes:
I like nested-classes as they are in D, but we could really use a true
nested-class as well. We /can/ explicitly build an inner class by providing
the ctor with a handle to the host; manually dereferencing host attributes
and so on.

But there's a particular, and common, pattern that begs for the management
to be handled under the covers instead. I'm talking about the 'adapter'
pattern. Implementing parts of an adapter within a hosting class would be
simplified considerably were the compiler to support a true inner-class ~
simply because the adapter-specifics very often (almost always?) address
attributes of the host. Rather than having to manually and explicitly manage
the scope relationship between the hosting & hosted classes, the compiler
should ideally handle that part under the covers. Managing the scope by hand
is tedious and error-prone, but this something that compilers are very good
at.

Note that this notion is currently available for trivial 'Adapters' with
just one method: you use a delegate instead (and the entire notion of an
Adapter is moot). However, that quickly falls apart once you consider
something with a little more complexity ~ more than one method, for example.

Note that nested delegates (and functions) correctly handle the scope issue.
Nested classes do not. This is a request to support the latter as well (in
addition to traditional nested classes).

Further: one can declare an anonymous delegate "in place" as an argument.
Such 'delegate literals' are very, very handy; particularly so in an
event-processing type of environment. That's great, but what happens where
there's more than one callback method involved? This is where an anonymous
class, or anonymous adapter, steps forward. It would be ideal to support
true inner-classes, plus provide the ability to declare them inline too
(just like a function-literal).

Why not pass multiple function-literal arguments to a callee instead? Well,
that precludes the notion of predefined functionality of which only /parts/
are customized in any given usage. This is core to the notion of the Adapter
Pattern. You could kinda' hack something together with an extended suite of
pre-defined delegates ~ but that is not at all extensible (in the class
fashion); nor does it embody encapsulation to any reasonable degree of
understanding. This is one area where the usage of classes can shine. It
would be good to support that fully.

I could use it, extensively, right now. The alternatives are not at all
attractive.
Apr 08 2005
next sibling parent reply Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Kris schrieb am Fri, 8 Apr 2005 22:32:41 -0700:
 I like nested-classes as they are in D, but we could really use a true
 nested-class as well. We /can/ explicitly build an inner class by providing
 the ctor with a handle to the host; manually dereferencing host attributes
 and so on.

 But there's a particular, and common, pattern that begs for the management
 to be handled under the covers instead. I'm talking about the 'adapter'
 pattern. Implementing parts of an adapter within a hosting class would be
 simplified considerably were the compiler to support a true inner-class ~
 simply because the adapter-specifics very often (almost always?) address
 attributes of the host. Rather than having to manually and explicitly manage
 the scope relationship between the hosting & hosted classes, the compiler
 should ideally handle that part under the covers. Managing the scope by hand
 is tedious and error-prone, but this something that compilers are very good
 at.

Suggestion # class A{ # static class B{ # } # class C{ # } # } B is a traditional nested-class - in the D sence. C is a "hosted class". This feature is very usefull and the syntax should be clear - it's the one also used by by Java.
 Note that nested delegates (and functions) correctly handle the scope issue.
 Nested classes do not. This is a request to support the latter as well (in
 addition to traditional nested classes).

<snip>
 I could use it, extensively, right now. The alternatives are not at all
 attractive.

Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCV38V3w+/yD4P9tIRAjRXAJ43nMsh3288O1hEar4faN2w2/ZzcgCcDUES ahjAcLRxMOtnaIeDK6NIBNk= =2lQn -----END PGP SIGNATURE-----
Apr 09 2005
parent reply "Kris" <fu bar.com> writes:
"Thomas Kuehne" <thomas-dloop kuehne.thisisspam.cn> wrote in message
news:lhbki2-a24.ln1 lnews.kuehne.cn...
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Kris schrieb am Fri, 8 Apr 2005 22:32:41 -0700:
 I like nested-classes as they are in D, but we could really use a true
 nested-class as well. We /can/ explicitly build an inner class by


 the ctor with a handle to the host; manually dereferencing host


 and so on.

 But there's a particular, and common, pattern that begs for the


 to be handled under the covers instead. I'm talking about the 'adapter'
 pattern. Implementing parts of an adapter within a hosting class would


 simplified considerably were the compiler to support a true inner-class


 simply because the adapter-specifics very often (almost always?) address
 attributes of the host. Rather than having to manually and explicitly


 the scope relationship between the hosting & hosted classes, the


 should ideally handle that part under the covers. Managing the scope by


 is tedious and error-prone, but this something that compilers are very


 at.

Suggestion # class A{ # static class B{ # } # class C{ # } # } B is a traditional nested-class - in the D sence. C is a "hosted class". This feature is very usefull and the syntax should be clear - it's the one also used by by Java.

Aye. It also happens to be backward compatible.
Apr 09 2005
parent reply "Carlos Santander B." <csantander619 gmail.com> writes:
Kris wrote:
 "Thomas Kuehne" <thomas-dloop kuehne.thisisspam.cn> wrote in message
 news:lhbki2-a24.ln1 lnews.kuehne.cn...
Suggestion
# class A{
#     static class B{
#     }
#     class C{
#     }
# }

B is a traditional nested-class - in the D sence.
C is a "hosted class".

This feature is very usefull and the syntax should be clear - it's the
one also used by by Java.

Aye. It also happens to be backward compatible.

I don't think it is. Like Thomas said, in his proposed syntax B would be a nested class. C right now would be nested, while with his syntax it'd become inner. -- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 09 2005
parent "Kris" <fu bar.com> writes:
Yes, it would be a true inner class. But it's still backward compatible, due
to that earlier bug whereby the hosting class scope used to be visible
anyway. Because of that, the change to a true inner class would be highly
unlikely to cause compile issues (since potential name clashes would have
happened in the past, due to that bug).

That aside, it's the functionality that's important.


 I don't think it is. Like Thomas said, in his proposed syntax B would be
 a nested class. C right now would be nested, while with his syntax it'd
 become inner.

 -- 
 Carlos Santander Bernal

 JP2, you'll always live in our minds

Apr 09 2005
prev sibling next sibling parent reply Brad Anderson <brad dsource.dot.org> writes:
Kris wrote:
 I like nested-classes as they are in D, but we could really use a true
 nested-class as well.

Odd that your '===' and 'is' thread got more attention than this one, which is the more pressing need. :( I wonder how many of the 23 patterns in 'Design Patterns' are currently possible in D... BA
Apr 10 2005
parent "Kris" <fu bar.com> writes:
"Brad Anderson" <brad dsource.dot.org> wrote in message
 Kris wrote:
 I like nested-classes as they are in D, but we could really use a true
 nested-class as well.

Odd that your '===' and 'is' thread got more attention than this one, which is the more pressing need. :(

Perhaps GW's post on the "= = =" and "is" thread is relevant here, too? I think that's perhaps a reflection on what people are currently doing with D. The adapter pattern ~ and relatives ~ which can really leverage true-inner-classes, seem to be something of an oddity here; based upon the lack of strong ongoing support for such a feature. Not to say such patterns are unimportant, because they most certainly are important. It's just that without libraries that expose functionality in this manner, very few will be clamouring to get it implemented. Classic chicken and egg scenario. If D had a true inner-class, I'd be wringing the last drops out of them for specific design situations where a single-callback is simply too weak, and exposing that as a means of library usage for said scenarios. An advanced listener framework, for example, can profit generously via such patterns. As was noted previously, manually hooking & scoping a nested-class to be a true inner-class is entirely possible right now. But in practice, it's far more painful for the end-user than it ought to be; and I really don't wish to start exposing that kind of approach at this time. In other words, I'm fine with the current situation for my own work, but I balk at exposing such patterns to library *users* without better compiler support (chicken and egg ~ reprised). Anonymous class literals, aka uber-function-literals, are part and parcel of the same vessel, thought perhaps slightly less essential. I do have a very practical application of all this in mind ~ referenced vaguely in that other thread ~ which is currently stalled due to these concerns.
 I wonder how many of the 23 patterns in 'Design Patterns' are currently
 possible in D...

I would imagine rather a lot; perhaps all? Can't imagine they'd all be as straightforward as they might, though. There's a whole lot to be said for simplicity of use, and this is one potent arena (Patterns) that's had comparatively scant attention in D. Almost zero attention, apparently. Perhaps the fact this is coming up now can be attributed to D slowly arriving at a stage of real utility? Has perhaps matured past the stage of how to best implement booleans? If so, that can only be a good thing. How about it? What does it take to get better support for Patterns? True inner-classes are one powerful and convenient thing the compiler can help out with. What else?
Apr 10 2005
prev sibling parent "Regan Heath" <regan netwin.co.nz> writes:
On Fri, 8 Apr 2005 22:32:41 -0700, Kris <fu bar.com> wrote:
 I like nested-classes as they are in D, but we could really use a true
 nested-class as well. We /can/ explicitly build an inner class by  
 providing
 the ctor with a handle to the host; manually dereferencing host  
 attributes
 and so on.

 But there's a particular, and common, pattern that begs for the  
 management
 to be handled under the covers instead. I'm talking about the 'adapter'
 pattern. Implementing parts of an adapter within a hosting class would be
 simplified considerably were the compiler to support a true inner-class ~
 simply because the adapter-specifics very often (almost always?) address
 attributes of the host. Rather than having to manually and explicitly  
 manage
 the scope relationship between the hosting & hosted classes, the compiler
 should ideally handle that part under the covers. Managing the scope by  
 hand
 is tedious and error-prone, but this something that compilers are very  
 good
 at.

 Note that this notion is currently available for trivial 'Adapters' with
 just one method: you use a delegate instead (and the entire notion of an
 Adapter is moot). However, that quickly falls apart once you consider
 something with a little more complexity ~ more than one method, for  
 example.

 Note that nested delegates (and functions) correctly handle the scope  
 issue.
 Nested classes do not. This is a request to support the latter as well  
 (in
 addition to traditional nested classes).

 Further: one can declare an anonymous delegate "in place" as an argument.
 Such 'delegate literals' are very, very handy; particularly so in an
 event-processing type of environment. That's great, but what happens  
 where
 there's more than one callback method involved? This is where an  
 anonymous
 class, or anonymous adapter, steps forward. It would be ideal to support
 true inner-classes, plus provide the ability to declare them inline too
 (just like a function-literal).

 Why not pass multiple function-literal arguments to a callee instead?  
 Well,
 that precludes the notion of predefined functionality of which only  
 /parts/
 are customized in any given usage. This is core to the notion of the  
 Adapter
 Pattern. You could kinda' hack something together with an extended suite  
 of
 pre-defined delegates ~ but that is not at all extensible (in the class
 fashion); nor does it embody encapsulation to any reasonable degree of
 understanding. This is one area where the usage of classes can shine. It
 would be good to support that fully.

 I could use it, extensively, right now. The alternatives are not at all
 attractive.

If you have the time/patience can you explain the (give an example) problem adapters solve. Pretend I know nothing about adapters and where you'd use them (and you'd be pretty close to them truth). From the paragraph above I'm imagining it's a collection of delegates/functions that perform some task when coupled with another object, eg. POP3Adapter, IMAPAdapter coupled with Socket where the user code simply calls a login method and depending on the adpater chosen it does a POP3 or IMAP login via the Socket. Regan
Apr 10 2005