Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2005-01-06 00:11:13


[I've sent the reply below yesterday, but for some reason it didn't go through]

Daniel Wallin writes:
>
> Well OK, let's do that. What are your thoughts about adding something
> like this?
>
> template<
> typename BOOST_MPL_AUX_NA_PARAM(T)
> >
> struct unlambda
> {
> template<
> typename X = na
> BOOST_MPL_PP_NESTED_DEF_PARAMS_TAIL(1, typename X, na)
> >
> struct apply
> {
> typedef T type;
> };
>
> typedef unlambda type;
> };
>
> ...
>
> /// special case for 'unlambda'
> template< typename T, typename Tag >
> struct lambda< mpl::unlambda<T>,Tag, int_<1> >
> {
> typedef true_ is_le;
> typedef mpl::bind0<mpl::unlambda<T> > result_;
> typedef result_ type;
> };

While straightforward, a primitive like 'unlambda' won't cover many
use cases that I consider important. I'd be inclined towards more
systematic approach to nested scoping, something along the lines of
what is discussed in the attached conversation (long, but
insightful). May be even implicit scoping for the library algorithms
as described in one of these emails.

Thoughts are welcome.


Subject: Topics

Topics:
   phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   RE: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   RE: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   RE: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   RE: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   RE: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   RE: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example
   Re: phoenix lambda-lambda for_each example

Date: Wed, 03 Mar 2004 10:21:10 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Noah Stein <Noah_at_[hidden]>
CC: enki_at_[hidden], David Abrahams <dave_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: phoenix lambda-lambda for_each example
Message-ID: <40454116.5000400_at_[hidden]>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="====-=-="

--====-=-=
Content-Type: text/plain; format=flowed

Hi,

<shameless plug>

    phoenix is rockin' rollin cool :-)

</shameless plug>

It's extensibility has proven itself time and again. Already,
we have lazy versions of almost all STL sequence functions
such as push_back, insert, remove, etc. Angus Leeming implemented
them, after learning the library in a couple of days!

Example usage:

     push_back(arg1, back(arg1)+1)

Now, the algorithms...

I took a few minutes to write a lazy for_each.

Consider this:

     std::vector<std::vector<int> > v;
     ...
     for_each(arg1, for_each(arg1, cout << arg1 << ' '))
     (v);

Prints all the elements of v.

Cool? I would say ROCKIN' !!!

See attached. We'll be seeing a full lazy STL very soon! Noah Stein
will be working on it. Noah? :-)

Regards,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net
--====-=-=
Content-Type: text/x-cpp; name=phx_for_each.cpp
Content-Disposition: inline; filename=phx_for_each.cpp
#include <boost/spirit/phoenix.hpp>
#include <vector>
#include <iostream>
#include <algorithm>
namespace phoenix
{
    struct for_each_impl
    {
        template <typename C, typename F>
        struct result { typedef void type; };
        template <typename C, typename F>
        void operator()(C& c, F f)
        {
            std::for_each(c.begin(), c.end(), f);
        }
    };
    template <typename C, typename F>
    inline typename impl::make_composite<for_each_impl, C, actor<value<F> > >::type
    for_each(C const& c, F f)
    {
        typedef
            typename impl::make_composite<
                for_each_impl, C, actor<value<F> > >::composite_type
        ret_t;
        return ret_t(
            for_each_impl(),
            as_actor<C>::convert(c),
            value<F>(f)
        );
    }
}
int
main()
{
    int v_[] = { 1, 2, 3, 4, 5 };
    std::vector<std::vector<int> > v;
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 5; ++j)
            v_[j] *= 2;
        v.push_back(std::vector<int>(v_, v_+5));
    }
    using namespace phoenix;
    namespace phx = phoenix;
    using namespace std;
    phx::for_each(arg1, phx::for_each(arg1, cout << arg1 << ' '))
    (v);
}
--====-=-=--

Date: Tue, 02 Mar 2004 21:33:59 -0500
From: David Abrahams <dave_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: Noah Stein <Noah_at_[hidden]>, enki_at_[hidden],
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <uoeremzfs.fsf_at_[hidden]>
References: <40454116.5000400_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman <joel_at_[hidden]> writes:

> Consider this:
>
> std::vector<std::vector<int> > v;
> ...
> for_each(arg1, for_each(arg1, cout << arg1 << ' '))
> (v);
>
> Prints all the elements of v.

Actually that case is kind of strange. I think in MPL we're deciding
that you need to do something like:

  for_each(arg1, function(for_each(arg1, cout << arg1 << ' ')))(v)

to prevent v from being substituted into *all* of the arg1s.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Wed, 03 Mar 2004 11:22:50 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: David Abrahams <dave_at_[hidden]>
CC: Noah Stein <Noah_at_[hidden]>, enki_at_[hidden],
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <40454F8A.1020107_at_[hidden]>
References: <40454116.5000400_at_[hidden]>
        <uoeremzfs.fsf_at_[hidden]>
MIME-Version: 1.0

David Abrahams wrote:

> Joel de Guzman <joel_at_[hidden]> writes:
>
>
>>Consider this:
>>
>> std::vector<std::vector<int> > v;
>> ...
>> for_each(arg1, for_each(arg1, cout << arg1 << ' '))
>> (v);
>>
>>Prints all the elements of v.
>
>
> Actually that case is kind of strange. I think in MPL we're deciding
> that you need to do something like:
>
>
> for_each(arg1, function(for_each(arg1, cout << arg1 << ' ')))(v)
>
> to prevent v from being substituted into *all* of the arg1s.

I thought about that too. Upon meditation, I realized it is
not necessary. In this case, Phoenix has scope! That's why I
wrote the title "lamda-lambda". Consider:

     std::vector<std::vector<int> > v;
     ...
     for_each(arg1, for_each(arg1, cout << arg1 << ' '))
     (v);

* The first arg1 gets a std::vector<std::vector<int> >
* The second arg1 gets a std::vector<int>
* the third arg1 gets an int.

Each lambda has its own scope. Try the attached example, if you
are not convinced.

Cheers,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 09:32:52 -0500
From: David Abrahams <dave_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: Noah Stein <Noah_at_[hidden]>, enki_at_[hidden],
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <un06yknl7.fsf_at_[hidden]>
References: <40454116.5000400_at_[hidden]>
        <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman <joel_at_[hidden]> writes:

> I thought about that too. Upon meditation, I realized it is
> not necessary. In this case, Phoenix has scope! That's why I
> wrote the title "lamda-lambda". Consider:
>
> std::vector<std::vector<int> > v;
> ...
> for_each(arg1, for_each(arg1, cout << arg1 << ' '))
> (v);
>
> * The first arg1 gets a std::vector<std::vector<int> >
> * The second arg1 gets a std::vector<int>
> * the third arg1 gets an int.
>
> Each lambda has its own scope. Try the attached example, if you
> are not convinced.

I'm not saying that I don't believe it can be done.
I'm saying that there's an inherent ambiguity and you need some way to
represent the other semantics, where v gets substituted for arg1
everywhere.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Wed, 03 Mar 2004 23:28:21 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: David Abrahams <dave_at_[hidden]>
CC: Noah Stein <Noah_at_[hidden]>, enki_at_[hidden],
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045F995.5040609_at_[hidden]>
References: <40454116.5000400_at_[hidden]> <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]>
        <un06yknl7.fsf_at_[hidden]>
MIME-Version: 1.0

David Abrahams wrote:

> Joel de Guzman <joel_at_[hidden]> writes:
>
>
>>I thought about that too. Upon meditation, I realized it is
>>not necessary. In this case, Phoenix has scope! That's why I
>>wrote the title "lamda-lambda". Consider:
>>
>> std::vector<std::vector<int> > v;
>> ...
>> for_each(arg1, for_each(arg1, cout << arg1 << ' '))
>> (v);
>>
>>* The first arg1 gets a std::vector<std::vector<int> >
>>* The second arg1 gets a std::vector<int>
>>* the third arg1 gets an int.
>>
>>Each lambda has its own scope. Try the attached example, if you
>>are not convinced.
>
>
> I'm not saying that I don't believe it can be done.
> I'm saying that there's an inherent ambiguity and you need some way to
> represent the other semantics, where v gets substituted for arg1
> everywhere.

I don't see it as inherently ambiguous. It's simple to explain
and visualize that a new scope is introduced anywhere a lambda-
function is required:

     for_each(c, lambda)

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 10:47:30 -0500
From: David Abrahams <dave_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: Noah Stein <Noah_at_[hidden]>, enki_at_[hidden],
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <usmgqj5kd.fsf_at_[hidden]>
References: <40454116.5000400_at_[hidden]>
        <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]>
        <un06yknl7.fsf_at_[hidden]>
        <4045F995.5040609_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman <joel_at_[hidden]> writes:

> David Abrahams wrote:
>
>> Joel de Guzman <joel_at_[hidden]> writes:
>>
>>>I thought about that too. Upon meditation, I realized it is
>>>not necessary. In this case, Phoenix has scope! That's why I
>>>wrote the title "lamda-lambda". Consider:
>>>
>>> std::vector<std::vector<int> > v;
>>> ...
>>> for_each(arg1, for_each(arg1, cout << arg1 << ' '))
>>> (v);
>>>
>>>* The first arg1 gets a std::vector<std::vector<int> >
>>>* The second arg1 gets a std::vector<int>
>>>* the third arg1 gets an int.
>>>
>>>Each lambda has its own scope. Try the attached example, if you
>>>are not convinced.
>> I'm not saying that I don't believe it can be done.
>> I'm saying that there's an inherent ambiguity and you need some way to
>> represent the other semantics, where v gets substituted for arg1
>> everywhere.
>
> I don't see it as inherently ambiguous. It's simple to explain
> and visualize that a new scope is introduced anywhere a lambda-
> function is required:
>
> for_each(c, lambda)

Giving that explanation is one way of resolving the ambiguity, but
then you still need some mechanism to get the other semantics.
Currently you seem to be exploring the use of "outer".

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Tue, 02 Mar 2004 21:31:19 -0600
From: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: David Abrahams <dave_at_[hidden]>, Noah Stein <Noah_at_[hidden]>,
        enki_at_[hidden], Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <m2u116txmg.fsf_at_[hidden]>
References: <40454116.5000400_at_[hidden]>
        <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman writes:
>> Actually that case is kind of strange. I think in MPL we're
>> deciding
>> that you need to do something like:
>> for_each(arg1, function(for_each(arg1, cout << arg1 << ' ')))(v)
>> to prevent v from being substituted into *all* of the arg1s.
>
> I thought about that too. Upon meditation, I realized it is
> not necessary. In this case, Phoenix has scope!

What if I don't want the scope there?

    std::vector<int> v1, v2;
    copy( arg1, back_inserter(arg2) )(v1, v2); // fails???

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Wed, 03 Mar 2004 11:39:26 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
CC: David Abrahams <dave_at_[hidden]>, Noah Stein <Noah_at_[hidden]>,
        enki_at_[hidden], Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045536E.7080309_at_[hidden]>
References: <40454116.5000400_at_[hidden]> <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]> <m2u116txmg.fsf_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy wrote:

> Joel de Guzman writes:
>
>>>Actually that case is kind of strange. I think in MPL we're
>>>deciding
>>>that you need to do something like:
>>> for_each(arg1, function(for_each(arg1, cout << arg1 << ' ')))(v)
>>>to prevent v from being substituted into *all* of the arg1s.
>>
>>I thought about that too. Upon meditation, I realized it is
>>not necessary. In this case, Phoenix has scope!
>
>
> What if I don't want the scope there?
>
> std::vector<int> v1, v2;
> copy( arg1, back_inserter(arg2) )(v1, v2); // fails???

No, that's ok! Why? because copy does not require a lambda-lambda.
The signature of for_each is: for_each(c, lambda) while the signature
of copy is simply copy(c, c).

Cheers,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Tue, 02 Mar 2004 22:15:55 -0600
From: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: David Abrahams <dave_at_[hidden]>, Noah Stein <Noah_at_[hidden]>,
        enki_at_[hidden], Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <m2ptbutvk4.fsf_at_[hidden]>
References: <40454116.5000400_at_[hidden]>
        <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]> <m2u116txmg.fsf_at_[hidden]>
        <4045536E.7080309_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman writes:
> Aleksey Gurtovoy wrote:
>> What if I don't want the scope there?
>> std::vector<int> v1, v2;
>> copy( arg1, back_inserter(arg2) )(v1, v2); // fails???
>
> No, that's ok! Why? because copy does not require a lambda-lambda.
> The signature of for_each is: for_each(c, lambda) while the signature
> of copy is simply copy(c, c).

OK, 'copy' is not very interesting then. Hopefully this one
demonstrates my question better:

    for_each( v1, push_back(arg1, arg1) )( v2 ); // works?
    for_each( arg1, push_back(arg2, arg1) )( v1, v2 ); // doesn't, right?

Actually, the latter is not achievable even with explicit scoping, so
I guess it's not the question of explicit vs. implicit scopes, but
rather how to override the default behavior.

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Wed, 03 Mar 2004 12:48:52 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
CC: David Abrahams <dave_at_[hidden]>, Noah Stein <Noah_at_[hidden]>,
        enki_at_[hidden], Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <404563B4.6090700_at_[hidden]>
References: <40454116.5000400_at_[hidden]> <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]> <m2u116txmg.fsf_at_[hidden]>
        <4045536E.7080309_at_[hidden]> <m2ptbutvk4.fsf_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy wrote:

> Joel de Guzman writes:
>
>>Aleksey Gurtovoy wrote:
>>
>>>What if I don't want the scope there?
>>> std::vector<int> v1, v2;
>>> copy( arg1, back_inserter(arg2) )(v1, v2); // fails???
>>
>>No, that's ok! Why? because copy does not require a lambda-lambda.
>>The signature of for_each is: for_each(c, lambda) while the signature
>>of copy is simply copy(c, c).
>
>
> OK, 'copy' is not very interesting then. Hopefully this one
> demonstrates my question better:
>
> for_each( v1, push_back(arg1, arg1) )( v2 ); // works?
> for_each( arg1, push_back(arg2, arg1) )( v1, v2 ); // doesn't, right?
>
> Actually, the latter is not achievable even with explicit scoping, so
> I guess it's not the question of explicit vs. implicit scopes, but
> rather how to override the default behavior.

I encountered this problem with phoenix's local vars too.
The solution I had was to use outer(arg1) to refer to the
outer scope:

     for_each(arg1, push_back(outer(arg2), arg1) )( v1, v2 );

I am also contemplating on incorporating FC++ style scopes
as an optional scheme:

     lambda(seq)
     [
         for_each(seq,
             lambda(elem)
             [
                 push_back(seq, elem)
             ]
         )
     ]
     (v1, v2);

but I find it too noisy for my taste ;-) Comments?

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 00:23:30 -0800
From: "Noah Stein" <enki_at_[hidden]>
To: "Joel de Guzman" <joel_at_[hidden]>,
        "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>
Cc: "David Abrahams" <dave_at_[hidden]>, <enki_at_[hidden]>,
        "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: RE: phoenix lambda-lambda for_each example
Message-ID: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
MIME-Version: 1.0

> From: Joel de Guzman [mailto:joel_at_[hidden]]

