May 27, 2004
In article <c932li$77f$1@digitaldaemon.com>, Sean Kelly says...
>
>In article <c930sq$4c4$1@digitaldaemon.com>, Kevin Bealer says...
>>
>>I don't have a problem with those semantics at all.  I was thinking of something like this:
>>
>>>-----------------------
>>> Mixins can parameterize symbols using alias parameters:
>>>        template Foo(alias b)
>>>        {
>>>            // The caller won't mind if I borrow "Z".
>>>            int abc() { return b + Z; }
>>>        }
>>>
>>>        void test()
>>>        {
>>>            int y = 8;
>>>            int Z = 99;  // The mixin might want one of these.
>>>            mixin Foo!(y);
>>>            assert(abc() == 8);
>>>        }
>>>------------------------
>>
>>.. Where anything can bleed in or out of the mixin.
>
>This is kind of a special case, as it only works because the mixin is a template and Z is defined at the POI.  Since the template can't stand on its own, it's reasonable to assume that it's designed specifically to be a mixin and carries with it special requirements.  Since this would likely not happen by accident, I'd consider this a feature of mixins rather than a flaw.

Er.. perhaps I should mention that I was under the impression that the above "poor case" was actually already not supported.  Is it legal now?  [I could try to compile, but that won't tell me if it's legal, only if it works.]

Kevin


May 27, 2004
J Anderson wrote:

> Sure but I've a feeling that they may lead to some places where we don't want to go.  I'm not quite sure where yet.

Guess, they are only the next step on the trip that was started when templates were introduced to C++: A hell of a ride without safety-belt:

We have that meta-language of D that does not have any type-check at all. (I.e.: template arguments are basically just fit in via copy&paste)

The checks that are done on a template are nothing but syntax checks needed for parsing the code. A stand-alone template cannot be checked. It cannot be said correct or incorrect, this always depends on its use. There is no interface of a template.

Any C/C++/D programmer feels awkward using a weakly-typed language. I have been using Matlab for a while now, and it still feels strange to define functions without being able to specify what type the arguments are.

I don't know where this read will lead us. Maybe it really is the wrong direction. Anyhow, it was not started with mixins but with templates.

May 27, 2004
Norbert Nemec wrote:

>J Anderson wrote:
>  
>
>>Sure but I've a feeling that they may lead to some places where we don't
>>want to go.  I'm not quite sure where yet.
>>    
>>
>
>I don't know where this read will lead us. Maybe it really is the wrong
>direction. Anyhow, it was not started with mixins but with templates.
>  
>
Actually it was started with macros.


-- 
-Anderson: http://badmama.com.au/~anderson/
May 27, 2004
"Kevin Bealer" <Kevin_member@pathlink.com> wrote in message news:c93uco$1fab$1@digitaldaemon.com...
> In article <c932li$77f$1@digitaldaemon.com>, Sean Kelly says...
> >
> >In article <c930sq$4c4$1@digitaldaemon.com>, Kevin Bealer says...
> >>
> >>I don't have a problem with those semantics at all.  I was thinking of
something
> >>like this:
> >>
> >>>-----------------------
> >>> Mixins can parameterize symbols using alias parameters:
> >>>        template Foo(alias b)
> >>>        {
> >>>            // The caller won't mind if I borrow "Z".
> >>>            int abc() { return b + Z; }
> >>>        }
> >>>
> >>>        void test()
> >>>        {
> >>>            int y = 8;
> >>>            int Z = 99;  // The mixin might want one of these.
> >>>            mixin Foo!(y);
> >>>            assert(abc() == 8);
> >>>        }
> >>>------------------------
> >>
> >>.. Where anything can bleed in or out of the mixin.
> >
> >This is kind of a special case, as it only works because the mixin is a
template
> >and Z is defined at the POI.  Since the template can't stand on its own,
it's
> >reasonable to assume that it's designed specifically to be a mixin and
carries
> >with it special requirements.  Since this would likely not happen by
accident,
> >I'd consider this a feature of mixins rather than a flaw.
>
> Er.. perhaps I should mention that I was under the impression that the
above
> "poor case" was actually already not supported.  Is it legal now?  [I
could try
> to compile, but that won't tell me if it's legal, only if it works.]
>
> Kevin
>

I tried it and it works, it throws the assertion failiure because 8+99 != 8
I don't see a reason why this shouldn't work? Mixin makes sence only when
it gets mixed in, and why shouldn't it require Z to be defined in the
location where
it is mixed in?



May 27, 2004
"Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:c9125r$6tn$1@digitaldaemon.com...
> Nothing specific. Just a feeling at the moment.
>
> Sorry to be vague.

I had a feeling too but i know what it is!
We can mixin declarations (of varaibles, functions, structs,
and classes) and it is ok, but what about mixing of other types
of code.
for example:

<EXAMPLE1>
template mytest(alias a, alias b)
{
    //some test on a and b, possibly something complex
    a==b; // :)
}
int main(char[][] args)
{
    float x=3,y=3;
    if(mixin mytest!(x,y))
    {//...
    }
}
</EXAMPLE1>

or

<EXAMPLE2>
template callfunc(alias b)
{
    .b();
}
class A
{
    int func(){return 0;}
}
int main(char[][] args)
{
    A a = new A();

    a mixin callfunc!(func);
}
</EXAMPLE2>

Probbably like all of my crazzy ideas this one is crazzy too :)

But if we have language support of copy-paste why not copy-paste something else.


> "Walter" <newshound@digitalmars.com> wrote in message news:c910ga$4fc$1@digitaldaemon.com...
> >
> > "Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:c90ql8$2u1r$1@digitaldaemon.com...
> > > As a general point, I'm still a little nervous about the potential
> > ubituity of
> > > mixins, as supported by their current implementation, but I guess
we'll
> > just have
> > > to suck it and see.
> >
> > ?
> >
> >
>
>


May 27, 2004
J Anderson wrote:

> Norbert Nemec wrote:
> 
>>J Anderson wrote:
>> 
>>
>>>Sure but I've a feeling that they may lead to some places where we don't want to go.  I'm not quite sure where yet.
>>> 
>>>
>>
>>I don't know where this read will lead us. Maybe it really is the wrong direction. Anyhow, it was not started with mixins but with templates.
>> 
>>
> Actually it was started with macros.

OK, that was in the old C era. Now, with D, we thought we had left that bag of problems behind by retiring the CPP.

Anyhow, templates were left in place, and these already contain the whole complexity of an untyped compile-time language. Mixins only are a completion to templates.

Mixins did not open the box of Pandora. That box was opened by templates some while ago. Mixins only make the problems more obvious.

May 27, 2004
In article <c9459p$1pln$1@digitaldaemon.com>, Ivan Senji says... ..
>
>I tried it and it works, it throws the assertion failiure because 8+99 != 8
>I don't see a reason why this shouldn't work? Mixin makes sence only when
>it gets mixed in, and why shouldn't it require Z to be defined in the
>location where
>it is mixed in?

You're probably right.  My objection was that you have no idea where the variables are coming from when you write the mixin.  If you mention "x" you don't know what type it is, whether it is part of the module or the current class or what not.

I was thinking that if the spelling of the variable was off, the mixin could attach itself to a "global variable" in any module.  But I guess D doesn't having any data items at larger than module scope, so it shouldn't be a big deal.  Just another matter of programmer judgement.

Kevin



May 27, 2004
>I was thinking that if the spelling of the variable was off, the mixin could attach itself to a "global variable" in any module.  But I guess D doesn't having any data items at larger than module scope, so it shouldn't be a big deal.  Just another matter of programmer judgement.

If you guys don't mind, I'd like to chime in here. :)

First of all, I couldn't agree more with this sentiment.  There is a huge potential for bugs and scope problems in the misuse of mixins. I went about trying to investigate the problem, and try to uncover where this might cause problems.  I wound up digging up some interesting bugs...

I've always felt that the 'borrowing' feature (as Kevin put it) of mixins as more of a side-effect of plonking a mixin into a given namespace than an intentional feature.  It's probably the kind of thing that should be used carefully, much like fallthroughs on switch statements or treating an int like a bool (checking for i!=0 instead of i>0).

So I thought a little bit about what would be best practice for mixins given the example so far.  I figured that a good solution for the 'borrowing' problem is just to do it as little as possible, whenever possible.  For example, declaring a mixin type as requiring all fields it uses as template parameters, rather than just blindly borrowing one by name.

template Foo(alias b,alias Z)
{
int abc() { return b + Z; }
}
void test()
{
int y = 8;
int Z = 99;
mixin Foo!(y,Z);
printf("abc() = %d\n",abc());
}

The mixin responds with 'abc() = 107' and is much harder to misuse, nor will it generate any odd side-effects.

I would also advocate declaring any variable the mixin uses wherever possible, so as to minimize trouble using a given mixin (treating it kind of like a local class instance w/o a namespace):

template Foo(alias b)
{
int Z;
int abc() { return b + Z; }
}

However, defining the mixin template like this yields some strange things, none of which are expected:

void test(){
int y = 8;
mixin Foo!(y);  // mixin declares 'Z' internally
printf("abc() = %d\n",abc());
}

The above prints out garbage since Foo.int is never initalized.  Even setting an
initalizer in the template (eg: int Z = whatever; ) doesn't work either. (is
this a bug in V.90?)

void test(){
int y = 8;
mixin Foo!(y);
Z = 88; // try to initalize 'Z'
printf("abc() = %d\n",abc());
}

Why this fails I'll probably never know.  The compiler seems to understand that 'Z' is defined in the current scope, but again, Foo.Z never gets the assigned value.


void test(){
int y = 8;
mixin Foo!(y);
int Z = 88; // try to define and initalize 'Z'
printf("abc() = %d\n",abc());
}

I'm pretty sure this shouldn't even compile.  Once again, garbage is produced in the output.


