What are the benefits of using Boost.Phoenix? - c++

I can not understand what the real benefits of using Boost.Phoenix.
When I use it with Boost.Spirit grammars, it's really useful:
double_[ boost::phoenix::push_back( boost::phoenix::ref( v ), _1 ) ]
When I use it for lambda functions, it's also useful and elegant:
boost::range::for_each( my_string, if_ ( '\\' == arg1 ) [ arg1 = '/' ] );
But what are the benefits of everything else in this library? The documentation says: "Functors everywhere". I don't understand what is the good of it?

I'll point you out what is the critical difference between Boost.Lambda and Boost.Phoenix:
Boost.Phoenix supports (statically) polymorphic functors, while Boost.Lambda binds are always monomorphic.
(At the same time, in many aspects the two libraries can be combined, so they are not exclusive choices.)
Let me illustrate (Warning: Code not tested.):
Phoenix
In Phoenix a functor can converted into a Phoenix "lazy function" (from http://www.boost.org/doc/libs/1_54_0/libs/phoenix/doc/html/phoenix/starter_kit/lazy_functions.html)
struct is_odd_impl{
typedef bool result_type; // less necessary in C++11
template <typename Arg>
bool operator()(Arg arg1) const{
return arg1 % 2 == 1;
}
};
boost::phoenix::function<is_odd_impl> is_odd;
is_odd is truly polymorphic (as the functor is_odd_impl). That is is_odd(_1) can act on anything (that makes sense). For example in is_odd(_1)(2u)==true and is_odd(_1)(2l)==true. is_odd can be combined into a more complex expression without losing its polymorphic behavior.
Lambda attempt
What is the closest we can get to this in Boost.Lambda?, we could defined two overloads:
bool is_odd_overload(unsigned arg1){return arg1 % 2 == 1;}
bool is_odd_overload(long arg1){return arg1 % 2 == 1;}
but to create a Lambda "lazy function" we will have to choose one of the two:
using boost::lambda::bind;
auto f0 = bind(&is_odd_overload, _1); // not ok, cannot resolve what of the two.
auto f1 = bind(static_cast<bool(*)(unsigned)>(&is_odd_overload), _1); //ok, but choice has been made
auto f2 = bind(static_cast<bool(*)(long)>(&is_odd_overload), _1); //ok, but choice has been made
Even if we define a template version
template<class T>
bool is_odd_template(T arg1){return arg1 % 2 == 1;}
we will have to bind to a particular instance of the template function, for example
auto f3 = bind(&is_odd_template<unsigned>, _1); // not tested
Neither f1 nor f2 nor f3 are truly polymorphic since a choice has been made at the time of binding.
(Note1: this may not be the best example since things may seem to work due to implicit conversions from unsigned to long, but that is another matter.)
To summarize, given a polymorphic function/functor Lambda cannot bind to the polymorphic function (as far as I know), while Phoenix can. It is true that Phoenix relies on the "Result Of protocol" http://www.boost.org/doc/libs/1_54_0/libs/utility/utility.htm#result_of but 1) at least it is possible, 2) This is less of a problem in C++11, where return types are very easy to deduce and it can be done automatically.
In fact, in C++11, Phoenix lambdas are still more powerful than C++11
built-in lambdas. Even in C++14, where template generic lambdas are
implemented, Phoenix is still more general, because it allows a
certain level of introspection. (For this an other things, Joel de
Guzman (developer of Phoenix) was and still is well ahead of his
time.)

Well, its a very powerful lambda language.
I used it to create a prototype for a math-like DSL:
http://code.google.com/p/asadchev/source/browse/trunk/work/cxx/interval.hpp
and many other things:
http://code.google.com/p/asadchev/source/browse/#svn%2Ftrunk%2Fprojects%2Fboost%2Fphoenix

I have never used Phoenix, but...
From the Phoenix Library docs:
The Phoenix library enables FP techniques such as higher order functions, lambda (unnamed functions), currying (partial function application) and lazy evaluation in C++
From the Wikipedia article on Functional programming:
... functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data. It emphasizes the application of functions, in contrast to the imperative programming style, which emphasizes changes in state
So, Phoenix is a library for enabling Functional Programming in C++.
The major interest in Functional Programming these days seems to stem from the perceived advantages in correctness, and performance, due to limiting or eliminating side-effects.
Correctness, because without side-effects, the code that you see is everything going on in the system. Some other code won't be changing your state underneath you. You can much more easily write bug-free code in this sort of environment.
Performance, because without side-effects, the code you write can safely run in parallel, without any resource managing primitives, or atomic-access tricks. Multi-threading can be enabled extremely easily, even automatically, and operate extremely efficiently.

Don't look at Boost.Phoenix2.
Evolution of lambda expressions in boost looks like:
Bind -> Lambda, Phoenix2 (as Spirit part) -> Phoenix3 (as separate library, under development).
Result is single lambda-library with polymorphic functors support (others are going to become deprecated).

Functional programming in C++. It's hard to explain unless you have previously used a language with proper support for functional programming, such as SML. I tried to use Phoenix and found it nice, but very impractical in real-life projects because it greatly increases compilation times, and error messages are awful when you do something wrong. I rememeber getting a few megabytes of errors from GCC when I played with Phoenix. Also, debugging deeply nested template instantiations is a PITA. (Actually, these are also all the arguments against using most of boost.)

Related

Could std::foo::transform one day support any functor?

std::transform from the <algorithm> header applies to ranges, and it is what "enables" us to use ranges as the functors they are (in the sense of category theory(¹)). std::transform is iterator-based, yes, but std::ranges::views::transform is not, and its signature closely matches the signature of corresponding functions in functional languages (modulo the different order of the two arguments, but this is not a big deal).
When I saw this question (and in the process of answering to it), I learned that C++23 introduces std::optional<T>::transform, which makes std::optional a functor too.
All these news truly excite me, but I can't help thinking that functors are general, and that it'd be nice to have a uniform interface to transform any functor, as is the case in Haskell, for instance.
This makes me think that an object similar to std::ranges::views::transform (with a different name not alluding to ranges) could be made a customization point that the STL would customize not just for ranges, but also for std::optional and for any other functor in the STL, whereas the programmer could customize it for their user-defined classes.
Quite similarly, C++23 also introduces std::optional<T>::and_then, which is basically the monadic binding for std::optional. I'm not aware of any similar function that implements monadic binding for ranges, but C++20's some_range | std::ranges::views::transform(f) | std::ranges::views::join is essentially the monadic binding of some_range with f.
And this makes me think that there could be some generic interface, name it mbind, that one can opt in with any type. The STL would opt in for std::optional by implementing it in terms of std::optional<T>::and_then, for instance.
Is there any chance, or are there any plans that the language will one day support such a genericity?
I can certainly see some problems. Today std::ranges::views::transform(some_optional, some_func) is invalid, so some code might be relying on that via SFINAE. Making it suddenly work would break the code.
(¹) As regards the word functor, I refer to the definition that is given in category theory (see also this), not to the concept of "object of a class which has operator() defined"; the latter is not defined anywhere in the standard and is not even mentioned on cppreference, which instead uses the term FunctionObject to refer to
an object that can be used on the left of the function call operator
I'm not aware of any similar function that implements monadic binding for ranges, but C++20's some_range | std::ranges::views::transform(f) | std::ranges::views::join is essentially the monadic binding of some_range with f.
ranges::views::for_each is monadic bind for ranges (read), although it is just views::transform | views::join under the hood.
As for whether you'll get a generic interface for Functor and Monad. I doubt it unless such genericity will be useful to library writers writing templates. std::expiremental::future is monadic also (and I imagine Executors are too), so one could to write generic algorithms such as foldM over these three types. I think Erik Niebler has shown with range-v3 that it is possible to write a Functor/Monad library at the expense of hand coding every pipe operator i.e.
#include <fp_extremist.hpp>
template <typename M> requires Monad<M>
auto func(M m)
{
return m
| fp::extremist::fmap([](auto a) { return ...; })
| fp::extremist::mbind([](auto b) { return ...; })
;
}
What I think is actually possible, is that we'll get UFCS and a |> operator so we can get the benefits of invocable |> east syntax and the ability to pipe to algorithms. From Barry's blog:
It doesn’t work because while the range adapters are pipeable, the algorithms are not. ...
That is, x |> f still evaluates as f(x) as before… but x |> f(y) evaluates as f(x, y).
P.S. it's not hard to give the definition of a Functor in c++: <typename T> struct that provides transform.
P.S.S
Edit: I realised how to handle applicatives.
Applicative<int> a, b, c;
auto out = a
| zip_transform(b, c
, [](int a, int b, int c){ return a + b + c; })
;
zip_transform because it zips a, b, c into a Applicative<std::tuple<int, int, int>> and then transforms it (think optional, future, range). Although you could always work with Applicatives of partially applied functions, but that would involve lots of nested functions which is not the style of c++ and would disrupt the top to bottom reading order.
And this makes me think that there could be some generic interface, name it mbind, that one can opt in with any type. ...
Is there any chance, or are there any plans that the language will one
day support such a genericity?
There is P0650 which proposes a non-member monadic interface, customizable using traits. The paper shows customizations for expected and other types, implementable in C++17.
The accepted proposal for std::optional monadic operations P0798 §13.1 references P0650 while discussing alternatives to member-function syntax:
Unfortunately doing the kind of composition described above would be very verbose with the current proposal without some kind of Haskell-style do notation
std::optional<int> get_cute_cat(const image& img) {
return functor::map(
functor::map(
monad::bind(
monad::bind(crop_to_cat(img),
add_bow_tie),
make_eyes_sparkle),
make_smaller),
add_rainbow);
}
My proposal is not necessarily an alternative to [P0650]; compatibility between the two could be ensured and the generic proposal could use my proposal as part of its implementation.
It goes on to mention how other C++ features still in development, like unified call syntax, might provide a more concise syntax for generic monadic operations.
The accepted proposal for std::expected monadic operations P2505 doesn't reference P0650 directly, but discusses "Free vs member functions" as part of its design considerations, ultimately prioritizing consistency with the std::optional monadic interface.

What are the use cases of C++20 Concepts?

I found about Concepts while reviewing C++20 features. I found that they add validation to templates arguments but apart from that I don't understand what are the real world use cases of C++20 concepts.
C++ already has things like std::is_integral and they can perform validation very well.
I'm sure I am missing something about C++20 concepts and what it enables.
SFINAE (see here & here) was an accidentally Turing complete sublanguage that executes at overload resolution and template specialization selection time.
Turns out it is used a lot in template code.
Concepts and requires clauses are an attempt to take that accidentally useful language feature and make it suck less.
The origin of concepts was going to have 3 pieces; (a) describing what is required for a given bit of template code in a clean way, (b) also provide a way to map other types to satisfy those requirements non-intrusively, and (c) check template code so that any type which satisfies the concept is guaranteed to compile
All attempts at (a) plus (c) sucked, usually taking forever to compile and/or restricting what you can check with (a). (b) was also dropped to ensure (a) was better; you can write such concept map machinery manually in many cases, but C++ doesn't provide it for you.
So, now what is it good for?
auto sum( Addable auto... values )
that uses the concept of Addable to concisely express an interface of a template. Error messages you get when passing a non-addable highlight it isn't Addable, and the expression that doesn't work.
template<class T, class A>
struct vector{
bool operator==(vector<t,A>const& o)requires EquallyComparible<T>;
};
here, we state this vector has a == if and only if the T does. Doing this before concepts is an annoying undertaking, and even adding the specs to the standard is.
This is the turing tar pit; everyting is equivalent, but nothing is easy. All programs can be written with I/O plus a (a=(a-b);(a<0)?goto c:next 3 argument instruction; but a richer language makes programs suck less. Concepts takes an esoteric branch of C++, SFINAE, and makes it clean and simpler (so more people can leverage it), and improves error messages.

Efficiency of std::bind vs lambda

I have searched around a bit and found many examples and discussions of cases where you would use std::bind instead of a lambda, but the burning question I have is whether or not there is any performance benefit to one over the other. I will describe my use case:
I have a generic A* I have implemented, to which I pass successor, heuristic distance, and move cost functions.
Here is an example of my heuristic function ready to be passed off for a search (in both forms):
std::function<float(const Location*, const Location*)> hdist = std::bind(&TerrainMap::straightLineDist, this, std::placeholders::_1, std::placeholders::_2);
std::function<float(const Location*, const Location*)> hdist2 = [this](const Location* a, const Location* b){
return straightLineDist(a,b);
};
Is there any difference in the performance of these approaches? I realize the difference is probably negligible but I am curious enough to want to know.
Is there any difference in the performance of these approaches?
Perhaps, perhaps not; as commenters suggest - profile to check, or look at the assemby code you get (e.g. using the GodBolt Compiler Explorer). But you're asking the wrong question, for two main reasons:
You should probably not be passing lambda's, nor bind() results, around in the part of your code that's performance-critical.
You should definitely avoid invoking arbitrary functions via function pointer or std::function variables in performance-critical areas of your code (except if this can be de-virtualized and inlined by the compiler).
and one mind reason:
Lambdas (and std::bind()'s) are usable, and useful, without being wrapped in std::function; this wrapper has its own performance penalty, so you would only be comparing one way of using these constructs.
Bottom line recommendation: Just use Lambdas. They're cleaner, easier to understand, cheaper to compile, and more flexible syntactically. So don't worry and be happy :-) . And in performance-critical code, either use Lambda's without std::function, or don't use any of the two.

Are there any C++ language obstacles that prevent adopting D ranges?

This is a C++ / D cross-over question. The D programming language has ranges that -in contrast to C++ libraries such as Boost.Range- are not based on iterator pairs. The official C++ Ranges Study Group seems to have been bogged down in nailing a technical specification.
Question: does the current C++11 or the upcoming C++14 Standard have any obstacles that prevent adopting D ranges -as well as a suitably rangefied version of <algorithm>- wholesale?
I don't know D or its ranges well enough, but they seem lazy and composable as well as capable of providing a superset of the STL's algorithms. Given their claim to success for D, it would seem very nice to have as a library for C++. I wonder how essential D's unique features (e.g. string mixins, uniform function call syntax) were for implementing its ranges, and whether C++ could mimic that without too much effort (e.g. C++14 constexpr seems quite similar to D compile-time function evaluation)
Note: I am seeking technical answers, not opinions whether D ranges are the right design to have as a C++ library.
I don't think there is any inherent technical limitation in C++ which would make it impossible to define a system of D-style ranges and corresponding algorithms in C++. The biggest language level problem would be that C++ range-based for-loops require that begin() and end() can be used on the ranges but assuming we would go to the length of defining a library using D-style ranges, extending range-based for-loops to deal with them seems a marginal change.
The main technical problem I have encountered when experimenting with algorithms on D-style ranges in C++ was that I couldn't make the algorithms as fast as my iterator (actually, cursor) based implementations. Of course, this could just be my algorithm implementations but I haven't seen anybody providing a reasonable set of D-style range based algorithms in C++ which I could profile against. Performance is important and the C++ standard library shall provide, at least, weakly efficient implementations of algorithms (a generic implementation of an algorithm is called weakly efficient if it is at least as fast when applied to a data structure as a custom implementation of the same algorithm using the same data structure using the same programming language). I wasn't able to create weakly efficient algorithms based on D-style ranges and my objective are actually strongly efficient algorithms (similar to weakly efficient but allowing any programming language and only assuming the same underlying hardware).
When experimenting with D-style range based algorithms I found the algorithms a lot harder to implement than iterator-based algorithms and found it necessary to deal with kludges to work around some of their limitations. Of course, not everything in the current way algorithms are specified in C++ is perfect either. A rough outline of how I want to change the algorithms and the abstractions they work with is on may STL 2.0 page. This page doesn't really deal much with ranges, however, as this is a related but somewhat different topic. I would rather envision iterator (well, really cursor) based ranges than D-style ranges but the question wasn't about that.
One technical problem all range abstractions in C++ do face is having to deal with temporary objects in a reasonable way. For example, consider this expression:
auto result = ranges::unique(ranges::sort(std::vector<int>{ read_integers() }));
In dependent of whether ranges::sort() or ranges::unique() are lazy or not, the representation of the temporary range needs to be dealt with. Merely providing a view of the source range isn't an option for either of these algorithms because the temporary object will go away at the end of the expression. One possibility could be to move the range if it comes in as r-value, requiring different result for both ranges::sort() and ranges::unique() to distinguish the cases of the actual argument being either a temporary object or an object kept alive independently. D doesn't have this particular problem because it is garbage collected and the source range would, thus, be kept alive in either case.
The above example also shows one of the problems with possibly lazy evaluated algorithm: since any type, including types which can't be spelled out otherwise, can be deduced by auto variables or templated functions, there is nothing forcing the lazy evaluation at the end of an expression. Thus, the results from the expression templates can be obtained and the algorithm isn't really executed. That is, if an l-value is passed to an algorithm, it needs to be made sure that the expression is actually evaluated to obtain the actual effect. For example, any sort() algorithm mutating the entire sequence clearly does the mutation in-place (if you want a version doesn't do it in-place just copy the container and apply the in-place version; if you only have a non-in-place version you can't avoid the extra sequence which may be an immediate problem, e.g., for gigantic sequences). Assuming it is lazy in some way the l-value access to the original sequence provides a peak into the current status which is almost certainly a bad thing. This may imply that lazy evaluation of mutating algorithms isn't such a great idea anyway.
In any case, there are some aspects of C++ which make it impossible to immediately adopt the D-sytle ranges although the same considerations also apply to other range abstractions. I'd think these considerations are, thus, somewhat out of scope for the question, too. Also, the obvious "solution" to the first of the problems (add garbage collection) is unlikely to happen. I don't know if there is a solution to the second problem in D. There may emerge a solution to the second problem (tentatively dubbed operator auto) but I'm not aware of a concrete proposal or how such a feature would actually look like.
BTW, the Ranges Study Group isn't really bogged down by any technical details. So far, we merely tried to find out what problems we are actually trying to solve and to scope out, to some extend, the solution space. Also, groups generally don't get any work done, at all! The actual work is always done by individuals, often by very few individuals. Since a major part of the work is actually designing a set of abstractions I would expect that the foundations of any results of the Ranges Study Group is done by 1 to 3 individuals who have some vision of what is needed and how it should look like.
My C++11 knowledge is much more limited than I'd like it to be, so there may be newer features which improve things that I'm not aware of yet, but there are three areas that I can think of at the moment which are at least problematic: template constraints, static if, and type introspection.
In D, a range-based function will usually have a template constraint on it indicating which type of ranges it accepts (e.g. forward range vs random-access range). For instance, here's a simplified signature for std.algorithm.sort:
auto sort(alias less = "a < b", Range)(Range r)
if(isRandomAccessRange!Range &&
hasSlicing!Range &&
hasLength!Range)
{...}
It checks that the type being passed in is a random-access range, that it can be sliced, and that it has a length property. Any type which does not satisfy those requirements will not compile with sort, and when the template constraint fails, it makes it clear to the programmer why their type won't work with sort (rather than just giving a nasty compiler error from in the middle of the templated function when it fails to compile with the given type).
Now, while that may just seem like a usability improvement over just giving a compilation error when sort fails to compile because the type doesn't have the right operations, it actually has a large impact on function overloading as well as type introspection. For instance, here are two of std.algorithm.find's overloads:
R find(alias pred = "a == b", R, E)(R haystack, E needle)
if(isInputRange!R &&
is(typeof(binaryFun!pred(haystack.front, needle)) : bool))
{...}
R1 find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle)
if(isForwardRange!R1 && isForwardRange!R2 &&
is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool) &&
!isRandomAccessRange!R1)
{...}
The first one accepts a needle which is only a single element, whereas the second accepts a needle which is a forward range. The two are able to have different parameter types based purely on the template constraints and can have drastically different code internally. Without something like template constraints, you can't have templated functions which are overloaded on attributes of their arguments (as opposed to being overloaded on the specific types themselves), which makes it much harder (if not impossible) to have different implementations based on the genre of range being used (e.g. input range vs forward range) or other attributes of the types being used. Some work has been being done in this area in C++ with concepts and similar ideas, but AFAIK, C++ is still seriously lacking in the features necessary to overload templates (be they templated functions or templated types) based on the attributes of their argument types rather than specializing on specific argument types (as occurs with template specialization).
A related feature would be static if. It's the same as if, except that its condition is evaluated at compile time, and whether it's true or false will actually determine which branch is compiled in as opposed to which branch is run. It allows you to branch code based on conditions known at compile time. e.g.
static if(isDynamicArray!T)
{}
else
{}
or
static if(isRandomAccessRange!Range)
{}
else static if(isBidirectionalRange!Range)
{}
else static if(isForwardRange!Range)
{}
else static if(isInputRange!Range)
{}
else
static assert(0, Range.stringof ~ " is not a valid range!");
static if can to some extent obviate the need for template constraints, as you can essentially put the overloads for a templated function within a single function. e.g.
R find(alias pred = "a == b", R, E)(R haystack, E needle)
{
static if(isInputRange!R &&
is(typeof(binaryFun!pred(haystack.front, needle)) : bool))
{...}
else static if(isForwardRange!R1 && isForwardRange!R2 &&
is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool) &&
!isRandomAccessRange!R1)
{...}
}
but that still results in nastier errors when compilation fails and actually makes it so that you can't overload the template (at least with D's implementation), because overloading is determined before the template is instantiated. So, you can use static if to specialize pieces of a template implementation, but it doesn't quite get you enough of what template constraints get you to not need template constraints (or something similar).
Rather, static if is excellent for doing stuff like specializing only a piece of your function's implementation or for making it so that a range type can properly inherit the attributes of the range type that it's wrapping. For instance, if you call std.algorithm.map on an array of integers, the resultant range can have slicing (because the source range does), whereas if you called map on a range which didn't have slicing (e.g. the ranges returned by std.algorithm.filter can't have slicing), then the resultant ranges won't have slicing. In order to do that, map uses static if to compile in opSlice only when the source range supports it. Currently, map 's code that does this looks like
static if (hasSlicing!R)
{
static if (is(typeof(_input[ulong.max .. ulong.max])))
private alias opSlice_t = ulong;
else
private alias opSlice_t = uint;
static if (hasLength!R)
{
auto opSlice(opSlice_t low, opSlice_t high)
{
return typeof(this)(_input[low .. high]);
}
}
else static if (is(typeof(_input[opSlice_t.max .. $])))
{
struct DollarToken{}
enum opDollar = DollarToken.init;
auto opSlice(opSlice_t low, DollarToken)
{
return typeof(this)(_input[low .. $]);
}
auto opSlice(opSlice_t low, opSlice_t high)
{
return this[low .. $].take(high - low);
}
}
}
This is code in the type definition of map's return type, and whether that code is compiled in or not depends entirely on the results of the static ifs, none of which could be replaced with template specializations based on specific types without having to write a new specialized template for map for every new type that you use with it (which obviously isn't tenable). In order to compile in code based on attributes of types rather than with specific types, you really need something like static if (which C++ does not currently have).
The third major item which C++ is lacking (and which I've more or less touched on throughout) is type introspection. The fact that you can do something like is(typeof(binaryFun!pred(haystack.front, needle)) : bool) or isForwardRange!Range is crucial. Without the ability to check whether a particular type has a particular set of attributes or that a particular piece of code compiles, you can't even write the conditions which template constraints and static if use. For instance, std.range.isInputRange looks something like this
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
{
R r = void; // can define a range object
if (r.empty) {} // can test for empty
r.popFront(); // can invoke popFront()
auto h = r.front; // can get the front of the range
}));
}
It checks that a particular piece of code compiles for the given type. If it does, then that type can be used as an input range. If it doesn't, then it can't. AFAIK, it's impossible to do anything even vaguely like this in C++. But to sanely implement ranges, you really need to be able to do stuff like have isInputRange or test whether a particular type compiles with sort - is(typeof(sort(myRange))). Without that, you can't specialize implementations based on what types of operations a particular range supports, you can't properly forward the attributes of a range when wrapping it (and range functions wrap their arguments in new ranges all the time), and you can't even properly protect your function against being compiled with types which won't work with it. And, of course, the results of static if and template constraints also affect the type introspection (as they affect what will and won't compile), so the three features are very much interconnected.
Really, the main reasons that ranges don't work very well in C++ are the some reasons that metaprogramming in C++ is primitive in comparison to metaprogramming in D. AFAIK, there's no reason that these features (or similar ones) couldn't be added to C++ and fix the problem, but until C++ has metaprogramming capabilities similar to those of D, ranges in C++ are going to be seriously impaired.
Other features such as mixins and Uniform Function Call Syntax would also help, but they're nowhere near as fundamental. Mixins would help primarily with reducing code duplication, and UFCS helps primarily with making it so that generic code can just call all functions as if they were member functions so that if a type happens to define a particular function (e.g. find) then that would be used instead of the more general, free function version (and the code still works if no such member function is declared, because then the free function is used). UFCS is not fundamentally required, and you could even go the opposite direction and favor free functions for everything (like C++11 did with begin and end), though to do that well, it essentially requires that the free functions be able to test for the existence of the member function and then call the member function internally rather than using their own implementations. So, again you need type introspection along with static if and/or template constraints.
As much as I love ranges, at this point, I've pretty much given up on attempting to do anything with them in C++, because the features to make them sane just aren't there. But if other folks can figure out how to do it, all the more power to them. Regardless of ranges though, I'd love to see C++ gain features such as template constraints, static if, and type introspection, because without them, metaprogramming is way less pleasant, to the point that while I do it all the time in D, I almost never do it in C++.

Intermediate results using expression templates

in C++ Template Metaprogramming : Concepts, Tools, and Techniques from Boost and Beyond
... One drawback of expression templates is that they tend to encourage writing large, complicated expressions, because evaluation is only delayed until the assignment operator is invoked. If a programmer wants to reuse some intermediate result without evaluating it early, she may be forced to declare a complicated type like:
Expression<
Expression<Array,plus,Array>,
plus,
Expression<Array,minus,Array>
> intermediate = a + b + (c - d);
(or worse). Notice how this type not only exactly and redundantly reflects the structure of the computationand so would need to be maintained as the formula changes but also overwhelms it? This is a long-standing problem for C++ DSELs. The usual workaround is to capture the expression using type erasure, but in that case one pays for dynamic dispatching. There has been much discussion recently, spearheaded by Bjarne Stroustrup himself, about reusing the vestigial auto keyword to get type deduction in variable declarations, so that the above could be rewritten as:
auto intermediate = a + b + (c - d);
This feature would be a huge advantage to C++ DSEL authors and users alike...
Is it possible to solve this problem with the current c++ std. (non C++0X)
For Example i want to write a Expression like:
Expr X,Y
Matrix A,B,C,D
X=A+B+C
Y=X+C
D:=X+Y
Where operator := evaluate the expression at the latest Time.
For now, you can always use BOOST_AUTO() in the place of C++0x's auto keyword to get intermediate results more easily.
Matrix x, y;
BOOST_AUTO(result, (x + y) * (x + y)); // or whatever.
I don't understand your question. auto is going to be reused in C++0x for automatic type inference.
I personally see this as a drawback for expression templates since they often relay on having a smaller life span than the objects they are built upon which can turn out to be false if the expression template is captured as I explain here.