Boost logo

Boost :

From: joel de guzman (djowel_at_[hidden])
Date: 2002-03-22 10:02:05


Hi Joel,

Why do I get the feeling that I am talking to myself :-)

> The equivalent of the scheme function:
>
> > - \ \
> > doub - /\ f . /\ x. f(f x)
> > - / \ / \
>

I see now. This was giberish when I first read it using proportional
font (non-mono-spaced). The ascii formatting was broken and I
thought to myself, what the heck is this ;-]

Anyway. Please see the code below. I wonder if I can make
this more generic. Hmmm... Comments very welcome.

The actual code is:

    cout << doub(square)(5.0)() << endl;
    cout << doub(doub(square))(5.0)() << endl;
    cout << doub(doub(doub(square)))(5.0)() << endl;

And the printout is:

    625
    1.52588e+11
    8.63617e+178

Note. X is polymorphic. However, if I use 5 instead of 5.0,
the integer overflows.

Regards,
--Joel

PS> Took the liberty to re-post this to boost. I'd like to get as
much feedback as I can.

==================================================
 start snipet
==================================================

#include <iostream>
#include "boost/phoenix/operators.hpp"
#include "boost/phoenix/primitives.hpp"
#include "boost/phoenix/composite.hpp"
#include "boost/phoenix/special_ops.hpp"
#include "boost/phoenix/statements.hpp"
#include "boost/phoenix/functions.hpp"

//////////////////////////////////
using namespace std;
using namespace phoenix;

//////////////////////////////////
struct square_ {

    template <typename X>
    struct result { typedef X type; };

    template <typename X>
    X operator()(X x)
    {
        return x * x;
    }
};

function<square_> square;

//////////////////////////////////
template <typename F>
struct ffx {

    template <typename X>
    struct result { typedef X type; };

    ffx(F f_) : f(f_) {}

    template <typename X>
    X operator()(X x)
    {
        return f(f(x));
    }

    F f;
};

template <typename F>
function<ffx<F> >
doub(function<F> f)
{
    return function<ffx<F> >(f.op);
}

//////////////////////////////////
int
main()
{
    cout << doub(square)(5.0)() << endl;
    cout << doub(doub(square))(5.0)() << endl;
    cout << doub(doub(doub(square)))(5.0)() << endl;
    return 0;
}

==================================================
 end snipet
==================================================

----- Original Message -----
From: "Joel Young" :

>
> Hi Joel
>
> Yeah, that is the first implementation I had. What I want is a function
> that takes a function and builds a new function g where g(x) is
> f(f(x)).
>
> The equivalent of the scheme function:
>
> > - \ \
> > doub - /\ f . /\ x. f(f x)
> > - / \ / \
>
> So then I can write double(square)(5) and get 625 and I could write
> double(double(square))(5)= 5^16.
>
> I know I can get the same meaning out of square(square(square(square(5))))()
> but I want the general type of solution.
>
> I am exploring phoenix and a functional programming friend suggested I
> try and code the above with phoenix as a challenge.
>
> Thanks.
>
> Joel
> jdy_at_[hidden]
>
> ps. I didn't reply to boost cause after I sent the first one, I kind of
> felt it was the wrong place. If you think that the boost list would be
> fine, then I give permission to send your reply to the list.
>
> --------
> From: "joel de guzman" <djowel_at_[hidden]>
> Date: Fri, 22 Mar 2002 10:37:15 +0800
> To: <boost_at_[hidden]>
> Cc: <jdy_at_[hidden]>
> Subj: Re: [boost] Phoenix and lambda...
>
> Hi,
>
> How about this code:
>
> struct square_ {
> template <typename ArgX>
> struct result { typedef ArgX type; };
>
> template <typename ArgX>
> ArgX operator()(ArgX arg1) {
> return arg1 * arg1;
> }
> };
>
> function<square_> square;
>
> int
> main()
> {
> std::cout << "Square of " << 5 << " is " << square(5)() << std::endl;
> std::cout << "Double Square of " << 5 << " is " << square(square(5))() << std::endl;
> }
>
> will print out:
>
> Square of 5 is 25
> Double Square of 5 is 625
>
> Am I missing something? If so, pardon my for being slow.
>
> Cheers,
> --Joel
>
> ----- Original Message -----
> From: "Joel Young" :
>
> >
> > So phoenix looks really cool!
> >
> > I was playing around with Phoenix trying to get the following:
> >
> > - \ \
> > double - /\ f . /\ x. f(f x)
> > - / \ / \
> >
> >
> > but the best I was able to figure out is:
> >
> >
> > - \
> > double - /\ (f, x).f(f x)
> > - / \
> >
> >
> > where double = fof in below code snippet:
> >
> > Any suggestions?
> >
> > // cut
> > struct fof_ {
> > template <typename ArgF, typename ArgX>
> > struct result { typedef ArgX type; };
> >
> > template <typename ArgF, typename ArgX>
> > ArgX operator()(ArgF arg1, ArgX arg2) {
> > return arg1(arg1(arg2))();
> > }
> > };
> >
> > // fof equiv lambda(f,x).f(f x)
> > function<fof_> fof;
> >
> > struct square_ {
> > template <typename ArgX>
> > struct result { typedef ArgX type; };
> >
> > template <typename ArgX>
> > ArgX operator()(ArgX arg1) {
> > return arg1 * arg1;
> > }
> > };
> >
> > function<square_> square;
> >
> > int
> > main()
> > {
> > std::cout << "Square of " << 5 << " is " << square(5)() << std::endl;
> > std::cout << "Double Square of " << 5 << " is " << fof(square,5)() << std::endl;
> > }
> > // cut
> >
> > Joel
>


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