On 6/25/2012 2:26 PM, Manu wrote:
On 25 June 2012 23:30, Walter Bright <[email protected]
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.