www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Red Code, Green Code (nwcpp video)

reply sergk <why.you.need my.email> writes:
I've just noticed a Northwest C++ Users Group presentation
"Red Code, Green Code:  Generalizing const" by Scott Meyers, and found it quite
interesting.

So here it is:
http://nwcpp.org/Meetings/2007/04.html


PS./OT: seems Scott do not really enjoying C++ template meta programming =)

-- serg.
May 07 2007
next sibling parent Stephen Waits <steve waits.net> writes:
sergk wrote:
 PS./OT: seems Scott do not really enjoying C++ template meta programming =)

Well, he *is* a pretty smart guy. --Steve
May 07 2007
prev sibling next sibling parent reply janderson <askme me.com> writes:
sergk wrote:
 I've just noticed a Northwest C++ Users Group presentation
 "Red Code, Green Code:  Generalizing const" by Scott Meyers, and found it
quite interesting.
 
 So here it is:
 http://nwcpp.org/Meetings/2007/04.html
 
 
 PS./OT: seems Scott do not really enjoying C++ template meta programming =)
 
 -- serg.

The next time some tries to argue library over language, or that templates in C++ are perfect, we should point them to that video. PS - What would be the nicest way to do this in D using current syntax?
May 07 2007
parent reply Pragma <ericanderton yahoo.removeme.com> writes:
janderson wrote:
 sergk wrote:
 I've just noticed a Northwest C++ Users Group presentation
 "Red Code, Green Code:  Generalizing const" by Scott Meyers, and found 
 it quite interesting.

 So here it is:
 http://nwcpp.org/Meetings/2007/04.html


 PS./OT: seems Scott do not really enjoying C++ template meta 
 programming =)

 -- serg.

The next time some tries to argue library over language, or that templates in C++ are perfect, we should point them to that video. PS - What would be the nicest way to do this in D using current syntax?

Well, we can trans-literate from the C++ code to get the same results. Here I have an example that replaces the functionality from the vector template with tuples, and some additional template namespaces and operations to make it all come together. The actual example is in the bottom third of this snippet. (Mucking with code from http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!207.entry) // This is placed in the Public Domain template Tuple(V...){ alias V Tuple; } template InTuple(Item){ const bool InTuple = false; } template InTuple(Item,First,V...){ static if(is(Item == First)){ const bool InTuple = true; } else alias InTuple!(Item,V) InTuple; } template TupleRemoveAll(Item){ alias Tuple!() TupleRemoveAll; } template TupleRemoveAll(Item,First,V...){ static if(is(Item == First)){ alias TupleRemoveAll!(Item,V) TupleRemoveAll; } else alias Tuple!(First,TupleRemoveAll!(Item,V)) TupleRemoveAll; } // use template 'struct' to prevent tuple flattening when passing constraints around template Constraints(V...){ alias V list; } template ConstraintRemove(alias Constraints){ alias Constraints.list list; } template ConstraintRemove(alias Constraints,First,V...){ alias Cosntraints!(TupleRemoveAll!(First,Constraints.list)) newConstraints; alias Tuple!(newConstraints,ConstraintRemove!(newConstraints,V)) list; } struct IgnoreConstraints {} template ConstraintCheck(alias Local,Caller:IgnoreConstraints){ const bool ConstraintCheck = true; } // ensure that all local constraints are satisfied by caller template ConstraintCheck(alias Local,alias Caller){ static if(Local.list.length > 0){ static if(Caller.list.length > 0){ alias Local.list[0] first; static if(InTuple!(Local.list[0],Caller.list)){ alias Constraints!(TupleRemoveAll!(first,Local.list)) newLocalConstraints; alias ConstraintCheck!(newLocalConstraints,Caller) ConstraintCheck; } else{ const bool ConstraintCheck = false; } } else{ // nothing left to check const bool ConstraintCheck = false; } } else{ // nothing left to check const bool ConstraintCheck = true; } } // Here's the useful part: struct ExceptionSafe {} struct LGPLed {} struct Reviewed {} void f(alias CallerConstraints)(Params params){ alias Constraints!(ExceptionSafe) MyConstraints; static assert(ConstraintCheck!(MyConstraints,CallerConstraints)); /* do something */ } void g(alias CallerConstraints)(){ alias Constraints!(ExceptionSafe,Reviewed) MyConstraints; static assert(ConstraintCheck!(MyConstraints,CallerConstraints)); // try to call the other function f!(MyConstraints)(); // error, trying to call unreviewed code from reviewed code f!(ConstraintRemove!(MyConstraints,Reviewed))(); // ok, ignore Reviewed constraint f!(IgnoreConstraints)(); // ok, explicitly ignore constraints entirely } void main(){ alias Constraints!(ExceptionSafe,Reviewed) MyConstraints; g!(MyConstraints)(); } This won't compile under DMD 0.012 and later - Bug 1196 keeps operations like InTuple!() from operating correctly. So this is only half-tested. There are also a few different ways one could implement this. I opted for this particular definition of Constraints!() to allow for the ConstraintCheck!() operation to work for comparing two tuple lists (otherwise, they'd collapse into a single tuple). Aside from the advantages that tuples offer, I'm having a hard time seeing a clear advantage over the C++ version. We still get template bloat, and namespace concerns, plus it's not much more readable. At a minimum, the lack of a need for a heavy amount of compile-time code is a clear advantage and I think (not sure here) the concerns about virtual methods are also addressed thanks to D's design. So I think this edges out the C++ version rather invisibly. -- - EricAnderton at yahoo
May 08 2007
parent reply janderson <askme me.com> writes:
Pragma wrote:
 janderson wrote:
 sergk wrote:
 I've just noticed a Northwest C++ Users Group presentation
 "Red Code, Green Code:  Generalizing const" by Scott Meyers, and 
 found it quite interesting.

 So here it is:
 http://nwcpp.org/Meetings/2007/04.html


 PS./OT: seems Scott do not really enjoying C++ template meta 
 programming =)

 -- serg.