> I encountered this problem with phoenix's local vars too.
> The solution I had was to use outer(arg1) to refer to the
> outer scope:
>
> for_each(arg1, push_back(outer(arg2), arg1) )( v1, v2 );
>
> I am also contemplating on incorporating FC++ style scopes
> as an optional scheme:
>
> lambda(seq)
> [
> for_each(seq,
> lambda(elem)
> [
> push_back(seq, elem)
> ]
> )
> ]
> (v1, v2);
>
> but I find it too noisy for my taste ;-) Comments?

I find it a bit noisy, too; however, is there any other solution that solves
a 3-layer (or greater) set of scopes? Does outer refer to the immediately
preceding scope or the topmost scope? Is there some kind of method that can
be used to only mark those items that need to be accessed across scopes?
Something along the lines of one of the following:

    for_each(arg1, push_back(seq, arg1) )(v1,seq(v2));
    for_each(arg1, push_back(seq, arg1) )(v1,seq=v2);

It might not be possible to get the above syntax to work. I think there
might be a convoluted method to get it to work that doesn't require run-time
overhead. Unfortunately it would dramatically complicate the
behind-the-scenes code.

-- Noah

Date: Wed, 03 Mar 2004 18:00:12 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Noah Stein <enki_at_[hidden]>
CC: Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045ACAC.3080003_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
MIME-Version: 1.0

Noah Stein wrote:

> I find it a bit noisy, too; however, is there any other solution that solves
> a 3-layer (or greater) set of scopes? Does outer refer to the immediately
> preceding scope or the topmost scope? Is there some kind of method that can
> be used to only mark those items that need to be accessed across scopes?
> Something along the lines of one of the following:
>
> for_each(arg1, push_back(seq, arg1) )(v1,seq(v2));
> for_each(arg1, push_back(seq, arg1) )(v1,seq=v2);
>
> It might not be possible to get the above syntax to work. I think there
> might be a convoluted method to get it to work that doesn't require run-time
> overhead. Unfortunately it would dramatically complicate the
> behind-the-scenes code.

Remember that we do not have control over the invocation
(function call) of the lambda. The rightmost parens are
not part of the lambda.

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 03:52:25 -0800
From: "Noah Stein" <enki_at_[hidden]>
To: "Joel de Guzman" <joel_at_[hidden]>,
        "Noah Stein" <enki_at_[hidden]>
Cc: "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>,
        "David Abrahams" <dave_at_[hidden]>,
        "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: RE: phoenix lambda-lambda for_each example
Message-ID: <OOEKLMLDGFMOOCCDEHIAAEOGCMAA.enki_at_[hidden]>
MIME-Version: 1.0

> From: Joel de Guzman [mailto:joel_at_[hidden]]

> Noah Stein wrote:
> > for_each(arg1, push_back(seq, arg1) )(v1,seq(v2));
> > for_each(arg1, push_back(seq, arg1) )(v1,seq=v2);
> >
> > It might not be possible to get the above syntax to work. I think there
> > might be a convoluted method to get it to work that doesn't require
run-time
> > overhead. Unfortunately it would dramatically complicate the
> > behind-the-scenes code.
>
> Remember that we do not have control over the invocation
> (function call) of the lambda. The rightmost parens are
> not part of the lambda.

I figured we didn't have that capability currently. My suggestion was to
add the functionality to support having the invocation parameters optionally
support certain the proposed construct. The need to discriminate between
"regular" and "scope-bound" parameters is the "convoluted method" I was
trying to communicate. I think it's possible functionality. I'm not
certain its worth the effort and convolution of the library code.

I like the thought that the user code could be much cleaner. The scoping
mechanism is much less intrusive on user code visually than the lambda
example. It is only apparent when used. I also like that no matter how the
"topology" of the nested scopes changes, the references never change (unlike
outer<2> that might need to change to an outer<3>). And if properly
implemented, I think it can be done with little to no runtime overhead (in
release mode).

Unfortunately, I think it would most likely require a large-scale change
inside the guts of the system. I think the change will greatly complicate
the codebase and be nearly incomprehensible to the average user. If that
issue is of great concern (and I know it can be), I support the idea of
outer<n>.

-- Noah

Date: Wed, 03 Mar 2004 20:44:38 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Noah Stein <enki_at_[hidden]>
CC: Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045D336.1020806_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAAEOGCMAA.enki_at_[hidden]>
MIME-Version: 1.0

Noah Stein wrote:

>>From: Joel de Guzman [mailto:joel_at_[hidden]]
>
>>Remember that we do not have control over the invocation
>>(function call) of the lambda. The rightmost parens are
>>not part of the lambda.
>
>
> I figured we didn't have that capability currently. My suggestion was to
> add the functionality to support having the invocation parameters optionally
> support certain the proposed construct. The need to discriminate between
> "regular" and "scope-bound" parameters is the "convoluted method" I was
> trying to communicate. I think it's possible functionality. I'm not
> certain its worth the effort and convolution of the library code.
>
> I like the thought that the user code could be much cleaner. The scoping
> mechanism is much less intrusive on user code visually than the lambda
> example. It is only apparent when used. I also like that no matter how the
> "topology" of the nested scopes changes, the references never change (unlike
> outer<2> that might need to change to an outer<3>). And if properly
> implemented, I think it can be done with little to no runtime overhead (in
> release mode).
>
> Unfortunately, I think it would most likely require a large-scale change
> inside the guts of the system. I think the change will greatly complicate
> the codebase and be nearly incomprehensible to the average user. If that
> issue is of great concern (and I know it can be), I support the idea of
> outer<n>.

I guess I didn't communicate my message well. What I am saying is that
we do not have the liberty to impose any syntax tricks outside the
lambda expression. That's simply outside the jurisdiction of the anonymous
function. Consider:

     std::for_each(c.begin(), c.end(),
         phoenix::for_each(arg1, cout << arg1 << ' ')
     );

std::for_each supplies the arguments to our lambda-function. We do not
have control over that. Inside std::for_each, our lambda-function
is invoked:

     f(*i++)

In short, with

     for_each(arg1, push_back(outer(arg2), arg1))(v1, v2);

the (v1, v2) portion is *not* part of the user code.

... Unless, of course, if what you meant was adding another level of
wrapping over the lambda-expression. If that's what you meant, then
it will still have the same problems of the FC++ style scoping
mechanism.

Cheers,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 02:50:12 -0600
From: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
To: "Noah Stein" <enki_at_[hidden]>
Cc: "Joel de Guzman" <joel_at_[hidden]>,
        "David Abrahams" <dave_at_[hidden]>,
        "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <m2llmitiuz.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
MIME-Version: 1.0

Noah Stein writes:
>> From: Joel de Guzman [mailto:joel_at_[hidden]]
>
>> I encountered this problem with phoenix's local vars too.
>> The solution I had was to use outer(arg1) to refer to the
>> outer scope:
>>
>> for_each(arg1, push_back(outer(arg2), arg1) )( v1, v2 );
>>
>> I am also contemplating on incorporating FC++ style scopes
>> as an optional scheme:
>>
>> lambda(seq)
>> [
>> for_each(seq,
>> lambda(elem)
>> [
>> push_back(seq, elem)
>> ]
>> )
>> ]
>> (v1, v2);
>>
>> but I find it too noisy for my taste ;-) Comments?
>
>
> I find it a bit noisy, too; however, is there any other solution
> that solves a 3-layer (or greater) set of scopes? Does outer refer
> to the immediately preceding scope or the topmost scope?

FWIW, I'd expect/implement it to refer to the immediately preceding
scope, and support the nested usage like 'outer(outer(arg#))' for the
case of multiply-nested scopes.

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Wed, 3 Mar 2004 01:02:01 -0800
From: "Noah Stein" <enki_at_[hidden]>
To: "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>,
        "Noah Stein" <enki_at_[hidden]>
Cc: "Joel de Guzman" <joel_at_[hidden]>,
        "David Abrahams" <dave_at_[hidden]>,
        "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: RE: phoenix lambda-lambda for_each example
