RE: [boost] Re: Policy or Trait?

From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org]
On Behalf Of David Abrahams
Rob Stewart <stewart@sig.com> writes:
I think your definitions are mostly on target, but I think where you go wrong is that traits/policies has less to do with how a template is defined than how it's used.
Can a method call be part of a trait class? I don't think traits should have anything to do with enacting behaviour (they may describe it). If it is not clear and I see a method I think of it as policy-like. A collection of types and static constants and I think of it as trait-like. I think it gets confusing with the overloading of the English word policy. A policy on how to do something could be passed by value as a polymorphic object or as a simple Boolean flag for that matter... which is not the common intended meaning that MCD brought into common focus. I'll try to add something... Traits are used to get information at compile time. Policies are used to modify behaviour. Traits could be used by a client to modify behaviour which makes them feel like a policy class, but they aren't in what we normally think of as a policy. If a trait is used to direct the modification of behaviour, is it a policy from the client classes point of view I guess... which points to the terminology confusion. Policies can be chained, multiply inherited from or just be ordinary template classes with static methods, maybe such different styles should have different names... a chain aspect, a base aspect (MCD-like), a static aspect... You could then say aspects and traits could be used as policies perhaps... A policy is then something that maybe used to modify behaviour. A trait carries information for use such as for behaviour modification. An aspect extends the definition of trait to also encapsulate behaviour. An aspect and a trait may be used as a policy. Does that work? It would be nice if something new like "aspect class" or some such could be defined and used commonly to avoid the mess, but I suspect it is too late. Regards, Matt Hurd _______________________ Susquehanna Pacific P/L hurdm@sig.com +61.2.8226.5029 _______________________ IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

"Hurd, Matthew" <hurdm@sig.com> wrote in message news:BA1220310B07EC4A8E321B451E07AF47314473@msgbal501.ds.susq.com...
From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org]
On Behalf Of David Abrahams
Rob Stewart <stewart@sig.com> writes:
I think your definitions are mostly on target, but I think where you go wrong is that traits/policies has less to do with how a template is defined than how it's used.
Can a method call be part of a trait class? I don't think traits should have anything to do with enacting behaviour (they may describe it).
If it is not clear and I see a method I think of it as policy-like. A collection of types and static constants and I think of it as trait-like.
See my other post on the topic.In short - I disagree.
I think it gets confusing with the overloading of the English word policy. A policy on how to do something could be passed by value as a polymorphic object or as a simple Boolean flag for that matter... which is not the common intended meaning that MCD brought into common focus.
I'll try to add something...
Traits are used to get information at compile time. Policies are used to modify behaviour. Traits could be used by a client to modify behaviour which makes them feel like a policy class, but they aren't in what we normally think of as a policy.
If a trait is used to direct the modification of behaviour, is it a policy from the client classes point of view I guess... which points to the terminology confusion.
Policies can be chained, multiply inherited from or just be ordinary template classes with static methods, maybe such different styles should have different names... a chain aspect, a base aspect (MCD-like), a static aspect...
You could then say aspects and traits could be used as policies perhaps...
A policy is then something that maybe used to modify behaviour. A trait carries information for use such as for behaviour modification. An aspect extends the definition of trait to also encapsulate behaviour.
An aspect and a trait may be used as a policy.
Does that work?
It would be nice if something new like "aspect class" or some such could be defined and used commonly to avoid the mess, but I suspect it is too late.
As you admit yourself both trait and policy could be used to modify the way the component is working. Key here is how/where you do that: If you supply custom something as a template parameter (or runtime parameter for that matter - in which case you have an example of runtime policy) - this is policy. If you use template specialization to customize the component behavior - it's an example of a trait. Essentially you modify type definition before supplying it as a parameter to the component. The best place to do it right after this type definition. If you intent your users to specify different traits values in different instantiation of the component - you should be using policy instead: a.hpp class A {} b.hpp template<> my_trait<A> { value = value1; } my_component<A> my_c1; c.hpp template<> my_trait<A> { value = valueC; } my_component<A> my_c2; This is an example if incorrect design. If both usages are valid my_component should've been defined to accept Policy that defines value to be used. Gennadiy.

From: "Hurd, Matthew" <hurdm@sig.com> [...]
It would be nice if something new like "aspect class" or some such could
Interesting name! I second your opinion in many ways. I don't think that differentiating between traits and policy makes too much sense or really necessary. As for now to me, they both are parts of the same concept. The idea is that a class can define an API specification. The user is responsible for implementing the API and supplying the implementation to the class as a template parameter. Traditionally an API is not a set of just behaviors or just data structures. It is a combination of both and it doesn't have to be stateless. So what's so unique about API's from the OOP standpoint especially. Well, an API as such cannot be INSTANTIATED. It just EXISTs as a set of rules, etc. It is like namespaces in C++. You cannot instantiate a namespace! You can instantiate data types defined by the API though. So to me, both traits and policies are sort of interchangeable namespaces. Perhaps my view is too simplistic. I sometimes do something like this template< typename MatrixApi > struct equation_system_solver {...}; struct api { private: //** note private here api(); }; struct my_vector_api : api {...}; template< typename VectrorApi > struct my_matrix_api : api {...}; equation_system_solver< my_matrix_api<my_vector_api> > s; Eugene

My 2 Öre: First of all, I knew this was going to explode the conceptual network of the Boost community. We all pretend/think we know exactly what the difference is, and some of us have a fairly stable idea. None of us has a stable enough idea to formalize it into a communicable form. Alas, this is an important field of study, and for subsequent convergence. Having said that, I will nevertheless try to formalize my view of these two important notions. I agree with David A. regarding the (presumed) use of the construct being the vital discriminator, and that a policy (and a traits, in fact, which would make it a quite non-generic one...) does not have to be template-based. In my extremely humble opinion, a trait is strongly coupled to Feature Modeling in GP, providing a mapping from a Model for a particular Concept to the Model-invariant parts of the Features, i.e., placing a Model in a Feature Model. These invariant parts are mostly related types and constant values. One can then use these invariant pieces to get to the dynamic Features of the Concept. To be really convenient, the trait should cover all Models for a Concept, i.e., be generic (read "templates and specializations"...) A policy, on the other hand, is a (compile-time or runtime) behavioral alteration/add-on, not carrying any Concept-related information, but rather decorating a Model for a Concept. So, for me it is pretty easy, traits *only* describes Model-invariant parts of Concept Features while policies furnish Models of Concepts. Unfortunately, the words have been used more or less interchangeably in the early GP days of C++. We here have a golden opportunity to change that... /David

So, for me it is pretty easy, traits *only* describes Model-invariant parts of Concept Features while policies furnish Models of Concepts.
Skipping all the GP stuff: traits DESCRIBE and policies ACT.
And why would we name these concepts Trait and Policy? Describe/Act classification could be interesting, but IMO it has *nothing* to do with Trait/Policy one. See my other post for one example. Here another one: how ConversionPolicy in SmartPointer design act? Let me repeat very simple rule (though a bit simplistic to be correct in general case) I believe is keystone to the Trait/Policy separation: Trait is specific to the type Policy is orthogonal to the type. Do you have an example refuting my view?
/David
Gennadiy.

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> wrote in message news:c4ivdk$hgl$1@sea.gmane.org...
[...] Trait is specific to the type Policy is orthogonal to the type. [...]
Where "the type", I presume, is the [template] class using the policy | trait? That sounds like a good distinction to me. May I formalize it by proposing that: 1. A trait is a metafunction of the client type. 2. A client type is a metafunction of a policy. So definition 1 means that a trait is a metafunction which maps a client type X to a specific trait type trait<X>. Definition 2 means that a policy client X is a metafunction which maps the client type to X<policy>. This makes it clear why a policy *class* need not be a template class. It also shows why a traits *client* need not be a template class. But I would welcome examples of non-template traits classes or non-template policy clients. Now, the definitions I give are necessary but not sufficient conditions for defining traits and policies. You also need to add fluff about modifying behavior, yada yada yada. Dave --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.581 / Virus Database: 368 - Release Date: 2/9/2004

From: "David B. Held" <dheld@codelogicconsulting.com>
"Gennadiy Rozental" <gennadiy.rozental@thomson.com> wrote in message news:c4ivdk$hgl$1@sea.gmane.org...
[...] Trait is specific to the type Policy is orthogonal to the type. [...]
Where "the type", I presume, is the [template] class using the policy | trait? That sounds like a good distinction to me. May I
No, it is the type for which you need the information or behavior. So, in the case of std::basic_string<T>, "the type" is not std::basic_string<T>, but rather T. (Perhaps that's what you meant, but it isn't what I read.)
formalize it by proposing that:
1. A trait is a metafunction of the client type.
2. A client type is a metafunction of a policy.
So definition 1 means that a trait is a metafunction which maps a client type X to a specific trait type trait<X>. Definition 2 means that a policy client X is a metafunction which maps the client type to X<policy>. This makes it clear why a policy *class* need not be a template class. It also shows why a traits *client* need not be a template class. But I would welcome examples of non-template traits classes or non-template policy clients.
That's an interesting way to describe them and I think it fits my model well. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Gennadiy wrote (in response to my GP-ish classification):
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Gennadiy Rozental Sent: Friday, April 02, 2004 12:58 AM To: boost@lists.boost.org Subject: [boost] Re: Re: Policy or Trait?
So, for me it is pretty easy, traits *only* describes Model-invariant parts of Concept Features while policies furnish Models of Concepts.
Skipping all the GP stuff: traits DESCRIBE and policies ACT.
And why would we name these concepts Trait and Policy?
I ended with a simple discriminating rule to apply if one is insecure about a particular notion being either a trait or a policy. It is not the definition, i.e., it is not the case that *anything* that describes something is a trait or that *anything* that act is a policy.
Describe/Act classification could be interesting, but IMO it has *nothing* to do with Trait/Policy one.
Not even as a discriminator? So, you do not agree that traits should always describe a type or, more accurately, a Concept?
See my other post for one example. Here another one: how ConversionPolicy in SmartPointer design act?
I do not follow you.
Let me repeat very simple rule (though a bit simplistic to be correct in general case) I believe is keystone to the Trait/Policy separation:
Trait is specific to the type Policy is orthogonal to the type.
If you read my original message, you will see that I classify trait as specific to the "type," although the correct nomenclature would be that a trait is specific to the Concept, in *positioning* the Model of a Concept in the Feature Model corresponding to the Concept. That simple. So: 1. Trait is *both* specific to a "type" and descriptive. In that same message, I stated that a policy furnishes, or decorates, a Model of a Concept. That decoration can definitely be viewed as an orthogonal aspect to the Model/Concept plane. Not that different from your separation. Again, combining our views, we get: 2. Policy is *both* orthogonal to a "type" and behavioral. What do you think about these combinations?
Do you have an example refuting my view?
Yes, but I have to eat now. Will be back... /David

1. Trait is *both* specific to a "type" and descriptive.
If you accept that trait could describe how component act then ok.
2. Policy is *both* orthogonal to a "type" and behavioral.
If you mean it behave to update type description/definition then ok. Gennadiy.

From: "David Bergman" <davidb@home.se>
So, for me it is pretty easy, traits *only* describes Model-invariant parts of Concept Features while policies furnish Models of Concepts.
Skipping all the GP stuff: traits DESCRIBE and policies ACT.
I don't agree. I think it has to do with how the classes are used. A template parameter permits clients to inject different information and behavior, making it a policy class. When the class is well known and is "just used" where needed, it is a traits class. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob wrote:
From: "David Bergman" <davidb@home.se>
So, for me it is pretty easy, traits *only* describes Model-invariant parts of Concept Features while policies furnish Models of Concepts.
Skipping all the GP stuff: traits DESCRIBE and policies ACT.
I don't agree. I think it has to do with how the classes are used.
So, if they are *used* to DESCRIBE, they are traits, and if they are used to ACT, they are policies. Satisfied? ;-)
A template parameter permits clients to inject different information and behavior, making it a policy class. When the class is well known and is "just used" where needed, it is a traits class.
I agree with your first statement, that injection of information and behavior defines a policy. If the injection is via a template parameter, it is a compile-time policy. Great. I do not agree with the distinction lying in whether it is a type parameter or not, which your second statement implies. A trait should *not* be used to add behavior, but just to, in the end, specialize behavior - often via template specialization or function overloading on a related type or value provided by the trait, in its role as a meta function. The specialization of behavior is a result of the structural impact of the trait. So, even though the end result is always behavioral (after all, we are dealing with Turing machines ;-)), the trait itself should *not* be behavioral. See the last paragraph of this e-mail for a less whimsical description. A trait should always be a meta function, but that is, obviously, not enough. It also has to map to entities that are associated with the types on which it acts, i.e., it has a Concept as its domain and the various related Concepts and Features as its ranges. On the meta level, a trait places a Concept in relation to other Concepts, i.e., a trait is STRUCTURAL. On the object-level, a Model is related to other Models or Features. trait<Type>::neighbor_type - relates two Concepts trait<Type>::child_type - adds a Feature A policy is BEHAVIORAL. And one often uses policies in a dynamic setting, adding them in runtime. We, of course, often implicitly refer to the compile-time policies... One cool thing about traits is that some of the Features it maps to can actually be policies. This might be what makes the distinction a bit tricky, or? Look at std::char_traits, which takes a Character Concept and maps it into its various Features. Look further into the Feature of equality, i.e., the function "static bool eq(const T& c1, const T& c2)." That particular Feature, given by the trait, can be used as a policy. So, a lot of the Features (I will stop using upper-case initial letters soon...) are behaviors that are often used as policies. We use the trait as a meta function to access a policy. Simple. /David

