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

Noam Yorav-Raphael noamraph at gmail.com
Wed Jun 11 13:30:40 PDT 2014


Thanks!

I looked at http://qt-project.org/doc/qt-4.8/qwidget.html, which has
several overloaded functions, and didn't find overloaded functions with
different return types. If there are, there are probably rare - I really
think that overloaded functions with different return types are an
abomination.



On Wed, Jun 11, 2014 at 8:23 PM, Kevin Cantu <me at kevincantu.org> wrote:

> Noam, that's awesome.  It even works for tuples like so (I didn't think it
> would):
>
> ```
> enum AaBbEnum {
>     Aa,
>     Bb,
> }
>
> trait AaBb {
>     fn get_type(&self) -> AaBbEnum;
>     fn get_aa(self) -> (int, f64) { fail!(); }
>     fn get_bb(self) -> (f64) { fail!(); }
> }
>
> impl AaBb for (int, f64) {
>     fn get_type(&self) -> AaBbEnum { Aa }
>     fn get_aa(self) -> (int, f64) { self }
> }
>
> impl AaBb for (f64) {
>     fn get_type(&self) -> AaBbEnum { Bb }
>     fn get_bb(self) -> (f64) { self }
> }
>
> #[cfg(not(test))]
> fn overloaded<T: AaBb>(x: T) {
>     match x.get_type() {
>         Aa => println!("got Aa: {}", x.get_aa()),
>         Bb => println!("got Bb: {}", x.get_bb()),
>     }
> }
>
> fn overloaded_format<T: AaBb>(x: T) -> String {
>     match x.get_type() {
>         Aa => format!("got Aa: {}", x.get_aa()),
>         Bb => format!("got Bb: {}", x.get_bb()),
>     }
> }
>
> #[cfg(not(test))]
> #[main]
> fn main() {
>     overloaded((5i, 7.3243)); // prints: got Aa: (5, 7.3243)
>     overloaded((3.5)); // prints: got Bb: 3.5
> }
>
> #[test]
> fn overloaded_with_same_return_works() {
>     // now with a shared return
>     let x: String = overloaded_format((5i, 7.3243));
>     let y: String = overloaded_format((3.5));
>     assert_eq!(x, "got Aa: (5, 7.3243)".to_string());
>     assert_eq!(y, "got Bb: 3.5".to_string());
> }
> ```
>
> I imagine if the functions being overloaded have different return types,
> this gets uglier to use, but this is pretty good!
>
>
> Kevin
>
>
> On Wed, Jun 11, 2014 at 4:35 AM, Noam Yorav-Raphael <noamraph at gmail.com>
> wrote:
>
>> You can achieve overloading which is equivalent to C++ by defining a
>> trait for all the types a specific argument can get:
>>
>> ```
>> enum IntOrFloatEnum {
>>     Int,
>>     F64,
>> }
>>
>> trait IntOrFloat {
>>     fn get_type(&self) -> IntOrFloatEnum;
>>     fn get_int(self) -> int { fail!(); }
>>     fn get_f64(self) -> f64 { fail!(); }
>> }
>>
>> impl IntOrFloat for int {
>>     fn get_type(&self) -> IntOrFloatEnum { Int }
>>     fn get_int(self) -> int { self }
>> }
>>
>> impl IntOrFloat for f64 {
>>     fn get_type(&self) -> IntOrFloatEnum { F64 }
>>     fn get_f64(self) -> f64 { self }
>> }
>>
>> fn overloaded<T: IntOrFloat>(x: T) {
>>     match x.get_type() {
>>         Int => println!("got int: {}", x.get_int()),
>>         F64 => println!("got f64: {}", x.get_f64()),
>>     }
>> }
>>
>> fn main() {
>>     overloaded(5i); // prints: got int: 5
>>     overloaded(3.5); // prints: got f64: 3.5
>> }
>> ```
>>
>> This is equivalent to having to functions, overloaded(int) and
>> overloaded(f64). From what I see, the compiler even optimizes away the
>> logic, so the generated code is actually equivalent to this:
>>
>> ```
>> fn overloaded_int(x: int) { println!("got int: {}", x); }
>> fn overloaded_f64(x: f64) { println!("got f64: {}", x); }
>> fn main() {
>>     overloaded_int(5i);
>>     overloaded_f64(3.5);
>> }
>> ```
>>
>> (I actually think that if Rust gains one day some support for
>> overloading, it should be syntactic sugar for the above, which will allow
>> you to define a function whose argument can be of multiple types. I don't
>> like the C++ style of defining several different functions with the same
>> name and letting the compiler choose which function should actually be
>> called).
>>
>> Using this method you can solve both the problem of overloading and
>> default arguments. For every possible number of arguments that C++ would
>> allow, define a function funcN<T0, T1, TN-1>(arg0: T0, arg1: T1, ...,
>> argN-1: TN-1). The function would check the actual types of the arguments
>> and call the right C++ function, filling default arguments on the way. So
>> the only difference between C++ and Rust code would be that you'd have to
>> add the number of arguments to the method name.
>>
>> It would probably not be easy to generate the required code, but I think
>> it would solve the problem perfectly.
>>
>> Cheers,
>> Noam
>>
>>
>> On Thu, May 22, 2014 at 11:27 PM, Alexander Tsvyashchenko <ndl at endl.ch>
>> wrote:
>>
>>>   Hi All,
>>>
>>> Recently I was playing with bindings generator from C++ to Rust. I
>>> managed to make things work for Qt5 wrapping, but stumbled into multiple
>>> issues along the way.
>>>
>>> I tried to summarize my "pain points" in the following blog post:
>>> http://endl.ch/content/cxx2rust-pains-wrapping-c-rust-example-qt5
>>>
>>> I hope that others might benefit from my experience and that some of
>>> these "pain points" can be fixed in Rust.
>>>
>>> I'll try to do my best in answering questions / acting on feedback, if
>>> any, but I have very limited amount of free time right now so sorry in
>>> advance if answers take some time.
>>>
>>> Thanks!
>>>
>>> --
>>> 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
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140611/9642ddfe/attachment.html>


More information about the Rust-dev mailing list