Message-ID: <OOEKLMLDGFMOOCCDEHIAOEODCMAA.enki_at_[hidden]>
MIME-Version: 1.0

> From: Aleksey Gurtovoy [mailto:agurtovoy_at_[hidden]]

> FWIW, I'd expect/implement it to refer to the immediately preceding
> scope, and support the nested usage like 'outer(outer(arg#))' for the
> case of multiply-nested scopes.

That makes sense. It sure is ugly, though.

-- Noah

Date: Wed, 03 Mar 2004 18:05:15 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Noah Stein <enki_at_[hidden]>
CC: Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045ADDB.4040901_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAOEODCMAA.enki_at_[hidden]>
MIME-Version: 1.0

Noah Stein wrote:

>>From: Aleksey Gurtovoy [mailto:agurtovoy_at_[hidden]]
>
>
>>FWIW, I'd expect/implement it to refer to the immediately preceding
>>scope, and support the nested usage like 'outer(outer(arg#))' for the
>>case of multiply-nested scopes.
>
>
> That makes sense. It sure is ugly, though.

You can have named outer placeholders if you wish:

    outer_argument<1, 1> x; // x == outer(arg1)
    outer_argument<2, 1> xx; // xx == outer(outer(arg1))

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 17:59:57 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
CC: Noah Stein <enki_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045AC9D.2020001_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy wrote:

> Noah Stein writes:
>>
>>I find it a bit noisy, too; however, is there any other solution
>>that solves a 3-layer (or greater) set of scopes? Does outer refer
>>to the immediately preceding scope or the topmost scope?
>
>
> FWIW, I'd expect/implement it to refer to the immediately preceding
> scope, and support the nested usage like 'outer(outer(arg#))' for the
> case of multiply-nested scopes.

Of course. To be clear:

     arg1 // current scope
     outer(arg1) // outer scope. 1 scope above
     outer(outer(arg1)) // 2 scopes above

<< BTW, Noah, let's move to _1 syntax. It's already ubiquitious >>

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 19:00:32 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
CC: Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Noah Stein <enki_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045BAD0.2060208_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]>
        <4045AC9D.2020001_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman wrote:

> Aleksey Gurtovoy wrote:
>
>> Noah Stein writes:
>>
>>>
>>> I find it a bit noisy, too; however, is there any other solution
>>> that solves a 3-layer (or greater) set of scopes? Does outer refer
>>> to the immediately preceding scope or the topmost scope?
>>
>>
>>
>> FWIW, I'd expect/implement it to refer to the immediately preceding
>> scope, and support the nested usage like 'outer(outer(arg#))' for the
>> case of multiply-nested scopes.
>
>
> Of course. To be clear:
>
> arg1 // current scope
> outer(arg1) // outer scope. 1 scope above
> outer(outer(arg1)) // 2 scopes above
>
> << BTW, Noah, let's move to _1 syntax. It's already ubiquitious >>

An alternative syntax is:

     arg1 // current scope
     outer<1>(arg1) // outer scope. 1 scope above
     outer<2>(arg1) // 2 scopes above

Thoughts?

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 07:31:15 -0600
From: "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>
To: "Joel de Guzman" <joel_at_[hidden]>
Cc: "Noah Stein" <enki_at_[hidden]>,
        "David Abrahams" <dave_at_[hidden]>,
        "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]>
        <4045AC9D.2020001_at_[hidden]>
        <4045BAD0.2060208_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman wrote:
> >> FWIW, I'd expect/implement it to refer to the immediately preceding
> >> scope, and support the nested usage like 'outer(outer(arg#))' for the
> >> case of multiply-nested scopes.
> >
> >
> > Of course. To be clear:
> >
> > arg1 // current scope
> > outer(arg1) // outer scope. 1 scope above
> > outer(outer(arg1)) // 2 scopes above
> >
> > << BTW, Noah, let's move to _1 syntax. It's already ubiquitious >>
>
> An alternative syntax is:
>
> arg1 // current scope
> outer<1>(arg1) // outer scope. 1 scope above
> outer<2>(arg1) // 2 scopes above
>
> Thoughts?

We can easily have both. Or 'outer(arg1)' as a synonym for 'outer<1>(arg1)',
and "numbered" versions only for greater scopes.

--
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Wed, 03 Mar 2004 09:48:48 -0500
From: David Abrahams <dave_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
Cc: Noah Stein <enki_at_[hidden]>,
        Joel de Guzman <joel_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <uishmkmun.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy <agurtovoy_at_[hidden]> writes:

> Noah Stein writes:
>>> From: Joel de Guzman [mailto:joel_at_[hidden]]
>>
>>> I encountered this problem with phoenix's local vars too.
>>> The solution I had was to use outer(arg1) to refer to the
>>> outer scope:
>>>
>>> for_each(arg1, push_back(outer(arg2), arg1) )( v1, v2 );
>>>
>>> I am also contemplating on incorporating FC++ style scopes
>>> as an optional scheme:
>>>
>>> lambda(seq)
>>> [
>>> for_each(seq,
>>> lambda(elem)
>>> [
>>> push_back(seq, elem)
>>> ]
>>> )
>>> ]
>>> (v1, v2);
>>>
>>> but I find it too noisy for my taste ;-) Comments?

I prefer the explicit and readable to the cryptic.

         lambda(seq)
         [
              for_each(seq, push_back(seq, arg1) )
         ]

Isn't too bad.

>> I find it a bit noisy, too; however, is there any other solution
>> that solves a 3-layer (or greater) set of scopes? Does outer refer
>> to the immediately preceding scope or the topmost scope?
>
> FWIW, I'd expect/implement it to refer to the immediately preceding
> scope, and support the nested usage like 'outer(outer(arg#))' for the
> case of multiply-nested scopes.

Ugly :(

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Wed, 03 Mar 2004 23:42:46 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: David Abrahams <dave_at_[hidden]>
CC: Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Noah Stein <enki_at_[hidden]>, Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045FCF6.50800_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]> <m2llmitiuz.fsf_at_[hidden]>
        <uishmkmun.fsf_at_[hidden]>
MIME-Version: 1.0

David Abrahams wrote:

> I prefer the explicit and readable to the cryptic.
>
> lambda(seq)
> [
> for_each(seq, push_back(seq, arg1) )
> ]
>
> Isn't too bad.

Hmmm. Conflict ;-)

How about a compromise:

     for_each[seq](seq, push_back(seq, arg1))

But hey! We can probably have absolute place-holders
and scope-relative place-holders at the same time:

     for_each(seq, push_back(seq, arg1))

where seq is an absolute place-holder referring to the
outermost scope where it is first seen and arg1 is a
scope-relative place-holder (as usual).

<<< Perhaps that's what Noah meant. Hmmm... Now,
I wonder how difficult it would be to implement that. >>>

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 11:03:17 -0500
From: David Abrahams <dave_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Noah Stein <enki_at_[hidden]>, Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <ubrndkjei.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]> <uishmkmun.fsf_at_[hidden]>
        <4045FCF6.50800_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman <joel_at_[hidden]> writes:

> David Abrahams wrote:
>
>> I prefer the explicit and readable to the cryptic.
>> lambda(seq)
>> [
>> for_each(seq, push_back(seq, arg1) )
>> ]
>> Isn't too bad.
>
> Hmmm. Conflict ;-)
>
> How about a compromise:
>
> for_each[seq](seq, push_back(seq, arg1))
>
> But hey! We can probably have absolute place-holders
> and scope-relative place-holders at the same time:
>
> for_each(seq, push_back(seq, arg1))
>
> where seq is an absolute place-holder referring to the
> outermost scope where it is first seen and arg1 is a
> scope-relative place-holder (as usual).
>
> <<< Perhaps that's what Noah meant. Hmmm... Now,
> I wonder how difficult it would be to implement that. >>>

I thought that's what I meant.

Incidentally, "outer" is growing on me.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Wed, 3 Mar 2004 11:56:52 -0800
From: "Noah Stein" <enki_at_[hidden]>
To: "Joel de Guzman" <joel_at_[hidden]>,
        "David Abrahams" <dave_at_[hidden]>
Cc: "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>,
        "Noah Stein" <enki_at_[hidden]>, "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: RE: phoenix lambda-lambda for_each example
Message-ID: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
MIME-Version: 1.0

> From: Joel de Guzman [mailto:joel_at_[hidden]]

> Sent: Wednesday, March 03, 2004 7:43 AM
> To: David Abrahams
> Cc: Aleksey Gurtovoy; Noah Stein; Jaakko Jarvi
> Subject: Re: phoenix lambda-lambda for_each example

> How about a compromise:
>
> for_each[seq](seq, push_back(seq, arg1))
>
> But hey! We can probably have absolute place-holders
> and scope-relative place-holders at the same time:
>
> for_each(seq, push_back(seq, arg1))
>
> where seq is an absolute place-holder referring to the
> outermost scope where it is first seen and arg1 is a
> scope-relative place-holder (as usual).
>
> <<< Perhaps that's what Noah meant. Hmmm... Now,
> I wonder how difficult it would be to implement that. >>>

This is essentially what I was talking about. Your scheme would be much,
much easier to implement than my suggestion. I would like to see if we're
on the same page. In my plan, seq would be a place holder object (similar
to say an argument<> object) that would become an identifier for binding
when placed in the brackets. How would you propose handling the binding of
only a second parameter? I don't think that matters for the STL algorithms,
but I could imagine it might for a general case.

-- Noah

Date: Thu, 04 Mar 2004 09:16:11 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Noah Stein <enki_at_[hidden]>
CC: David Abrahams <dave_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4046835B.5060809_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
MIME-Version: 1.0

Noah Stein wrote:
>>From: Joel de Guzman [mailto:joel_at_[hidden]]
>
>
>>Sent: Wednesday, March 03, 2004 7:43 AM
>>To: David Abrahams
>>Cc: Aleksey Gurtovoy; Noah Stein; Jaakko Jarvi
>>Subject: Re: phoenix lambda-lambda for_each example
>
>
>>How about a compromise:
>>
>> for_each[seq](seq, push_back(seq, arg1))
>>
>>But hey! We can probably have absolute place-holders
>>and scope-relative place-holders at the same time:
>>
>> for_each(seq, push_back(seq, arg1))
>>
>>where seq is an absolute place-holder referring to the
>>outermost scope where it is first seen and arg1 is a
>>scope-relative place-holder (as usual).
>>
>><<< Perhaps that's what Noah meant. Hmmm... Now,
>>I wonder how difficult it would be to implement that. >>>
>
>
> This is essentially what I was talking about. Your scheme would be much,
> much easier to implement than my suggestion. I would like to see if we're
> on the same page. In my plan, seq would be a place holder object (similar
> to say an argument<> object) that would become an identifier for binding
> when placed in the brackets. How would you propose handling the binding of
> only a second parameter? I don't think that matters for the STL algorithms,
> but I could imagine it might for a general case.

Honestly, I still prefer the "outer" approach. Upon inspection,
the example we are using is flawed. Let me start again with
a problem: I want to push_back x to all sequences in v when
calling a lambda-function f:

     f(v, x);

The lambda expression, using outer, is:

     for_each(_1, push_back(_1, outer(_2)))

I honestly find nothing confusing here. I actually see it as simple
and elegant. Compare this with the alternate scheme:

     absolute_argument<1> v; // need to declare
     absolute_argument<2> x; // need to declare

     for_each[v, x](v, push_back(_1, x))

I really do not find this to be any better than the terse, single
line lambda expression. 1) You'll have to declare the place-holders.
2) The syntax does not look like a c++ function call.

Cheers,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 23:13:38 -0500 (EST)
From: Jaakko Jarvi <jajarvi_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
cc: Noah Stein <enki_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <Pine.LNX.4.58.0403032254380.581_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
        <4046835B.5060809_at_[hidden]>
MIME-Version: 1.0

> Honestly, I still prefer the "outer" approach. Upon inspection,
> the example we are using is flawed. Let me start again with
> a problem: I want to push_back x to all sequences in v when
> calling a lambda-function f:
>
> f(v, x);
>
> The lambda expression, using outer, is:
>
> for_each(_1, push_back(_1, outer(_2)))
>
> I honestly find nothing confusing here. I actually see it as simple
> and elegant. Compare this with the alternate scheme:
>
> absolute_argument<1> v; // need to declare
> absolute_argument<2> x; // need to declare
>
> for_each[v, x](v, push_back(_1, x))
>
> I really do not find this to be any better than the terse, single
> line lambda expression. 1) You'll have to declare the place-holders.
> 2) The syntax does not look like a c++ function call.

I'd think that we'd have two sets of predefined placeholders:
_1, _2, ... for scoped placeholders,
abs_1, abs_2, ... for absolute placeholders,
so the burden of declarations would not necessary be that bad.

This was just to point out something for fair comparison,
I think I find Joel's suggestion more appealing.
One can't get much more concise.

One more point...
In Joel's suggestion, basically all arguments
on parameter slots expecting a function object will be
interpreted as lambdas. It first seemed a bit scary that this
information is only at the defintion of the function that is being
called and there is no visual clue at the call site
where the boundaries of lambdas are. But after pondering this
for a while, it worries me less.
In any case, if one gets things wrong, it's very unlikely
that the code compiles.

  Jaakko

Date: Thu, 04 Mar 2004 04:07:09 -0600
From: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
To: Jaakko Jarvi <jajarvi_at_[hidden]>
Cc: Joel de Guzman <joel_at_[hidden]>,
        Noah Stein <enki_at_[hidden]>, David Abrahams <dave_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <m2vfllrkmq.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
        <4046835B.5060809_at_[hidden]>
        <Pine.LNX.4.58.0403032254380.581_at_[hidden]>
MIME-Version: 1.0

Jaakko Jarvi writes:
> One more point...
> In Joel's suggestion, basically all arguments
> on parameter slots expecting a function object will be
> interpreted as lambdas. It first seemed a bit scary that this
> information is only at the defintion of the function that is being
> called and there is no visual clue at the call site
> where the boundaries of lambdas are. But after pondering this
> for a while, it worries me less.

That was basically my reaction, too.

It's interesting how compile-time and run-time lambdas differ here: in
MPL, there is no way to automatically determine the implicit scope:

     // sums a sequence of sequence of numbers
     typedef fold< _1, int_<0>
         , fold< _2, _1, plus<_1,_2> >
     // ^^^^^^^^^^ third scope, same question
     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ second scope, but how do we know?
> f;

, at least without some additional metafunction's markup which would
indicate that 'fold's third argument is a predicate, e.g.:

    template< typename T1, typename T2, typename T3 >
    struct scope< fold<T1,T2,T3> >
    {
        typedef fold<T1,T2,scope<T3> > type;
    };

In contrast, if you want to add implicit scope wrapping to a run-time
lambda, it almost comes "for free" since lambda subexpressions are
passed through anyway:

    fold(_1, 0, fold(_2, _1, _1 + _2))
    // ^^^^^^^ passed through the nested 'fold'
    // which has a chance to wrap it in
    // a scope

so it's just a matter of wrapping them accordingly.

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Thu, 04 Mar 2004 08:01:28 -0500
From: David Abrahams <dave_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
Cc: Jaakko Jarvi <jajarvi_at_[hidden]>,
        Joel de Guzman <joel_at_[hidden]>, Noah Stein <enki_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <u7jy0epg7.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
        <4046835B.5060809_at_[hidden]>
        <Pine.LNX.4.58.0403032254380.581_at_[hidden]>
        <m2vfllrkmq.fsf_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy <agurtovoy_at_[hidden]> writes:

> Jaakko Jarvi writes:
>> One more point...
>> In Joel's suggestion, basically all arguments
>> on parameter slots expecting a function object will be
>> interpreted as lambdas. It first seemed a bit scary that this
>> information is only at the defintion of the function that is being
>> called and there is no visual clue at the call site
>> where the boundaries of lambdas are. But after pondering this
>> for a while, it worries me less.
>
> That was basically my reaction, too.

> It's interesting how compile-time and run-time lambdas differ here: in
> MPL, there is no way to automatically determine the implicit scope:
>

<snip explanation>

I still don't see why compile-time has to be different from runtime in
this regard. The fold algorithm calls lambda<> on its 3rd argument;
that should be enough to indicate where the scope resides.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Thu, 04 Mar 2004 09:04:04 -0600
From: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
To: David Abrahams <dave_at_[hidden]>
Cc: Jaakko Jarvi <jajarvi_at_[hidden]>,
        Joel de Guzman <joel_at_[hidden]>, Noah Stein <enki_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <m2k720slgb.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
        <4046835B.5060809_at_[hidden]>
        <Pine.LNX.4.58.0403032254380.581_at_[hidden]>
        <m2vfllrkmq.fsf_at_[hidden]> <u7jy0epg7.fsf_at_[hidden]>
MIME-Version: 1.0

David Abrahams writes:
> I still don't see why compile-time has to be different from runtime in
> this regard. The fold algorithm calls lambda<> on its 3rd argument;
> that should be enough to indicate where the scope resides.

The point is that run-time 'fold' call is basically two-phase --
during the first phase the arguments, including lambda expressions,
are passed through, composing a function object; then you invoke
the function object and the "real" call happens.

At compile time, everything is different. When you pass a lambda
expression to 'apply', nothing gets evaluated at the point of the
lambda expression definition:

     typedef fold< _1, int_<0>
         , fold< _2, _1, plus<_1,_2> >
> f; // nothing here

     typedef apply< f, vector< vector_c<int,0,1,2> > >::type r;

Instead, 'apply' has to "parse" the whole thing from outside, and
without some additional metadata about metafunctions involved, it has
no chances of figuring out implicit scopes. Compare that to the
following run-time equivalent, keeping in mind the first paragraph,
and you'll see the difference:

     template< typename F, typename T >
     void apply( F f, T x )
     {
        f(x);
     }

     apply(
          fold(_1, 0, fold(_2, _1, _1 + _2)) // 'fold's get evaluated,
                                             // taking care of scope parsing
        , std::vector< std::vector<int> >()
        );

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Thu, 04 Mar 2004 07:56:31 -0500
From: David Abrahams <dave_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: Noah Stein <enki_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <ubrncepog.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
        <4046835B.5060809_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman <joel_at_[hidden]> writes:

> f(v, x);
>
> The lambda expression, using outer, is:
>
> for_each(_1, push_back(_1, outer(_2)))
>
> I honestly find nothing confusing here. I actually see it as simple
> and elegant.

Agreed, but...

> Compare this with the alternate scheme:
>
> absolute_argument<1> v; // need to declare
> absolute_argument<2> x; // need to declare
>
> for_each[v, x](v, push_back(_1, x))
>
> I really do not find this to be any better than the terse, single
> line lambda expression.

It will be better for some cases.

> 1) You'll have to declare the place-holders.

Consider this, which I believe can be made to work:

       for_each[_2, _3](_2, push_back(_1, _3))

You may shriek with horror, but I think it's not so terrible. It does
indicate that we may not need a separate absolute_argument type. I
think the placement of the []s is strange, though.

> 2) The syntax does not look like a c++ function call.

Not a problem, IMO.

    lambda(x,y)[ for_each(x, push_back(_1, y)) ]

is much better though.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Fri, 05 Mar 2004 00:00:51 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: David Abrahams <dave_at_[hidden]>
CC: Noah Stein <enki_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <404752B3.8030800_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]> <4046835B.5060809_at_[hidden]>
        <ubrncepog.fsf_at_[hidden]>
MIME-Version: 1.0

David Abrahams wrote:
> Joel de Guzman <joel_at_[hidden]> writes:

>>1) You'll have to declare the place-holders.
>
>
> Consider this, which I believe can be made to work:
>
> for_each[_2, _3](_2, push_back(_1, _3))
>
> You may shriek with horror, but I think it's not so terrible. It does
> indicate that we may not need a separate absolute_argument type. I
> think the placement of the []s is strange, though.
>
>
>>2) The syntax does not look like a c++ function call.
>
>
> Not a problem, IMO.
>
> lambda(x,y)[ for_each(x, push_back(_1, y)) ]
>
> is much better though.

MPL got me convinced that familiar syntax is an important factor.
There was a time when I was not convinced MPL should follow
the STL conventions since it is in a purely functional domain.
I thought that borrowing the look and feel of an FP language
such as Haskell was the right way to go. You guys made me a
convert.

Now, I am carrying on with that belief. The tide has turned and
I see now that FC++'s look and feel as alien and so detached from
the C++ syntax. I believe that one reason for MPL's success is it's
instant familiarity. As much as posible, I would like to use
a syntax that would give the user an almost instant "aha!".

So, here's a refinement to my proposal:

* All arguments on parameter slots expecting a function object
will be interpreted as scoped lambdas. (implicit scoping)

* Let the usual _1 ... _10 place holders retain its current
meaning. It's scope will always be the outermost scope of a
lambda expression.

* Introduce a new set of placeholders _a ... _j. The scope of
these place-holders will be the innermost lambda where it
is found.

Here again is our sample. I want to push_back argument _2 to all
sequences in argument _1:

     for_each(_a, push_back(_a, _2))

Notice that the leftmost _a can be replaced by _1 but
the second _a cannot.

I believe this is the best syntax so far. With this scheme,
there might be no need for "outer" anymore. The only drawback
is that we cannot refer to some arguments in middle scopes. I
am not sure if that's a problem. If it is, we can still re-
introduce it, after all, the presence of _N in inner scopes
will implicitly use it anyway.

Cheers,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Thu, 04 Mar 2004 11:49:42 -0500
From: David Abrahams <dave_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: Noah Stein <enki_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <ueks8a76h.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]>
        <4046835B.5060809_at_[hidden]>
        <ubrncepog.fsf_at_[hidden]>
        <404752B3.8030800_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman <joel_at_[hidden]> writes:

> Now, I am carrying on with that belief. The tide has turned and
> I see now that FC++'s look and feel as alien and so detached from
> the C++ syntax. I believe that one reason for MPL's success is it's
> instant familiarity. As much as posible, I would like to use
> a syntax that would give the user an almost instant "aha!".
>
> So, here's a refinement to my proposal:
>
> * All arguments on parameter slots expecting a function object
> will be interpreted as scoped lambdas. (implicit scoping)
>
> * Let the usual _1 ... _10 place holders retain its current
> meaning. It's scope will always be the outermost scope of a
> lambda expression.
>
> * Introduce a new set of placeholders _a ... _j. The scope of
> these place-holders will be the innermost lambda where it
> is found.
>
> Here again is our sample. I want to push_back argument _2 to all
> sequences in argument _1:
>
> for_each(_a, push_back(_a, _2))
>
> Notice that the leftmost _a can be replaced by _1 but
> the second _a cannot.
>
> I believe this is the best syntax so far.

Wow. Makes my head spin.

> With this scheme, there might be no need for "outer" anymore.

That was far more intuitive to me.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Date: Fri, 05 Mar 2004 01:13:06 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: David Abrahams <dave_at_[hidden]>
CC: Noah Stein <enki_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <404763A2.4030602_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAIEOJCMAA.enki_at_[hidden]> <4046835B.5060809_at_[hidden]>
        <ubrncepog.fsf_at_[hidden]>
        <404752B3.8030800_at_[hidden]>
        <ueks8a76h.fsf_at_[hidden]>
