www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.mixins

reply dsimcha <dsimcha yahoo.com> writes:
I've been toying for a long time with the idea of a std.mixins for Phobos that
would contain meta-implementations of commonly needed boilerplate code for
mixing into classes and and structs.  I've started to prototype it
(http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
 So far I have a mixin for struct comparisons, which is useful if you need a
total ordering for use with sorting or binary trees, but don't care exactly
how that ordering is defined.  I've also got a mixin that converts a class to
a Singleton, and uses thread-safe but efficient mechanisms to deal with the
__gshared singleton case.

I'm also thinking of creating some mixins to allow cloning of arbitrarily
complicated object graphs, provided that you don't stray outside of SafeD.  Is
this worth implementing or will it likely be solved in some other way at some
point?

Right now I'd just like to milk the D community for ideas.  What other pieces
of boilerplate code do you find yourself writing often that the standard
library should help with?
Aug 30 2010
next sibling parent Jonathan M Davis <jmdavisprog gmail.com> writes:
On Monday 30 August 2010 18:04:10 dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for Phobos
 that would contain meta-implementations of commonly needed boilerplate
 code for mixing into classes and and structs.  I've started to prototype
 it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.
 d). So far I have a mixin for struct comparisons, which is useful if you
 need a total ordering for use with sorting or binary trees, but don't care
 exactly how that ordering is defined.  I've also got a mixin that converts
 a class to a Singleton, and uses thread-safe but efficient mechanisms to
 deal with the __gshared singleton case.
 
 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD. 
 Is this worth implementing or will it likely be solved in some other way
 at some point?
 
 Right now I'd just like to milk the D community for ideas.  What other
 pieces of boilerplate code do you find yourself writing often that the
 standard library should help with?
The ones that I've wanted to implement but haven't yet (due to issues figuring out how to do them with __traits and std.traits) are opEquals(), opCmp(), and toHash(). Ideally, by default, they'd just process each of the member variables in lexical order (or whatever deterministic order you get them from __traits or std.traits), but you could give them a list of the member variables, and then only those member variables would be used, and they'd be used in the order that they were given. I figured that toHash() could use the hashing method described in Effective Java, since it seems solid, and that's what Apache uses for their function which generates a hash function (though, lacking all of D's compile- time code generation, their generative functions use reflection at runtime, which is obviously far less efficient). I'm willing to take a hack at implementing them again, but I'd given up with the idea of trying again when __traits and std.traits were more complete. - Jonathan M Davis
Aug 30 2010
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"dsimcha" <dsimcha yahoo.com> wrote in message 
news:i5hkea$2sud$1 digitalmars.com...
 I've been toying for a long time with the idea of a std.mixins for Phobos 
 that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
 So far I have a mixin for struct comparisons, which is useful if you need 
 a
 total ordering for use with sorting or binary trees, but don't care 
 exactly
 how that ordering is defined.  I've also got a mixin that converts a class 
 to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with 
 the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD. 
 Is
 this worth implementing or will it likely be solved in some other way at 
 some
 point?

 Right now I'd just like to milk the D community for ideas.  What other 
 pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
Definitely trace and traceVal/traceValCT from my lib: http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/mixins.d Every time I work on D code from a codebase that doesn't use my lib and I shouldn't/can't/don't feel like adding it as a dependancy, I find the lack of my trace and traceVal/traceValCT to be a real pain. Having it in the std lib would be *really* helpful, even for me. The traceMixin can be helpful too. Also, getter and getterLazy from the same module. I find the built-in property-definition syntax (even with the new property) to be painfully verbose and non-DRY for simple cases (which in my experience are the most common ones - specifically, every time I want a publically-read-only field). The getter and getterLazy take care of that. The other stuff in that module are other mixins I've also found useful, although to a much lesser extent than trace/traceVal/getter/getterLazy. I'm completely ok with any of that being included in or adapted for phobos. Be aware though, I've recently converted it from D1/Tango to D2/Phobos, so some of it might not be completely D2-ified yet (though it does at least work on D2/Phobos).
Aug 30 2010
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Nick Sabalausky (a a.a)'s article
 "dsimcha" <dsimcha yahoo.com> wrote in message
 news:i5hkea$2sud$1 digitalmars.com...
 I've been toying for a long time with the idea of a std.mixins for Phobos
 that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
 So far I have a mixin for struct comparisons, which is useful if you need
 a
 total ordering for use with sorting or binary trees, but don't care
 exactly
 how that ordering is defined.  I've also got a mixin that converts a class
 to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with
 the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD.
 Is
 this worth implementing or will it likely be solved in some other way at
 some
 point?

 Right now I'd just like to milk the D community for ideas.  What other
 pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
Definitely trace and traceVal/traceValCT from my lib: http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/mixins.d Every time I work on D code from a codebase that doesn't use my lib and I shouldn't/can't/don't feel like adding it as a dependancy, I find the lack of my trace and traceVal/traceValCT to be a real pain. Having it in the std lib would be *really* helpful, even for me. The traceMixin can be helpful too. Also, getter and getterLazy from the same module. I find the built-in property-definition syntax (even with the new property) to be painfully verbose and non-DRY for simple cases (which in my experience are the most common ones - specifically, every time I want a publically-read-only field). The getter and getterLazy take care of that. The other stuff in that module are other mixins I've also found useful, although to a much lesser extent than trace/traceVal/getter/getterLazy. I'm completely ok with any of that being included in or adapted for phobos. Be aware though, I've recently converted it from D1/Tango to D2/Phobos, so some of it might not be completely D2-ified yet (though it does at least work on D2/Phobos).
Awesome. Could you do me a favor, though? Please put a license block in the file just so it's absolutely clear to everyone, even far in the future when this post is buried in the archives, that borrowing from it is fair game.
Aug 30 2010
parent "Nick Sabalausky" <a a.a> writes:
"dsimcha" <dsimcha yahoo.com> wrote in message 
news:i5hs3o$9ev$1 digitalmars.com...
 == Quote from Nick Sabalausky (a a.a)'s article
 Definitely trace and traceVal/traceValCT from my lib:
 http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/mixins.d
 Every time I work on D code from a codebase that doesn't use my lib and I
 shouldn't/can't/don't feel like adding it as a dependancy, I find the 
 lack
 of my trace and traceVal/traceValCT to be a real pain. Having it in the 
 std
 lib would be *really* helpful, even for me. The traceMixin can be helpful
 too.
 Also, getter and getterLazy from the same module. I find the built-in
 property-definition syntax (even with the new  property) to be painfully
 verbose and non-DRY for simple cases (which in my experience are the most
 common ones - specifically, every time I want a publically-read-only 
 field).
 The getter and getterLazy take care of that.
 The other stuff in that module are other mixins I've also found useful,
 although to a much lesser extent than trace/traceVal/getter/getterLazy.
 I'm completely ok with any of that being included in or adapted for 
 phobos.
 Be aware though, I've recently converted it from D1/Tango to D2/Phobos, 
 so
 some of it might not be completely D2-ified yet (though it does at least
 work on D2/Phobos).
