November 01, 2008
Alexander Pánek escribió:
> Ary Borenszweig wrote:
>> Mike James escribió:
>>> Not sure if this has been suggested before as an addition to D but what about introducing a partial class as per C# - with all the benefits it would bring...
>>
>> Julio's second example convinced me that partial classes are useful. But in D you can already do that, sort of:
>>
>> class Foo {
>>
>>   // Methods handled by the user
>>   void one() { }
>>   void two() { }
>>   // ...
>>
>>   mixin GeneratedFoo!();
>>
>> }
>>
>> // far, far away
>> template GeneratedFoo() {
>>
>>   void three() { }
>>   void four() { }
>>
>> }
> 
> You can’t just “monkey-patch” the original class, though. With partial classes you could just inject some additional code to the original class.

The thing is, in C# all pieces of a partial class must be defined in the same assembly, and it also must be defined as "partial class". So if you can "monkey-patch" a partial class, you could just as easily go to the class' source code and inject that additional code.

Partial classes are just a convenience for defining many pieces of a class in multiple files.

> 
> I don’t think partial classes fit into D. You can do the same thing via abstract classes and subclassing without altering the original class/interface.

Yes, I don't like much the idea either. I like to have all of a class' code in one file. Otherwise, at least for me, it makes it hard to follow code, to know where something is defined.
November 01, 2008
Julio César Carrascal Urquijo wrote:
> Hello Ary,
> 
>> Conclusion: the motivation is coming from the UI, and to make life
>> easier for them. (Maybe there are other reasons? I've been programming
>> a lot in C# lately, and I never needed a partial class)
>>
>> Since D doesn't have a UI designer or nothing is integrated that
>> much... what would you use partial classes for?
>>
>> If it's not for that reason, I think it makes it harder to know where
>> is defined the code you are looking for.
> 
> One place I've used them is when calling web-services. Most web-services calls need to generate a very specific XML document and building this manually means that methods grow hundreds of lines. I use partial class to separate each of this monster methods form connection pooling and other concerns of the same class:
> 
> ServiceConnection.cs // Connection pooling
> ServiceConnection.OTA_AirAvailRQ.cs
> ServiceConnection.OTA_AirBookRQ.cs
> ...
> 
> An the usage is like this:
> 
> using (var conn = new ServiceConnection(connectionString))
> {
>    conn.Open();
>    var result = conn.OTA_AirAvailRQ(...);
>    ...
> }
> 
> You might say that we could separate things into several objects but that's the whole point of the Facade pattern: Making one big call with all the data needed to avoid several round trips over a slow network.

Model / view / presenter?
http://martinfowler.com/eaaDev/SupervisingPresenter.html

I'm not sure what you mean by "avoid several round trips over a slow network" -- having one extra class won't force that. It's the difference between your view generating a partial request and your view generating a complete request (and perhaps submitting it at the same time). You'd have the exact same approach with partial classes as with multiple classes.
November 01, 2008
Hello Christopher,

> Model / view / presenter?
> http://martinfowler.com/eaaDev/SupervisingPresenter.html
> I'm not sure what you mean by "avoid several round trips over a slow
> network" -- having one extra class won't force that. It's the
> difference between your view generating a partial request and your
> view generating a complete request (and perhaps submitting it at the
> same time). You'd have the exact same approach with partial classes as
> with multiple classes.

This section of the system is a rewrite of and older system where multiple classes where used to send partial messages. I used this pattern to aggregate messages in one SOAP envelop.

You are right that multiple classes doesn't imply multiple messages but putting all calls on one class surely helps making sure those messages are aggregated. The downside is of course the class grows pretty rapidly but thats where partial classes come into play :D

My point with the example is that Facade pattern benefits from "partial" because the point of the pattern is to provide a coarse grained interface to the client.


November 01, 2008
Hello Ary,

> Mike James escribió:
> Julio's second example convinced me that partial classes are useful.
> But in D you can already do that, sort of:


Yes that's possible right now but, sadly, it can't do this:

class Foo
{
	mixin GeneratedFoo!();
}

// far, far away
template GeneratedFoo()
{
	void three() { }
	void four()
	{ 		one();	// Might not be implemented by the class
	}
}

Which means that Foo has to be polluted with default implementations of every partial method. In C# the user can decide which methods to implement:

// Controlled by the user.
partial class Foo
{
}

// Controlled by the tool.
partial class Foo
{
	partial void one();

	void four()
	{
		one();
	}
}


November 01, 2008
Ary Borenszweig wrote:
> Alexander Pánek escribió:
>> You can’t just “monkey-patch” the original class, though. With partial classes you could just inject some additional code to the original class.
> 
> The thing is, in C# all pieces of a partial class must be defined in the same assembly, and it also must be defined as "partial class". So if you can "monkey-patch" a partial class, you could just as easily go to the class' source code and inject that additional code.

Although C# partial classes must be defined in the same assembly, you can also use "extension methods" for adding new methods to an already-defined class, no matter what assembly it comes from. Even the core classes, like String, can be modified using extension methods.

The D trick where "static method(a, b)" is the same as "a.method(b)" is almost identical to the C# extension methods. The only real difference is that the trick can only be used on functions defined as extension methods, not for any arbitrary function. I like that.

--benji
November 01, 2008
Julio César Carrascal Urquijo escribió:
> Hello Ary,
> 
>> Mike James escribió:
>> Julio's second example convinced me that partial classes are useful.
>> But in D you can already do that, sort of:
> 
> 
> Yes that's possible right now but, sadly, it can't do this:
> 
> class Foo
> {
>     mixin GeneratedFoo!();
> }
> 
> // far, far away
> template GeneratedFoo()
> {
>     void three() { }
>     void four()
>     {         one();    // Might not be implemented by the class
>     }
> }
> 
> Which means that Foo has to be polluted with default implementations of every partial method. In C# the user can decide which methods to implement:
> 
> // Controlled by the user.
> partial class Foo
> {
> }
> 
> // Controlled by the tool.
> partial class Foo
> {
>     partial void one();
> 
>     void four()
>     {
>         one();
>     }
> }

Wow, I didn't know there were also partial methods. Something new. :-)
November 01, 2008
Hello Ary,

> Julio César Carrascal Urquijo escribió:
> Wow, I didn't know there were also partial methods. Something new. :-)
> 

Yep. They where added in C# 3.0 for this very same use case. (^_^) \m/


November 03, 2008
Julio César Carrascal Urquijo wrote:
> Hello Christopher,
> 
>> Model / view / presenter?
>> http://martinfowler.com/eaaDev/SupervisingPresenter.html
>> I'm not sure what you mean by "avoid several round trips over a slow
>> network" -- having one extra class won't force that. It's the
>> difference between your view generating a partial request and your
>> view generating a complete request (and perhaps submitting it at the
>> same time). You'd have the exact same approach with partial classes as
>> with multiple classes.
> 
> This section of the system is a rewrite of and older system where multiple classes where used to send partial messages. I used this pattern to aggregate messages in one SOAP envelop.
> 
> You are right that multiple classes doesn't imply multiple messages but putting all calls on one class surely helps making sure those messages are aggregated. The downside is of course the class grows pretty rapidly but thats where partial classes come into play :D

Storing all the data in one class makes sure those messages are aggregated. The methods to manipulate that data can be in a second class if that's reasonable, and the methods to determine how to manipulate that class can be in a third.

> My point with the example is that Facade pattern benefits from "partial" because the point of the pattern is to provide a coarse grained interface to the client.

In this case, you can determine what the interface is -- the presenter or the view.

If you want to provide both a low level interface and a high level interface, inheritance is a reasonable facsimile of partial classes. Otherwise, I'd prefer MVP.
November 07, 2008
Fri, 31 Oct 2008 21:39:42 +0300, Denis Koroskin wrote:

> On Fri, 31 Oct 2008 20:59:23 +0300, KennyTM~ <kennytm@gmail.com> wrote:
> 
>> Denis Koroskin wrote:
>>> On Fri, 31 Oct 2008 20:06:42 +0300, KennyTM~ <kennytm@gmail.com> wrote:
>>>
>>>> Denis Koroskin wrote:
>>>>> On Fri, 31 Oct 2008 17:37:42 +0300, Mike James <foo@bar.com> wrote:
>>>>>
>>>>>> Not sure if this has been suggested before as an addition to D but what about introducing a partial class as per C# - with all the benefits it would bring...
>>>>>>
>>>>>> -=mike=-
>>>>>   I must be missing something, but D already supports defining class
>>>>> methods in one file and implementing them in another one.
>>>>
>>>> Something like this:
>>>>
>>>>
>>>> partial class A {
>>>>      int someMember;
>>>>      public A(int x) { someMember = x; }
>>>> }
>>>>
>>>> // Far, far apart
>>>>
>>>> partial class A {
>>>>      public int getSomeMember() { return someMember; }
>>>> }
>>>>
>>>>
>>>> class X {
>>>>      static void Main() {
>>>>          var someA = new A(12);
>>>>          System.Console.WriteLine(someA.getSomeMember());
>>>>      }
>>>> }
>>>  Is this worth the trouble? You can have
>>>  class A {
>>>     int someMember;
>>>     public A(int x) { someMember = x; }
>>>     public int getSomeMember();
>>> }
>>>  in one module and implement getSomeMember() in another module. I
>>> believe all the class methods should be defined in one place so that
>>> user don't need to import class definition from multiple places. This
>>> also makes semantic analysis more complex.
>>
>> Right. It may be useful when you want to provide additional function, e.g. a getRandom method to a NormalDistribution class where normally that function would not be needed.
>>
>>    module math.normaldistrib;
>>
>>    partial class NormalDistribution : IDistribution {
>>      double mean() { ... }
>>      double stdev() { ... }
>>      // etc.
>>    }
>>
>> in another module:
>>
>>    module random.normal;
>>
>>    partial class NormalDistribution : IRandomGenerator {
>>      double getRandom() {
>>        // complete something the math. package's author
>>        // don't bother to do.
>>        ...
>>      }
>>    }
>>
>> But again I said this can be solved with equating a.method(b) to method(a,b), which has been in the TODO list long long time ago.
>>
>>    double getRandom(NormalDistribution nd) {
>>      // a catch: you can't access private members here.
>>      ...
>>    }
>>
>> .NET uses partial class to separate generated UI code and custom UI code, though subclassing the UI look and do the implementation in that subclass also solves the problem. (Qt works in this way.)
> 
> Note that partial classes also compromise code security:
> 
> partial class Foo
> {
>      private int secret;
> }
> 
> // HA-HA-HACK!
> partial class Foo
> {
>      int hack() { return secret; }
> }
> 
> I wouldn't trust these.

C++ and D are not Java.  You cannot base any security upon member access attributes because any member is accessible via a minimal amount of pointer magic.  But, with partial classes, you can definitely kiss goodbye to encapsulation.
November 07, 2008
Julio César Carrascal Urquijo wrote:
> Which means that Foo has to be polluted with default implementations of every partial method. In C# the user can decide which methods to implement:
> 
> // Controlled by the user.
> partial class Foo
> {
> }
> 
> // Controlled by the tool.
> partial class Foo
> {
>     partial void one();
> 
>     void four()
>     {
>         one();
>     }
> }
> 
> 

What happens if one is not implemented?


-- 
Bruno Medeiros - Software Developer, MSc. in CS/E graduate
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D