MIME-Version: 1.0

David Abrahams wrote:

> Joel de Guzman <joel_at_[hidden]> writes:
>
is our sample. I want to push_back argument _2 to all
>>sequences in argument _1:
>>
>> for_each(_a, push_back(_a, _2))
>>
>>Notice that the leftmost _a can be replaced by _1 but
>>the second _a cannot.
>>
>>I believe this is the best syntax so far.
>
>
> Wow. Makes my head spin.
>
>
>>With this scheme, there might be no need for "outer" anymore.
>
>
> That was far more intuitive to me.

If it makes your head spin, then it must be bad.
Revert... revert... ;-)

Cheers,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 17:55:13 -0800
From: "Noah Stein" <enki_at_[hidden]>
To: "Joel de Guzman" <joel_at_[hidden]>,
        "Noah Stein" <enki_at_[hidden]>
Cc: "David Abrahams" <dave_at_[hidden]>,
        "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>,
        "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: RE: phoenix lambda-lambda for_each example
Message-ID: <OOEKLMLDGFMOOCCDEHIAMEOLCMAA.enki_at_[hidden]>
MIME-Version: 1.0

> From: Joel de Guzman [mailto:joel_at_[hidden]]

> Honestly, I still prefer the "outer" approach. Upon inspection,
> the example we are using is flawed. Let me start again with
> a problem: I want to push_back x to all sequences in v when
> calling a lambda-function f:
>
> f(v, x);
>
> The lambda expression, using outer, is:
>
> for_each(_1, push_back(_1, outer(_2)))
>
> I honestly find nothing confusing here. I actually see it as simple
> and elegant. Compare this with the alternate scheme:
>
> absolute_argument<1> v; // need to declare
> absolute_argument<2> x; // need to declare
>
> for_each[v, x](v, push_back(_1, x))
>
> I really do not find this to be any better than the terse, single
> line lambda expression. 1) You'll have to declare the place-holders.
> 2) The syntax does not look like a c++ function call.

For simple examples, I agree that outer is simpler and cleaner. For larger
blocks of code with more complex structure the use of outer beyond the
immediately enclosing scope can be much more difficult. Updating outer<2>
to outer<3> in all instances that need it when a scope changes could
theoretically be problematic. If, however, most code blocks are not that
large and do not contain much nesting, this is a non-issue. How large and
complex do you expect lazy code blocks? If they don't reach much beyond
your example then I'd be fine going with outer.

-- Noah

Date: Thu, 04 Mar 2004 10:17:29 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Noah Stein <enki_at_[hidden]>
CC: David Abrahams <dave_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <404691B9.2000200_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAMEOLCMAA.enki_at_[hidden]>
MIME-Version: 1.0

Noah Stein wrote:

>>From: Joel de Guzman [mailto:joel_at_[hidden]]
>
>
>>Honestly, I still prefer the "outer" approach. Upon inspection,
>>the example we are using is flawed. Let me start again with
>>a problem: I want to push_back x to all sequences in v when
>>calling a lambda-function f:
>>
>> f(v, x);
>>
>>The lambda expression, using outer, is:
>>
>> for_each(_1, push_back(_1, outer(_2)))
>>
>>I honestly find nothing confusing here. I actually see it as simple
>>and elegant. Compare this with the alternate scheme:
>>
>> absolute_argument<1> v; // need to declare
>> absolute_argument<2> x; // need to declare
>>
>> for_each[v, x](v, push_back(_1, x))
>>
>>I really do not find this to be any better than the terse, single
>>line lambda expression. 1) You'll have to declare the place-holders.
>>2) The syntax does not look like a c++ function call.
>
>
> For simple examples, I agree that outer is simpler and cleaner. For larger
> blocks of code with more complex structure the use of outer beyond the
> immediately enclosing scope can be much more difficult. Updating outer<2>
> to outer<3> in all instances that need it when a scope changes could
> theoretically be problematic. If, however, most code blocks are not that
> large and do not contain much nesting, this is a non-issue. How large and
> complex do you expect lazy code blocks? If they don't reach much beyond
> your example then I'd be fine going with outer.

Beyond a certain limit, an inlined anonymous function will tend to
obscure the code that I would prefer writing it as a regular
function/functor. I am not sure what that limit is. I'm quite confident
though that this limit is far above the point where the problems
you mentioned become real issues.

In any case, the "outer" solution is orthogonal to the absolute-argument
solution anyway. We can implement "outer" now, and, add the absolute-
argument mechanism later, once we find a better syntax.

Cheers,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 22:44:51 -0800
From: "Noah Stein" <enki_at_[hidden]>
To: "Joel de Guzman" <joel_at_[hidden]>,
        "Noah Stein" <enki_at_[hidden]>
Cc: "David Abrahams" <dave_at_[hidden]>,
        "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>,
        "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: RE: phoenix lambda-lambda for_each example
Message-ID: <OOEKLMLDGFMOOCCDEHIAEEONCMAA.enki_at_[hidden]>
MIME-Version: 1.0

> From: Joel de Guzman [mailto:joel_at_[hidden]]

> In any case, the "outer" solution is orthogonal to the absolute-argument
> solution anyway. We can implement "outer" now, and, add the absolute-
> argument mechanism later, once we find a better syntax.

Sounds fine to me. That would mean then that the plan is to implement the
various STL algorithms according to the template presented in Joel's
for_each example?

-- Noah

Date: Fri, 05 Mar 2004 00:06:48 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Noah Stein <enki_at_[hidden]>
CC: David Abrahams <dave_at_[hidden]>,
        Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <40475418.2080107_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEONCMAA.enki_at_[hidden]>
MIME-Version: 1.0

Noah Stein wrote:

>>From: Joel de Guzman [mailto:joel_at_[hidden]]
>
>
>>In any case, the "outer" solution is orthogonal to the absolute-argument
>>solution anyway. We can implement "outer" now, and, add the absolute-
>>argument mechanism later, once we find a better syntax.
>
>
> Sounds fine to me. That would mean then that the plan is to implement the
> various STL algorithms according to the template presented in Joel's
> for_each example?

Basically, yes... Once we agree on something ;-) It seems we're
getting there.

Regards,

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 00:04:40 -0600
From: "Aleksey Gurtovoy" <agurtovoy_at_[hidden]>
To: "Joel de Guzman" <joel_at_[hidden]>
Cc: "David Abrahams" <dave_at_[hidden]>, "Noah Stein" <Noah_at_[hidden]>,
        <enki_at_[hidden]>, "Jaakko Jarvi" <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
References: <40454116.5000400_at_[hidden]> <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]> <m2u116txmg.fsf_at_[hidden]>
        <4045536E.7080309_at_[hidden]> <m2ptbutvk4.fsf_at_[hidden]>
        <404563B4.6090700_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman writes:
> > OK, 'copy' is not very interesting then. Hopefully this one
> > demonstrates my question better:
> >
> > for_each( v1, push_back(arg1, arg1) )( v2 ); // works?
> > for_each( arg1, push_back(arg2, arg1) )( v1, v2 ); // doesn't,
right?
> >
> > Actually, the latter is not achievable even with explicit scoping, so
> > I guess it's not the question of explicit vs. implicit scopes, but
> > rather how to override the default behavior.
>
> I encountered this problem with phoenix's local vars too.
> The solution I had was to use outer(arg1) to refer to the
> outer scope:
>
> for_each(arg1, push_back(outer(arg2), arg1) )( v1, v2 );

That's exactly the scheme I was thinking of, too (including the name!).

