Boost logo

Boost :

Subject: Re: [boost] [local] Help for the Alternatives section
From: lcaminiti (lorcaminiti_at_[hidden])
Date: 2011-05-03 15:44:09


Mathias Gaunard-2 wrote:
>
> On 02/05/2011 23:33, lcaminiti wrote:
>>> Simply put, the function cannot take its arguments as template
>>> parameters, and also requires that the types of the arguments be
>>> specified.
>>>
>>
>> As I mentioned, Boost.Local does not require to specify the bound
>> variable
>> types
>
> Note I said 'arguments'.
>
>> [can bind variable without knowing their type]
>> Question: Does this make Boost.Local local functions polymorphic
>
> No.
>
>> I also think this feature would be valuable. Do you have any specific use
>> case in mind?
>
> Parametric polymorphism is a very important property of functional
> programming. System F, the theory behind the ML family of languages, is
> polymorphic lambda calculus.
>

OK, thanks a lot for the clarification! I still don't think I understand
this topic well but I am venturing a question... sorry in advance if it
doesn't make sense :)

For example, it would be useful to program a polymorphic global functor to
add a vector of doubles and ints using the same global_add algorithm
(without duplicating the code to implement two different algorithms):

#include <iostream>
#include <vector>
#include <algorithm>

template<typename T>
struct global_add {
    global_add(double& _sum, const int& _factor): sum(_sum), factor(_factor)
{}
    inline void operator()(T num) {
        sum += factor * num;
    }
private:
    double& sum;
    const int& factor;
};

int main() {
    double sum = 0.0;
    int factor = 10;

    std::vector<double> v(3);
    v[0] = 1.0; v[1] = 2.0; v[2] = 3.0;
    std::for_each(v.begin(), v.end(), global_add<double>(sum, factor));

    std::vector<int> w(3);
    w[0] = -1; w[1] = -2; w[2] = -3;
    std::for_each(w.begin(), w.end(), global_add<int>(sum, factor));

    std::cout << sum << std::endl;
    return 0;
}

Now, if I want to program this global_add locally within the main() but
still retaining its polymorphism in T, I cannot do that using Boost.Local.
If I understand it right, that is what makes Boost.Local local function
monomorphic in its function argument types.

How would I program the polymorphic global_add locally using Boost.Phoenix
(or Boost.Lambda)? For example, I think I would need to do something like
this (which of course does not compile):

int main() {
    double sum = 0.0;
    int factor = 10;

    __some_local_template_type__ local_add = let(_f = cref(factor))[
        ref(sum) += _f * _1
    ];

    std::vector<double> v(3);
    v[0] = 1.0; v[1] = 2.0; v[2] = 3.0;
    std::for_each(v.begin(), v.end(), local_add<double>(sum, factor));

    std::vector<int> w(3);
    w[0] = -1; w[1] = -2; w[2] = -3;
    std::for_each(w.begin(), w.end(), local_add<int>(sum, factor));

    std::cout << sum << std::endl;
    return 0;
}

Note that I'd need to:
1) Program the Boost.Phoenix functor locally within the main() body.
2) Program the Boost.Phoenix functor only once (to avoid code duplication)
and then use it on the two different types double and int.

Is there a way to do this or something similar with Boost.Phoenix (or
Boost.Lambda)?

Thanks a lot.
--Lorenzo

--
View this message in context: http://boost.2283326.n4.nabble.com/local-Help-for-the-Alternatives-section-tp3408469p3493365.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

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