May 27, 2004
In article <c95h4u$1jbj$1@digitaldaemon.com>, EricAnderton at yahoo dot com says...
>First of all, I couldn't agree more with this sentiment.  There is a huge potential for bugs and scope problems in the misuse of mixins. I went about trying to investigate the problem, and try to uncover where this might cause problems.  I wound up digging up some interesting bugs...
>
>I've always felt that the 'borrowing' feature (as Kevin put it) of mixins as more of a side-effect of plonking a mixin into a given namespace than an intentional feature.  It's probably the kind of thing that should be used carefully, much like fallthroughs on switch statements or treating an int like a bool (checking for i!=0 instead of i>0).
>
>So I thought a little bit about what would be best practice for mixins given the example so far.  I figured that a good solution for the 'borrowing' problem is just to do it as little as possible, whenever possible.  For example, declaring a mixin type as requiring all fields it uses as template parameters, rather than just blindly borrowing one by name.

I'm not changing my opinion here - I still think the borrowing is going to be a maintainence issue if misused ... but I just thought of a potential use for it:

Essentially, mixins could borrow from *each other*.


Consider if you will, a set of related mixins.

SocketLike_Socket: provides a set of variables and methods that track a socket connection.

CommandQueue: provides queueing operations that use the methods of SocketLike.

StatsModule: provides a set of methods to store statistics, and a method to get the formatted results, DisplayStats.

NullStats: provides empty methods with same interface as StatsModule, except that it doesn't provide DisplayStats.


Now, the user of this library can mix-and-match to make their own Mr. Potato Head version of the socket handling library.  They can include CommandQueue, which provides a framework for processing network requests.  Or they can provide their own methods to replace that functionality.

They can use StatsModule to get detailed statistics on the socket's communication behaviour;  or they can use NullStats to eliminate statistics gathering, in which case the user can't call DisplayStats because it isnt defined.

They can use SocketLike_Socket for true network communication; or they can define the associated methods to get data to and from a pipe, file, XML channel of some kind, other classes or child processes, graphical widget set.  Each of these has a name like "SocketLike_wxWindows_menu_item" and provides the socket framework.

Hence is realized "aspect" like programming.  You can pull in whatever functionality, and put your own interface on the outside of the class.  Each mixin is optional, but they talk to each other .... because the variables and methods mix.

Kevin


May 27, 2004
If I understand you correctly, you could do the same thing using abstract-base-classes and/or Interfaces (via well documented patterns); which would offer far more robustness than what appears to be a bunch of loosely-bound global variables and methods ...

Just my 2 pence worth.

- Kris


"Kevin Bealer" <Kevin_member@pathlink.com> wrote in message news:c95irt$1m6g$1@digitaldaemon.com...
> In article <c95h4u$1jbj$1@digitaldaemon.com>, EricAnderton at yahoo dot
com
> says...
> >First of all, I couldn't agree more with this sentiment.  There is a huge potential for bugs and scope problems in the misuse of mixins. I went
about
> >trying to investigate the problem, and try to uncover where this might
cause
> >problems.  I wound up digging up some interesting bugs...
> >
> >I've always felt that the 'borrowing' feature (as Kevin put it) of mixins
as
> >more of a side-effect of plonking a mixin into a given namespace than an intentional feature.  It's probably the kind of thing that should be used carefully, much like fallthroughs on switch statements or treating an int
like a
> >bool (checking for i!=0 instead of i>0).
> >
> >So I thought a little bit about what would be best practice for mixins
given the
> >example so far.  I figured that a good solution for the 'borrowing'
problem is
> >just to do it as little as possible, whenever possible.  For example,
declaring
> >a mixin type as requiring all fields it uses as template parameters,
rather than
> >just blindly borrowing one by name.
>
> I'm not changing my opinion here - I still think the borrowing is going to
be a
> maintainence issue if misused ... but I just thought of a potential use
for it:
>
> Essentially, mixins could borrow from *each other*.
>
>
> Consider if you will, a set of related mixins.
>
> SocketLike_Socket: provides a set of variables and methods that track a
socket
> connection.
>
> CommandQueue: provides queueing operations that use the methods of
SocketLike.
>
> StatsModule: provides a set of methods to store statistics, and a method
to get
> the formatted results, DisplayStats.
>
> NullStats: provides empty methods with same interface as StatsModule,
except
> that it doesn't provide DisplayStats.
>
>
> Now, the user of this library can mix-and-match to make their own Mr.
Potato
> Head version of the socket handling library.  They can include
CommandQueue,
> which provides a framework for processing network requests.  Or they can
provide
> their own methods to replace that functionality.
>
> They can use StatsModule to get detailed statistics on the socket's communication behaviour;  or they can use NullStats to eliminate
statistics
> gathering, in which case the user can't call DisplayStats because it isnt defined.
>
> They can use SocketLike_Socket for true network communication; or they can define the associated methods to get data to and from a pipe, file, XML
channel
> of some kind, other classes or child processes, graphical widget set.
Each of
> these has a name like "SocketLike_wxWindows_menu_item" and provides the
socket
> framework.
>
> Hence is realized "aspect" like programming.  You can pull in whatever functionality, and put your own interface on the outside of the class.
Each
> mixin is optional, but they talk to each other .... because the variables
and
> methods mix.
>
> Kevin
>
>