Re: Conversion policies

David Abrahams <[email protected]>
Newsgroups gmane.comp.lib.boost.langbinding
Message-ID <[email protected]>
Daniel Wallin <[email protected]> writes:

> At 03:04 2003-08-27, David Abrahams wrote:
>>Daniel Wallin <[email protected]> writes:
>>
>> > At 21:31 2003-08-26, David Abrahams wrote:
>> >>Daniel Wallin <[email protected]> writes:
>> >>
>> >> >>I confess, though, that I am really confused about where this is
>> >> >>coming from, since I was sure you had agreed that "100% compile-time
>> >> >>converters" are not worth their costs.
>> >> >
>> >> > Yeah you're right, I did agree to that. I'm just trying to clear
>> >> > things up. ;) It is still unclear to me how runtime and compile time
>> >> > converters will interact though
>> >>
>> >>Didn't we just say there weren't going to be any "compile-time
>> >>converters?"  Or did you mean something else?
>> >
>> > I don't know, we certainly already have a system which allows for
>> > both type of converters.
>>
>>Well, let me back up.  I was talking about XXX -> C++ converters.  In
>>ther other direction, provided XXX is truly dynamically typed,
>>compile-time converter selection makes sense.
>
> Hm Ok, I was talking about both directions I guess.
>
>> > IIRC, during earlier conversations we did agree that runtime converters
>> > was better, but that it should also be possible to override the runtime
>> > system with compile time selections.
>>
>>Do you mean on a "per-wrapped function argument" basis?  I'm OK with
>>that, though I don't love it because it will tend to mask viable
>>converter "overloads" unless we use the runtime system as a fallback.
>>
>>If you mean on an extension-wide basis, I think I'm against it, since
>>I see no advantages.
>
> Right, I'm talking about "per-wrapped function argument". 

Oh, why didn't you say so?! That makes everything much more agreeable :-)

> Also in some cases masking is just what you want, for instance if
> you are wrapping a function that takes a void*, or a A* but wants
> this to map to a null terminated list of A's.

I still don't see why you want masking.  If the actual arg is as
expected, the specified converter will be used.  Otherwise, something
else *may* get used.  Seems OK to me.

>> >> > like in the case of our "adopt" policy.. In luabind it's a
>> >> > converter, in langbinding perhaps it will be a policy with a
>> >> > post-call action which removes ownership instead. I don't know..
>> >>
>> >>Err...
>> >>
>> >>I don't see how "it's a converter" vs. "it's a policy" is anything
>> >>more than a name game.  Ultimately it needs to do the same thing.
>> >
>> > We are yet to define "policy" and "converter" in langbinding, but
>> in luabind
>> > they are different things. Policies can generate converters, but they don't
>> > perform any actual conversion. They do however have static pre/post-call
>> > functions.
>>
>>Likewise in Boost.Python.  However, so far call policies in
>>Boost.Python only generate return value converters.
>>
>>Incidentally, I don't know if "policy" is actually an appropriate
>>term here.
>
> No? Don't they match the common definition of policies?

Well, I guess "policy" has a particular technical meaning
(c.f. "policy-based design") which might not be a perfect fit.  Can't
think of a better term, though.

>> >>As for whether ownership is removed post- call, it may be important to
>> >>choose pre-call removal in case an exception is thrown from the call
>> >>and the callee has already claimed ownership.
>> >
>> > Ok, is this less dangerous than assuming the callee never got to claiming
>> > ownership?
>>
>>No; I just think it may be important to allow the user to decide which
>>one to use.  See
>>with_custodian_and_ward/with_custodian_and_ward_postcall
>
> Agreed. I generally tend to not think about exception safety as much
> as I should. ;)

You're a member of a very large club ;-)

>> >> > I should have named "chain" "composite" instead; it tries all it's
>> >> > converters and returns a best match, just like the runtime system
>> >> > does.
>> >>
>> >>Most confusing.
>> >
>> > What is confusing here? Consider for just a moment that we had
>> > compile time converters AND runtime converters, it would be
>> > really good to be able to use both together.
>>
>>I don't even know what you mean by "compile time converters" yet.
>
> Ok, if you look further down I've posted the current converter concept.
> The runtime converter system and a "compile time converter" is just
> an implementation of this concept.

OK, this is a from_xxx converter, not a to_xxx converter.

I don't like the term "compile time converter", because its work is
not done at compile-time, and because I'm still not willing to give up
on matching other converters as a fallback even for these cases.  I
would prefer "explicit converter", because IIUC the programmer is
explicitly requesting a particular conversion mechanism.

>> > Here some sample code for a simple composite converter that
>> > uses a converter generated both from my_policy and from the
>> > default policy:
>> >
>> > Just assume param_type is just a parameter in the interpreter
>> > environment; PyObject* or whatever.
>> >
>> > template<class T>
>> > struct my_composite_converter
>> > {
>> >     typedef typename my_policy::template apply<T>::type c0_t;
>> >     typedef typename default_policy::template apply<T>::type c1_t;
>> >
>> >     std::size_t choice;
>> >     c0_t c0;
>> >     c0_t c1;
>> >
>> >     int match(const param_type& param)
>> >     {
>> >        int r0 = c0.match(param);
>> >        int r1 = c1.match(param);
>> >
>> >        choice = r0 > r1 ? 0 : 1;
>> >        return r0 > r1 ? r0 : r1;
>> >     }
>> >
>> >     T convert(const param_type& param)
>> >     {
>> >        switch (choice)
>> >        {
>> >           case 0: return c0.convert(param);
>> >           case 1: return c1.convert(param);
>> >        }
>> >     }
>> > };
>>
>>IIUC, this is for per-function-argument conversion customization.  Why
>>don't we use the same converter interface in all cases, and just have
>>the policy build a converter chain which starts with the custom
>>converter and uses the "default" converter chain as its tail?
>
> I think this is at least close to what I'm saying. What I mean is that
> the policy system can generate the above function for various number
> of combined policies, and the default converter.

The above makes little sense to me.  I am assuming that all explicitly
requested converters will use the registry chain as a fallback; is
there really a case where you want to promote *two* different
converters for a single argument in preference over the conversions
that are already registered?

BTW, I think I need to be convinced that there's a role for "best
match" from_xxx converter selection.  Remember, a from_xxx converter
typically works on a single Python type (or a small range of Python
types) and produces a single C++ type.  It is fairly uncommon to
*ever* have more than one conversion for a single C++ type in the
first place.  I believe that registry scoping is mechanism enough for
prioritizing converters.


> I'm not sure what you mean by "converter interface" here. This is the
> current converter concept:
>
> template<class T>
> struct converter
> {
>     int match(param_type);
>     T convert(param_type);
> };
>
> Or do you mean the policies should build an actual lvalue/rvalue chain?

What I think of as the converter interface is the signatures of the
functions which get registered,
c.f. boost/python/converter/convertible_function.hpp,
boost/python/converter/constructor_function.hpp.

Yes, I do appreciate how nasty that interface can be for people who
need to write them; we may want to provide friendlier but
potentially-less-efficient high level mechanisms for people who want
to define their own converters, e.g. an interface-transforming wrapper
template (c.f. boost/python/converter/as_to_python_function.hpp) which
produces the neccessary interface from a converter concept like the
one you've outlined above, or from a converter which dynamically
allocates its result (for expensive-to-copy types).

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



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.