Jump to page: 1 2
Thread overview
Partial classes
Jun 25, 2012
Manu
Jun 25, 2012
Regan Heath
Jun 26, 2012
Kapps
Jun 26, 2012
Regan Heath
Jun 25, 2012
Timon Gehr
Jun 25, 2012
Walter Bright
Jun 25, 2012
Max Samukha
Jun 25, 2012
Manu
Jun 25, 2012
Timon Gehr
Jun 25, 2012
Walter Bright
Jun 26, 2012
Max Samukha
Jun 26, 2012
Jacob Carlborg
Jun 26, 2012
Walter Bright
Jun 26, 2012
Artur Skawina
Jun 26, 2012
Timon Gehr
Jun 26, 2012
Walter Bright
Jun 26, 2012
Jacob Carlborg
June 25, 2012
I suspect this isn't possible in a compiled language like D, but I wonder
anyway, has anyone considered partial classes in D? Are they technically
possible?
How would they work? Would it depend on link-time code generation?
I can imagine an implementation where each 'part' occupies a separate
allocation, and some pointer in Object or somewhere like that (somewhere
near the typeinfo pointer) binds them together.

I often find myself wanting to add some extra pizazz to classes using
template/mixin magic, but I may not have control over the original code
where it is defined...
C# at least can do this, and it's very useful in many situations...


June 25, 2012
On Mon, 25 Jun 2012 16:26:27 +0100, Manu <turkeyman@gmail.com> wrote:

> I suspect this isn't possible in a compiled language like D, but I wonder
> anyway, has anyone considered partial classes in D? Are they technically
> possible?
> How would they work? Would it depend on link-time code generation?
> I can imagine an implementation where each 'part' occupies a separate
> allocation, and some pointer in Object or somewhere like that (somewhere
> near the typeinfo pointer) binds them together.
>
> I often find myself wanting to add some extra pizazz to classes using
> template/mixin magic, but I may not have control over the original code
> where it is defined...
> C# at least can do this, and it's very useful in many situations...

I thought that the various parts of partial classes in C# had to be compiled together.  For example, I once tried to put a partial class into a C# dll, and the rest in a C# executable using that first dll and it just plain wont let you do this.

However, the c# code generated for me by sqlmetal produces a partial class derived from a DataContext (in one file), which I can extend and/or modify by implementing the rest of the partial class (in another file), in the same project (exe or dll) and if I compile them together I actually just get one merged class.

D could easily implement a partial class feature with the restriction that they need to be compiled together.  But IMO unless this is a trivial feature to implement, I wouldn't think it would be high on the priority list just yet.

Partial classes make customizing auto generated (especially repeatedly auto generated) code much easier.  #c uses them in it's form designer, placing all the designed code in a partial class in one file, and all user code in another file (in the same partial class).

R


-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
June 25, 2012
On 06/25/2012 05:26 PM, Manu wrote:
> I suspect this isn't possible in a compiled language like D, but I
> wonder anyway, has anyone considered partial classes in D? Are they
> technically possible?
> How would they work? Would it depend on link-time code generation?

Ideally yes, but it should be possible to initialize the relevant data structures at program load time. (druntime is already able to locate class type infos by their fully qualified names, so it should be
feasible.)

> I can imagine an implementation where each 'part' occupies a separate
> allocation, and some pointer in Object or somewhere like that (somewhere
> near the typeinfo pointer) binds them together.
>
> I often find myself wanting to add some extra pizazz to classes using
> template/mixin magic, but I may not have control over the original code
> where it is defined...

How can you declare the class as partial if you do not have control
over the original code?

> C# at least can do this, and it's very useful in many situations...

I think the blocking issues are in the frontend: partial classes
as done in C# require the 'namespace' feature. D conflates modules and
name spaces.
June 25, 2012
On 6/25/2012 8:26 AM, Manu wrote:
> I suspect this isn't possible in a compiled language like D, but I wonder
> anyway, has anyone considered partial classes in D? Are they technically possible?
> How would they work? Would it depend on link-time code generation?
> I can imagine an implementation where each 'part' occupies a separate
> allocation, and some pointer in Object or somewhere like that (somewhere near
> the typeinfo pointer) binds them together.

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, you can use UFCS to "add" member functions to an existing class.

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).
June 25, 2012
On Monday, 25 June 2012 at 20:31:18 UTC, Walter Bright wrote:
> On 6/25/2012 8:26 AM, Manu wrote:
>> I suspect this isn't possible in a compiled language like D, but I wonder
>> anyway, has anyone considered partial classes in D? Are they technically possible?
>> How would they work? Would it depend on link-time code generation?
>> I can imagine an implementation where each 'part' occupies a separate
>> allocation, and some pointer in Object or somewhere like that (somewhere near
>> the typeinfo pointer) binds them together.
>
> 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, you can use UFCS to "add" member functions to an existing class.
>
> 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).

He's talking about this: http://msdn.microsoft.com/en-us/library/wa80x488(v=vs.80).aspx.
June 25, 2012
On 25 June 2012 23:30, Walter Bright <newshound2@digitalmars.com> wrote:

> On 6/25/2012 8:26 AM, Manu wrote:
>
>> I suspect this isn't possible in a compiled language like D, but I wonder
>> anyway, has anyone considered partial classes in D? Are they technically
>> possible?
>> How would they work? Would it depend on link-time code generation?
>> I can imagine an implementation where each 'part' occupies a separate
>> allocation, and some pointer in Object or somewhere like that (somewhere
>> near
>> the typeinfo pointer) binds them together.
>>
>
> 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, 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.

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.

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...

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.


June 25, 2012
On 06/25/2012 11:26 PM, Manu wrote:
> On 25 June 2012 23:30, Walter Bright <newshound2@digitalmars.com
> <mailto:newshound2@digitalmars.com>> wrote:
>
>     On 6/25/2012 8:26 AM, Manu wrote:
>
>         I suspect this isn't possible in a compiled language like D, but
>         I wonder
>         anyway, has anyone considered partial classes in D? Are they
>         technically possible?
>         How would they work? Would it depend on link-time code generation?
>         I can imagine an implementation where each 'part' occupies a
>         separate
>         allocation, and some pointer in Object or somewhere like that
>         (somewhere near
>         the typeinfo pointer) binds them together.
>
>
>     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, except to me it feels
> like less of a hack than UFCS (which I personally find rather dirty by
> contrast).

UFCS is just syntax. There is nothing deep/hacky/dirty behind it.

> 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.
>

It is not fair to say it is not fair, because the interpretation he has
given as a premise does not exist successfully in other languages. ;)

> 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.

What mechanism do you use? You cannot add symbols to a module without having dedicated code in the module that does it. Why is the mechanism
insufficient for classes? How would partial classes change the
situation?

> 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.

It would be useful if you showed some pseudocode.

> 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.

If the compiler can resolve symbols, in principle, an IDE should be able to list them.

> 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.
>

It does not break the encapsulation principle. Embedded class
functionality weakens data encapsulation.


>     But, you can use UFCS to "add" member functions to an existing class.
>
>
> Indeed, but it's not quite the same.
>
>     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.

public class ImACSharpClass{ }

How to extend this class without changing the code?

What I don't get yet is why adding 'partial' to the class definition is any better than adding 'import myadditionalfunctionality; mixin MyAdditionalFunctionality'. Is it about the separate compilation? Or is
this just too 'hacky'?

> 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...
>
> 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.

You can always use aggregation or inheritance. An use case would be of help here.



June 25, 2012
On 6/25/2012 2:26 PM, Manu wrote:
> On 25 June 2012 23:30, Walter Bright <newshound2@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.
June 26, 2012
Any reason that just using mixin(import("myclass.partial.d")) wouldn't work?


June 26, 2012
On Monday, 25 June 2012 at 23:44:09 UTC, Walter Bright wrote:

> 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?
>

That is not exactly the same. The important difference is that partial definitions can have attributes, interfaces, nested partial definitions etc., which will be merged in the resulting definition. That is not achievable with mixins or pimpl in a satisfactory way. See http://msdn.microsoft.com/en-us/library/wa80x488(v=vs.80).aspx.

Not arguing for this feature. Simply noting that it is NOT the same as mixins/pimpl.
« First   ‹ Prev
1 2