Awesome. Could you do me a favor, though? Please put a license block in the file just so it's absolutely clear to everyone, even far in the future when this post is buried in the archives, that borrowing from it is fair game.
The whole project is zlib/libpng, there's a LICENSE.txt in the root of the svn tree. I've just added a notice about it to the main project page ( http://www.dsource.org/projects/semitwist/ ). I'll also put a notice of being zlib/libpng and URL to the license file in each source if you think that'll help. If inclusion in phobos needs anything special beyond just being under zlib/libpng, I'd be happy to provide phobos with whatever formal or informal special permission or license needed.
Aug 30 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for Phobos that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
   So far I have a mixin for struct comparisons, which is useful if you need a
 total ordering for use with sorting or binary trees, but don't care exactly
 how that ordering is defined.  I've also got a mixin that converts a class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD.  Is
 this worth implementing or will it likely be solved in some other way at some
 point?

 Right now I'd just like to milk the D community for ideas.  What other pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
Sounds like a good idea, but I think the name is not too descriptive as it refers to mechanism. We shouldn't have std.classes or std.structs in there, should we? :o) Therefore std.mixins sounds like an awkward way to group together pieces of functionality that may be very diverse. FWIW I think you don't need any mixins to implement cloning. But I do encourage you to work on cloning - I wanted for the longest time and couldn't get to it. A cloning routine would need to keep a map of pointer to pointer to make sure in only clones each object in a graph once. Andrei
Aug 30 2010
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for Phobos that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
   So far I have a mixin for struct comparisons, which is useful if you need a
 total ordering for use with sorting or binary trees, but don't care exactly
 how that ordering is defined.  I've also got a mixin that converts a class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD.  Is
 this worth implementing or will it likely be solved in some other way at some
 point?

 Right now I'd just like to milk the D community for ideas.  What other pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
Sounds like a good idea, but I think the name is not too descriptive as it refers to mechanism. We shouldn't have std.classes or std.structs in there, should we? :o) Therefore std.mixins sounds like an awkward way to group together pieces of functionality that may be very diverse. FWIW I think you don't need any mixins to implement cloning. But I do encourage you to work on cloning - I wanted for the longest time and couldn't get to it. A cloning routine would need to keep a map of pointer to pointer to make sure in only clones each object in a graph once. Andrei
I had an almost working implementation of cloning that didn't depend on mixins a long time (like 2 years) ago. It didn't work with raw pointers to non-primitive data (supporting this would, of course, be impossible) or where polymorphism was involved. The big problem with cloning is derived classes. Give a class reference whose compile time type is Base, but whose runtime type is Derived, how do you clone the derived fields w/o some boilerplate code either being written, mixed in, or generated by the compiler? Keep in mind that D's compilation model prevents you from being able to get a tuple of all derived classes of a base class at compile time. Actually, IIRC you were the one who explained this to me back when I first tried to make cloning work and asked how to get such a tuple.
Aug 30 2010
parent Jacob Carlborg <doob me.com> writes:
On 2010-08-31 05:49, dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for Phobos that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
    So far I have a mixin for struct comparisons, which is useful if you need a
 total ordering for use with sorting or binary trees, but don't care exactly
 how that ordering is defined.  I've also got a mixin that converts a class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD.  Is
 this worth implementing or will it likely be solved in some other way at some
 point?

 Right now I'd just like to milk the D community for ideas.  What other pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
Sounds like a good idea, but I think the name is not too descriptive as it refers to mechanism. We shouldn't have std.classes or std.structs in there, should we? :o) Therefore std.mixins sounds like an awkward way to group together pieces of functionality that may be very diverse. FWIW I think you don't need any mixins to implement cloning. But I do encourage you to work on cloning - I wanted for the longest time and couldn't get to it. A cloning routine would need to keep a map of pointer to pointer to make sure in only clones each object in a graph once. Andrei
I had an almost working implementation of cloning that didn't depend on mixins a long time (like 2 years) ago. It didn't work with raw pointers to non-primitive data (supporting this would, of course, be impossible) or where polymorphism was involved. The big problem with cloning is derived classes. Give a class reference whose compile time type is Base, but whose runtime type is Derived, how do you clone the derived fields w/o some boilerplate code either being written, mixed in, or generated by the compiler? Keep in mind that D's compilation model prevents you from being able to get a tuple of all derived classes of a base class at compile time. Actually, IIRC you were the one who explained this to me back when I first tried to make cloning work and asked how to get such a tuple.
Exactly, this is not currently possible in D without having to implement an extra function doing the cloning, I had the same problem implementing my serialization library Orange (http://dsource.org/projects/orange/). Actually a serialization library could be used to implement cloning, seem my reply to Andrei: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=116518 -- /Jacob Carlborg
Aug 31 2010
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2010-08-31 05:17, Andrei Alexandrescu wrote:
 On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for
 Phobos that
 would contain meta-implementations of commonly needed boilerplate code
 for
 mixing into classes and and structs. I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).

 So far I have a mixin for struct comparisons, which is useful if you
 need a
 total ordering for use with sorting or binary trees, but don't care
 exactly
 how that ordering is defined. I've also got a mixin that converts a
 class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal
 with the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of
 SafeD. Is
 this worth implementing or will it likely be solved in some other way
 at some
 point?

 Right now I'd just like to milk the D community for ideas. What other
 pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
Sounds like a good idea, but I think the name is not too descriptive as it refers to mechanism. We shouldn't have std.classes or std.structs in there, should we? :o) Therefore std.mixins sounds like an awkward way to group together pieces of functionality that may be very diverse. FWIW I think you don't need any mixins to implement cloning. But I do encourage you to work on cloning - I wanted for the longest time and couldn't get to it. A cloning routine would need to keep a map of pointer to pointer to make sure in only clones each object in a graph once. Andrei
My serialization library Orange (http://dsource.org/projects/orange/) could be used for cloning. The easiest way to do this is just to serialize a value and then deserialize the data and return the new value. Of course this wouldn't be the most efficient way, for that one could build a cloning library/function out of the front end of the serializer. -- /Jacob Carlborg
Aug 31 2010
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 31 Aug 2010 19:13:17 +0400, Jacob Carlborg <doob me.com> wrote:

 On 2010-08-31 05:17, Andrei Alexandrescu wrote:
 On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for
 Phobos that
 would contain meta-implementations of commonly needed boilerplate code
 for
 mixing into classes and and structs. I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).

 So far I have a mixin for struct comparisons, which is useful if you
 need a
 total ordering for use with sorting or binary trees, but don't care
 exactly
 how that ordering is defined. I've also got a mixin that converts a
 class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal
 with the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of  
 arbitrarily
 complicated object graphs, provided that you don't stray outside of
 SafeD. Is
 this worth implementing or will it likely be solved in some other way
 at some
 point?

 Right now I'd just like to milk the D community for ideas. What other
 pieces
 of boilerplate code do you find yourself writing often that the  
 standard
 library should help with?
Sounds like a good idea, but I think the name is not too descriptive as it refers to mechanism. We shouldn't have std.classes or std.structs in there, should we? :o) Therefore std.mixins sounds like an awkward way to group together pieces of functionality that may be very diverse. FWIW I think you don't need any mixins to implement cloning. But I do encourage you to work on cloning - I wanted for the longest time and couldn't get to it. A cloning routine would need to keep a map of pointer to pointer to make sure in only clones each object in a graph once. Andrei
My serialization library Orange (http://dsource.org/projects/orange/) could be used for cloning. The easiest way to do this is just to serialize a value and then deserialize the data and return the new value. Of course this wouldn't be the most efficient way, for that one could build a cloning library/function out of the front end of the serializer.
A generic clone function is a very interesting idea, it is also a safe way of creating immutable copies of mutable data structures (assumeUnique is great but a dangerous one to use). Now that we talk about serializing, I wrote a serialization library of my own, too :) Unlike yours, it uses binary serialization, though. What it does is what a Moving GC would do, i.e. compacting objects to use less memory, so de-serialization is done at constant time (unless you need to adjust pointers) and it's also happen to be the most efficient way to object cloning. I believe binary serialization is the most suitable solution for passing data structures of any complexity between threads, over network or loading resources from disk due to its performance and low memory usage. It also improves data locality, so just cloning your data may lead to a significant speedup in data processing and reduced memory usage.
Aug 31 2010
parent Jacob Carlborg <doob me.com> writes:
On 2010-08-31 18:11, Denis Koroskin wrote:
 On Tue, 31 Aug 2010 19:13:17 +0400, Jacob Carlborg <doob me.com> wrote:

 On 2010-08-31 05:17, Andrei Alexandrescu wrote:
 On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for
 Phobos that
 would contain meta-implementations of commonly needed boilerplate code
 for
 mixing into classes and and structs. I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).


 So far I have a mixin for struct comparisons, which is useful if you
 need a
 total ordering for use with sorting or binary trees, but don't care
 exactly
 how that ordering is defined. I've also got a mixin that converts a
 class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal
 with the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of
 arbitrarily
 complicated object graphs, provided that you don't stray outside of
 SafeD. Is
 this worth implementing or will it likely be solved in some other way
 at some
 point?

 Right now I'd just like to milk the D community for ideas. What other
 pieces
 of boilerplate code do you find yourself writing often that the
 standard
 library should help with?
