[rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback

Kevin Cantu me at kevincantu.org
Sun Jun 8 01:28:02 PDT 2014


Well, I've experimented a bit, and read some helpful things --
http://tomlee.co/2014/04/03/a-more-detailed-tour-of-the-rust-compiler/ --
and now I'm pretty sure that I could make what I imagined work for literal
arguments, but not for arguments which we need the type system for.

That is, if I understand correctly, macros are expanded before either that
token (or AST node, e.g., in a procedural macro), has its type known:
```
let xx = ...
my_terrible_macro!(xx);   // xx is of type ???
```

So better to work on smarter binding generators using more sophisticated
generics...


Kevin




On Fri, Jun 6, 2014 at 2:54 AM, Kevin Cantu <me at kevincantu.org> wrote:

> Apologies for the accidentally sent email.  Not sure what GMail just did
> for me there.  Anyways, with a macro it should be possible to use the types
> given to choose between mangled names, for example, at compile time.
>
> Kevin
>
>
>
>
>
>
>
> On Fri, Jun 6, 2014 at 2:44 AM, Kevin Cantu <me at kevincantu.org> wrote:
>
>> I imagine a macro like the following, which is NOT a macro, because I
>> don't know how to write macros yet:
>>
>>
>> macro fillRect(args...) {
>>
>> fillRect_RF_B ( const QRectF & rectangle, const QBrush & brush )
>> fillRect_I_I_I_I_BS ( int x, int y, int width, int height, Qt::BrushStyle
>> style )
>> fillRect_Q_BS ( const QRect & rectangle, Qt::BrushStyle style )
>> fillRect_RF_BS ( const QRectF & rectangle, Qt::BrushStyle style )
>> fillRect_R_B ( const QRect & rectangle, const QBrush & brush )
>> fillRect_R_C ( const QRect & rectangle, const QColor & color )
>> fillRect_RF_C ( const QRectF & rectangle, const QColor & color )
>> fillRect_I_I_I_I_B ( int x, int y, int width, int height, const QBrush &
>> brush )
>> fillRect_I_I_I_I_C ( int x, int y, int width, int height, const QColor &
>> color )
>> fillRect_I_I_I_I_GC ( int x, int y, int width, int height,
>> Qt::GlobalColor color )
>> fillRect_R_GC ( const QRect & rectangle, Qt::GlobalColor color )
>> fillRect_RF_GC ( const QRectF & rectangle, Qt::GlobalColor color )
>>
>>
>>
>>
>>
>>
>>
>>
>> On Fri, Jun 6, 2014 at 2:35 AM, Kevin Cantu <me at kevincantu.org> wrote:
>>
>>> Since C# allows overloaded methods, but F# doesn't want them, what F#
>>> does is somewhat interesting: "overloaded methods are permitted in the
>>> language, provided that the arguments are in tuple form, not curried form."
>>> [http://msdn.microsoft.com/en-us/library/dd483468.aspx]
>>>
>>> In practice, this means that all the calls to C# (tupled arguments) can
>>> be resolved, but idiomatic F# doesn't have overloaded methods.
>>>
>>> // tuple calling convention: looks like C#
>>> let aa = csharp_library.mx(1, 2)
>>> let bb = csharp_library.mx(1)
>>>
>>> // curried calling convention: makes dd, below, a function not a value
>>> let cc = fsharp_library.m2 1 2
>>> let dd = fsharp_library.m2 1
>>>
>>> Would it be useful to use pattern matching over some generic sort of
>>> tuples to implement something similar in Rust?
>>>
>>>
>>> Kevin
>>>
>>>
>>>
>>> On Sat, May 24, 2014 at 3:45 AM, Matthieu Monrocq <
>>> matthieu.monrocq at gmail.com> wrote:
>>>
>>>>
>>>>
>>>>
>>>> On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980 at gmail.com> wrote:
>>>>
>>>>> Alexander, your option 2 could be done automatically. By appending
>>>>> postfixes to the overloaded name depending on the parameter types.
>>>>> Increasing the number of letters used till the ambiguity is fully resolved.
>>>>>
>>>>> What do you think?
>>>>>
>>>>>
>>>>> fillRect_RF_B ( const QRectF & rectangle, const QBrush & brush )
>>>>> fillRect_I_I_I_I_BS ( int x, int y, int width, int height,
>>>>> Qt::BrushStyle style )
>>>>> fillRect_Q_BS ( const QRect & rectangle, Qt::BrushStyle style )
>>>>> fillRect_RF_BS ( const QRectF & rectangle, Qt::BrushStyle style )
>>>>> fillRect_R_B ( const QRect & rectangle, const QBrush & brush )
>>>>> fillRect_R_C ( const QRect & rectangle, const QColor & color )
>>>>> fillRect_RF_C ( const QRectF & rectangle, const QColor & color )
>>>>> fillRect_I_I_I_I_B ( int x, int y, int width, int height, const QBrush
>>>>> & brush )
>>>>> fillRect_I_I_I_I_C ( int x, int y, int width, int height, const QColor
>>>>> & color )
>>>>> fillRect_I_I_I_I_GC ( int x, int y, int width, int height,
>>>>> Qt::GlobalColor color )
>>>>> fillRect_R_GC ( const QRect & rectangle, Qt::GlobalColor color )
>>>>> fillRect_RF_GC ( const QRectF & rectangle, Qt::GlobalColor color )
>>>>>
>>>>>
>>>>> I believe this alternative was considered in the original blog post
>>>> Alexander wrote: this is, in essence, mangling. It makes for ugly function
>>>> names, although the prefix helps in locating them I guess.
>>>>
>>>>
>>>> Before we talk about generation though, I would start about
>>>> investigating where those overloads come from.
>>>>
>>>> First, there are two different objects being manipulated here:
>>>>
>>>> + QRect is a rectangle with integral coordinates
>>>> + QRectF is a rectangle with floating point coordinates
>>>>
>>>>
>>>> Second, a QRect may already be build from "(int* x*, int* y*, int*
>>>> width*, int* height*)"; thus all overloads taking 4 hints instead of a
>>>> QRect are pretty useless in a sense.
>>>>
>>>> Third, in a similar vein, QBrush can be build from "(Qt::BrushStyle)",
>>>> "(Qt::GlobalColor)" or "(QColor const&)". So once again those overloads are
>>>> pretty useless.
>>>>
>>>>
>>>> This leaves us with:
>>>>
>>>> + fillRect(QRect const&, QBrush const&)
>>>> + fillRect(QRectF const&, QBrush const&)
>>>>
>>>> Yep, that's it. Of all those inconsistent overloads (missing 4 taking 4
>>>> floats, by the way...) only 2 are ever useful. The other 10 can be safely
>>>> discarded without impacting the expressiveness.
>>>>
>>>>
>>>> Now, of course, the real question is how well a tool could perform this
>>>> reduction step. I would note here that the position and names of the
>>>> "coordinate" arguments of "fillRect" is exactly that of those to "QRect";
>>>> maybe a simple exhaustive search would thus suffice (though it does require
>>>> semantic understanding of what a constructor and default arguments are).
>>>>
>>>> It would be interesting checking how many overloads remain *after* this
>>>> reduction step. Here we got a factor of 6 already (should have been 8 if
>>>> the interface had been complete).
>>>>
>>>> It would also be interesting checking if the distinction int/float
>>>> often surfaces, there might be an opportunity here.
>>>>
>>>>
>>>> -- Matthieu
>>>>
>>>>
>>>> Alexander Tsvyashchenko wrote:
>>>>>
>>>>>>  So far I can imagine several possible answers:
>>>>>>
>>>>>>    1. "We don't care, your legacy C++ libraries are bad and you
>>>>>>    should feel bad!" - I think this stance would be bad for Rust and would
>>>>>>    hinder its adoption, but if that's the ultimate answer - I'd personally
>>>>>>    prefer it said loud and clear, so that at least nobody has any illusions.
>>>>>>
>>>>>>    2. "Define & maintain the mapping between C++ and Rust function
>>>>>>    names" (I assume this is what you're alluding to with "define meaningful
>>>>>>    unique function names" above?) While this might be possible for smaller
>>>>>>    libraries, this is out of the question for large libraries like Qt5 - at
>>>>>>    least I won't create and maintain this mapping for sure, and I doubt others
>>>>>>    will: just looking at the stats from 3 Qt5 libraries (QtCore, QtGui and
>>>>>>    QtWidgets) out of ~30 Qt libraries in total, from the 50745 wrapped
>>>>>>    methods 9601 were overloads and required renaming.
>>>>>>
>>>>>>    Besides that, this has a disadvantage of throwing away majority
>>>>>>    of the experience people have with particular library and forcing them to
>>>>>>    le-learn its API.
>>>>>>
>>>>>>    On top of that, not for every overload it's easy to come up with
>>>>>>    short, meaningful, memorable and distinctive names - you can try that
>>>>>>    exercise for
>>>>>>    http://qt-project.org/doc/qt-4.8/qpainter.html#fillRect ;-)
>>>>>>
>>>>>>    3. "Come up with some way to allow overloading / default
>>>>>>    parameters" - possibly with reduced feature set, i.e. if type inference is
>>>>>>    difficult in the presence of overloads, as suggested in some overloads
>>>>>>    discussions (although not unsolvable, as proven by other languages that
>>>>>>    allow both type inference & overloading?), possibly exclude overloads from
>>>>>>    the type inference by annotating overloaded methods with special attributes?
>>>>>>
>>>>>>    4. Possibly some other options I'm missing?
>>>>>>
>>>>>>  --
>>>>>> Good luck!                                     Alexander
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> Rust-dev mailing list
>>>>>> Rust-dev at mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Rust-dev mailing list
>>>>> Rust-dev at mozilla.org
>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> Rust-dev mailing list
>>>> Rust-dev at mozilla.org
>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140608/dfd2d431/attachment.html>


More information about the Rust-dev mailing list