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

Manish Goregaokar manishsmail at gmail.com
Fri Jun 6 07:54:48 PDT 2014


FWIW you can achieve overloading by means of a parameter enum that captures
all the various ways of entering data. Usually an overloaded function is
just that -- each variant does the same thing, just that the initial data
is in a different format.

So you drive down to the essence of the overloading -- here the overloading
boils down to "give me a rectangle, in some format, and a color, in some
format" -- so do just that, give it enum parameters. One that is "a
rectangle, in some format", and the other is "a color, in some format".

This is actually cleaner, IMO, and as an added bonus you only have to
define the function once with a match statement inside to normalize the
data. This also lets one "bubble" the overloading out, you can call this
from within a similar "rust-overloaded" function that needs, say, a
rectangle, a circle, and a color, without having to tweak the parameters
for every overloaded instance

True, in some cases overloaded functions have different behavior based on
which one is used, but that can be handled here too, and for that matter if
they behave differently it might be best to give them different names :)

For example, the two ways of specifying a rect can be managed via:
enum Rectangle {
 Rect(Qrect),
 Coord(int, int, int, int)
}

and for the colors
enum ColorProvider {
 Brush(QBrush),
 Color(QColor),
 GColor(GlobalColor)
}

-Manish Goregaokar


On Fri, Jun 6, 2014 at 3:24 PM, 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
>>>>
>>>>
>>>
>>
>
> _______________________________________________
> 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/20140606/de4bf01d/attachment.html>


More information about the Rust-dev mailing list