Sounds like a good idea, but I think the name is not too descriptive as it refers to mechanism. We shouldn't have std.classes or std.structs in there, should we? :o) Therefore std.mixins sounds like an awkward way to group together pieces of functionality that may be very diverse. FWIW I think you don't need any mixins to implement cloning. But I do encourage you to work on cloning - I wanted for the longest time and couldn't get to it. A cloning routine would need to keep a map of pointer to pointer to make sure in only clones each object in a graph once. Andrei
My serialization library Orange (http://dsource.org/projects/orange/) could be used for cloning. The easiest way to do this is just to serialize a value and then deserialize the data and return the new value. Of course this wouldn't be the most efficient way, for that one could build a cloning library/function out of the front end of the serializer.
A generic clone function is a very interesting idea, it is also a safe way of creating immutable copies of mutable data structures (assumeUnique is great but a dangerous one to use). Now that we talk about serializing, I wrote a serialization library of my own, too :) Unlike yours, it uses binary serialization, though.
I have not looked at your serialization library but mine has a separate front end (the serializer) and back end (the archive). Currently the library only has an XML archive but it would be possible to implement a binary archive as well.
 What it does is what a Moving GC would do, i.e. compacting objects to
 use less memory, so de-serialization is done at constant time (unless
 you need to adjust pointers) and it's also happen to be the most
 efficient way to object cloning.

 I believe binary serialization is the most suitable solution for passing
 data structures of any complexity between threads, over network or
 loading resources from disk due to its performance and low memory usage.
 It also improves data locality, so just cloning your data may lead to a
 significant speedup in data processing and reduced memory usage.
-- /Jacob Carlborg
Aug 31 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for Phobos that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
   So far I have a mixin for struct comparisons, which is useful if you need a
 total ordering for use with sorting or binary trees, but don't care exactly
 how that ordering is defined.  I've also got a mixin that converts a class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with the
 __gshared singleton case.
Upon a second look I think the Singleton implementation is not up to snuff and reflects a common misunderstanding of the pattern. The point of the Singleton is that you can instantiate it with a derived class. Otherwise, it's the less interesting Monostate pattern. The code as is right now uses hardcoded calls to new, and it shouldn't. Andrei
Aug 30 2010
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 On 8/30/10 20:04 PDT, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for Phobos that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
   So far I have a mixin for struct comparisons, which is useful if you need a
 total ordering for use with sorting or binary trees, but don't care exactly
 how that ordering is defined.  I've also got a mixin that converts a class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with the
 __gshared singleton case.
Upon a second look I think the Singleton implementation is not up to snuff and reflects a common misunderstanding of the pattern. The point of the Singleton is that you can instantiate it with a derived class. Otherwise, it's the less interesting Monostate pattern. The code as is right now uses hardcoded calls to new, and it shouldn't. Andrei
Interersting. The Wikipedia examples don't seem to allow this. Can you elaborate? How would the class know when to use which derived class?
Aug 30 2010
parent BCS <none anon.com> writes:
Hello dsimcha,

 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s
 article
 
 On 8/30/10 20:04 PDT, dsimcha wrote:
 
 I've been toying for a long time with the idea of a std.mixins for
 Phobos that would contain meta-implementations of commonly needed
 boilerplate code for mixing into classes and and structs.  I've
 started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_m
 ixins.d). So far I have a mixin for struct comparisons, which is
 useful if you need a total ordering for use with sorting or binary
 trees, but don't care exactly how that ordering is defined.  I've
 also got a mixin that converts a class to a Singleton, and uses
 thread-safe but efficient mechanisms to deal with the __gshared
 singleton case.
 
Upon a second look I think the Singleton implementation is not up to snuff and reflects a common misunderstanding of the pattern. The point of the Singleton is that you can instantiate it with a derived class. Otherwise, it's the less interesting Monostate pattern. The code as is right now uses hardcoded calls to new, and it shouldn't. Andrei
Interersting. The Wikipedia examples don't seem to allow this. Can you elaborate? How would the class know when to use which derived class?
A proposed API: template Singleton(T, string name, bool populate = true, D = T) { bool SetOrDie(U, A...)(A a); T SetOrGet(U, A...)(A a); T Set(U, A...)(A a); T Get(); } void SingletonClearAll(); useage: alias Singleton!(Foo, "bar") foo; foo.Get().Whatever(); foo.SetOrGet!(FooSub)().Whatever(); // same as get foo.Set!(FooSub)(); // over write SingletonClearAll(); foo.SetOrGet!(FooSub)(); // same as set foo.SetOrDie!(FooSub)(); // already set; foo. -- ... <IXOYE><
Aug 31 2010
prev sibling next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
dsimcha wrote:

 I've been toying for a long time with the idea of a std.mixins for Phobos that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
  So far I have a mixin for struct comparisons, which is useful if you need a
 total ordering for use with sorting or binary trees, but don't care exactly
 how that ordering is defined.  I've also got a mixin that converts a class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with the
 __gshared singleton case.
 
 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD.  Is
 this worth implementing or will it likely be solved in some other way at some
 point?
 
 Right now I'd just like to milk the D community for ideas.  What other pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
Instead of std.mixins, perhaps it is better to fold the code with std.typecons or create new modules as needed (std.pattern?). There is also some private boilerplate code here and there in phobos that help with ctfe and metaprogramming, some people may also find that useful if packaged as a seperate utility module. My suggestion is to include a mixin for unrolling loops. Also something like defineEnum, but for generating bitflags. (I have some code for this). I would also like to see a mixin for generating the boilerplate for decorator forwarding, which is annoying. This should be not that hard with the existing code in std.typecons. Furthermore (not mixin related perse) more phobos code could be made to work at compile time. I am pleasantly surprised a lot has improved in this respect the last few releases, but more can be done (sorting for example is useful and possible). The dranges project at dsource is awesome, it wouldn't hurt to put some of that good stuff in phobos.
Aug 31 2010
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Lutger (lutger.blijdestijn gmail.com)'s article
 Instead of std.mixins, perhaps it is better to fold the code with std.typecons
 or create new modules as needed (std.pattern?).
I initially thought std.mixins would be a good idea, since it would be a one-stop shop for all kinds of misc. boilerplate code that doesn't really fit anywhere else, but the consensus seems to be that this is a bad way to define a module. I'll reconsider.
 There is also some private
 boilerplate code here and there in phobos that help with ctfe and
 metaprogramming, some people may also find that useful if packaged as a
seperate
 utility module.
Yea, that should probably be a todo.
 My suggestion is to include a mixin for unrolling loops.
I thought about this. Simple loop unrolling doesn't seem like a very useful optimization on modern hardware because branch prediction and pipelining have gotten so good. It can still be useful if you also change the loop body a little, for example using multiple accumulators to increase instruction level parallelism, but this is hard to write generically. I can't think of a way to write such a mixin such that it would be both generic and useful.
 Also something like
 defineEnum, but for generating bitflags. (I have some code for this).
Can you give an example? I'm not sure what you mean.
 I would
 also like to see a mixin for generating the boilerplate for decorator
 forwarding, which is annoying. This should be not that hard with the existing
 code in std.typecons.
Shouldn't opDispatch basically handle this for you? I think that's one reason why it was created.
 Furthermore (not mixin related perse) more phobos code could be made to work at
 compile time. I am pleasantly surprised a lot has improved in this respect the
 last few releases, but more can be done (sorting for example is useful and
 possible).
Slowly but surely...
 The dranges project at dsource is awesome, it wouldn't hurt to put
 some of that good stuff in phobos.
Agreed. It's Philippe Sigaud's project and he's been recently added to the roster of Phobos devs. I assume he intends to integrate at least the more generally useful parts of dranges eventually.
Aug 31 2010
next sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
dsimcha wrote:

...
 My suggestion is to include a mixin for unrolling loops.
I thought about this. Simple loop unrolling doesn't seem like a very useful optimization on modern hardware because branch prediction and pipelining have gotten so good. It can still be useful if you also change the loop body a little, for example using multiple accumulators to increase instruction level parallelism, but this is hard to write generically. I can't think of a way to write such a mixin such that it would be both generic and useful.
Probably not for performance, but as a utility for metaprogramming I find it sometimes convenient. The loop index would be written as a literal and thus can be used as a compile time constant. I think in phobos recursive templates are the way to do this? I have hacked something like this, the ' ' will be replaced with the loop index: enum someConstarray = makeConstArray(); mixin(unroll( 0, someConstarray.length, q{ processMember!(someConstArray[ ])() }));
 Also something like
 defineEnum, but for generating bitflags. (I have some code for this).
Can you give an example? I'm not sure what you mean.
I have this example from an earlier discussion, I think with bearophile: mixin( defineBitflags("Todo", q{ do_nothing, walk_dog, cook_breakfast, morning_task = walk_dog | cook_breakfast }) ); turns into: enum Todo { do_nothing = 1, walk_dog = 2, cook_breakfast = 4, morning_task = walk_dog | cook_breakfast } With some bit twiddling you can actually create a range for it too, to iterate all the flags set.
 I would
 also like to see a mixin for generating the boilerplate for decorator
 forwarding, which is annoying. This should be not that hard with the existing
 code in std.typecons.
Shouldn't opDispatch basically handle this for you? I think that's one reason why it was created.
Not exactly, i don't think you can implement an interface with opDispatch. But perhaps this is too fringe for phobos which isn't exactly big on OOP anyway.
 The dranges project at dsource is awesome, it wouldn't hurt to put
 some of that good stuff in phobos.
Agreed. It's Philippe Sigaud's project and he's been recently added to the roster of Phobos devs. I assume he intends to integrate at least the more generally useful parts of dranges eventually.
I hope so.
Aug 31 2010
parent reply "Nick Sabalausky" <a a.a> writes:
"Lutger" <lutger.blijdestijn gmail.com> wrote in message 
news:i5jiap$rvb$1 digitalmars.com...
 dsimcha wrote:

 ...
 My suggestion is to include a mixin for unrolling loops.
I thought about this. Simple loop unrolling doesn't seem like a very useful optimization on modern hardware because branch prediction and pipelining have gotten so good.
We shouldn't forget, D is supposed to be a systems language, so it needs to work well for a variety of embedded systems. We can't assume all CPUs are going to be just as advanced as a modern desktop CPU. Plus, as a systems language, we shouldn't rule out people who have a reason to optimize for lower-end hardware.
It can still be useful if you also change the loop body a
 little, for example using multiple accumulators to increase instruction 
 level
 parallelism,
 but this is hard to write generically.  I can't think of a way to write 
 such a
 mixin such that it would be both generic and useful.
Probably not for performance, but as a utility for metaprogramming I find it sometimes convenient.
Isn't performance the whole point of loop unrolling? What other use could there be?
Aug 31 2010
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
Nick Sabalausky wrote:

 "Lutger" <lutger.blijdestijn gmail.com> wrote in message
 news:i5jiap$rvb$1 digitalmars.com...
 dsimcha wrote:

 ...
 My suggestion is to include a mixin for unrolling loops.
I thought about this. Simple loop unrolling doesn't seem like a very useful optimization on modern hardware because branch prediction and pipelining have gotten so good.
We shouldn't forget, D is supposed to be a systems language, so it needs to work well for a variety of embedded systems. We can't assume all CPUs are going to be just as advanced as a modern desktop CPU. Plus, as a systems language, we shouldn't rule out people who have a reason to optimize for lower-end hardware.
It can still be useful if you also change the loop body a
 little, for example using multiple accumulators to increase instruction
 level
 parallelism,
 but this is hard to write generically.  I can't think of a way to write
 such a
 mixin such that it would be both generic and useful.
Probably not for performance, but as a utility for metaprogramming I find it sometimes convenient.
Isn't performance the whole point of loop unrolling? What other use could there be?
I should have called it 'static foreach'
Aug 31 2010
next sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Lutger (lutger.blijdestijn gmail.com)'s article
 Nick Sabalausky wrote:
 "Lutger" <lutger.blijdestijn gmail.com> wrote in message
 news:i5jiap$rvb$1 digitalmars.com...
 dsimcha wrote:

 ...
 My suggestion is to include a mixin for unrolling loops.
I thought about this. Simple loop unrolling doesn't seem like a very useful optimization on modern hardware because branch prediction and pipelining have gotten so good.
We shouldn't forget, D is supposed to be a systems language, so it needs to work well for a variety of embedded systems. We can't assume all CPUs are going to be just as advanced as a modern desktop CPU. Plus, as a systems language, we shouldn't rule out people who have a reason to optimize for lower-end hardware.
It can still be useful if you also change the loop body a
 little, for example using multiple accumulators to increase instruction
 level
 parallelism,
 but this is hard to write generically.  I can't think of a way to write
 such a
 mixin such that it would be both generic and useful.
Probably not for performance, but as a utility for metaprogramming I find it sometimes convenient.
Isn't performance the whole point of loop unrolling? What other use could there be?
I should have called it 'static foreach'
Ok, now we're talking, so its use would be more for metaprogramming than for performance optimization?
Aug 31 2010
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Lutger" <lutger.blijdestijn gmail.com> wrote in message 
news:i5jmlc$13li$1 digitalmars.com...
 Nick Sabalausky wrote:

 "Lutger" <lutger.blijdestijn gmail.com> wrote in message
 news:i5jiap$rvb$1 digitalmars.com...
 dsimcha wrote:
It can still be useful if you also change the loop body a
 little, for example using multiple accumulators to increase instruction
 level
 parallelism,
 but this is hard to write generically.  I can't think of a way to write
 such a
 mixin such that it would be both generic and useful.
Probably not for performance, but as a utility for metaprogramming I find it sometimes convenient.
Isn't performance the whole point of loop unrolling? What other use could there be?
I should have called it 'static foreach'
Ok, but I guess I still don't see how that relates to a mixin for loop unrolling...? You seemed to be implying that you'd find a mixin for loop unrolling useful for something other than performace. Do you just mean using it like a "static foreach" back *before* "static foreach" was added?
Aug 31 2010
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
Nick Sabalausky wrote:

 "Lutger" <lutger.blijdestijn gmail.com> wrote in message
 news:i5jmlc$13li$1 digitalmars.com...
 Nick Sabalausky wrote:

 "Lutger" <lutger.blijdestijn gmail.com> wrote in message
 news:i5jiap$rvb$1 digitalmars.com...
 dsimcha wrote:
It can still be useful if you also change the loop body a
 little, for example using multiple accumulators to increase instruction
 level
 parallelism,
 but this is hard to write generically.  I can't think of a way to write
 such a
 mixin such that it would be both generic and useful.
Probably not for performance, but as a utility for metaprogramming I find it sometimes convenient.
Isn't performance the whole point of loop unrolling? What other use could there be?
I should have called it 'static foreach'
Ok, but I guess I still don't see how that relates to a mixin for loop unrolling...? You seemed to be implying that you'd find a mixin for loop unrolling useful for something other than performace. Do you just mean using it like a "static foreach" back *before* "static foreach" was added?
Wait what, we have static foreach? I thought that didn't work out. I want this to work or something like it, is it possible? enum test = [1,2, 3]; foreach(i; 0..test.length) { pragma(msg, to!string(test[i]) ); }
Aug 31 2010
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Aug 31, 2010 at 22:41, Lutger <lutger.blijdestijn gmail.com> wrote:

 Wait what, we have static foreach? I thought that didn't work out.
foreach is automatically done at compile-time if you iterate in typetuples string toStrings(Args...)(Args args) //btw, I regularly need this { string result; foreach(i,Type; Args) { result ~= args[i] ~ " "; } return result; } In the above example, I iterate in Args, getting all types and their respective indicex in turn, and use the *compile-time* index i to address the i-th value in the expression tuple args.
 I want this to work or something like it, is it possible?

 enum test = [1,2, 3];

 foreach(i; 0..test.length) {
    pragma(msg, to!string(test[i]) );
 }
Well, 0..someEnum is not recognized by the compiler. The workaround is to create a typetuple of the correct length and use it as a support for iteration: template ZeroTo(int to) if (to >= 0) { static if (to == 0) alias TypeTuple!() ZeroTo; else static if (to == 1) alias TypeTuple!(0) ZeroTo; else alias TypeTuple!(ZeroTo!(to-1), to-1) ZeroTo; // here I use the fact that integers are accepted directly as template parameters and that TypeTuple auto-flatten } so ZeroTo!3 is (0,1,2), since I made it a range open on the right. ZeroTo!0 is empty... enum test = [1,2, 3]; foreach(i; ZeroTo!(test.length)) { pragma(msg, to!string(test[i]) ); } The from -> to version is easy, along with a step parameter. Philippe
Aug 31 2010
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
Philippe Sigaud wrote:

...
 I want this to work or something like it, is it possible?

 enum test = [1,2, 3];

 foreach(i; 0..test.length) {
    pragma(msg, to!string(test[i]) );
 }
Well, 0..someEnum is not recognized by the compiler. The workaround is to create a typetuple of the correct length and use it as a support for iteration: template ZeroTo(int to) if (to >= 0) { static if (to == 0) alias TypeTuple!() ZeroTo; else static if (to == 1) alias TypeTuple!(0) ZeroTo; else alias TypeTuple!(ZeroTo!(to-1), to-1) ZeroTo; // here I use the fact that integers are accepted directly as template parameters and that TypeTuple auto-flatten } so ZeroTo!3 is (0,1,2), since I made it a range open on the right. ZeroTo!0 is empty... enum test = [1,2, 3]; foreach(i; ZeroTo!(test.length)) { pragma(msg, to!string(test[i]) ); } The from -> to version is easy, along with a step parameter. Philippe
wtf it works! That's a cool trick / workaround, thanks.
Aug 31 2010
next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Sep 1, 2010 at 00:05, Lutger <lutger.blijdestijn gmail.com> wrote:


 wtf it works! That's a cool trick / workaround, thanks.
That'd be cool if this worked too: foreach(i,_; test) // since test is iterable or even: foreach(i,_; typeof(test)) // int[3] -> consider it as (int,int,int) and iterate. Halas, no. Though it's easy to transform a static array into a type tuple of the same length and same element type. Philippe
Aug 31 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Lutger:
 wtf it works! That's a cool trick / workaround, thanks.
See bug 4085 Bye, bearophile
Aug 31 2010
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
dsimcha:
 I thought about this.  Simple loop unrolling doesn't seem like a very useful
 optimization on modern hardware because branch prediction and pipelining have
 gotten so good.  It can still be useful if you also change the loop body a
little,
 for example using multiple accumulators to increase instruction level
parallelism,
 but this is hard to write generically.  I can't think of a way to write such a
 mixin such that it would be both generic and useful.
Today loop unrolling is still a basic tool for optimization. Dynamic loop unrolling is one of the most important optimizations done today by the Sun JavaVM. My best code for loop unrolling is inside bug 4085, but as I have explained there I think it's not a good idea to add it to Phobos. It's better to add even a very minimal version of static foreach in the language (despite what Andrej Mitrovic has recently said). Bye, bearophile
Aug 31 2010
prev sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Aug 31, 2010 at 20:03, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from Lutger (lutger.blijdestijn gmail.com)'s article
 Instead of std.mixins, perhaps it is better to fold the code with
std.typecons
 or create new modules as needed (std.pattern?).
I initially thought std.mixins would be a good idea, since it would be a one-stop shop for all kinds of misc. boilerplate code that doesn't really fit anywhere else, but the consensus seems to be that this is a bad way to define a module. I'll reconsider.
Dunno. I quite liked std.mixins. But then, std.pattern(s?) is good too, except many people will think GoF-patterns. btw, doesn't std.pattern already exist, to show some OOP-patterns already coded in D? We could show some humor and call it std.boilerplate :)
 There is also some private
 boilerplate code here and there in phobos that help with ctfe and
 metaprogramming, some people may also find that useful if packaged as a
seperate
 utility module.
Yea, that should probably be a todo.
std.typecons is full of good stuff. I learnt quite a lot reading it. The Any code gave many hours of reading, compiling the resulting code in my head, so to say. Then I went a little mad ;) My initial suggestion for your OP was a mixin to put in a class/struct to make it extensible: using opDispatch to transform a method call a.foo(args...) into the free function foo(a, args). That way a library author makes her class extensible, and I, as a user, add free functions-passing-as-methods as I see fit. template MakeExtensible() { auto opDispatch(string s, Args...)(Args args) if(is(typeof(mixin(s~"(this, args)")))) { mixin("return "~s~"(this, args);"); } } It's a 3-line mixin, but it suffers from a nasty problem: opDispatch only sees the symbols defined in the class modules, which forces the user to define the free functions in the class module and that rather defeats the point :( The only solution I found was to make a wrapper template: struct (or class) Extend!Type that will act as a Type in most cases and uses an opDispatch to remain open. Note that 'alias this' has priority on opDispatch, so I couldn't use alias this in this case: the free-functions-as-method calls would be propagated to the wrapped struct/class and create an error there, without being rerouted through opDispatch. Anyway... To solve the symbol-visibility problem, I made the whole machinery a template, which should be mixed in the main module. For the user, it's trivial, add: mixin Extensible; in your main module (or in any module you'll use free functions, but symbol visibility will be affected ). You can then use extend(value) to get an extensible version of a class or struct. I have to complete to code to forward all operator calls to the wrapped value, since I cannot use alias this. In the end, I project to extract this part to make a generic ParallelType!Type wrapper that is not a subtype of Type (as alias this would). Indeed ExtendType is just a parallel type wich forward unknown methods to free functions. Another proposal I have is a mixin that creates a string enum, Names, containing the local scope qualified name. module pack.mod; mixin(ScopeName); // Names is "pack.mod" int foo(int j) { mixin(ScopeName); // Names is "pack.mod.foo" } class C(A,B) { struct S { void method() { mixin(ScopeName); // Once C is instantiated Names is "pack.mod.C!(type1, type2).S.method" } } } And so on... The code is _heavily_ based on std.demangle.demangle, with some subtle differences to make it work at compile-time. I'm not sure that would be good practice to duplicate such a function in Phobos... Use case : as an helper for other mixins, giving them access to the local scope name. For example the local function name/class name for logging, or the current module name to test the existence of a type, etc.
 The dranges project at dsource is awesome, it wouldn't hurt to put
 some of that good stuff in phobos.
Agreed. It's Philippe Sigaud's project and he's been recently added to the roster of Phobos devs. I assume he intends to integrate at least the more generally useful parts of dranges eventually.
Thanks for the kind words, both of you. It's on my todo list on the short term (~ 1 week). I'll extract some code and propose if for review. David just has to stop launching interesting threads or asking for review of his own code :) Philippe
Aug 31 2010
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Philippe Sigaud (philippe.sigaud gmail.com)'s article
 std.typecons is full of good stuff. I learnt quite a lot reading it. The Any
 code gave many hours of reading, compiling the resulting code in my head, so
 to say. Then I went a little mad ;)
 My initial suggestion for your OP was a mixin to put in a class/struct to
 make it extensible: using opDispatch to transform a method call
 a.foo(args...) into the free function foo(a, args). That way a library
 author makes her class extensible, and I, as a user, add free
 functions-passing-as-methods as I see fit.
 template MakeExtensible()
 {
     auto opDispatch(string s, Args...)(Args args)
 if(is(typeof(mixin(s~"(this, args)"))))
     {
        mixin("return "~s~"(this, args);");
     }
 }
 It's a 3-line mixin, but it suffers from a nasty problem: opDispatch only
 sees the symbols defined in the class modules, which forces the user to
 define the free functions in the class module and that rather defeats the
 point :(
 The only solution I found was to make a wrapper template: struct (or class)
 Extend!Type that will act as a Type in most cases and uses an opDispatch to
 remain open. Note that 'alias this' has priority on opDispatch, so I
 couldn't use alias this in this case: the free-functions-as-method calls
 would be propagated to the wrapped struct/class and create an error there,
 without being rerouted through opDispatch.
 Anyway...
 To solve the symbol-visibility problem, I made the whole machinery a
 template, which should be mixed in the main module.
 For the user, it's trivial, add:
 mixin Extensible;
 in your main module (or in any module you'll use free functions, but symbol
 visibility will be affected ). You can then use extend(value) to get an
 extensible version of a class or struct.
 I have to complete to code to forward all operator calls to the wrapped
 value, since I cannot use alias this. In the end, I project to extract this
 part to make a generic ParallelType!Type wrapper that is not a subtype of
 Type (as alias this would). Indeed ExtendType is just a parallel type wich
 forward unknown methods to free functions.
 Another proposal I have is a mixin that creates a string enum, Names,
 containing the local scope qualified name.
 module pack.mod;
 mixin(ScopeName); // Names is "pack.mod"
 int foo(int j)
 {
 mixin(ScopeName); // Names is "pack.mod.foo"
 }
 class C(A,B)
 {
     struct S
     {
         void method()
         {
         mixin(ScopeName); // Once C is instantiated Names is
 "pack.mod.C!(type1, type2).S.method"
         }
     }
 }
Isn't this a core language feature that's in the spec but is only currently implemented for arrays? I thought eventually uniform function call syntax was coming for classes and structs, too.
Aug 31 2010
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Aug 31, 2010 at 23:49, dsimcha <dsimcha yahoo.com> wrote:

 Isn't this a core language feature that's in the spec but is only currently
 implemented for arrays?  I thought eventually uniform function call syntax
 was
 coming for classes and structs, too.
Yes I heard that too. But it will be at least a year coming, so I decided to roll my own :-) I admit its utility is less that what I thought at first. Now, I'm salivating over a recent proposal by Andrei to do lowering, allowing a void delegate() as the ast arg of a function to be written outside it. Which just shows I'm a fashion victim. Ah, I have a mixin called Disable!(function names) that generates the disabled versions of a class supertype. Could that be useful? I also have a template that gets the list of all members of an aggregate type (classes, structs and, well, modules, in a way), even the constructors, even the overloaded members, separated by type, and list them with their names and associated type. It even gets the types aliases and unittests, though I don't know what to do with the latter. That was part of a project to duplicate a type: generate a new type with this extracted info. I had vague projects to transform the methods into their const equivalent for example or to render the fields immutable, but didn't get that far. Would that be interesting to someone?
Aug 31 2010
parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Philippe Sigaud <philippe.sigaud gmail.com> wrote:

 I also have a template that gets the list of all members of an aggregate
 type (classes, structs and, well, modules, in a way), even the  
 constructors,
 even the overloaded members, separated by type, and list them with their
 names and associated type. It even gets the types aliases and unittests,
 though I don't know what to do with the latter. That was part of a  
 project
 to duplicate a type: generate a new type with this extracted info. I had
 vague projects to transform the methods into their const equivalent for
 example or to render the fields immutable, but didn't get that far. Would
 that be interesting to someone?
I could imagine extracting the unittests could be useful for making a unittest system. Are they only included when passing -unittest? -- Simen
Sep 01 2010
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Sep 1, 2010 at 15:25, Simen kjaeraas <simen.kjaras gmail.com> wrote:

 Philippe Sigaud <philippe.sigaud gmail.com> wrote:

  I also have a template that gets the list of all members of an aggregate
 type (classes, structs and, well, modules, in a way), even the
 constructors,
 even the overloaded members, separated by type, and list them with their
 names and associated type. It even gets the types aliases and unittests,
 though I don't know what to do with the latter. That was part of a project
 to duplicate a type: generate a new type with this extracted info. I had
 vague projects to transform the methods into their const equivalent for
 example or to render the fields immutable, but didn't get that far. Would
 that be interesting to someone?
I could imagine extracting the unittests could be useful for making a unittest system. Are they only included when passing -unittest?
Hmm, don't know. Let see: import std.stdio; class C { int i; unittest { assert(true); writeln("Hello World!"); } } void main() { writeln([__traits(allMembers, C)]); writeln(typeof(C.__unittest1()).stringof); C.__unittest1(); } No, compile this with and without -unittest, and __unittest1 is present. Oh, btw, contrary to the docs __traits(getOverloads, T) works also for structs and modules, not only classes. The unittests type is void delegate(), which is coherent with them being blocks of instructions. You can even call it like a function (see the last line of main). Strange, I never could get that to work... Maybe I didn't try this with a class. Philippe
Sep 01 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisprog gmail.com> writes:
On Tuesday, August 31, 2010 14:49:43 dsimcha wrote:
 Isn't this a core language feature that's in the spec but is only currently
 implemented for arrays?  I thought eventually uniform function call syntax
 was coming for classes and structs, too.
There are people who keep asking for it, but as far as I know, Walter has never agreed to add it. Though, if it were truly universal, it would work on integers and the like too, not just arrays, classes, and structs. - Jonathan M Davis
Aug 31 2010
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"dsimcha" <dsimcha yahoo.com> wrote in message 
news:i5jtdn$1g4t$1 digitalmars.com...
 Isn't this a core language feature that's in the spec but is only 
 currently
 implemented for arrays?  I thought eventually uniform function call syntax 
 was
 coming for classes and structs, too.
I've been really wishing for a long time that would actually happen. It's annoying enough not to be able to do it for most types, but then the fact that it's special-cased at all is a bit of a bizarre inconsistency.
Aug 31 2010
parent reply Torarin <torarind gmail.com> writes:
TDPL says it should work for any type.
http://d.puremagic.com/issues/show_bug.cgi?id=3D3382

2010/9/1 Nick Sabalausky <a a.a>:
 "dsimcha" <dsimcha yahoo.com> wrote in message
 news:i5jtdn$1g4t$1 digitalmars.com...
 Isn't this a core language feature that's in the spec but is only
 currently
 implemented for arrays? =A0I thought eventually uniform function call sy=
ntax
 was
 coming for classes and structs, too.
I've been really wishing for a long time that would actually happen. It's annoying enough not to be able to do it for most types, but then the fact that it's special-cased at all is a bit of a bizarre inconsistency.
Sep 01 2010
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Torarin" <torarind gmail.com> wrote in message 
news:mailman.31.1283345570.858.digitalmars-d puremagic.com...
2010/9/1 Nick Sabalausky <a a.a>:
 "dsimcha" <dsimcha yahoo.com> wrote in message
 news:i5jtdn$1g4t$1 digitalmars.com...
 Isn't this a core language feature that's in the spec but is only
 currently
 implemented for arrays? I thought eventually uniform function call 
 syntax
 was
 coming for classes and structs, too.
I've been really wishing for a long time that would actually happen. It's annoying enough not to be able to do it for most types, but then the fact that it's special-cased at all is a bit of a bizarre inconsistency.
TDPL says it should work for any type. http://d.puremagic.com/issues/show_bug.cgi?id=3382
/me squeals with excitement like a schoolgirl
Sep 01 2010
next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Sep 1, 2010 at 20:59, Nick Sabalausky <a a.a> wrote:

 "Torarin" <torarind gmail.com> wrote in message>TDPL says it should work
 for any type.
http://d.puremagic.com/issues/show_bug.cgi?id=3382
/me squeals with excitement like a schoolgirl Any type, really? Even the basic built-in types, not only class/struct?
That'd fun.
Sep 01 2010
prev sibling next sibling parent reply Torarin <torarind gmail.com> writes:
It says: "If a.fun(b, c, d) is seen but fun is not a member of a's
type, D rewrites that as fun(a, b, c, d) and tries that as well."
So I guess it's possible it won't work with numerical types because
they can never have members.

2010/9/1 Philippe Sigaud <philippe.sigaud gmail.com>:
 On Wed, Sep 1, 2010 at 20:59, Nick Sabalausky <a a.a> wrote:
 "Torarin" <torarind gmail.com> wrote in message>TDPL says it should work
 for any type.