David Bergman wrote:
On the meta level, a trait places a Concept in relation to other Concepts, i.e., a trait is STRUCTURAL. On the object-level, a Model is related to other Models or Features.
trait<Type>::neighbor_type - relates two Concepts trait<Type>::child_type - adds a Feature
A policy is BEHAVIORAL. And one often uses policies in a dynamic setting, adding them in runtime. We, of course, often implicitly refer to the compile-time policies...
So... In A<X>::frobnicate(), 'A' is a policy, because it's behavioral, and in template<class B> struct X { template typename B::value_type value_type; }; 'B' is a trait, because it's structural?

Peter Dimov wrote:
David Bergman wrote:
On the meta level, a trait places a Concept in relation to other Concepts, i.e., a trait is STRUCTURAL. On the object-level,
a Model is
related to other Models or Features.
trait<Type>::neighbor_type - relates two Concepts trait<Type>::child_type - adds a Feature
A policy is BEHAVIORAL. And one often uses policies in a dynamic setting, adding them in runtime. We, of course, often implicitly refer to the compile-time policies...
So...
In A<X>::frobnicate(), 'A' is a policy, because it's behavioral, and in
No, A is not behavioral. The feature "frobnicate" of the type X is. And, that mapped behaviors can definitely be used as a policy.
template<class B> struct X { template typename B::value_type value_type; };
'B' is a trait, because it's structural?
No, since a trait not only has to be structural, but *also* be a (set of) meta functions with the Concept as a range. /David

From: "David Bergman" <davidb@home.se>
Rob wrote:
From: "David Bergman" <davidb@home.se>
So, for me it is pretty easy, traits *only* describes Model-invariant parts of Concept Features while policies furnish Models of Concepts.
Skipping all the GP stuff: traits DESCRIBE and policies ACT.
I don't agree. I think it has to do with how the classes are used.
So, if they are *used* to DESCRIBE, they are traits, and if they are used to ACT, they are policies. Satisfied? ;-)
Not entirely.
A template parameter permits clients to inject different information and behavior, making it a policy class. When the class is well known and is "just used" where needed, it is a traits class.
I agree with your first statement, that injection of information and behavior defines a policy. If the injection is via a template parameter, it is a compile-time policy. Great.
Good.
I do not agree with the distinction lying in whether it is a type parameter or not, which your second statement implies. A trait should *not* be used to add behavior, but just to, in the end, specialize behavior - often via template specialization or function overloading on a related type or value provided by the trait, in its role as a meta function. The specialization of behavior is a result of the structural impact of the trait. So, even though the end result is always behavioral (after all, we are dealing with Turing machines ;-)), the trait itself should *not* be behavioral. See the last paragraph of this e-mail for a less whimsical description.
So you're saying that a traits class cannot have behavior? You're saying that, for example, std::char_traits<T>::length() means that std::char_traits is not a traits class? While I agree that there should be little behavior in traits classes as a rule, if that behavior is peculiar to the traits class (specialization of class template, typically), then it is reasonable. I say that because you can count on the consistency of that behavior and the specific behavior is based upon the combination of the traits class and the type for which you want the traits.
A trait should always be a meta function, but that is, obviously, not enough. It also has to map to entities that are associated with the types on which it acts, i.e., it has a Concept as its domain and the various related Concepts and Features as its ranges.
Again, I take it that you're excluding behavior, with which I disagree.
On the meta level, a trait places a Concept in relation to other Concepts, i.e., a trait is STRUCTURAL. On the object-level, a Model is related to other Models or Features.
trait<Type>::neighbor_type - relates two Concepts trait<Type>::child_type - adds a Feature
A policy is BEHAVIORAL. And one often uses policies in a dynamic setting, adding them in runtime. We, of course, often implicitly refer to the compile-time policies...
I just don't find this compelling. Gennadiy was trying to ask before about specific smart_ptr policies that don't have behavior. The implied question is that if they don't have any behavior, why are they called policies? Conversely, I recall that he was asking about some so-called traits classes that have behavior; were they wrongly classified?
One cool thing about traits is that some of the Features it maps to can actually be policies. This might be what makes the distinction a bit tricky, or? Look at std::char_traits, which takes a Character Concept and maps it into its various Features. Look further into the Feature of equality, i.e., the function "static bool eq(const T& c1, const T& c2)." That particular Feature, given by the trait, can be used as a policy. So, a lot of the Features (I will stop using upper-case initial letters soon...) are behaviors that are often used as policies. We use the trait as a meta function to access a policy. Simple.
I see what you mean, but it doesn't fit prior art, at least not to me. For me, a type that unequivocally associates information and yes, even behavior, with another type is a traits class. A type that can be injected via template parameter to control the behavior of a template is a policy. The distinction is whether all code has equal access to the information (traits) or whether only a specific template has the information (policy). Traits are characteristics associated with another type. Policies are imposed by any client of the template using the policy. (BTW, you might want to shorten your lines a bit so they don't get rewrapped after being quoted just a couple of times.) -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob wrote:
I don't agree. I think it has to do with how the classes are used.
So, if they are *used* to DESCRIBE, they are traits, and if they are used to ACT, they are policies. Satisfied? ;-)
Not entirely.
I kind of assumed you would not ;-)
I agree with your first statement, that injection of information and behavior defines a policy. If the injection is via a template parameter, it is a compile-time policy. Great.
Good.
Yes, so we should not have any problem deciding whether a "thing" is a policy or not. A good first step. [snip]
So you're saying that a traits class cannot have behavior?
Yes, that is what I am saying, weird as it might sound... Not "have" behavior, but certainly map to... yes, the distinction is partly philosophical, I admit that.
You're saying that, for example, std::char_traits<T>::length() means that std::char_traits is not a traits class?
No, in my twisted world view 'std::char_traits' is a trait (template) class manifesting some features of the Character concept. One of the features is a behavior, 'length.'
While I agree that there should be little behavior in traits classes as a rule, if that behavior is peculiar to the traits class (specialization of class template, typically), then it is reasonable.
It might be reasonable to let the trait (template) class map to certain behavioral features of the concept, yes. Again, the crucial part is that trait classes realize relationships and features found in the concept model, where you get the *actual* correspondents (types, values, and, yes, behavior) of the model provided as type parameter.
I say that because you can count on the consistency of that behavior and the specific behavior is based upon the combination of the traits class and the type for which you want the traits.
Ok, makes sense. If that kind of behavior is expected for all models of a concept, it might make sense to realize it via a trait, such as "std::char_traits<C>::eq(const C& c1, const C& c2)."
A trait should always be a meta function, but that is, obviously, not enough. It also has to map to entities that are associated with the types on which it acts, i.e., it has a Concept as its domain and the various related Concepts and Features as its ranges.
Again, I take it that you're excluding behavior, with which I disagree.
No, I am not excluding behavior. Some of the features in the Feature Model might be behavior, but when using GP in C++, one should use syntax as triggering the behavior, without going through traits, in my very humble opinion. That is, in C++ we define a number of pseduo-syntactical constructs, such as "The concept Comparable has an operator '<'" and use that '<', without going through a trait. Had C++ been a true GP-embedding language, like Haskell, we could have coded that constraint directly. So, we use template<typename T> T min(const T& t1, const T& t2) { return t1 < t2 ? t1 : t2; } instead of template<typename T> T min(const T& t1, const T& t2) { return rob::comp_trait<T>::less(t1, t2) ? t1 : t2; } [snip]
Gennadiy was trying to ask before about specific smart_ptr policies that don't have behavior. The implied question is that if they don't have any behavior, why are they called policies?
I missed that sub thread, but when the user code, such as a smart pointer framework, expects something to happen, in delegating to a policy object, even the absence of behavior is behavior... This touches at the focus of David A., in the use of the construct as the defining point.
Conversely, I recall that he was asking about some so-called traits classes that have behavior; were they wrongly classified?
I know that a lot of non-trait classes are called "..._traits." So, yes, some of them are wrongly classified, since a lot of people, even the highly skilled ones at certain committees, have used policy and trait interchangeably. [snip]
We use the trait as a meta function to access a policy. Simple.
I see what you mean, but it doesn't fit prior art, at least not to me.
I agree, sadly.
For me, a type that unequivocally associates information and yes, even behavior, with another type is a traits class.
For me, the trait concept is more tighly associated with a GP feature model and conceptual network, but I could swallow that view point, being more succinct and more down-to-earth C++-ish ;-), and change my semantics accordingly. Clean enough, in other words. The important, perhaps philosophical, issue is your use of "associated ... behavior," which is totally aligned with my view, i.e., *not*
A type that can be injected via template parameter to control the behavior of a template is a policy.
Yes [but in my world of development there are also runtime policies, implemented via objects.]
The distinction is whether all code has equal access to the information (traits) or whether only a specific template has the information (policy).
Hmm, but what happened to the nice injective property of policies of which you (and I) talked?
Traits are characteristics associated with another type.
Ok.
Policies are imposed by any client of the template using the policy.
So, you do share David A.'s view, that the usage is important? Is it fair to say that a policy is defined by its use and a trait by its describing characteristics of types? If so, it is fairly close to my original DESCRIBE/ACT dichotomy... ;)
(BTW, you might want to shorten your lines a bit so they don't get rewrapped after being quoted just a couple of times.)
I will, next time. /David

From: "David Bergman" <davidb@home.se>
Rob wrote:
So you're saying that a traits class cannot have behavior?
Yes, that is what I am saying, weird as it might sound... Not "have" behavior, but certainly map to... yes, the distinction is partly philosophical, I admit that.
You've lost me. I don't understand the distinction you're trying to make.
You're saying that, for example, std::char_traits<T>::length() means that std::char_traits is not a traits class?
No, in my twisted world view 'std::char_traits' is a trait (template) class manifesting some features of the Character concept. One of the features is a behavior, 'length.'
I'm further confused. For the record, std::char_traits is a traits class in my world.
While I agree that there should be little behavior in traits classes as a rule, if that behavior is peculiar to the traits class (specialization of class template, typically), then it is reasonable.
It might be reasonable to let the trait (template) class map to certain behavioral features of the concept, yes.
Try again. I don't understand what you're trying to say. If there's a static mf in the traits class, then it has behavior.
Again, the crucial part is that trait classes realize relationships and features found in the concept model, where you get the *actual* correspondents (types, values, and, yes, behavior) of the model provided as type parameter.
OK, I think I understand what you're trying to say here, but given my confusion with your previous statements, I must not.
I say that because you can count on the consistency of that behavior and the specific behavior is based upon the combination of the traits class and the type for which you want the traits.
Ok, makes sense. If that kind of behavior is expected for all models of a concept, it might make sense to realize it via a trait, such as "std::char_traits<C>::eq(const C& c1, const C& c2)."
Yep, std::char_traits has a static mf eq(), so it has behavior. Any specialization of std::char_traits is expected to provide that same mf unless some other aspect of that specialization precludes equality comparison so that clients know better than to try to use eq() in that case. [snip]
No, I am not excluding behavior. Some of the features in the Feature Model might be behavior, but when using GP in C++, one should use syntax as triggering the behavior, without going through traits, in my very humble
Isn't that beside the point? We're trying to figure out what traits and policies are, not whether we should use traits for a particular purpose.
opinion. That is, in C++ we define a number of pseduo-syntactical constructs, such as "The concept Comparable has an operator '<'" and use that '<', without going through a trait. Had C++ been a true GP-embedding language, like Haskell, we could have coded that constraint directly.
So, we use
template<typename T> T min(const T& t1, const T& t2) { return t1 < t2 ? t1 : t2; }
instead of
template<typename T> T min(const T& t1, const T& t2) { return rob::comp_trait<T>::less(t1, t2) ? t1 : t2; }
If we can rely on the "normal" semantics of operator <() for T, then that works great. If the "normal" semantics are not appropriate, then we must identify the alternative semantics ("rob::comp_trait<T>::less() in your example).
[snip]
We use the trait as a meta function to access a policy. Simple.
I see what you mean, but it doesn't fit prior art, at least not to me.
I agree, sadly.
For me, a type that unequivocally associates information and yes, even behavior, with another type is a traits class.
For me, the trait concept is more tighly associated with a GP feature model and conceptual network, but I could swallow that view point, being more succinct and more down-to-earth C++-ish ;-), and change my semantics accordingly. Clean enough, in other words. The important, perhaps philosophical, issue is your use of "associated ... behavior," which is totally aligned with my view, i.e., *not*
It seems like we agree, and then you say things like this. I don't understand the distinctions you're trying to make.
A type that can be injected via template parameter to control the behavior of a template is a policy.
Yes [but in my world of development there are also runtime policies, implemented via objects.]
Sure, but I'm focused on defining traits classes and policy classes.
The distinction is whether all code has equal access to the information (traits) or whether only a specific template has the information (policy).
Hmm, but what happened to the nice injective property of policies of which you (and I) talked?
It's still there, just implied: the specific template knows about the policy because it's a template argument.
Traits are characteristics associated with another type.
Ok.
Policies are imposed by any client of the template using the policy.
So, you do share David A.'s view, that the usage is important?
Is it fair to say that a policy is defined by its use and a trait by its describing characteristics of types? If so, it is fairly close to my original DESCRIBE/ACT dichotomy... ;)
No, I don't think you get the point I'm (feebly?) attempting to make. A policy class may be so because it was created expressly to be used as one among many policies for a template. A traits class may be a policy class in the context of its use as a template argument. However, such a class is still inherently a traits class because it was conceived to be used "globally" by its one name. I'll use std::char_traits and std::basic_string to make some more concrete points, but I'm not sure std::char_traits is a good example of anything for my purposes! std::char_traits is a traits class provided it is reasonable to use it by that name throughout your code. Gennadiy, or course, thinks that's how std::basic_string should have been implemented in the first place. (Many would agree.) I'm not sure that many (any?) people write code using std::char_traits by itself. If that is true, then std::char_traits is not a traits class. std::basic_string was implemented with a template parameter called "traits" which is, within std::basic_string a policy class. It just so happens that std::basic_string's "traits" policy has the same interface, for good or ill, as std::char_traits. Thus, std::char_traits can be used as std::basic_string's "traits" template argument, becoming a policy class within std::basic_string. Phew! I don't know if I helped or hurt my cause. It is partly a matter of intent, I guess. If the class is supposed to augment a type with additional (meta)information, then its a traits class. If its supposed to be used to parameterize a template in order to affect the behavior of the template, then its a policy class. If it serves both purposes, I'd call it a traits class. A more important distinction, perhaps, is whether the name is well known. A traits class is to be used by the same name in all contexts. A policy class may be aliased by being a template parameter and isn't supposed to be known by name for any other purpose. Did that help or hurt? -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

