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