The next time some tries to argue library over language, or that templates in C++ are perfect, we should point them to that video. PS - What would be the nicest way to do this in D using current syntax?

Well, we can trans-literate from the C++ code to get the same results. Here I have an example that replaces the functionality from the vector template with tuples, and some additional template namespaces and operations to make it all come together. The actual example is in the bottom third of this snippet. (Mucking with code from http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!207.entry) // This is placed in the Public Domain template Tuple(V...){ alias V Tuple; } template InTuple(Item){ const bool InTuple = false; } template InTuple(Item,First,V...){ static if(is(Item == First)){ const bool InTuple = true; } else alias InTuple!(Item,V) InTuple; } template TupleRemoveAll(Item){ alias Tuple!() TupleRemoveAll; } template TupleRemoveAll(Item,First,V...){ static if(is(Item == First)){ alias TupleRemoveAll!(Item,V) TupleRemoveAll; } else alias Tuple!(First,TupleRemoveAll!(Item,V)) TupleRemoveAll; } // use template 'struct' to prevent tuple flattening when passing constraints around template Constraints(V...){ alias V list; } template ConstraintRemove(alias Constraints){ alias Constraints.list list; } template ConstraintRemove(alias Constraints,First,V...){ alias Cosntraints!(TupleRemoveAll!(First,Constraints.list)) newConstraints; alias Tuple!(newConstraints,ConstraintRemove!(newConstraints,V)) list; } struct IgnoreConstraints {} template ConstraintCheck(alias Local,Caller:IgnoreConstraints){ const bool ConstraintCheck = true; } // ensure that all local constraints are satisfied by caller template ConstraintCheck(alias Local,alias Caller){ static if(Local.list.length > 0){ static if(Caller.list.length > 0){ alias Local.list[0] first; static if(InTuple!(Local.list[0],Caller.list)){ alias Constraints!(TupleRemoveAll!(first,Local.list)) newLocalConstraints; alias ConstraintCheck!(newLocalConstraints,Caller) ConstraintCheck; } else{ const bool ConstraintCheck = false; } } else{ // nothing left to check const bool ConstraintCheck = false; } } else{ // nothing left to check const bool ConstraintCheck = true; } } // Here's the useful part: struct ExceptionSafe {} struct LGPLed {} struct Reviewed {} void f(alias CallerConstraints)(Params params){ alias Constraints!(ExceptionSafe) MyConstraints; static assert(ConstraintCheck!(MyConstraints,CallerConstraints)); /* do something */ } void g(alias CallerConstraints)(){ alias Constraints!(ExceptionSafe,Reviewed) MyConstraints; static assert(ConstraintCheck!(MyConstraints,CallerConstraints)); // try to call the other function f!(MyConstraints)(); // error, trying to call unreviewed code from reviewed code f!(ConstraintRemove!(MyConstraints,Reviewed))(); // ok, ignore Reviewed constraint f!(IgnoreConstraints)(); // ok, explicitly ignore constraints entirely } void main(){ alias Constraints!(ExceptionSafe,Reviewed) MyConstraints; g!(MyConstraints)(); } This won't compile under DMD 0.012 and later - Bug 1196 keeps operations like InTuple!() from operating correctly. So this is only half-tested. There are also a few different ways one could implement this. I opted for this particular definition of Constraints!() to allow for the ConstraintCheck!() operation to work for comparing two tuple lists (otherwise, they'd collapse into a single tuple). Aside from the advantages that tuples offer, I'm having a hard time seeing a clear advantage over the C++ version. We still get template bloat, and namespace concerns, plus it's not much more readable. At a minimum, the lack of a need for a heavy amount of compile-time code is a clear advantage and I think (not sure here) the concerns about virtual methods are also addressed thanks to D's design. So I think this edges out the C++ version rather invisibly.

