recursive types, struct, custom, dict, etc.

Olivier Andrieu oliv__a at users.sourceforge.net
Thu Jun 3 18:54:30 PDT 2004


 Havoc Pennington [Wed, 02 Jun 2004]:
 > On Wed, 2004-06-02 at 00:04, Olivier Andrieu wrote:
 > > That's the crux of the problem I think : having both non-parametrized
 > > union type (ANY) and a parametrized product type (STRUCT). ANY is a
 > > bit of pain to handle in a statically typed language (you have to
 > > dispatch on it in unmarshaling functions) and having it pratically
 > > eliminates the benefits of knowing the types appearing in the struct
 > > since any of them could be a variant. On the other hand, not having
 > > ANY may be a pain for dynamically typed language (in marshaling
 > > functions).
 > 
 > Right, both are useful. Note that e.g. Java does have both, in effect
 > (the base Object type functions as a variant type).
 > 
 > >  >  - maps more naturally to statically typed languages
 > > 
 > > not really (because of the variants)
 > 
 > I don't think variants break anything. If multiple possible types are
 > expected as arguments, you _want_ to expose variants to the statically
 > typed language via something like QVariant or GValue. In this case the
 > "IDL" specifies variant:
 > 
 >   void SetProperty (in STRING propName, in VARIANT propValue);

Sure. That's why it's not really "natural": we need to add this sum
type to the language. Of course it's fine for glib and its GValue but
that's only because C+glib isn't really a statically typed language
anymore :).

 > However, in other cases variants are used on the wire because a dynamic
 > language binding doesn't know what's in the "IDL" - but static bindings
 > still see a fixed type. So the actual method might be:
 >  
 >   INT32 GetCount ();
 > 
 > however, when the Python binding for this chains to a Python method, the
 > Python bindings know the Python method returned a Python int, but don't
 > know whether the "IDL" is:
 >   INT64 GetCount ();
 >   INT32 GetCount ();
 >   VARIANT GetCount ();
 > or even 
 >   DOUBLE GetCount ();
 >   UINT32 GetCount ();
 > as a result the Python bindings could simply throw a VARIANT containing
 > an int on the wire, and then the caller of GetCount() could perform the
 > "cast"

hrmmm, I'd be wary of these implicit casts. Couldn't the python
binding introspect this ? And that would make 3 possible behaviours
for a _get_int32 unpack function:

 - just get an INT32 without checking anything (what we have right
   now)
 - get a 'naked' INT32 or an INT32 wrapped in a variant but fail on
   other variants
 - get INT32s and try to cast other variants; but when do you stop
   converting: INT64? DOUBLE? STRING?

I'd rather see the IDL as a kind of protocol specification that
everybody is conforming too rather than some optional optimization
directives for static languages.

 > Similarly when Python passes an argument to SetCount(), it could pass a
 > variant on the wire.
 > 
 > Despite this variant on the wire, C/C++ would see a method that returns
 > a fixed integer type, and unpacking of the variant happens
 > automatically.

As long as there is a clear API and well defined rules for the
conversion ...

 > So we have two separate occasions where variants come up; in the first
 > we expect to genuinely have different types at runtime, and in the
 > second we're just making dynamically typed languages work smoothly.

yep.

 > >  >  - structs are probably sort of annoying to deal with in language
 > >  >    bindings
 > > 
 > > why ? I rather had the impression they were not a problem. Either
 > > handle them generically using introspection data and a big unmarshling
 > > function, or handle them statically using some sort of code generation
 > > (preprocessor, IDL compiler, etc.).
 > 
 > Right, I'm defining both of those as "sort of annoying" ;-)

Well that's annoying for the bindings authors. Once this is done, the
application developers can use this easily.

 > Yes it's workable, but it's more work than dealing with primitive types.
 > 
 > > I'd say: add a non-parametrized STRUCT type,
 > 
 > non-parameterized STRUCT is the same thing as ARRAY of ANY, right?

Exactly.

 > >  a non-parametrized ANY
 > > type
 > 
 > Agree we should just do ANY rather than union { int, bool } type of
 > stuff. i.e. we should do ANY-which-is-one-of-some-set, just keep it
 > simple. IPC already allows runtime failures, so static type _checking_
 > doesn't make sense; type checking is inherently dynamic. 

Aren't contradicting yourself here ? Type checking is what you want to
do with the separate signatures, no ? ;)

 > > , and forget about separating type signatures.
 > 
 > I'm not sold here. Also, Matthias really wanted to see this.

even with the variants ?


 > >  I think we need ANY
 > > because of DICTs and since having an ANY type constitutes an escape
 > > hatch that can make type signatures almost useless in some cases, I'm
 > > not sure separating type signatures is worth the effort.
 > 
 > The signatures still give us a nice speedup and allow method overloading
 > in the static-language-to-static-language case at least. One some level
 > we might consider the signature purely an optimization... well we've
 > already established that a system with only variant types will work,
 > that's what Lisp or Python has. It's just an efficiency issue to split
 > the type from the data.
 > 
 > I think a worthwhile optimization, though.

I don't see where the optimisation would be, compared to what we have
now. Right now, the signature is built as a message is validated,
correct ? Is this step of signature building really slow ?

-- 
   Olivier



More information about the dbus mailing list