Boost logo

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