Expressions are numerical operations on collections.
The result of an expression can be another collection or can be a scalar.
For example, when `v` and `w` are a `dense_vector`:

`norm_2(v)`has a scalar result,`v+w`is a collection.`trans(v)*w`is a scalar or a collection.

In order to illustrate the mechanism of the expression evaluation system,
suppose we want to apply a unary function ` op(v)` to a Collection

Each collection takes an attribute.
For a model `C` of
Collection, the attribute can be computed with the
meta function
`attribute<C>::type`.
An attribute must be a model of Attribute.

The GLAS Collections have an attribute of the form
`attribute_list`.
For example, a
`dense_vector` that is supposed to use BLAS, has the
attribute
`attribute_list<dense_collection_type,column_orientation,blas_implementation_type>`.
The dispatcher of expressions recognizes this attribute and calls the appropriate function.

The evaluation of functions uses two structs: one that extracts the information needed for the dispatching, and one that computes the function, using this dispatching information.

For the operation ` op(v)`, we define a
UnaryFunction

typenameop_function<Collection>::result_typeop( Collection const& collection ) { returnop_function<Collection>::apply( collection ) ; }

The UnaryFunction ` op_function<Collection>`
is derived from

template <class Collection, class SomeAttributeInformation> structThis struct is specialized for the different choices ofop_function_impl {};

Instead, we define the
MetaFunction
` op_attribute<Attribute>` that maps the Collection's attribute
to

template <class Collection> structop_function :op_function_impl<Collection, typenameop_attribute< typename attribute<Collection>::type>::type > {};

Why do we need the ` op_attribute` Meta function?
Suppose the user extends GLAS with some functionalities, e.g. distributed collections.
Then he may wish to use the same function names,

The value_type of a function usually is the value_type of the arguments. If the arguments, e.g. of a binary function, have the same value_type's, the result_type depends on this common value_type.

If the value_type is different,
the resulting value_type usually depends on the value_type
of `x+y` or `x*y`.
The function
`operator_plus_function``<X,Y>::result_type` is the type of
the result of `x+y` where `x` and `y` have
types `X` and `Y` respectively.
The function
`operator_times_function``<X,Y>::result_type` is the type of
the result of `x*y` where `x` and y have
types `X` and `Y` respectively.

The computation of the result_type uses typeof.hpp
for integral and float types.
For other types, the user must provide the specializations.
For, `std::complex` types, the specialization is included by
complex.hpp