www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - mixins rock

reply Ben Hinkle <bhinkle4 juno.com> writes:
Here I thought mixins were a pain but I've been going through mintl and
experimenting with consolidating shared code into mixins and they've been
working great. I'd like to really say thanks to Walter for adding mixins. I
wasn't convinced before but I'm really liking them now. In my sandbox mintl
now has three mixins: 
- one for opCat-like functions (6 functions)
- one for opApply overloads and variations (8 functions)
- one for backwards opApply and toSeq variations (5 functions)

They cut way down on the cut-and-paste aspect of mintl that had been
bothering me. It's to the point where there isn't any "boilerplate" code in
the individual containers.

I've found using public mixins to be more successful that using private
mixins. Private symbols seem to trip up mixins. The rules are probably
obvious but I haven't taken the time to figure them out so I've gotten in
the habit of only mixing in public declarations and having the mixins only
reference public symbols.

-Ben
Sep 09 2004
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Ben Hinkle" <bhinkle4 juno.com> wrote in message
news:chr4dn$u29$1 digitaldaemon.com...
 Here I thought mixins were a pain but I've been going through mintl and
 experimenting with consolidating shared code into mixins and they've been
 working great. I'd like to really say thanks to Walter for adding mixins.

 wasn't convinced before but I'm really liking them now. In my sandbox

 now has three mixins:
 - one for opCat-like functions (6 functions)
 - one for opApply overloads and variations (8 functions)
 - one for backwards opApply and toSeq variations (5 functions)

 They cut way down on the cut-and-paste aspect of mintl that had been
 bothering me. It's to the point where there isn't any "boilerplate" code

 the individual containers.

Template mixins were a bit of a shot in the dark. They don't exist in other languages, so although I was pretty sure they were useful, it's good to see they are panning out.
 I've found using public mixins to be more successful that using private
 mixins. Private symbols seem to trip up mixins. The rules are probably
 obvious but I haven't taken the time to figure them out so I've gotten in
 the habit of only mixing in public declarations and having the mixins only
 reference public symbols.

I'd like to see some small examples of the tripups. There might be a stupid mistake in the parser (not that that has ever happened before <g>).
Sep 09 2004
next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
On Thu, 9 Sep 2004 20:10:57 -0700, Walter <newshound digitalmars.com> 
wrote:

<snip>

 I've found using public mixins to be more successful that using private
 mixins. Private symbols seem to trip up mixins. The rules are probably
 obvious but I haven't taken the time to figure them out so I've gotten 
 in
 the habit of only mixing in public declarations and having the mixins 
 only
 reference public symbols.

I'd like to see some small examples of the tripups. There might be a stupid mistake in the parser (not that that has ever happened before <g>).

I'm not sure whether this is what Ben has encountered but if you say this... --[mixin2.d]-- import mixin2_def.d; void main() { B b = new B(); b.foo(); } --[mixin2_def.d]-- module mixin2_def.d; template A() { public: int public_value; private: int private_value; } class B { mixin A; void foo() { public_value = 3; private_value = 4; } } Then you get... D:\D\src\temp>dmd mixin2.d mixin2_def.d mixin2_def.d(12): class B A!().private_value is private It could be that this is the intended behaviour, it just seemed weird to me at first (I expected the private to be mixed into the class) and now that Ben mentions something like it bothering him I thought it was a good idea to bring it up again. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Sep 09 2004
next sibling parent Ben Hinkle <bhinkle4 juno.com> writes:
Regan Heath wrote:

 On Thu, 9 Sep 2004 20:10:57 -0700, Walter <newshound digitalmars.com>
 wrote:
 
 <snip>
 
 I've found using public mixins to be more successful that using private
 mixins. Private symbols seem to trip up mixins. The rules are probably
 obvious but I haven't taken the time to figure them out so I've gotten
 in
 the habit of only mixing in public declarations and having the mixins
 only
 reference public symbols.

I'd like to see some small examples of the tripups. There might be a stupid mistake in the parser (not that that has ever happened before <g>).

I'm not sure whether this is what Ben has encountered but if you say this... --[mixin2.d]-- import mixin2_def.d; void main() { B b = new B(); b.foo(); } --[mixin2_def.d]-- module mixin2_def.d; template A() { public: int public_value; private: int private_value; } class B { mixin A; void foo() { public_value = 3; private_value = 4; } } Then you get... D:\D\src\temp>dmd mixin2.d mixin2_def.d mixin2_def.d(12): class B A!().private_value is private It could be that this is the intended behaviour, it just seemed weird to me at first (I expected the private to be mixed into the class) and now that Ben mentions something like it bothering him I thought it was a good idea to bring it up again. Regan

yep, that looks familiar. One would think "private" meant the usual D notion of private: "public in the module".
Sep 10 2004
prev sibling parent "Walter" <newshound digitalmars.com> writes:
Ok, I understand.
Sep 10 2004
prev sibling parent Marcello Gnani<marcello_gnani tiscali.it> writes:
In article <chr6fc$uos$1 digitaldaemon.com>, Walter says...
"Ben Hinkle" <bhinkle4 juno.com> wrote in message
news:chr4dn$u29$1 digitaldaemon.com...
 Here I thought mixins were a pain but I've been going through mintl and
 experimenting with consolidating shared code into mixins and they've been
 working great. I'd like to really say thanks to Walter for adding mixins.

 wasn't convinced before but I'm really liking them now. In my sandbox

 now has three mixins:
 - one for opCat-like functions (6 functions)
 - one for opApply overloads and variations (8 functions)
 - one for backwards opApply and toSeq variations (5 functions)

 They cut way down on the cut-and-paste aspect of mintl that had been
 bothering me. It's to the point where there isn't any "boilerplate" code

 the individual containers.

Template mixins were a bit of a shot in the dark. They don't exist in other languages, so although I was pretty sure they were useful, it's good to see they are panning out.
 I've found using public mixins to be more successful that using private
 mixins. Private symbols seem to trip up mixins. The rules are probably
 obvious but I haven't taken the time to figure them out so I've gotten in
 the habit of only mixing in public declarations and having the mixins only
 reference public symbols.

I'd like to see some small examples of the tripups. There might be a stupid mistake in the parser (not that that has ever happened before <g>).

Thanks for your "shot in the dark". Marcello
Sep 10 2004
prev sibling next sibling parent Sean Kelly <sean f4.ca> writes:
In article <chr4dn$u29$1 digitaldaemon.com>, Ben Hinkle says...
Here I thought mixins were a pain but I've been going through mintl and
experimenting with consolidating shared code into mixins and they've been
working great. I'd like to really say thanks to Walter for adding mixins.

Agreed. I've found them to be tremendously useful in avoiding duplicate code and suspect they'll come in handy for other purposes as well.
I've found using public mixins to be more successful that using private
mixins. Private symbols seem to trip up mixins. The rules are probably
obvious but I haven't taken the time to figure them out so I've gotten in
the habit of only mixing in public declarations and having the mixins only
reference public symbols.

I personally haven't had problems with either, though I've tended to use alias parameters if I want mixins to access hidden members. Sean
Sep 09 2004
prev sibling next sibling parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
I agree with all you say here, and i have found them usefull too,
but shouldn't we have a way to mixin construcors?

"Ben Hinkle" <bhinkle4 juno.com> wrote in message
news:chr4dn$u29$1 digitaldaemon.com...
 Here I thought mixins were a pain but I've been going through mintl and
 experimenting with consolidating shared code into mixins and they've been
 working great. I'd like to really say thanks to Walter for adding mixins.

 wasn't convinced before but I'm really liking them now. In my sandbox

 now has three mixins:
 - one for opCat-like functions (6 functions)
 - one for opApply overloads and variations (8 functions)
 - one for backwards opApply and toSeq variations (5 functions)

 They cut way down on the cut-and-paste aspect of mintl that had been
 bothering me. It's to the point where there isn't any "boilerplate" code

 the individual containers.

 I've found using public mixins to be more successful that using private
 mixins. Private symbols seem to trip up mixins. The rules are probably
 obvious but I haven't taken the time to figure them out so I've gotten in
 the habit of only mixing in public declarations and having the mixins only
 reference public symbols.

 -Ben

Sep 09 2004
prev sibling parent reply "Craig Black" <cblack ara.com> writes:
In C++ the -> operator is overloaded for iterators in order to access nodes
in a container.  How does D do this?  Would it be useful to have something
similar to a mixin that was a pointer?

(I'm not a D programmer so forgive me if my syntax is off.)
Something like:

template ListNode(T)
{
  mixin T;
  ListNode *next, *previos;
}

template ListIterator(T)
{
  mixin ListNode(T) *node;
}
Sep 13 2004
next sibling parent pragma <pragma_member pathlink.com> writes:
In article <ci4plq$302s$1 digitaldaemon.com>, Craig Black says...
In C++ the -> operator is overloaded for iterators in order to access nodes
in a container.  How does D do this?  Would it be useful to have something
similar to a mixin that was a pointer?

(I'm not a D programmer so forgive me if my syntax is off.)
Something like:

template ListNode(T)
{
  mixin T;
  ListNode *next, *previos;
}

template ListIterator(T)
{
  mixin ListNode(T) *node;
}

I'm not sure how exactly you plan on approaching a linked list using D templates, but here's just one example of how to proceed: # // (assuming you want templated classes) # # class Listnode(T){ # T value; // no mixin needed here # Listnode!(T) next, previous; # } # # class ListIterator(T){ # mixin Listnode!(T); # } In the above example, there's almost no difference between a mixin and a template instance in the ListIterator class. Mixins really show their value when you start throwing in additional methods that can be coalesed into a general behavior... this technique is great for Aspect-Oriented design. - Pragma [[ Eric Anderton at yahoo dot com ]]
Sep 13 2004
prev sibling parent Ben Hinkle <bhinkle4 juno.com> writes:
Craig Black wrote:

 In C++ the -> operator is overloaded for iterators in order to access
 nodes
 in a container.  How does D do this?  Would it be useful to have something
 similar to a mixin that was a pointer?
 
 (I'm not a D programmer so forgive me if my syntax is off.)
 Something like:
 
 template ListNode(T)
 {
   mixin T;
   ListNode *next, *previos;
 }
 
 template ListIterator(T)
 {
   mixin ListNode(T) *node;
 }

A mixin is basically just a way of saving typing so it is independent of operator overloading. To "dereference" an iterator I'd either make a property and/or deal with slices instead of iterators and use array indexing expressions. In MinTL instead of writing *i to dereference an iterator one writes i[0] to dereference the first item in the slice. D doesn't support overloading the dereferencing operators "." or "*". Usually, though, one just foreach'es over the container and avoid iterators entirely. -Ben
Sep 13 2004