April 22, 2004
Ruby (and, I hope, D): A mixin is a class-like entity whose methods/fields are mixed-in to the mixing class just as if the author of that class had written them manually.

C++: A mixin class is a non-primary base class, which generally provides only types and static & non-virtual methods. (If it contains fields / virtual methods, it's a fully fledged base class, IMO)



"Warren" <warrens@seanet.com> wrote in message
news:c647qp$11vo$1@digitaldaemon.com...
What's a mixin?
I presume fred meant to ask "Are mixins planned..."
"fred" <info@fleet-manage.com> wrote in message
news:c625pc$6np$1@digitaldaemon.com...
> Is Mixins planned for the version 1.0 release ?



April 23, 2004
Apologies if some of this seems bleeding obvious, but I hope it may add to the discussion.

From what I was taught, there are two primary types of relationships in OOP: "is-a" and "has-a" or Inheritance and Aggregation.

// Inheritance Example
class Parent {
public:
    Parent() {}
    void DoSomething() {/* does something */}
}

class Child : public Parent {
public:
    Child() : Parent() {}
    void DoSomethingElse() {/* does something else */}
}

void main()
{
    Child child;
    child.DoSomething();        // call  to parent's method
    child.DoSomethingElse();  // call  to child's method
}

// Aggregation Example
class Body {
public:
    Body() {}
};

class Switch {
public:
    Switch() { bState = false; }
    void    Toggle() { !bState; }
    bool    State() { return bState; }
private:
    bool bState;
};

class Globe {
public:
    Globe() { bState = false; }
    void     Illuminate( bool state ) { bState = state; }
    bool    IsOn() { return bState; }
private:
    bool bState;
}

class PowerCord {
public:
    PowerCord() {}
};

// Parent class
class Light {
public:
    Light() {}
};

class Lamp : public Light {
public:
    Lamp() :  Light(), cBody(), cSwitch(), cGlobe(), cPowerCord {}
    void     Toggle( bool state ) { cSwitch.Toggle( state ); }
    bool     State() { return cSwitch.State(); }
    void     Illuminate( bool state ) { cGlobe.Illuminate( state ); }
    bool    IsOn() { return cGlobe.IsOn(); }
private:
    Body         cBody;
    Switch       cSwitch;
    Globe        cGlobe;
    PowerCord cPowerCord;
}

void main()
{
    Light lamp = new Lamp();
    if( DarkOutside() && !lamp.IsOn())
    {
        // require User Input here
        lamp.Toggle()
        lamp.Illuminate( lamp.State())
    }
}


Unfortuantely, the C++ language only supports the former (Inheritance) through the ":"
operator, whereas the later (Aggregation) does not have the same syntatical support.
As such, many programmers (wrongly, to the purists) use the Inheritance mechanism
to perform Aggregation operations, since it saves on coding through not having to
redirect methos of subordinate components.
For Example; the following produces the same outcome on the earlier main() program.

class Lamp : public Light,
                    public Body,
                    public Switch,
                    public Globe,
                    public PowerCord
{
public:
    Lamp() : Light(), Body(), Switch(), Globe(), PowerCord {}
}


This is where I think Mixins can add a great deal of value. For example;

class Lamp : public Light,
                    mixin Body        cBody,
                    mixin Switch      cSwitch,
                    mixin Globe        cGlobe,
                    mixin PowerCord cPowerCord
{
public:

    Lamp() :  Light(), cBody(), cSwitch(), cGlobe(), cPowerCord {}
}

This is about as lightweight as using multiple inheritance equivilant, and has the same advantage of not having to redefine all the methods from aggregated components.

I haven't thought this solution through properly, so excuse me if it appears somewhat haphazard.

Comments ???


"Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:c678mi$4mt$1@digitaldaemon.com...
> Ruby (and, I hope, D): A mixin is a class-like entity whose methods/fields are mixed-in to the mixing class just as if the author of that class had written them manually.
>
> C++: A mixin class is a non-primary base class, which generally provides only types and static & non-virtual methods. (If it contains fields / virtual methods, it's a fully fledged base class, IMO)
>


April 23, 2004
In article <c6ae9f$2cfh$1@digitaldaemon.com>, fred says...
>
>Apologies if some of this seems bleeding obvious, but I hope it may add to the >discussion.

Good discussion is always welcome.  See comments below.

>Unfortuantely, the C++ language only supports the former (Inheritance) through the ":"
>operator, whereas the later (Aggregation) does not have the same syntatical support.
>As such, many programmers (wrongly, to the purists) use the Inheritance mechanism
>to perform Aggregation operations, since it saves on coding through not having to
>redirect methos of subordinate components.
>For Example; the following produces the same outcome on the earlier main() program.
>
>class Lamp : public Light,
>                    public Body,
>                    public Switch,
>                    public Globe,
>                    public PowerCord
>{
>public:
>    Lamp() : Light(), Body(), Switch(), Globe(), PowerCord {}
>}
>
>
>This is where I think Mixins can add a great deal of value. For example;
>
>class Lamp : public Light,
>                    mixin Body        cBody,
>                    mixin Switch      cSwitch,
>                    mixin Globe        cGlobe,
>                    mixin PowerCord cPowerCord
>{
>public:
>
>    Lamp() :  Light(), cBody(), cSwitch(), cGlobe(), cPowerCord {}
>}
>
>This is about as lightweight as using multiple inheritance equivilant, and has the same advantage of not having to redefine all the methods from aggregated components.
>
>I haven't thought this solution through properly, so excuse me if it appears somewhat haphazard.
>
>Comments ???


Fred,  I agree 100% with you about aggregation not having the same versatility as inheritance.

In fact I tend to think that inheritance tends to make programmers think in term of hierarchies where they are not necessarily appropriate.  For example:

Vehicle
-Car
--Sports car
--Station Wagon
-Truck

While this hierarchy might be appropriate for organizational purposes you don't build a sports car by modifying some abstract concept of a Vehicle you build it by putting together specific types of components.

Sports Car: implements a Vehicle interface and is made up of high performance engine, sleek frame, two seats, manual transmission

Station Wagon: implements a Vehicle interface and is made up of ordinary engine, long frame, two bench seats, cargo space, automatic transmission, wood paneling

etc...

When I think about building software I tend to think less in terms of
hierarchies and more in terms of interfaces and building blocks.
The thing about build blocks is that you usually have ways of
connecting them together.  Right now for C++ and D this is a rather
manual process.  You aggregate all your building blocks into a class
and then add functions to the class to expose the functions of the building
blocks outside of the class and to wire together various functions of the
building blocks to each other.


With your mixin example to have hit on the one problem of exposing the functions of the building blocks outside of the class.  I'd like to address wiring together various functions of the building blocks to each other

Let take your example and go a little farther with it.  I'm playing with some syntax here:

interface PowerSource {
void DrawPower(bool);
}

interface PowerSink {
void UsePower(bool);
}

class Switch(source : PowerSource, sink : PowerSink) {
public:
Switch() { bState = false; }
void    Toggle()
{ bState = !bState; source.DrawPower(bState); sink.UsePower(bState);}
bool    State() { return bState; }
private:
bool bState;
};

class PowerCord  : PowerSource {
public:
PowerCord() {}
void DrawPower(bool);
};

class Globe : PowerSink {
public:
Globe() { bState = false; }
void     Illuminate( bool state ) { bState = state; }
bool    IsOn() { return bState; }
void UsePower(bool bState) { Illuminate(bState); }
private:
bool bState;
}


class Lamp : public Light {
public:
Lamp()  {}

private:
mixin Body         cBody;
mixin Switch       cSwitch(cPowerCord,cGlobe);
mixin Globe        cGlobe;
mixin PowerCord    cPowerCord;
}


Thus Switch becomes a mixin that can control anything with the correct interface




April 24, 2004
"Patrick Down" <Patrick_member@pathlink.com> wrote in message news:c6bg2p$146t$1@digitaldaemon.com...

Good expansion of the  code Patrick, as it shows how process can flow though the aggregated objects, however, there is one thing I would like to comment on.

> >
> >class Lamp : public Light,
> >             mixin Body      cBody,
> >             mixin Switch    cSwitch,
> >             mixin Globe     cGlobe,
> >             mixin PowerCord cPowerCord
> >{
> >public:
> >    Lamp() :  Light(), cBody(), cSwitch(cPowerCord,cGlobe), cGlobe(), cPowerCord() {}
> >}
> >

Versus

> class Lamp : public Light {
> public:
>     Lamp()  {}
> 
> private:
>     mixin Body         cBody;
>     mixin Switch       cSwitch(cPowerCord,cGlobe);
>     mixin Globe        cGlobe;
>     mixin PowerCord    cPowerCord;
> }

Originally, I too had the your later syntax, but changed it the the former for the reasons;

1.   Most object diagrams show aggregated objects as external objects, not internal. For example;

2.   In your example, you have placed (correctly may I say) the aggreagated objects as private.
      However, the code is accessing methods of these objects as though they were public.
      By placing the object declarations outside of the class, they can assume their original
      access status.

3.   As there will be many C++ programs that have been using MI for aggregation techniques,
      it would be easier to port these to D if their syntax was to remain similiar in structure.

I myself fit firmly in the the last categor. There is slabs and slabs of C++ code that I would like to correct the invalid use of Multiple Inheritance to perform Agregation operations.

Criticism/Comments ?






1 2
Next ›   Last »