Boost logo

Boost :

From: John Max Skaller (skaller_at_[hidden])
Date: 2001-08-18 20:10:43


Douglas Gregor wrote:

> > but such a decomposition only works for some constructions.
> > Other constructions cannot be wrapped. For example,
> > functions with n arguments, where n exceeds the number
> > supported by the library. Struct member access,
> > pointer to member formation, exception handling,
> > multiple inheritance ... the list is long.
>
> Most of these are possible - "n" can always be increased (and most libraries
> make it easy),

        ? I don't see how, unless the library is generated
by a program, and typically the exponential increase in size
creates an effective limit anyhow: header files in excess
of several megs aren't really practical :-)

> Lambda supports exception handling; struct member
> access/pointer to member formation can be done (just form a pointer-to-member
> and pass it).

        But that's the point: the library cannot do it, only
'lift' existing constructions: you can't write a template which
does the effect of:

        get<S,member_name>()

instead, you have to code

        get<S, &S::member_name>()

using an actual pointer to member. Considering the core language
algebra here is incomplete, I end up using

        offsetof(S,member_name)

anyhow.

This is not the case for tuples,
where you really _can_ generalise to 'nth component' with code like

        get<S,n>

provided n is statically known.

> An identifier is worth a hundred comments, IMHO. This is by far more of a
> religious issue than any other, but given:
>
> Container container;
> for(Container::iterator i = container.begin(), i != container.end(); ++i)
> {
> // code that does something
> }
>
> vs.
>
> for_each(container.begin(), container.end(), doSomething());
>
> I'll almost always take the second version, because doSomething can be an
> identifier that concisely state what operation is performed on each object.
> It couldn't possibly read more clearly.

        I agree -- provided you can wrap up the 'doSomething'
locally. Of course, you can do exactly this with ease in
functional programming languages. Even if you can do it with
libraries like Lambda in C++, the question has to be asked
why you are using a high level functional programming paradigm
with a language that isn't suited to it? You've obviously
recognized the requirements for good programming -- so why
not use an actual good programming language?

        One answer: 'management insists on C++' is obvious,
and another 'compatibility' is also fairly clear: are there
other reasons? I'm quite interested because

        a) I use Ocaml instead of C++ wherever possible
        b) I'm building Felix to address the compatibility
           issue (Felix is ML like, but supposedly provides
           seamless integration with C++)
        c) I may have missed something

The most interesting answer is: 'templates can do things
that no existing FP language can support'. I believe that
is the case, but I'm not sure. In particular, STL shows
how you can build iterators which are polymorphic on
the data functor (i.e. the container kind), and
this is not possible in ML.

An answer which no longer seems to be valid is 'efficiency',
since it seems Ocaml, Lisp, SML, and most other FP languages
now outperform C++ significantly (more likely due to the
style of coding than anything else, since C is still fastest)

-- 
John (Max) Skaller, mailto:skaller_at_[hidden] 
10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850
New generation programming language Felix  http://felix.sourceforge.net
Literate Programming tool Interscript     
http://Interscript.sourceforge.net

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk