View mode: basic / threaded / horizontal-split · Log in · Help
May 27, 2007
Re: Selftype: an idea from Scala for D2.0
eao197 wrote:
> Disclaimer. Yes, I know that Sensor could mixin Subject, not inherit it. 
> But I think there is probability that in some situation inheritance must 
> be used by some very important reasons.
I think mixins actually are the best way to do this. Here's how they 
would look with your example (note that there is very little 
modification of the code):

> template Subject(O, S)
> {
>     private O[] observers_ = [];
>     
>     public void subscribe(O observer)
>     {
>         observers_ ~= observer;
>     }
> 
>     public void publish()
>     {
>         foreach ( o; observers_ )
>             o.notify( this );
>     }
> }
> 
> interface Observer(S)
> {
>     void notify(S subj);
> }
> 
> class Sensor
>   {
>     mixin Subject!(Display, Sensor);
> 
>     private char[] label_;
>     private double value_;
> 
>     this( char[] label, double value )
>       {
>         label_ = label.dup;
>         value_ = value;
>       }
> 
>     char[] label() { return label_; }
>     double value() { return value_; }
>     void value( double v ) { value_ = v; publish; }
>   }
> 
> class Display : Observer!(Sensor)
>   {
>     void notify( Sensor subj )
>       {
>         Stdout( subj.label )( " has value " )( subj.value ).newline;
>       }
>   }

Using the syntax Subject is S automatically requires that any 
implementors of Subject!(Display, Sensor) inherit from Sensor. So why 
not simply make Sensor the inheritance root, as the mixin does? I don't 
see that any information is lost this way.

-- Reiner
May 27, 2007
Re: Selftype: an idea from Scala for D2.0
On Sun, 27 May 2007 05:23:55 +0400, Reiner Pope <some@address.com> wrote:

>>  class Sensor
>>   {
>>     mixin Subject!(Display, Sensor);
>>      private char[] label_;
>>     private double value_;
>>      this( char[] label, double value )
>>       {
>>         label_ = label.dup;
>>         value_ = value;
>>       }
>>      char[] label() { return label_; }
>>     double value() { return value_; }
>>     void value( double v ) { value_ = v; publish; }
>>   }
>>  class Display : Observer!(Sensor)
>>   {
>>     void notify( Sensor subj )
>>       {
>>         Stdout( subj.label )( " has value " )( subj.value ).newline;
>>       }
>>   }
>
> Using the syntax Subject is S automatically requires that any  
> implementors of Subject!(Display, Sensor) inherit from Sensor. So why  
> not simply make Sensor the inheritance root, as the mixin does? I don't  
> see that any information is lost this way.

In that example Sensor doesn't inherit from Subject. The base type for  
Sensor is Object.
But may be situations in such a class must be inherited from some  
domain-specific base class.

-- 
Regards,
Yauheni Akhotnikau
May 27, 2007
Re: Selftype: an idea from Scala for D2.0
eao197 wrote:
> On Sun, 27 May 2007 05:23:55 +0400, Reiner Pope <some@address.com> wrote:
> 
>>>  class Sensor
>>>   {
>>>     mixin Subject!(Display, Sensor);
>>>      private char[] label_;
>>>     private double value_;
>>>      this( char[] label, double value )
>>>       {
>>>         label_ = label.dup;
>>>         value_ = value;
>>>       }
>>>      char[] label() { return label_; }
>>>     double value() { return value_; }
>>>     void value( double v ) { value_ = v; publish; }
>>>   }
>>>  class Display : Observer!(Sensor)
>>>   {
>>>     void notify( Sensor subj )
>>>       {
>>>         Stdout( subj.label )( " has value " )( subj.value ).newline;
>>>       }
>>>   }
>>
>> Using the syntax Subject is S automatically requires that any 
>> implementors of Subject!(Display, Sensor) inherit from Sensor. So why 
>> not simply make Sensor the inheritance root, as the mixin does? I 
>> don't see that any information is lost this way.
> 
> In that example Sensor doesn't inherit from Subject. The base type for 
> Sensor is Object.
> But may be situations in such a class must be inherited from some 
> domain-specific base class.

I simply can't see the situation you describe. Suppose we had a 
situation where you needed multiple classes to inherit from 
Subject!(Display, Sensor). Well, why would that be? Presumably so you 
can use them polymorhpically, perhaps something like the following:

void main()
{
    // Let's suppose we could actually have a base type
    // Subject!(Display, Sensor) from which everything
    // was derived. Suppose 'self' is possible.
    alias Subject!(Display, Sensor) SubjectType;
    SubjectType[] allSubjects = getListOfAllSubjects();

    Observer!(Sensor) myGenericObserver = new Display();
    foreach (s; allSubjects)
        s.subscribe(myGenericObserver);
}

For example, perhaps you have lots of things which need specific 
observers, and you additionally want to log everything using 
myGenericObserver. In that case, it is beneficial for all the classes to 
be inherited from Subject!(Display, Sensor).

But the condition 'Subject is S' already requires that 'this' for any 
descendant of Subject!(Display, Sensor) can be implicitly converted to 
Sensor. Which means that any class which inherits from Subject!(Display, 
Sensor) also inherits from Sensor. So you can rewrite my example above as

void main()
{
    // Now we don't need to have a base
    // type Subject!(Display, Sensor). Instead,
    // our base type is simply Sensor (which is
    // implemented with a mixin)
    Sensor[] allSubjects = getListOfAllSubjects();

    Observer!(Sensor) myGenericObserver = new Display();
    foreach (s; allSubjects)
        s.subscribe(myGenericObserver);
}

   -- Reiner
May 27, 2007
Re: Selftype: an idea from Scala for D2.0
On Sun, 27 May 2007 09:26:56 +0400, Reiner Pope <some@address.com> wrote:

>>> Using the syntax Subject is S automatically requires that any  
>>> implementors of Subject!(Display, Sensor) inherit from Sensor. So why  
>>> not simply make Sensor the inheritance root, as the mixin does? I  
>>> don't see that any information is lost this way.
>>  In that example Sensor doesn't inherit from Subject. The base type for  
>> Sensor is Object.
>> But may be situations in such a class must be inherited from some  
>> domain-specific base class.
>
> I simply can't see the situation you describe. Suppose we had a  
> situation where you needed multiple classes to inherit from  
> Subject!(Display, Sensor).

That is not a desired situation :)
I don't want multiple classes inherited from Subject!(Display, Sensor). I  
want to have multiple distinct classes inherited from Subject (for  
example: SubjectObserver!(Notificator, Account) for banking accounting  
system, SubjectObserver!(Display, Sensor) for data acquisition system,  
SubjectObserver!(Mailbox, Topic) for message delivery system and so on)).  
Class Subject in template SubjectObjserver may be inherited from another  
useful class (Serializabe, Loggable, Dumpable or something else). This  
means that in the following case:

class Account : SubjectObserver!(Notificator, Account).Subject { ... }
class Topic : SubjectObserver!(Mailbox, Topic).Subject { ... }

classes Account and Topic will be automatically derived from Serializable  
(Loggable, Dumpable, ...) too.

In case of:

class Account {
  mixin Subject!(Notificator, Account);
  ...
}
class Topic {
  mixin Subject!(Mailbox, Topic);
  ...
}

it is neccessary to derive Account and Topic from Serializable (Loggable,  
Dumpable, ...) manually.

-- 
Regards,
Yauheni Akhotnikau
May 27, 2007
Re: Selftype: an idea from Scala for D2.0
eao197 wrote:
> That is not a desired situation :)
> I don't want multiple classes inherited from Subject!(Display, Sensor). 
> I want to have multiple distinct classes inherited from Subject (for 
> example: SubjectObserver!(Notificator, Account) for banking accounting 
> system, SubjectObserver!(Display, Sensor) for data acquisition system, 
> SubjectObserver!(Mailbox, Topic) for message delivery system and so 
> on)). Class Subject in template SubjectObjserver may be inherited from 
> another useful class (Serializabe, Loggable, Dumpable or something 
> else). This means that in the following case:
> 
> class Account : SubjectObserver!(Notificator, Account).Subject { ... }
> class Topic : SubjectObserver!(Mailbox, Topic).Subject { ... }
> 
> classes Account and Topic will be automatically derived from 
> Serializable (Loggable, Dumpable, ...) too.
> 
> In case of:
> 
> class Account {
>   mixin Subject!(Notificator, Account);
>   ...
> }
> class Topic {
>   mixin Subject!(Mailbox, Topic);
>   ...
> }
> 
> it is neccessary to derive Account and Topic from Serializable 
> (Loggable, Dumpable, ...) manually.
I see, you're right. :)

As a side not, there's one pattern which could be interesting in this 
kind of situation:

template Subject(O, S)
{
    ... // Implementation details

    alias Tuple!(Loggable, Dumpable, ...) ImplementedInterfaces;
}

...

class Account : Subject!(Notifier, Account).ImplementedInterfaces {
    mixin Subject!(Notifier, Account);
}

  -- Reiner
May 27, 2007
Re: Selftype: an idea from Scala for D2.0
On Sun, 27 May 2007 11:24:40 +0400, Reiner Pope <some@address.com> wrote:

> As a side not, there's one pattern which could be interesting in this  
> kind of situation:
>
> template Subject(O, S)
> {
>      ... // Implementation details
>
>      alias Tuple!(Loggable, Dumpable, ...) ImplementedInterfaces;
> }
>
> ...
>
> class Account : Subject!(Notifier, Account).ImplementedInterfaces {
>      mixin Subject!(Notifier, Account);
> }

Wow! Thank!
It's very interesting idea.

-- 
Regards,
Yauheni Akhotnikau
May 29, 2007
Re: Selftype: an idea from Scala for D2.0
On Sat, 26 May 2007 00:30:11 +0400, Jari-Matti Mäkelä  
<jmjmak@utu.fi.invalid> wrote:

> Can you show how this would work if there were multiple subclasses
> of 'Subject' and 'Observer'? (for example multiple sensor types in the
> SensorReader example) Does it require language support for multiple
> dispatch then?

More complex example is here:  
http://eao197.narod.ru/scala/AbstractTypesDemo.scala.html (thanks to  
aka50!)
I've add yet another descendant of Sensor -- CalibrateableSensor with can  
use Calibrator for adjusting his values. Display can show values from  
Sensor and from CalibrateableSensor, but Calibrator can work only with  
CalibrateableSensor.

Here is some difficalty in extending classes with selftypes by inheritance  
in Scala. It is impossible to simple inherit CalbrateableSensor from  
Sensor and add data necessary for calibration support to it. That is  
because it is necessary to define additional trait CalibrateableEntity and  
use it in 'requires' clause for CalibrateableSensor trait.

In D construct 'class A is B' for classes in template may be more useful  
and less restricted:

template SubjectObserver(S,O) {
  class Subject is S { ... }
  class Observer { ... }
}

template AbstractSensorReader(S,D) {
  class Sensor is S : SubjectObserver!(Sensor, D).Subject { ... }
  class Display : SubjectObserver!(S, D).Observer { ... }

  class CalibrateableSensor : Sensor { ... }
  class Calibrator { ... }
}

without need of additional interfaces an so on.

-- 
Regards,
Yauheni Akhotnikau
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home