Re: Re: Conversion policies

Daniel Wallin <[email protected]>
Newsgroups gmane.comp.lib.boost.langbinding
Message-ID <[email protected]>
At 20:12 2003-08-27, David Abrahams wrote:
>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.

No, my point was that the same type can sometimes have different meanings.
A* can be treated differently, a null terminated list of A's or a pointer 
to an A.
In these cases it is important to override the default converters, since they
would actually result in a core dump.

> >> >>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'm working on leaving that 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.

Right, the to_xxx interface is just one function.

>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.

Yeah I don't like the term either, but it's hard to think of good names. :)
Explicit converter sounds good though..

See my example above for cases when you don't want to use other
converters as fallback. In the general case you want to though.

> >> > 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?

I guess it's not very likely that you would want two explicit converters,
but like I stated earlier I don't think you _always_ want the registry chain
as a fallback.

>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 need to be convinced too. :) My current vision is that we choose the
first matching converter and the best matching overload. I also came
to the conclusion that it is so uncommon to have several converters
that can convert from the same python/lua type that it isn't worth it.

> > 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.

Ok.

>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).

I don't understand what we have to gain in making policies work with this
kind of restricted interface though. If the user has chosen an explicit
converter, why can't we do the work at compile time?

---
Daniel Wallin



-------------------------------------------------------
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.