View mode: basic / threaded / horizontal-split · Log in · Help
May 27, 2004
Re: What about some standard mixins
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
Re: What about some standard mixins
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
Re: What about some standard mixins
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
Re: What about some standard mixins
"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
Re: What about some standard mixins
"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
Re: What about some standard mixins
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
Re: What about some standard mixins
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
Re: What about some standard mixins
>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
Re: What about some standard mixins
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
Re: What about some standard mixins
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
>
>
1 2 3 4
Top | Discussion index | About this forum | D home