From: "David Bergman" <davidb@home.se>
First of all, I knew this was going to explode the conceptual network of the Boost community. We all pretend/think we know exactly what the difference is, and some of us have a fairly stable idea. None of us has a stable enough idea to formalize it into a communicable form. Alas, this is an important field of study, and for subsequent convergence.
That's exactly why I brought it up and, yes, I knew there's be a lot of input. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

From: "Hurd, Matthew" <hurdm@sig.com>
From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org]
On Behalf Of David Abrahams
Rob Stewart <stewart@sig.com> writes:
Can a method call be part of a trait class? I don't think traits should
In my book, certainly.
have anything to do with enacting behaviour (they may describe it).
I don't agree.
If it is not clear and I see a method I think of it as policy-like. A collection of types and static constants and I think of it as trait-like.
I only think of policies as template parameters that inject types, values, and functions to control the template. I think of traits as standalone entities known by their names. (That's not to say the latter can't be passed to a template to be used as the former.)
Traits are used to get information at compile time. Policies are used to modify behaviour. Traits could be used by a client to modify behaviour which makes them feel like a policy class, but they aren't in what we normally think of as a policy.
That's where we differ. In your example, the traits class is a policy class precisely because it is passed as a template parameter.
If a trait is used to direct the modification of behaviour, is it a policy from the client classes point of view I guess... which points to the terminology confusion.
A traits class is always used within the implementation by its well-known name.
Policies can be chained, multiply inherited from or just be ordinary template classes with static methods, maybe such different styles should have different names... a chain aspect, a base aspect (MCD-like), a static aspect...
I don't see how being able to chain policies requires a new name. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
participants (7)
-
David B. Held
-
David Bergman
-
E. Gladyshev
-
Gennadiy Rozental
-
Hurd, Matthew
-
Peter Dimov
-
Rob Stewart