|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-08-18 20:54:24
On Saturday 18 August 2001 09:10, you wrote:
> 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 :-)
Practically speaking one shouldn't need very large n. In many cases, the size
increase is only linear, and there is a practical limit on "n" beyond which
users will be hopelessly confused by the number of arguments (template,
function, or otherwise). The PREPROCESSOR library makes it (relatively) easy
to create libraries that can have a compile-time parameter (i.e., macro) for
n. I would hope that after the introduction of the PREPROCESSOR library,
those libraries that have an argument limit (tuples, function, bind, and
probably others) will migrate to use it an we can establish an overall
switch: compile with -DBOOST_MAX_ARGS=n and you get support for up to n
arguments from all of the Boost libraries.
> > 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.
It's more of an interface issue than a restriction on the language. Yes, the
get<S, member_name>() syntax would be useful, but does it enable
functionality that isn't achievable without it? I can't come up with an
example of any functionality gained at this time.
> 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.
Yes.
> > 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?
I happen to like C++'s possibilities. The fact that it can be extended via
_libraries_ to support new programming pardigms places it solidly ahead of
the majority of languages available today.
> 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.
Bingo. Generic programming is my area of interest, and C++ offers a powerful
environment for exploring generic programming. I have yet to see a language
that tops it in terms of 'explorability'. Indeed, many language designers are
shying aware from or crippling the notion of templates because "it's too
hard" (trying hard not to name language extension proposals...).
> 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)
I believe some of it has to do with compiler technology. I don't think
optimizations for C++ are well understood, because C++ optimizers essentially
don't exist in production compilers. The same old C optimizers are used for
C++ compilers, and information that may exist at the level of abstraction the
user sees (abstract data types) is completely unused. FP, on the other hand,
has been studied from an optimization point of view and is reaping the
rewards now.
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk