|
Boost : |
From: Andrei Alexandrescu (andrewalex_at_[hidden])
Date: 2002-04-13 12:09:48
"Vesa Karvonen" <vesa_karvonen_at_[hidden]> wrote in message
news:F289vDzPfYYXp0hFlJl0000d048_at_hotmail.com...
> Aleksey Gurtovoy:
> >Joel de Guzman:
> > > > Are you familiar with functional programming?
> > >
> > > What's the point of this question? To gauge my level of
competence
> > > to form an opinion?
> >
> >No, not at all. I just didn't want to reveal the second question
> >before you answer the first one :). The argument about "simplicity"
of
> >pattern-matching-self-recursive-partial-specialized 'count_if'
> >implementation is partially built around the assumption that it's
easy
> >to understand for somebody with functional programming background.
To
> >me, functional programming primitives like 'fold' et al. seem much
> >more important concepts than any esoteric low-level patterns
matching.
>
> FWIW, IMO, Aleksey is right here, and people who don't understand
the
> purpose of higher order sequence manipulation functions should
really read
> some book on functional programming.
Higher order sequence manipulation functions are indeed important.
Where I think otherwise is the simplicity argument.
IMHO, understanding matching for template arguments in the context of
C++ does not ask for a functional programming background. It asks for
C++ background. Template arguments are matched to template parameters,
and this is a fact of C++. This C++ feature can be useful in a number
of contexts.
My argument on the simplicity of the pattern-matching implementation
of count_if is NOT based on the assumption that people with functional
programming background would be comfortable with it. (I am not much of
a functional programmer myself.)
The implementation of count_if as a library artifact is largely
irrelevant. As long as a library function respects an interface, the
library user can only appreciate a more sophisticated implementation.
I understand we are discussing count_if as an example of typical
implementation of a user-defined algorithm.
Again, let me post some simple measurements of the two variants of
count_if.
The count_if implementation using mpl has 34 lines, defines 3 new
types, 1 new namespace, and relies on 5 artifacts defined elsewhere.
The count-if that works only for dot-typelists has 15 lines, defines 1
new type, and does not rely on any other artifacts than the typelist
itself.
This being said, my argument on the simplicity of the pattern-matching
implementation of count_if is based on the following points:
1. Show the sheer code to a C++ programmer. For completeness' sake, I
appended the code at the end of this post.
2. 15 < 34
3. 1 < 3
4. 0 < 1
5. 1 < 5
Several people have repeatedly asked for self-contained, sensical
examples demonstrating that using the style pioneered by MPL leads to
a good solution. I believe this is reasonable to ask for.
Andrei
-- Appendix: --------------- Version of count_if using MPL's facilities --------------- namespace aux { template< typename Predicate > struct next_if { template< typename N , typename T > struct apply { typedef typename select_if< apply<Predicate,T>::value , typename next<N>::type , N >::type type; }; }; } // namespace aux template< typename Sequence , typename Predicate > struct count_if { typedef typename fold< Sequence , integral_c<unsigned long, 0> , aux::next_if<Predicate> >::type type; BOOST_STATIC_CONSTANT(unsigned long , value = type::value ); }; --------------- Version of count_if that works on dot-typelists only --------------- template <class TList, class Predicate> struct count_if; template <class Predicate> struct count_if<Nulltype, Predicate> { BOOST_STATIC_CONSTANT( unsigned long, value = 0); }; template <class H, class T, class Predicate> struct count_if<typelist<H, T>, Predicate> { BOOST_STATIC_CONSTANT( unsigned long, value = (Predicate::apply<H>::value ? 1 : 0) + count_if<T, Predicate>::value); };
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk