* [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
@ 2014-05-22 20:27 Alexander Tsvyashchenko
2014-05-23 4:12 ` Patrick Walton
` (3 more replies)
0 siblings, 4 replies; 21+ messages in thread
From: Alexander Tsvyashchenko @ 2014-05-22 20:27 UTC (permalink / raw)
To: rust-dev
[-- Attachment #1: Type: text/plain, Size: 639 bytes --]
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
[-- Attachment #2: Type: text/html, Size: 886 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-22 20:27 [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback Alexander Tsvyashchenko
@ 2014-05-23 4:12 ` Patrick Walton
2014-05-23 18:26 ` Benjamin Striegel
2014-05-23 19:56 ` Alexander Tsvyashchenko
2014-05-23 4:15 ` Corey Richardson
` (2 subsequent siblings)
3 siblings, 2 replies; 21+ messages in thread
From: Patrick Walton @ 2014-05-23 4:12 UTC (permalink / raw)
To: Alexander Tsvyashchenko, rust-dev
[-- Attachment #1: Type: text/plain, Size: 1491 bytes --]
You can use "extern "Rust" fn" (or ||:'static) to achieve something like C++03 member function pointers without the lifetimes. Attacking Rust without asking first how to do this is unappreciated.
In the future, unboxed closures will make callbacks easier.
I am opposed to function overloading and default parameters. I do not see it as a burden to define meaningful unique function names. On the contrary, this helps greppability in large codebases.
Patrick
On May 22, 2014 1:27:42 PM PDT, Alexander Tsvyashchenko <ndl@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@mozilla.org
>https://mail.mozilla.org/listinfo/rust-dev
--
Sent from my Android phone with K-9 Mail. Please excuse my brevity.
[-- Attachment #2: Type: text/html, Size: 2019 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-22 20:27 [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback Alexander Tsvyashchenko
2014-05-23 4:12 ` Patrick Walton
@ 2014-05-23 4:15 ` Corey Richardson
2014-05-23 5:35 ` Huon Wilson
2014-06-11 11:35 ` Noam Yorav-Raphael
3 siblings, 0 replies; 21+ messages in thread
From: Corey Richardson @ 2014-05-23 4:15 UTC (permalink / raw)
To: Alexander Tsvyashchenko; +Cc: rust-dev
Given the size of the binaries it looks like you may not have been
passing -O, which often gives the best code size.
On Thu, May 22, 2014 at 1:27 PM, Alexander Tsvyashchenko <ndl@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@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
--
http://octayn.net/
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-22 20:27 [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback Alexander Tsvyashchenko
2014-05-23 4:12 ` Patrick Walton
2014-05-23 4:15 ` Corey Richardson
@ 2014-05-23 5:35 ` Huon Wilson
2014-06-11 11:35 ` Noam Yorav-Raphael
3 siblings, 0 replies; 21+ messages in thread
From: Huon Wilson @ 2014-05-23 5:35 UTC (permalink / raw)
To: rust-dev
[-- Attachment #1: Type: text/plain, Size: 1262 bytes --]
Hi Alexander,
I wrote up some feedback and tried to post it on your blog, but
unfortunately submitting a comment was failing with an nginx error, so I
posted it on /r/rust instead:
http://www.reddit.com/r/rust/comments/269t6i/cxx2rust_the_pains_of_wrapping_c_in_rust_on_the/
(It's good to see people experimenting with GUI frameworks in Rust!)
Huon
On 23/05/14 06:27, Alexander Tsvyashchenko 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@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
[-- Attachment #2: Type: text/html, Size: 2324 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-23 4:12 ` Patrick Walton
@ 2014-05-23 18:26 ` Benjamin Striegel
2014-05-23 20:06 ` Alexander Tsvyashchenko
2014-05-23 19:56 ` Alexander Tsvyashchenko
1 sibling, 1 reply; 21+ messages in thread
From: Benjamin Striegel @ 2014-05-23 18:26 UTC (permalink / raw)
Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 1147 bytes --]
On Fri, May 23, 2014 at 12:12 AM, Patrick Walton <pwalton@mozilla.com>wrote:
> You can use "extern "Rust" fn" (or ||:'static) to achieve something like
> C++03 member function pointers without the lifetimes. Attacking Rust
> without asking first how to do this is unappreciated.
>
I think that characterizing this as an "attack" is in bad faith. This is a
very impressive and insightful post. Alexander is a member of our primary
demographic, and it is immensely valuable to get real-world feedback on how
C++ users will receive the language when employing it for non-trivial
projects.
If there is a misunderstanding over some of Rust's features, then it is a
documentation deficiency that needs to be addressed. The fact that
Alexander took the effort to post this here at all shows that he wants to
understand the language, not to bash it. If only every blogger was so
considerate!
So thank you, Alexander. I hope that you found Rust enjoyable despite its
current rough edges! I'd love it if you kept an eye on the language as it
develops, and I'd be delighted to read a follow-up post incorporating the
feedback from here and from reddit.
[-- Attachment #2: Type: text/html, Size: 1613 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-23 4:12 ` Patrick Walton
2014-05-23 18:26 ` Benjamin Striegel
@ 2014-05-23 19:56 ` Alexander Tsvyashchenko
1 sibling, 0 replies; 21+ messages in thread
From: Alexander Tsvyashchenko @ 2014-05-23 19:56 UTC (permalink / raw)
To: Patrick Walton; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 4134 bytes --]
Hi Patrick,
Thanks for your answer! See comments below.
On 2014-05-23 06:12, Patrick Walton wrote:
> You can use "extern "Rust" fn" (or ||:'static) to achieve something like C++03 member function pointers without the lifetimes.
Do I understand correctly that by "extern "Rust" fn" you mean taking the
pointer to the global function? If yes, then I'm definitely aware of the
possibility to do that, but it is not helpful in the context of signals
/ slots. Please see my Reddit comment for more detailed explanation:
http://www.reddit.com/r/rust/comments/269t6i/cxx2rust_the_pains_of_wrapping_c_in_rust_on_the/chpfi1o
RE: (||:'static) - as you can see in my initial post, this is what I
ended up using - only without the explicit 'static annotation, but with
the same restriction of not having any captured state.
I agree that from what I've seen so far, ||:'static seems to be the
closest thing to member function pointers - but I'd argue it's still not
the full replacement as it's more verbose - that is, requires explicitly
passing the state + declaring & forwarding all function arguments, e.g.
instead of "slot(&obj, &Class::method)" it's "slot(&obj, |obj, arg1,
arg2, arg3, arg4, arg5, arg6, arg7| { obj.method(arg1, arg2, arg3, arg4,
arg5, arg6, arg7) })".
And yes, there are signals with up to 7 arguments in Qt5 ;-)
> I am opposed to function overloading and default parameters. I do not see it as a burden to define meaningful unique function names. On the contrary, this helps greppability in large codebases.
Yes, I do realize there are quite strong opinions regarding function
overloading and default parameters within Rust development community. I
hold strong opinions on this subject too, and these happen to be the
opposite ones to what you have - which is the perfect background to
start flame war, which I have zero interest in ;-)
Therefore, I suggest we move from the question "are function overloading
and default parameters good or bad?" to the question "Lots of existing
C++ libraries use function overloading and default parameters. How Rust
should deal with wrapping these?"
I believe the answer to this question is important because with all the
optimism around Rust adoption, I doubt all existing C++ libraries that
were developed over the last decades (Qt including) will be magically
re-implemented in Rust within the next year or two.
So far I can imagine several possible answers:
* "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.
* "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 ;-)
* "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?
* Possibly some other options I'm missing?
--
Good luck! Alexander
[-- Attachment #2: Type: text/html, Size: 4826 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-23 18:26 ` Benjamin Striegel
@ 2014-05-23 20:06 ` Alexander Tsvyashchenko
0 siblings, 0 replies; 21+ messages in thread
From: Alexander Tsvyashchenko @ 2014-05-23 20:06 UTC (permalink / raw)
To: Benjamin Striegel; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 2214 bytes --]
Hi Benjamin,
Thanks for the support and encouragement!
After spending days (evenings to be more precise ;-) wrestling with the
compiler & trying different workarounds to implement at least some form
of Qt5 bindings it's possible there's some frustration present in the
post, but as explicitly stated - I definitely didn't have in mind to
"attack" / "bash" anyone or anything, so if that was the impression my
post creates - I do apologize for that!
I've got some great feedback already (especially WRT enums / flags
wrapping) that I'm going to incorporate in bindings generation.
Also, as soon as Rust has unboxed closures support, I'll definitely try
to experiment with these in the bindings to get to the nicer and safer
signals / slots implementation.
On 2014-05-23 20:26, Benjamin Striegel wrote:
> On Fri, May 23, 2014 at 12:12 AM, Patrick Walton <pwalton@mozilla.com> wrote:
>
>> You can use "extern "Rust" fn" (or ||:'static) to achieve something like C++03 member function pointers without the lifetimes. Attacking Rust without asking first how to do this is unappreciated.
>
> I think that characterizing this as an "attack" is in bad faith. This is a very impressive and insightful post. Alexander is a member of our primary demographic, and it is immensely valuable to get real-world feedback on how C++ users will receive the language when employing it for non-trivial projects.
>
> If there is a misunderstanding over some of Rust's features, then it is a documentation deficiency that needs to be addressed. The fact that Alexander took the effort to post this here at all shows that he wants to understand the language, not to bash it. If only every blogger was so considerate!
>
> So thank you, Alexander. I hope that you found Rust enjoyable despite its current rough edges! I'd love it if you kept an eye on the language as it develops, and I'd be delighted to read a follow-up post incorporating the feedback from here and from reddit.
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev [1]
--
Good luck! Alexander
Links:
------
[1] https://mail.mozilla.org/listinfo/rust-dev
[-- Attachment #2: Type: text/html, Size: 3138 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-22 20:27 [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback Alexander Tsvyashchenko
` (2 preceding siblings ...)
2014-05-23 5:35 ` Huon Wilson
@ 2014-06-11 11:35 ` Noam Yorav-Raphael
2014-06-11 17:23 ` Kevin Cantu
3 siblings, 1 reply; 21+ messages in thread
From: Noam Yorav-Raphael @ 2014-06-11 11:35 UTC (permalink / raw)
To: Alexander Tsvyashchenko; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 3115 bytes --]
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@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@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
[-- Attachment #2: Type: text/html, Size: 4611 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-11 11:35 ` Noam Yorav-Raphael
@ 2014-06-11 17:23 ` Kevin Cantu
2014-06-11 20:30 ` Noam Yorav-Raphael
[not found] ` <CAKE6RfgoXSSkozqreZNW1MCemYP0KRc_3xqoOYL4eswFm9_tbQ@mail.gmail.com>
0 siblings, 2 replies; 21+ messages in thread
From: Kevin Cantu @ 2014-06-11 17:23 UTC (permalink / raw)
To: Noam Yorav-Raphael; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 4922 bytes --]
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@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@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@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
[-- Attachment #2: Type: text/html, Size: 7649 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-11 17:23 ` Kevin Cantu
@ 2014-06-11 20:30 ` Noam Yorav-Raphael
[not found] ` <CAKE6RfgoXSSkozqreZNW1MCemYP0KRc_3xqoOYL4eswFm9_tbQ@mail.gmail.com>
1 sibling, 0 replies; 21+ messages in thread
From: Noam Yorav-Raphael @ 2014-06-11 20:30 UTC (permalink / raw)
To: Kevin Cantu; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 5537 bytes --]
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@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@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@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@mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>>
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
[-- Attachment #2: Type: text/html, Size: 8597 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
[not found] ` <CAKE6RfgoXSSkozqreZNW1MCemYP0KRc_3xqoOYL4eswFm9_tbQ@mail.gmail.com>
@ 2014-06-11 23:13 ` Kevin Cantu
2014-06-12 6:25 ` Noam Yorav-Raphael
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Cantu @ 2014-06-11 23:13 UTC (permalink / raw)
To: Matthieu Monrocq, rust-dev, Noam Yorav-Raphael, Alexander Tsvyashchenko
[-- Attachment #1: Type: text/plain, Size: 1191 bytes --]
Matthew Monrocq suggests this improvement, which looks even cleaner to use,
although slightly more complicated to implement generation of:
On Wed, Jun 11, 2014 at 11:38 AM, Matthieu Monrocq <
matthieu.monrocq@gmail.com> wrote:
> [snip]
>
> I do like the idea of the trait, however I would rather do away with all
> the `get_aa`: why not directly wrap the parameters ?
>
> enum AaBbEnum {
> Aa(int, f64),
> Bb(f64),
> }
> trait AaBb {
> fn get(&self) -> AaBbEnum;
>
> }
>
> impl AaBb for (int, f64) {
> fn get(&self) -> AaBbEnum { match *self { (i, f) => Aa(i, f), } }
> }
>
> impl AaBb for (f64) {
> fn get(&self) -> AaBbEnum { Bb(*self) }
>
> }
>
> fn overloaded<T: AaBb>(x: T) {
> match x.get() {
> Aa(i, f) => println!("got Aa: {}", (i, f)),
> Bb(f) => println!("got Bb: {}", f),
>
> }
> }
>
> #[main]
> fn main() {
> overloaded((5i, 7.3243)); // prints: got Aa: (5, 7.3243)
> overloaded((3.5)); // prints: got Bb: 3.5
> }
>
> Now, there is no runtime failure => you cannot accidentally match on `Bb`
> and requests `get_aa`!
>
Kevin
[-- Attachment #2: Type: text/html, Size: 2086 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-11 23:13 ` Kevin Cantu
@ 2014-06-12 6:25 ` Noam Yorav-Raphael
2014-12-31 2:26 ` techabc
0 siblings, 1 reply; 21+ messages in thread
From: Noam Yorav-Raphael @ 2014-06-12 6:25 UTC (permalink / raw)
To: Kevin Cantu; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 1647 bytes --]
Cool. I was afraid that it will be harder for the compiler to optimize away
the enum, but it seems to be doing fine.
(If it does turn out that it's harder for the compiler, I don't see a real
problem with the approach I suggested, as a runtime failure can only be
caused by a bug in the code generator, not by user code)
On Thu, Jun 12, 2014 at 2:13 AM, Kevin Cantu <me@kevincantu.org> wrote:
> Matthew Monrocq suggests this improvement, which looks even cleaner to
> use, although slightly more complicated to implement generation of:
>
>
> On Wed, Jun 11, 2014 at 11:38 AM, Matthieu Monrocq <
> matthieu.monrocq@gmail.com> wrote:
>
>> [snip]
>>
>> I do like the idea of the trait, however I would rather do away with all
>> the `get_aa`: why not directly wrap the parameters ?
>>
>> enum AaBbEnum {
>> Aa(int, f64),
>> Bb(f64),
>> }
>> trait AaBb {
>> fn get(&self) -> AaBbEnum;
>>
>> }
>>
>> impl AaBb for (int, f64) {
>> fn get(&self) -> AaBbEnum { match *self { (i, f) => Aa(i, f), } }
>> }
>>
>> impl AaBb for (f64) {
>> fn get(&self) -> AaBbEnum { Bb(*self) }
>>
>> }
>>
>> fn overloaded<T: AaBb>(x: T) {
>> match x.get() {
>> Aa(i, f) => println!("got Aa: {}", (i, f)),
>> Bb(f) => println!("got Bb: {}", f),
>>
>> }
>> }
>>
>> #[main]
>> fn main() {
>> overloaded((5i, 7.3243)); // prints: got Aa: (5, 7.3243)
>> overloaded((3.5)); // prints: got Bb: 3.5
>> }
>>
>> Now, there is no runtime failure => you cannot accidentally match on `Bb`
>> and requests `get_aa`!
>>
>
>
>
> Kevin
>
>
[-- Attachment #2: Type: text/html, Size: 2912 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-12 6:25 ` Noam Yorav-Raphael
@ 2014-12-31 2:26 ` techabc
0 siblings, 0 replies; 21+ messages in thread
From: techabc @ 2014-12-31 2:26 UTC (permalink / raw)
To: rust-dev
[-- Attachment #1: Type: text/plain, Size: 2038 bytes --]
https://github.com/cyndis/qmlrs
qmlrs - QtQuick bindings for Rust
but , still hope qt5 binding for rust.
2014-06-12 14:25 GMT+08:00 Noam Yorav-Raphael <noamraph@gmail.com>:
> Cool. I was afraid that it will be harder for the compiler to optimize
> away the enum, but it seems to be doing fine.
> (If it does turn out that it's harder for the compiler, I don't see a real
> problem with the approach I suggested, as a runtime failure can only be
> caused by a bug in the code generator, not by user code)
>
>
> On Thu, Jun 12, 2014 at 2:13 AM, Kevin Cantu <me@kevincantu.org> wrote:
>
>> Matthew Monrocq suggests this improvement, which looks even cleaner to
>> use, although slightly more complicated to implement generation of:
>>
>>
>> On Wed, Jun 11, 2014 at 11:38 AM, Matthieu Monrocq <
>> matthieu.monrocq@gmail.com> wrote:
>>
>>> [snip]
>>>
>>> I do like the idea of the trait, however I would rather do away with all
>>> the `get_aa`: why not directly wrap the parameters ?
>>>
>>> enum AaBbEnum {
>>> Aa(int, f64),
>>> Bb(f64),
>>> }
>>> trait AaBb {
>>> fn get(&self) -> AaBbEnum;
>>>
>>> }
>>>
>>> impl AaBb for (int, f64) {
>>> fn get(&self) -> AaBbEnum { match *self { (i, f) => Aa(i, f), } }
>>> }
>>>
>>> impl AaBb for (f64) {
>>> fn get(&self) -> AaBbEnum { Bb(*self) }
>>>
>>> }
>>>
>>> fn overloaded<T: AaBb>(x: T) {
>>> match x.get() {
>>> Aa(i, f) => println!("got Aa: {}", (i, f)),
>>> Bb(f) => println!("got Bb: {}", f),
>>>
>>> }
>>> }
>>>
>>> #[main]
>>> fn main() {
>>> overloaded((5i, 7.3243)); // prints: got Aa: (5, 7.3243)
>>> overloaded((3.5)); // prints: got Bb: 3.5
>>> }
>>>
>>> Now, there is no runtime failure => you cannot accidentally match on
>>> `Bb` and requests `get_aa`!
>>>
>>
>>
>>
>> Kevin
>>
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
[-- Attachment #2: Type: text/html, Size: 3738 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-06 9:54 ` Kevin Cantu
2014-06-06 14:54 ` Manish Goregaokar
@ 2014-06-08 8:28 ` Kevin Cantu
1 sibling, 0 replies; 21+ messages in thread
From: Kevin Cantu @ 2014-06-08 8:28 UTC (permalink / raw)
To: Matthieu Monrocq; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 9378 bytes --]
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@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@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@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@gmail.com> wrote:
>>>
>>>>
>>>>
>>>>
>>>> On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980@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@mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Rust-dev mailing list
>>>>> Rust-dev@mozilla.org
>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> Rust-dev mailing list
>>>> Rust-dev@mozilla.org
>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>
>>>>
>>>
>>
>
[-- Attachment #2: Type: text/html, Size: 14293 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-06 14:54 ` Manish Goregaokar
@ 2014-06-06 20:53 ` Kevin Cantu
0 siblings, 0 replies; 21+ messages in thread
From: Kevin Cantu @ 2014-06-06 20:53 UTC (permalink / raw)
To: Manish Goregaokar; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 11148 bytes --]
Yeah, that's what I'd want to do for a user-developed binding. But for
automatically generated bindings, giving users a macro which inferred
function choice from the arguments -- and complained at compile time when
unable to -- would be really cool. Let me try to some sort of proof of
concept later this weekend, and then we can talk about automatically
generating my hypothetical macro.
Kevin
On Fri, Jun 6, 2014 at 7:54 AM, Manish Goregaokar <manishsmail@gmail.com>
wrote:
> 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@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@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@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@gmail.com> wrote:
>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980@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@mozilla.org
>>>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> Rust-dev mailing list
>>>>>> Rust-dev@mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Rust-dev mailing list
>>>>> Rust-dev@mozilla.org
>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>
>>>>>
>>>>
>>>
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
[-- Attachment #2: Type: text/html, Size: 16515 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-06 9:54 ` Kevin Cantu
@ 2014-06-06 14:54 ` Manish Goregaokar
2014-06-06 20:53 ` Kevin Cantu
2014-06-08 8:28 ` Kevin Cantu
1 sibling, 1 reply; 21+ messages in thread
From: Manish Goregaokar @ 2014-06-06 14:54 UTC (permalink / raw)
To: Kevin Cantu; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 10350 bytes --]
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@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@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@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@gmail.com> wrote:
>>>
>>>>
>>>>
>>>>
>>>> On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980@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@mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Rust-dev mailing list
>>>>> Rust-dev@mozilla.org
>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> Rust-dev mailing list
>>>> Rust-dev@mozilla.org
>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>
>>>>
>>>
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
[-- Attachment #2: Type: text/html, Size: 15498 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-06 9:44 ` Kevin Cantu
@ 2014-06-06 9:54 ` Kevin Cantu
2014-06-06 14:54 ` Manish Goregaokar
2014-06-08 8:28 ` Kevin Cantu
0 siblings, 2 replies; 21+ messages in thread
From: Kevin Cantu @ 2014-06-06 9:54 UTC (permalink / raw)
To: Matthieu Monrocq; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 8468 bytes --]
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@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@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@gmail.com> wrote:
>>
>>>
>>>
>>>
>>> On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980@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@mozilla.org
>>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> Rust-dev mailing list
>>>> Rust-dev@mozilla.org
>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>
>>>>
>>>
>>> _______________________________________________
>>> Rust-dev mailing list
>>> Rust-dev@mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>>
>>
>
[-- Attachment #2: Type: text/html, Size: 12911 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-06-06 9:35 ` Kevin Cantu
@ 2014-06-06 9:44 ` Kevin Cantu
2014-06-06 9:54 ` Kevin Cantu
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Cantu @ 2014-06-06 9:44 UTC (permalink / raw)
To: Matthieu Monrocq; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 7928 bytes --]
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@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@gmail.com> wrote:
>
>>
>>
>>
>> On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980@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@mozilla.org
>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>
>>>>
>>>
>>> _______________________________________________
>>> Rust-dev mailing list
>>> Rust-dev@mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>>
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
[-- Attachment #2: Type: text/html, Size: 12084 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-24 10:45 ` Matthieu Monrocq
@ 2014-06-06 9:35 ` Kevin Cantu
2014-06-06 9:44 ` Kevin Cantu
0 siblings, 1 reply; 21+ messages in thread
From: Kevin Cantu @ 2014-06-06 9:35 UTC (permalink / raw)
To: Matthieu Monrocq; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 6649 bytes --]
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@gmail.com> wrote:
>
>
>
> On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980@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@mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>>
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
[-- Attachment #2: Type: text/html, Size: 9361 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
2014-05-24 7:06 Zoltán Tóth
@ 2014-05-24 10:45 ` Matthieu Monrocq
2014-06-06 9:35 ` Kevin Cantu
0 siblings, 1 reply; 21+ messages in thread
From: Matthieu Monrocq @ 2014-05-24 10:45 UTC (permalink / raw)
To: Zoltán Tóth; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 5423 bytes --]
On Sat, May 24, 2014 at 9:06 AM, Zoltán Tóth <zo1980@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@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
[-- Attachment #2: Type: text/html, Size: 7354 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback
@ 2014-05-24 7:06 Zoltán Tóth
2014-05-24 10:45 ` Matthieu Monrocq
0 siblings, 1 reply; 21+ messages in thread
From: Zoltán Tóth @ 2014-05-24 7:06 UTC (permalink / raw)
To: Alexander Tsvyashchenko; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 3176 bytes --]
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 )
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@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
[-- Attachment #2: Type: text/html, Size: 4136 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2014-12-31 2:26 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-22 20:27 [rust-dev] Qt5 Rust bindings and general C++ to Rust bindings feedback Alexander Tsvyashchenko
2014-05-23 4:12 ` Patrick Walton
2014-05-23 18:26 ` Benjamin Striegel
2014-05-23 20:06 ` Alexander Tsvyashchenko
2014-05-23 19:56 ` Alexander Tsvyashchenko
2014-05-23 4:15 ` Corey Richardson
2014-05-23 5:35 ` Huon Wilson
2014-06-11 11:35 ` Noam Yorav-Raphael
2014-06-11 17:23 ` Kevin Cantu
2014-06-11 20:30 ` Noam Yorav-Raphael
[not found] ` <CAKE6RfgoXSSkozqreZNW1MCemYP0KRc_3xqoOYL4eswFm9_tbQ@mail.gmail.com>
2014-06-11 23:13 ` Kevin Cantu
2014-06-12 6:25 ` Noam Yorav-Raphael
2014-12-31 2:26 ` techabc
2014-05-24 7:06 Zoltán Tóth
2014-05-24 10:45 ` Matthieu Monrocq
2014-06-06 9:35 ` Kevin Cantu
2014-06-06 9:44 ` Kevin Cantu
2014-06-06 9:54 ` Kevin Cantu
2014-06-06 14:54 ` Manish Goregaokar
2014-06-06 20:53 ` Kevin Cantu
2014-06-08 8:28 ` Kevin Cantu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox