
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