> I am also contemplating on incorporating FC++ style scopes
> as an optional scheme:
>
> lambda(seq)
> [
> for_each(seq,
> lambda(elem)
> [
> push_back(seq, elem)
> ]
> )
> ]
> (v1, v2);
>
> but I find it too noisy for my taste ;-)

Considering that you'd also have to declare 'seq' and 'elem', yes, IMO it's
not worth the trouble, from both user and implementor POVs. I'd rather spent
time on writing a core language proposal for anonymous functions ;).

--
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Wed, 03 Mar 2004 18:01:49 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
CC: David Abrahams <dave_at_[hidden]>, Noah Stein <Noah_at_[hidden]>,
        enki_at_[hidden], Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045AD0D.10004_at_[hidden]>
References: <40454116.5000400_at_[hidden]> <uoeremzfs.fsf_at_[hidden]>
        <40454F8A.1020107_at_[hidden]> <m2u116txmg.fsf_at_[hidden]>
        <4045536E.7080309_at_[hidden]> <m2ptbutvk4.fsf_at_[hidden]>
        <404563B4.6090700_at_[hidden]>
        <064b01c400e5$8c7bc950$6401a8c0_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy wrote:

> Joel de Guzman writes:
>
>>I encountered this problem with phoenix's local vars too.
>>The solution I had was to use outer(arg1) to refer to the
>>outer scope:
>>
>> for_each(arg1, push_back(outer(arg2), arg1) )( v1, v2 );
>
>
> That's exactly the scheme I was thinking of, too (including the name!).

Hmmm... Convergence :-)

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 23:19:28 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
CC: Noah Stein <enki_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <4045F780.1070306_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]>
        <4045AC9D.2020001_at_[hidden]>
        <4045BAD0.2060208_at_[hidden]>
        <068501c40123$d097a9e0$6401a8c0_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy wrote:

> Joel de Guzman wrote:
>
>>>>FWIW, I'd expect/implement it to refer to the immediately preceding
>>>>scope, and support the nested usage like 'outer(outer(arg#))' for the
>>>>case of multiply-nested scopes.
>>>
>>>
>>>Of course. To be clear:
>>>
>>> arg1 // current scope
>>> outer(arg1) // outer scope. 1 scope above
>>> outer(outer(arg1)) // 2 scopes above
>>>
>>><< BTW, Noah, let's move to _1 syntax. It's already ubiquitious >>
>>
>>An alternative syntax is:
>>
>> arg1 // current scope
>> outer<1>(arg1) // outer scope. 1 scope above
>> outer<2>(arg1) // 2 scopes above
>>
>>Thoughts?
>
>
> We can easily have both. Or 'outer(arg1)' as a synonym for 'outer<1>(arg1)',
> and "numbered" versions only for greater scopes.

Can you do that? Or do you mean outer<>(arg1)?

Perhaps we can elide the <N> since, I imagine, practically, only a
few outer scopes, say, 1..10 are needed:

     outer(_1)
     outer2(_1) == outer(outer(_1))
     outer3(_1) == outer(outer(outer(_1)))

??

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 03 Mar 2004 17:07:05 -0600
From: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
Cc: Noah Stein <enki_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <m2hdx5ttra.fsf_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]> <4045AC9D.2020001_at_[hidden]>
        <4045BAD0.2060208_at_[hidden]>
        <068501c40123$d097a9e0$6401a8c0_at_[hidden]>
        <4045F780.1070306_at_[hidden]>
MIME-Version: 1.0

Joel de Guzman writes:
> Aleksey Gurtovoy wrote:
>> We can easily have both. Or 'outer(arg1)' as a synonym for
>> outer<1>(arg1)',
>> and "numbered" versions only for greater scopes.
>
> Can you do that?

Sure:

    // outer(arg1)
    template< int n >
    outer_argument<1,n> outer(arg<n>);

    // outer(... outer(arg1))
    template< int scope, int n >
    outer_argument<scope+1,n> outer(outer_argument<scope,n>);

    // outer<n>(arg1)
    template< int scope, int n >
    outer_argument<scope,n> outer(arg<n>);

> Or do you mean outer<>(arg1)?

Nope; besides, that's not possible -- function templates are not
allowed to have default template parameters.

>
> Perhaps we can elide the <N> since, I imagine, practically, only a
> few outer scopes, say, 1..10 are needed:
>
> outer(_1)
> outer2(_1) == outer(outer(_1))
> outer3(_1) == outer(outer(outer(_1)))
>
> ??

I like parametrized versions better.

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Date: Thu, 04 Mar 2004 09:23:31 +0800
From: Joel de Guzman <joel_at_[hidden]>
To: Aleksey Gurtovoy <agurtovoy_at_[hidden]>
CC: Noah Stein <enki_at_[hidden]>,
        David Abrahams <dave_at_[hidden]>,
        Jaakko Jarvi <jajarvi_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <40468513.1000106_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]> <m2llmitiuz.fsf_at_[hidden]>
        <4045AC9D.2020001_at_[hidden]>
        <4045BAD0.2060208_at_[hidden]>
        <068501c40123$d097a9e0$6401a8c0_at_[hidden]>
        <4045F780.1070306_at_[hidden]> <m2hdx5ttra.fsf_at_[hidden]>
MIME-Version: 1.0

Aleksey Gurtovoy wrote:

> Joel de Guzman writes:
>
>>Aleksey Gurtovoy wrote:
>>
>>>We can easily have both. Or 'outer(arg1)' as a synonym for
>>>outer<1>(arg1)',
>>>and "numbered" versions only for greater scopes.
>>
>>Can you do that?
>
>
> Sure:
>
> // outer(arg1)
> template< int n >
> outer_argument<1,n> outer(arg<n>);
>
> // outer(... outer(arg1))
> template< int scope, int n >
> outer_argument<scope+1,n> outer(outer_argument<scope,n>);
>
> // outer<n>(arg1)
> template< int scope, int n >
> outer_argument<scope,n> outer(arg<n>);

I learn C++ everyday! ;-)

>>Or do you mean outer<>(arg1)?
>
>
> Nope; besides, that's not possible -- function templates are not
> allowed to have default template parameters.

Of course.

>>Perhaps we can elide the <N> since, I imagine, practically, only a
>>few outer scopes, say, 1..10 are needed:
>>
>> outer(_1)
>> outer2(_1) == outer(outer(_1))
>> outer3(_1) == outer(outer(outer(_1)))
>>
>>??
>
>
> I like parametrized versions better.

Agreed!

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Date: Wed, 3 Mar 2004 22:52:11 -0500 (EST)
From: Jaakko Jarvi <jajarvi_at_[hidden]>
To: Joel de Guzman <joel_at_[hidden]>
cc: Aleksey Gurtovoy <agurtovoy_at_[hidden]>,
        Noah Stein <enki_at_[hidden]>, David Abrahams <dave_at_[hidden]>
Subject: Re: phoenix lambda-lambda for_each example
Message-ID: <Pine.LNX.4.58.0403032249280.581_at_[hidden]>
References: <OOEKLMLDGFMOOCCDEHIAEEODCMAA.enki_at_[hidden]>
        <m2llmitiuz.fsf_at_[hidden]> <4045AC9D.2020001_at_[hidden]>
        <4045BAD0.2060208_at_[hidden]>
        <068501c40123$d097a9e0$6401a8c0_at_[hidden]>
        <4045F780.1070306_at_[hidden]> <m2hdx5ttra.fsf_at_[hidden]>
        <40468513.1000106_at_[hidden]>
MIME-Version: 1.0

On Thu, 4 Mar 2004, Joel de Guzman wrote:

> > Nope; besides, that's not possible -- function templates are not
> > allowed to have default template parameters.
>
> Of course.
>
FYI, that'll change, committee has approved that change already.
But of course, we still have to live without them for a while.

  Jaakko


-- 
Aleksey Gurtovoy
MetaCommunications Engineering

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