Maybe something like C# user-definable attributes would help. (I'm sure someone has asked for this before).
May 08 2007
parent reply Pragma <ericanderton yahoo.removeme.com> writes:
janderson wrote:
 Pragma wrote:
 
 Maybe something like C# user-definable attributes would help. (I'm sure 
 someone has asked for this before).

I'm pretty sure I have on a few occasions. ;) One way I can see this working is to use a custom pragma() - I think I managed to talk Gregor into trying it out in Rodin, at some point or another. The suggestion isn't a personal bias, it's just that they're pretty much the ideal construct in D for supporting attributes. struct ExceptionSafe{ static ExceptionSafe opCall(){ ExceptionSafe_this; return _this; } } // attach the ExceptionSafe attribute to the function f() pragma(attr,ExceptionSafe()) void f(){ /* do something */ } But there are a few problems with using reflection to accomplish constraint checks. The most obvious of which is that we're now checking things at runtime rather than at compile-time; so you have to run a full test suite in order to make sure you coded things up correctly. Also, without being able to get the attributes for the current function, or even the calling function, there's no way to check the constraints without wrapping the call with a template. The mess from using templates for this comes from the fact that the constraints can be thrown into a list in any order, so it defies the built-in specialization and overloading mechanisms provided by D. If there were some way to specialize function declarations and calls, via an unordered property set (or by compile-time attributes), then it would be very easy to do. -- - EricAnderton at yahoo
May 09 2007
parent reply "David B. Held" <dheld codelogicconsulting.com> writes:
Pragma wrote:
 [...]
 One way I can see this working is to use a custom pragma() - I think I 
 managed to talk Gregor into trying it out in Rodin, at some point or 
 another.  The suggestion isn't a personal bias, it's just that they're 
 pretty much the ideal construct in D for supporting attributes.
 
 struct ExceptionSafe{
   static ExceptionSafe opCall(){
     ExceptionSafe_this;
     return _this;
   }
 }
 
 // attach the ExceptionSafe attribute to the function f()
 pragma(attr,ExceptionSafe()) void f(){
   /* do something */
 }
 [...]

Interestingly enough, this may well be only the second reasonable application of AOP that I've encountered. ;) The problem here is that we want to perform a certain check *on every function*, but we don't want to make it *look* like we are performing the check. Implementing these attributes as aspects actually makes a lot of sense. I wonder whether D should try to support AOP somehow... Dave
May 09 2007
parent Pragma <ericanderton yahoo.removeme.com> writes:
David B. Held wrote:
 Pragma wrote:
 [...]
 One way I can see this working is to use a custom pragma() - I think I 
 managed to talk Gregor into trying it out in Rodin, at some point or 
 another.  The suggestion isn't a personal bias, it's just that they're 
 pretty much the ideal construct in D for supporting attributes.

 struct ExceptionSafe{
   static ExceptionSafe opCall(){
     ExceptionSafe_this;
     return _this;
   }
 }

 // attach the ExceptionSafe attribute to the function f()
 pragma(attr,ExceptionSafe()) void f(){
   /* do something */
 }
 [...]

Interestingly enough, this may well be only the second reasonable application of AOP that I've encountered. ;) The problem here is that we want to perform a certain check *on every function*, but we don't want to make it *look* like we are performing the check. Implementing these attributes as aspects actually makes a lot of sense. I wonder whether D should try to support AOP somehow... Dave

Well, this example is really more of an attempt to emulate C#'s attribute feature, which is really just to help enrich reflection. I could easily see a pragma being used for AOP, though something like AOP (read: function-wrapping) should really be a first-class construct IMO. I have no clue what that would look like, since there's so many different ways developers would expect AOP to work (i.e. explicit meshing of aspects, cross-cutting, etc). You should drop a message in the "python style decorators thread". It has morphed into an AOP for D discussion. -- - EricAnderton at yahoo
May 10 2007
prev sibling parent reply Knud Soerensen <4tuu4k002 sneakemail.com> writes:
On Mon, 07 May 2007 10:58:24 -0400, sergk wrote:

 I've just noticed a Northwest C++ Users Group presentation
 "Red Code, Green Code:  Generalizing const" by Scott Meyers, and found it
quite interesting.
 
 So here it is:
 http://nwcpp.org/Meetings/2007/04.html
 

I am wondering if it is possible to extend the idea to ensure layering in code. I normally use 5 layers. Interface layer. Application layer. Domain layer. Technical layer. Platform layer. The constrain on the code is that it should only make call in it own layer or the layer below. I think it could be very useful. Knud
May 08 2007
parent Stephen Waits <steve waits.net> writes:
Knud Soerensen wrote:
 
 The constrain on the code is that it should only make call in it own layer
 or the layer below.
 
 I think it could be very useful.

I think this is a really interesting idea. --Steve
May 08 2007