Re: [proto] : Proto transform with state

2010-12-06 Thread Thomas Heller
Eric Niebler wrote:

> On 11/18/2010 3:31 PM, Eric Niebler wrote:
>> On 11/18/2010 1:45 PM, Thomas Heller wrote:
>>> Eric Niebler  writes:
 It's REALLY hard. The let context needs to be bundled with the Expr,
 State, or Data parameters somehow, but in a way that's transparent. I
 don't actually know if it's possible.
>>>
>>> Very hard ... yeah. I am thinking that we can maybe save these variables
>>> in the transform?
>> 
>> I'm thinking we just stuff it into the Data parameter. We have a
>> let_scope template that is effectively a pair containing:
>> 
>> 1. The user's original Data, and
>> 2. A Fusion map from local variables (_a) to values.
>> 
>> The let transform evaluates the bindings and stores the result in the
>> let_scope's Fusion map alongside the user's Data. We pass the let_scope
>> as the new Data parameter. _a is itself a transform that looks up the
>> value in Data's Fusion map. The proto::_data transform is changed to be
>> aware of let_scope and return only the original user's Data. This can
>> work. We also need to be sure not to break the new
>> proto::external_transform.
>> 
>> The problems with this approach as I see it:
>> 
>> 1. It's not completely transparent. Custom primitive transforms will see
>> that the Data parameter has been monkeyed with.
>> 
>> 2. Local variables like _a are not lexically scoped. They are, in fact,
>> dynamically scoped. That is, you can access _a outside of a let<>
>> clause, as long as you've been called from within a let clause.
>> 
>> Might be worth it. But as there's no pressing need, I'm content to let
>> this simmer. Maybe we can think of something better.
> 
> I played with the let transform idea over the weekend. It *may* be
> possible to accomplish without the two problems I described above. See
> the attached let transform (needs latest Proto trunk). I'm also
> attaching the Renumber example, reworked to use let.
> 
> This code is NOT ready for prime time. I'm not convinced it behaves
> sensibly in all cases. I'm only posting it as a curiosity. You're insane
> if you use this in production code. Etc, etc.

Without having looked at it too much ... this looks a lot like the 
environment in phoenix. Maybe this helps in cleaning it out a bit.
___
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto


Re: [proto] : Proto transform with state

2010-12-06 Thread Eric Niebler
On 11/18/2010 3:31 PM, Eric Niebler wrote:
> On 11/18/2010 1:45 PM, Thomas Heller wrote:
>> Eric Niebler  writes:
>>> It's REALLY hard. The let context needs to be bundled with the Expr,
>>> State, or Data parameters somehow, but in a way that's transparent. I
>>> don't actually know if it's possible.
>>
>> Very hard ... yeah. I am thinking that we can maybe save these variables in 
>> the 
>> transform?
> 
> I'm thinking we just stuff it into the Data parameter. We have a
> let_scope template that is effectively a pair containing:
> 
> 1. The user's original Data, and
> 2. A Fusion map from local variables (_a) to values.
> 
> The let transform evaluates the bindings and stores the result in the
> let_scope's Fusion map alongside the user's Data. We pass the let_scope
> as the new Data parameter. _a is itself a transform that looks up the
> value in Data's Fusion map. The proto::_data transform is changed to be
> aware of let_scope and return only the original user's Data. This can
> work. We also need to be sure not to break the new
> proto::external_transform.
> 
> The problems with this approach as I see it:
> 
> 1. It's not completely transparent. Custom primitive transforms will see
> that the Data parameter has been monkeyed with.
> 
> 2. Local variables like _a are not lexically scoped. They are, in fact,
> dynamically scoped. That is, you can access _a outside of a let<>
> clause, as long as you've been called from within a let clause.
> 
> Might be worth it. But as there's no pressing need, I'm content to let
> this simmer. Maybe we can think of something better.

I played with the let transform idea over the weekend. It *may* be
possible to accomplish without the two problems I described above. See
the attached let transform (needs latest Proto trunk). I'm also
attaching the Renumber example, reworked to use let.

This code is NOT ready for prime time. I'm not convinced it behaves
sensibly in all cases. I'm only posting it as a curiosity. You're insane
if you use this in production code. Etc, etc.

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com
#ifndef BOOST_PP_IS_ITERATING

///
/// \file let.hpp
/// Contains definition of the let transform.
//
//  Copyright 2010 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_PROTO_TRANSFORM_LET_HPP_EAN_12_04_2010
#define BOOST_PROTO_TRANSFORM_LET_HPP_EAN_12_04_2010

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

namespace boost { namespace proto
{
// Fwd declarations to be moved to proto_fwd.hpp
template<
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename 
Local, void)
  , typename Transform = void
>
struct let;

template
struct local;

namespace detail
{
// A structure that holds both a map of local variables as
// well as the original Data parameter passed to the let transform
template
struct let_scope
{
typedef LocalMap local_map_type;
typedef Data data_type;

let_scope(LocalMap l, Data d)
  : locals(l)
  , data(d)
{}

LocalMap locals;
Data data;

private:
let_scope &operator=(let_scope const &);
};

template
struct init_local_map;

// A transnform that fetches the original data parameter out of a 
let_scope
struct _get_data : transform<_get_data>
{
template
struct impl;

template
struct impl &>
  : transform_impl &>
{
typedef Data result_type;

Data operator()(
typename impl::expr_param
  , typename impl::state_param
  , typename impl::data_param d
) const
{
return d.data;
}
};
};

template
struct rewrite_transform;

template
struct rewrite_args
{
typedef T type;
};

// rewrite_object if T is not a template
template<
typename T
BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = 
mpl::aux::tem