
From: FlSt@gmx.de
[...]
Don't forget attributions for the text you quote.
If that is a useful expression, it's more of a set operation than a junction operation (as exemplified by Perl's junctions) anyway,
http://www.linux-magazine.com/issue/38/Perl_BlackJack.pdf. This is the article from where my idea comes to have something similar in C++ (I read the German translation in Linux Magazin 12/2003)
I see. That elucidates the duality concept you've been discussing.
right? Besides, normal algorithms can be used to express that quite succinctly. Do you need a new type for it? Maybe. I don't think it should be merged with the simpler ideas from Perl junctions. I think they are orthogonal behaviors, and the complexity argues against one type doing both tasks.
The Perl junctions aren't simpler, in Perl you can call functions either in a scalar context or in a list context. The called function can determine in which context it is called and return a scalar or a list. I think my mistake was, I tried to bring this concept into C++ for junctions, but it doesn't fit into the C++ type system. And there was no example for this in the article I denoted in my first message.
OK. You did mislead me with the initial references, but I now understand what you were trying to do.
A junction without junction result type and arithmetic operations is something completely different I had in mind at the beginning of this discussion. What remains now at the view point of the client are the
I think the creation of a new container with elements from another container that match a criteria is already well supported. It may yet be that some syntactic sugar can be overlaid to simplify it, however, so do keep that in mind. So, I think we're agreed that we're discussing four things that can be compared to each other as well as to single values. The supported comparisons are ==, !=, <, >, <=, and >=. If we're agreed, then we can discuss design.
four functions any_of<T>, all_of<T>, one_of<T> and none_of<T> and the comparison operators. The XXX_of functions should operate on ranges or containers. I aggree.
For the extraction of elements matching some criteria, you would likely use function templates. For the functionality we've whittled down junctions (or whatever name still fits) to include, you need types plus namespace scope operators: template <typename T> struct junction { range<T> range_; // for exposition only }; template <typename T> struct all_of : junction<T> { }; template <typename T> struct any_of : junction<T> { }; template <typename T> struct none_of : junction<T> { }; template <typename T> struct one_of : junction<T> { }; template <typename LHS, typename T> bool operator ==(call_traits<LHS>::param_type lhs_i, any_of<T> rhs_i); // maybe by reference to const template <typename LHS, typename T> bool operator !=(call_traits<LHS>::param_type lhs_i, any_of<T> rhs_i); // maybe by reference to const template <typename LHS, typename T> bool operator <(call_traits<LHS>::param_type lhs_i, any_of<T> rhs_i); // maybe by reference to const template <typename LHS, typename T> bool operator >(call_traits<LHS>::param_type lhs_i, any_of<T> rhs_i); // maybe by reference to const template <typename LHS, typename T> bool operator <=(call_traits<LHS>::param_type lhs_i, any_of<T> rhs_i); // maybe by reference to const template <typename LHS, typename T> bool operator >=(call_traits<LHS>::param_type lhs_i, any_of<T> rhs_i); // maybe by reference to const template < typename T, typename RHS> bool operator ==(any_of<T> rhs_i, // maybe by reference to const call_traits<RHS>::param_type rhs_i); etc. template <typename LHS, typename T> bool operator ==(call_traits<LHS>::param_type lhs_i, all_of<T> rhs_i); // maybe by reference to const etc., including those to compare any_of with all_of, all_of with one_of, and so on. Many of these operators will be defined in terms of others. For example, once you have the (lhs_i, any_of) operators, the (any_of, rhs_i) operators can be defined in terms of the former. Also, you can define the (lhs_i, all_of) operators in terms of the (lhs_i, any_of) operators, provided you can create an any_of<T> from an all_of<T>: template <typename T> struct any_of : junction<T> { explicit any_of(junction<T> junction_i); // maybe by reference to const }; Indeed, most cases can be handled once you implement the any_of and one_of variants. A better approach is probably for the operators to be implemented in terms of a number of implementation function templates that work only on junction<T>'s. Then, there's no conversion needed; the operators just need to call the right implementation function. That leaves the four derived types as just selectors for the right operator. Ideally, junction<T> will hide its range and the implementation function templates will be made friends. Using namespace scope operators, with the four derived types as selectors, we can support any combination of x op all_of(s), x op any_of(x), x op none_of(s), x op one_of(s), where x is a type convertible to the range's value type or another all_of, any_of, none_of, or one_of. What do you think of these ideas for the design? There's still the issue of naming. Should these be called junctions since they don't do all that Perl's junctions do? Besides, I think "junction" somehow fits better the notion of producing a result container that includes those elements of the range that satisfy the criteria. Quantum physics' superposition concept doesn't fit very well, because we're not talking about particles that can be in various places. That suggests "supervalue," but one might then ask, what makes the value so super? A common theme suggests "smart value," but that's not really helpful. At least the one-word "supervalue" is somehow indicative of "superposition." So, when someone is looking for a library to do what this one does, what name(s) would they think to look for? I'm at a loss for a good name. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;