http://d.puremagic.com/issues/show_bug.cgi?id=3382
/me squeals with excitement like a schoolgirl
Any type, really? Even the basic built-in types, not only class/struct? That'd fun.
Sep 01 2010
parent reply "Nick Sabalausky" <a a.a> writes:
"Torarin" <torarind gmail.com> wrote in message 
news:mailman.37.1283370434.858.digitalmars-d puremagic.com...
 It says: "If a.fun(b, c, d) is seen but fun is not a member of a's
 type, D rewrites that as fun(a, b, c, d) and tries that as well."
 So I guess it's possible it won't work with numerical types because
 they can never have members.
That's not the way I interpret that. If 'a' is a numeric primitive type and can never have members, then 'fun' can never be a member of 'a', therefore the rewritten version should always get tried. Unfortunately, at the moment, D2 is actually a little *further* from that universal ideal than D1 is: "Regression(2.020) Array member call syntax can't find matches in current class" http://d.puremagic.com/issues/show_bug.cgi?id=4525 When I converted some D1 code to D2 recently, I actually had to *remove* many of my array-member-call-syntax calls because of that bug.
Sep 01 2010
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Sep 1, 2010 at 22:18, Nick Sabalausky <a a.a> wrote:

 "Regression(2.020) Array member call syntax can't find matches in current
 class"
 http://d.puremagic.com/issues/show_bug.cgi?id=4525

 When I converted some D1 code to D2 recently, I actually had to *remove*
 many of my array-member-call-syntax calls because of that bug.
Sh*t. And trying to put Foo somewhere in there doesn't work either. str.Foo.bar(), str.(Foo.bar()). Anyway, that would defeat the purpose which is to get a clean, universal call syntax.
Sep 01 2010
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Sep 1, 2010 at 21:47, Torarin <torarind gmail.com> wrote:

 It says: "If a.fun(b, c, d) is seen but fun is not a member of a's
 type, D rewrites that as fun(a, b, c, d) and tries that as well."
 So I guess it's possible it won't work with numerical types because
 they can never have members.
I just tried this: int i; writeln(i.max); // writes int.max ! So it seems you can access the type properties through a value of that type. Man, I learnt two new things in two minutes... Philippe
Sep 01 2010
prev sibling parent Torarin <torarind gmail.com> writes:
2010/9/1 Philippe Sigaud <philippe.sigaud gmail.com>:
 I just tried this:


 =A0=A0=A0 int i;
 =A0=A0=A0 writeln(i.max); // writes int.max !

 So it seems you can access the type properties through a value of that ty=
pe.
 Man, I learnt two new things in two minutes...
Yay, looks pretty good, then! :)
Sep 01 2010
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2010-09-01 14:52, Torarin wrote:
 TDPL says it should work for any type.
 http://d.puremagic.com/issues/show_bug.cgi?id=3382

 2010/9/1 Nick Sabalausky<a a.a>:
 "dsimcha"<dsimcha yahoo.com>  wrote in message
 news:i5jtdn$1g4t$1 digitalmars.com...
 Isn't this a core language feature that's in the spec but is only
 currently
 implemented for arrays?  I thought eventually uniform function call syntax
 was
 coming for classes and structs, too.
I've been really wishing for a long time that would actually happen. It's annoying enough not to be able to do it for most types, but then the fact that it's special-cased at all is a bit of a bizarre inconsistency.
I'm not completely sure but I think someone said that the float literal syntax (.1 and 1.) is ambiguous with the uniform function call syntax. -- /Jacob Carlborg
Sep 01 2010
parent reply "Nick Sabalausky" <a a.a> writes:
"Jacob Carlborg" <doob me.com> wrote in message 
news:i5mg57$2shn$1 digitalmars.com...
 On 2010-09-01 14:52, Torarin wrote:
 TDPL says it should work for any type.
 http://d.puremagic.com/issues/show_bug.cgi?id=3382

 2010/9/1 Nick Sabalausky<a a.a>:
 "dsimcha"<dsimcha yahoo.com>  wrote in message
 news:i5jtdn$1g4t$1 digitalmars.com...
 Isn't this a core language feature that's in the spec but is only
 currently
 implemented for arrays?  I thought eventually uniform function call 
 syntax
 was
 coming for classes and structs, too.
I've been really wishing for a long time that would actually happen. It's annoying enough not to be able to do it for most types, but then the fact that it's special-cased at all is a bit of a bizarre inconsistency.
I'm not completely sure but I think someone said that the float literal syntax (.1 and 1.) is ambiguous with the uniform function call syntax.
I seem to remember a discussion about it being ambiguous with some proposed inclusing-range syntax. And yes, I can imagine that float syntax also being ambiguous with uniform function call syntax. But I also remember a certain someone (me!...plus some others) saying that .1 and 1. float literals are completely worthless and in the face of ambiguity with *useful* things, they need to DIE DIE DIE!!!
Sep 01 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:
 But I also remember a certain someone (me!...plus some others) saying that 
 .1 and 1. float literals are completely worthless and in the face of 
 ambiguity with *useful* things, they need to DIE DIE DIE!!!
See the second part of this (closed) enhancement request of mine :-) http://d.puremagic.com/issues/show_bug.cgi?id=3837 Bye, bearophile
Sep 01 2010
parent "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:i5mhnk$3013$1 digitalmars.com...
 Nick Sabalausky:
 But I also remember a certain someone (me!...plus some others) saying 
 that
 .1 and 1. float literals are completely worthless and in the face of
 ambiguity with *useful* things, they need to DIE DIE DIE!!!
See the second part of this (closed) enhancement request of mine :-) http://d.puremagic.com/issues/show_bug.cgi?id=3837
I'm glad you brought that up, because now I have an excuse to bitch about the octal literals again ;) So, *ahem*: As utterly useless as .1 and 1. are, octal literals SUCK! Twenty times more than .1 and 1.! Heh, ok, now that I've got that out of my system I'll be off...
Sep 01 2010
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2010-08-31 03:04, dsimcha wrote:
 I've been toying for a long time with the idea of a std.mixins for Phobos that
 would contain meta-implementations of commonly needed boilerplate code for
 mixing into classes and and structs.  I've started to prototype it
 (http://dsource.org/projects/scrapple/browser/trunk/std_mixins/std_mixins.d).
   So far I have a mixin for struct comparisons, which is useful if you need a
 total ordering for use with sorting or binary trees, but don't care exactly
 how that ordering is defined.  I've also got a mixin that converts a class to
 a Singleton, and uses thread-safe but efficient mechanisms to deal with the
 __gshared singleton case.

 I'm also thinking of creating some mixins to allow cloning of arbitrarily
 complicated object graphs, provided that you don't stray outside of SafeD.  Is
 this worth implementing or will it likely be solved in some other way at some
 point?

 Right now I'd just like to milk the D community for ideas.  What other pieces
 of boilerplate code do you find yourself writing often that the standard
 library should help with?
How about adding a static opDispatch (or alias this) that will forward every method call to the "instance" method. This would allow code like this: Foo.method; // shortcut for the line below Foo.instance.method; -- /Jacob Carlborg
Sep 01 2010