Partial classes

Walter Bright newshound2 at digitalmars.com
Mon Jun 25 16:43:43 PDT 2012


On 6/25/2012 2:26 PM, Manu wrote:
> On 25 June 2012 23:30, Walter Bright <newshound2 at digitalmars.com
>     Are you talking about adding fields/functions to an arbitrary class without
>     modifying the original definition of that class?
>
>     If so, this would violate principles of encapsulation, and there'd be
>     terrible consequences (as you could not rely on the class definition being
>     the class definition without examining the entire code base).
>
>
> But this is essentially no different than UFCS,

Adding behavior into an existing class that was not designed for it is, to me, 
like Ruby's "monkey-patching", since you could look at a class definition and 
have no clue if members were added by arbitrary other code or not. UFCS does it 
in a hygienic, encapsulated way.


> except to me it feels like less
> of a hack than UFCS (which I personally find rather dirty by contrast).
> Additionally, often enough, that UFCS function depend on adding a piece of data
> to the object in addition to the functionality it implements.
> I don't think it's fair to say it would lead to terrible consequences, because
> it exists, and it's used very successfully in other languages. It's proven to be
> very useful.

Monkey-patching has, in Ruby, been popular and powerful. It has also turned out 
to be a disaster. It does not scale, and is not conducive to more than one 
person/team working on the code base.


> I have a recurring problem where, at the module level, using CTFE I can scan the
> module for information, and generate bindings of things to their related systems
> without lots of manual, messy, error-prone hook-up code.
> For me, I think this has been the single biggest advantage I've gotten from
> using D yet hands down.
> The problem is, it's limited to things in the global scope. Partial classes are
> the completion of that concept, allowing it to be applied to classes too.
> If when scanning a class I find it has relationships to given systems, I can't
> then magically add the appropriate binding to that system into the class. There
> are some fairly messy hack-arounds that kinda work, but they don't very very
> tight, not like in C# for instance anyway.
> If it's not added to the class its self, all of the IDE features that I am
> always claiming are so critical don't really work. The self-documenting,
> self-writing, auto-completion, popup member/parameter helpers and stuff don't work.
> Also, quite to the contrary of what you say, separating the functionality that
> should be embedded in the class from the class, it breaks the encapsulation
> principle. The class should gain that property internally, not bolted on the
> side with some hacky mechanisms.
>
>     But, you can use UFCS to "add" member functions to an existing class.
>
>
> Indeed, but it's not quite the same.

You're right, and I'd argue that UFCS is hygienic, monkey-patching is not.

>
>     Adding data members can be done using the PIMPL technique, string mixins, or
>     template mixins (but the original class needs to be designed for that).
>
>
> And that's basically the limitation I'd like to overcome. The fact something
> needs to be designed for it in advance; that is completely unrealistic.
> No 3rd party can ever anticipate what you might want to do. Whether you want to
> unintrusively extend some existing code, or you provide a library which can
> extend things in a general way.. If you can craft your partial extension in such
> a way than it integrates neatly with the 3rd party stuff you're using, that
> seems like a much more sensible approach, since it leaves the customisation to
> you, rather than the original author to attempt to anticipate...

That violates encapsulation because the 3rd party library code may have subtle 
dependencies on it not being extended, like using a .sizeof. Or, what to do if 
two different pieces of source code extend a class in different ways? What to do 
if new overloads are added, and some code sees those overloads and some do not?


> I really hate it when I have to butcher 3rd party code to add my bits. It makes
> it hard to maintain, if the author updates the code. Much nicer to extend it
> with my bit as a partial, and keep my code clinically separated.

As Timon also said, in C# you have to add in "partial" to the class definition 
anyway - isn't that the same as inserting a template/string/import mixin or pimpl?

Adding functionality for classes is also straightforward - derive from it.

Adding functionality to structs is done with alias this.


More information about the Digitalmars-d mailing list