[C++-sig] Re: Interest in luabind

David Abrahams dave at boost-consulting.com
Fri Jun 27 23:31:15 CEST 2003

"Daniel Wallin" <dalwan01 at student.umu.se> writes:

>> "Daniel Wallin" <dalwan01 at student.umu.se> writes:
>> >> "Daniel Wallin" <dalwan01 at student.umu.se> writes:
>> >> >> Surely you want to be able to go in both
>> >> >> directions, though?  Surely not everyone using lua
>> >> >> is interested in just speed and not usability?
>> >> >
>> >> > We probably would like to be able to go in both
>> >> > directions.  We also don't want to force the user to
>> >> > compile with RTTI turned on
>> >>
>> >> I'm sure that's a capability some Boost.Python users
>> >> would appreciate, too.
>> >>
>> >> > so we currently supply a LUABIND_TYPEID macro to
>> >> > overload the typeid calls for a unique id for the
>> >> > type.
>> >>
>> >> This functions something like a specialization?
>> >
>> > Right. You could do something like:
>> >
>> > #define LUABIND_TYPE_INFO int
>> > #define LUABIND_TYPEID(type) my_type_id<type>::value
>> I don't see any reason to get macros involved here.
>> Users could just specialize or overload
>> boost::luapython::type_id, which, in the no-RTTI case,
>> has no no default definition.
> Note that we need to store the type_info object, and
> that's why we have macros for this. So that the user can
> change the type of that object. This wouldn't really work
> with specialization.

    template <class T> struct type_info
    #ifndef NO_RTTI
       typedef std::type_info type;
       static type get();

    template <int n> 
    struct int_type_info
        typedef int type;
        static int get() { return n; }

    template <>
    struct type_info<Foo>
      : int_type_info<42>

Of course I have no objection to using macros to generate

>> >> > This of course causes some problems if we want to
>> >> > downcast
>> >>
>> >> And if you want to support CBD (component based
>> >> development, i.e. cross-module conversions), unless you
>> >> can somehow get all authors to agree on how to identify
>> >> types.  Well, I guess they could use strings and manually
>> >> supply what std::type_info::name() does.
>> >
>> > It doesn't seem wrong that the authors need to use the
>> > same typeid. If you aren't developing a closed system,
>> > don't change typeid system.
>> I was thinking more of id collisions among extensions
>> which don't intend to share types.  It becomes less of an
>> issue if people use string ids.
> But like I said, if you intend to use your module with other
> modules; don't change the typeid system. 

I'm not talking about changing systems, just the need to
ensure unique type IDs for different types across modules.

> I don't like forcing the id type, if you want to use int's
> I think you should be allowed to.

Sure; I have no objection to that.

>> What kind of error checking gets turned off?
> Error checking when performing overload matching. In
> particular it turns off the pretty error messages.

Another feature I want to steal from you.  It's good that
it's configurable.

>> What kind of string copying gets disabled?
> It causes names to be held by const char* instead of
> std::string. (class names, function names etc).

Why not always do that?

>> > . and the typeid macros.
>> >
>> > Most are results of user requests. Massive configuration
>> > is quite important to our users, since lua is used alot on
>> > embedded systems.
>> Have your users come back after getting these features and
>> given you any feedback about how much performance they've
>> gained or space they've saved?
> No. But some of them is a must-have for alot of
> developers.  In particular the ability to turn off
> exception handling.

Oh sure, I believe that one, especially because some shops
(advisedly or no) have a policy against EH and RTTI.  You
don't want to just leave them out.  I am just leery of
configurability in general and would tend to resist making
any new macros part of the official release until users had
told me it made a big difference to them in alpha/beta
stages.  In particular, "massive" configurability is not
neccessarily desirable.  It creates "massive" maintenance
and testing headaches.

>> >> [I assume this means that all of your C++ objects are held
>> >> within their lua wrappers by pointer.  I went to
>> >> considerable lengths to allow them to be held by-value,
>> >> though I'm not sure the efficiency gain is worth the cost
>> >> in flexibility.]
>> >
>> > Correct. We hold all C++ objects by pointer. I can see why
>> > it could be interesting to be able to hold objects by value
>> > though, especially with small objects. I'm not sure it would
>> > be worth it though, since the user can just provide a custom
>> > pool allocator if allocation is an issue.
>> Still costs an extra 4 bytes (gasp!) for the pointer.
>> Yeah, it was in one of my contract specs, so I had to
>> implement it.  Besides, it seemed like fun, but I bet
>> nobody notices and I'd be very happy to rip it out and
>> follow your lead on this.
> Need to think about this some more. It's no special case
> in BPL though, it's just another type of instance_holder,
> correct?

Not only that.  It's an issue of where the instance holder
gets constructed.  In this case it is constructed directly
in the storage for the Python object.

>> > Wouldn't both the examples you provided require A to be held
>> > by auto_ptr<A> in python?
>> Only the A created by call_function for this callback.
>> You can have As held any number of ways in the same
>> program.
> Ah, right. You just instantiate different instance_holder's.
> Does this mean there's special handling of auto_ptr's?

What do you mean by "special handling"?  I think the answer
is no, though I also think there should be special handling
for convenience and efficiency.

> Otherwise, how can you tell which type is being held by
> the pointer? (In the call_function example).

The to-python converter that gets registered for auto_ptr<T>
by using it in a class<T, std::auto_ptr<T>, ... > or by
using register_pointer_to_python<std::auto_ptr<T> > knows
what to do.

>> >> I can begin to see the syntactic convenience of your way,
>> >> but I worry about the parameterizability.  In the first
>> >> case "result" is the only possible appropriate arg and in
>> >> the 2nd case it's "_1".
>> >
>> > What exactly do you worry about? That someone would use
>> > the wrong placeholder? I think the intended use is quite
>> > clear.
>> I guess I'm just a worrywart.  Do the other policies have
>> similar broad applicability?  If so, I'm inclined to
>> accept
>> that you have the right idea.
> Most conversion policies have double direction

Cool, I accept your scheme.

> and even the
> ones that doesn't can still be used in different contexts.
> ('result' when doing C++ -> lua, and '_N' when doing lua ->
> C++).

How is that *not* a case of bidirectionality?

That rule makes me nervous, because the terms are backwards
when calling lua/python from C++.  Do people get confused?

>> > void f(B*, B*, B*, python::list)
>> > void f(D*, D*, D*, std::vector<int>)
>> >
>> > f(D(), D(), D(), [1, 2, 3])
>> Yeah, I guess that looks right, but I don't know.  At some
>> point things are just ambiguous.
> Exactly. Perhaps introducing weights on conversions might
> increase the ambiguity for the user, since it's hard to tell
> at which point the overload system will turn around and
> choose another overload. Does this make any sense?

Yes.  But as I meant to say to Andrei, none of the "classic"
multimethod systems account for coercion, so if there's some
reason they can't use your simple rule it has to be
something you can understand in terms of simple inheritance

>> > To me it's sufficient to have a really simple overload
>> > system, and if that doesn't work the user can register the
>> > overloads with different names.
>> Hmm.  I like your philosophy.
>> As a last resort, let me ask someone I know who's done a
>> lot of multimethod dispatching stuff if there's any
>> reason to do something more complicated.
> Great, do that.

Too bad it didn't pan out :(
Dave Abrahams
Boost Consulting

More information about the Cplusplus-sig mailing list