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

2014-06-11 Thread Noam Yorav-Raphael
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  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.monr...@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(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


[rust-dev] Is there a Parsec equivalent in Rust?

2014-06-11 Thread Akira Hayakawa
Hi,

Haskell's Parsec is really a good tool to parse languages.
Scala also has the equivalent.

What about Rust?

-- 
Akira Hayakawa 
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-06-11 Thread Kevin Cantu
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.monr...@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(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


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread Tommi
On 2014-06-11, at 21:47, Tommi  wrote:

> I said `Mul` and similar should do it, i.e. functions that take a variable 
> and return a variable of that same type.


Although, a larger issue of genericity is that multiplication doesn't always 
return the same type as one of its arguments.

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-06-11 Thread Noam Yorav-Raphael
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  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(x: T) {
> match x.get_type() {
> Aa => println!("got Aa: {}", x.get_aa()),
> Bb => println!("got Bb: {}", x.get_bb()),
> }
> }
>
> fn overloaded_format(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 
> 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(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(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 
>> 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

Re: [rust-dev] Building rustc @ 1GB RAM?

2014-06-11 Thread Ian Daniher
Output of "make check" for those of you who are interested.

failures:
[run-pass] run-pass/intrinsic-alignment.rs
[run-pass] run-pass/rec-align-u64.rs
[run-pass] run-pass/stat.rs

test result: FAILED. 1469 passed; 3 failed; 32 ignored; 0 measured



On Wed, Jun 11, 2014 at 12:15 PM, Ian Daniher 
wrote:

> I have a dual core arm machine with 1GB of RAM keeping up with rust master
> - every 8hrs, it updates git, runs "make install," and 8hrs later I have an
> up-to-date rustc w/ libs.
>
> No swap, no compression kmods, just a build of rustc & libs that passes
> (almost) all tests.
>
> root@debian-0d0dd:/mnt/armscratch/node-v0.10.28# free -h; uname -a; cat
>> /proc/cpuinfo; rustc -v
>>  total   used   free sharedbuffers cached
>> Mem:  1.0G   982M24M 0B   155M   750M
>> -/+ buffers/cache:76M   930M
>> Swap:   0B 0B 0B
>> Linux debian-0d0dd 3.4.79-r0-s20-rm2+ #54 SMP Tue Feb 18 01:09:07 YEKT
>> 2014 armv7l GNU/Linux
>> Processor   : ARMv7 Processor rev 4 (v7l)
>> processor   : 0
>> BogoMIPS: 1819.52
>> processor   : 1
>> BogoMIPS: 1819.52
>> Features: swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls
>> vfpv4 idiva idivt
>> CPU implementer : 0x41
>> CPU architecture: 7
>> CPU variant : 0x0
>> CPU part: 0xc07
>> CPU revision: 4
>> Hardware: sun7i
>> Revision: 
>> Serial  : 
>> rustc 0.11.0-pre (f92a8fa 2014-06-10 18:07:07 -0700)
>> host: arm-unknown-linux-gnueabihf
>
>
>
>
> On Tue, Jun 10, 2014 at 5:19 PM, Igor Bukanov  wrote:
>
>> I tried building rust in a VM with 1GB of memory and it seems only
>> zswap works. With zram-only solution without any real swap I was not
>> able to compile rust at all. The compiler generated out-of-memory
>> exception with zram configured to take 30-70% of memory. With zswap
>> enabled, zswap.max_pool_percent=70  and the real swap of 2.5 GB the
>> compilation time for the latest tip was about 2 hours. This is on Mac
>> Air and Linux inside VirtualBox.
>>
>> On 5 June 2014 20:46, Ian Daniher  wrote:
>> > zram is a great suggestion, thanks! I'll give it a shot.
>> > —
>> > From My Tiny Glowing Screen
>> >
>> >
>> > On Thu, Jun 5, 2014 at 2:25 PM, Igor Bukanov  wrote:
>> >>
>> >> Have you considered to use zram? Typically the compression for
>> >> compiler memory is over a factor of 3 so that can be an option as the
>> >> performance degradation under swapping could be tolerable. A similar
>> >> option is to enable zswap, but as the max compression with it is
>> >> effectively limited by factor of 2, it may not be enough to avoid
>> >> swapping.
>> >>
>> >> On 5 June 2014 20:13, Ian Daniher  wrote:
>> >> > 1GB is close-ish to the 1.4GB last reported (over a month ago!) by
>> >> > http://huonw.github.io/isrustfastyet/mem/.
>> >> >
>> >> > Are there any workarounds to push the compilation memory down? I'm
>> also
>> >> > exploring distcc, but IRFY has a bit of semantic ambiguity as to
>> whether
>> >> > or
>> >> > not it's 1.4GB simultaneous or net total.
>> >> >
>> >> > Thanks!
>> >> > --
>> >> > Ian
>> >> >
>> >> > ___
>> >> > 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


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread Corey Richardson
Keeping in mind that the `self` value here can be a reference. Ie,
implementing the traits also for references to a type.

On Wed, Jun 11, 2014 at 11:47 AM, Tommi  wrote:
> On 2014-06-11, at 21:33, Daniel Micay  wrote:
>
> Cloning big integers, rationals based on big integers or arbitrary
> precision floating point values for every single operation has a high
> cost.
>
>
> I didn't say that all functions should start taking their arguments by
> value. I said `Mul` and similar should do it, i.e. functions that take a
> variable and return a variable of that same type. Instead of passing by
> reference and making a clone of the passed reference inside those functions,
> you force the caller to make the clone and mutate the passed argument in
> place. This enables the C++ like rvalue reference optimization for functions
> like multiplication.
>
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>



-- 
http://octayn.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread Tommi
On 2014-06-11, at 21:33, Daniel Micay  wrote:

> Cloning big integers, rationals based on big integers or arbitrary
> precision floating point values for every single operation has a high
> cost.

I didn't say that all functions should start taking their arguments by value. I 
said `Mul` and similar should do it, i.e. functions that take a variable and 
return a variable of that same type. Instead of passing by reference and making 
a clone of the passed reference inside those functions, you force the caller to 
make the clone and mutate the passed argument in place. This enables the C++ 
like rvalue reference optimization for functions like multiplication.

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread Daniel Micay
On 11/06/14 01:54 PM, Tommi wrote:
> If the `Mul` trait and similar were changed to take `self` by value, perhaps 
> the following kind of language design would make more sense:
> 
> If a variable of a type that has a destructor is passed to a function by 
> value (moved), and the variable is used after the function call, the variable 
> would be implicitly cloned before passing it to the function.

Cloning big integers, rationals based on big integers or arbitrary
precision floating point values for every single operation has a high
cost. One of Rust's strength's is that it doesn't have implicit cloning
as C++ does due to copy constructors.



signature.asc
Description: OpenPGP digital signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread Tommi
If the `Mul` trait and similar were changed to take `self` by value, perhaps 
the following kind of language design would make more sense:

If a variable of a type that has a destructor is passed to a function by value 
(moved), and the variable is used after the function call, the variable would 
be implicitly cloned before passing it to the function.

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


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

2014-06-11 Thread Kevin Cantu
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(x: T) {
match x.get_type() {
Aa => println!("got Aa: {}", x.get_aa()),
Bb => println!("got Bb: {}", x.get_bb()),
}
}

fn overloaded_format(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 
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(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(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 
> 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
>
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Building rustc @ 1GB RAM?

2014-06-11 Thread Ian Daniher
I have a dual core arm machine with 1GB of RAM keeping up with rust master
- every 8hrs, it updates git, runs "make install," and 8hrs later I have an
up-to-date rustc w/ libs.

No swap, no compression kmods, just a build of rustc & libs that passes
(almost) all tests.

root@debian-0d0dd:/mnt/armscratch/node-v0.10.28# free -h; uname -a; cat
> /proc/cpuinfo; rustc -v
>  total   used   free sharedbuffers cached
> Mem:  1.0G   982M24M 0B   155M   750M
> -/+ buffers/cache:76M   930M
> Swap:   0B 0B 0B
> Linux debian-0d0dd 3.4.79-r0-s20-rm2+ #54 SMP Tue Feb 18 01:09:07 YEKT
> 2014 armv7l GNU/Linux
> Processor   : ARMv7 Processor rev 4 (v7l)
> processor   : 0
> BogoMIPS: 1819.52
> processor   : 1
> BogoMIPS: 1819.52
> Features: swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls
> vfpv4 idiva idivt
> CPU implementer : 0x41
> CPU architecture: 7
> CPU variant : 0x0
> CPU part: 0xc07
> CPU revision: 4
> Hardware: sun7i
> Revision: 
> Serial  : 
> rustc 0.11.0-pre (f92a8fa 2014-06-10 18:07:07 -0700)
> host: arm-unknown-linux-gnueabihf




On Tue, Jun 10, 2014 at 5:19 PM, Igor Bukanov  wrote:

> I tried building rust in a VM with 1GB of memory and it seems only
> zswap works. With zram-only solution without any real swap I was not
> able to compile rust at all. The compiler generated out-of-memory
> exception with zram configured to take 30-70% of memory. With zswap
> enabled, zswap.max_pool_percent=70  and the real swap of 2.5 GB the
> compilation time for the latest tip was about 2 hours. This is on Mac
> Air and Linux inside VirtualBox.
>
> On 5 June 2014 20:46, Ian Daniher  wrote:
> > zram is a great suggestion, thanks! I'll give it a shot.
> > —
> > From My Tiny Glowing Screen
> >
> >
> > On Thu, Jun 5, 2014 at 2:25 PM, Igor Bukanov  wrote:
> >>
> >> Have you considered to use zram? Typically the compression for
> >> compiler memory is over a factor of 3 so that can be an option as the
> >> performance degradation under swapping could be tolerable. A similar
> >> option is to enable zswap, but as the max compression with it is
> >> effectively limited by factor of 2, it may not be enough to avoid
> >> swapping.
> >>
> >> On 5 June 2014 20:13, Ian Daniher  wrote:
> >> > 1GB is close-ish to the 1.4GB last reported (over a month ago!) by
> >> > http://huonw.github.io/isrustfastyet/mem/.
> >> >
> >> > Are there any workarounds to push the compilation memory down? I'm
> also
> >> > exploring distcc, but IRFY has a bit of semantic ambiguity as to
> whether
> >> > or
> >> > not it's 1.4GB simultaneous or net total.
> >> >
> >> > Thanks!
> >> > --
> >> > Ian
> >> >
> >> > ___
> >> > 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


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread SiegeLord

On 06/11/2014 10:10 AM, Sebastian Gesemann wrote:

On Wed, Jun 11, 2014 at 3:27 PM, SiegeLord wrote:

[...] Along the same lines, it is not immediately obvious
to me how to extend this lazy evaluation idea to something like num::BigInt.
So far, it seems like lazy evaluation will force dynamic dispatch in that
case which is a big shame (i.e. you'd store the operations in one array,
arguments in another and then play them back at the assignment time).


I havn't tried something like expression templates in Rust yet. How
did you come to the conclusion that it would require dynamic dispatch?


It's just the first idea I had with how this could work, but you're 
right, I can envision a way to do this without using dynamic dispatch. 
It'd look something like something like this: 
https://gist.github.com/SiegeLord/f1af81195df89ec04d10 . So, if nothing 
comes out of this discussion, at least you'd be able to do that. Note 
that the API is uglier, since you need to call 'eval' explicitly. 
Additionally, you need to manually borrow 'm' because you can't specify 
a lifetime of the &self argument in mul (another problem with 
by-ref-self methods).


-SL

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread Huon Wilson

On 11/06/14 23:27, SiegeLord wrote:
Aside from somewhat more complicated impl's, are there any downsides 
to never using anything but by value 'self' in traits?


Currently trait objects do not support `self` methods (#10672), and, 
generally, the interactions with trait objects seem peculiar, e.g. if 
you've implemented Trait for &Type, then you would want to be coercing a 
`&Type` to a `&Trait`, *not* a `&(&Type)` as is currently required.


However, I don't think these concerns affect the operator overloading 
traits.



https://github.com/mozilla/rust/issues/10672


Huon

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread Sebastian Gesemann
On Wed, Jun 11, 2014 at 3:27 PM, SiegeLord wrote:
> [...] Along the same lines, it is not immediately obvious
> to me how to extend this lazy evaluation idea to something like num::BigInt.
> So far, it seems like lazy evaluation will force dynamic dispatch in that
> case which is a big shame (i.e. you'd store the operations in one array,
> arguments in another and then play them back at the assignment time).

I havn't tried something like expression templates in Rust yet. How
did you come to the conclusion that it would require dynamic dispatch?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Porting a small DSP test from C++ to Rust: Comments and performance observations

2014-06-11 Thread Learn OpenGL ES
So I feel a little sheepish now, as I tried the C++ code again with LTO turned 
off, and it’s now slightly faster than the Rust version. I guess it’s a 
performance regression that gets triggered by LTO in this specific case. 

Here are the results I get now:

clang PerformanceTest.cpp dsp.cpp -std=c++11 -ffast-math -O3 -o PerformanceTest

Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.2.0
Thread model: posix

Iterations: 955
C results: 100,043,846 shorts per second.

Rust is still very competitive with 93M shorts/second, and I would hope to see 
the gap narrowed or eliminated as the compiler & language continue to be 
improved.

The code is also now available here if anyone is interested: 
https://gist.github.com/learnopengles/004ff4eee75057ca006c___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] &self/&mut self in traits considered harmful(?)

2014-06-11 Thread SiegeLord
First, let me begin with a small discussion about C++ rvalue references. 
As some of you know, they were introduced to C++ in part to solve 
problems like this:


Matrix m;
m.data = {1.0, 2.0, 3.0};
Matrix m2 = m * 2.0 * 5.0 * 10.0;

Before C++11, most implementations the multiplications on the third line 
would create two (unnecessary) temporary copies of the Matrix, causing 
widespread inefficiency if Matrix was large. By using rvalue references 
(see the implementation in this gist: 
https://gist.github.com/SiegeLord/85ced65ab220a3fdc1fc we can reduce the 
number of copies to one. What the C++ does is that the first 
multiplication (* 2.0) creates a copy of the matrix, and the remaining 
multiplications move that copy around.


If you look at the implementation, you'll note how complicated the C++ 
move semantics are compared to Rust's (you have to use std::move 
everywhere, define move-constructors and move-assignment with 
easy-to-get-wrong implementations etc.). Since Rust has simpler move 
semantics, can we do the same thing in Rust?


It turns out we cannot, because the operator overloading in Rust is done 
by overloading a trait with a method that takes self by reference:


pub trait Mul
{
fn mul(&self, rhs: &RHS) -> Result;
}

This means that the crucial step of moving out from the temporary cannot 
be done without complicated alternatives (explained at the end of this 
email). If we define an a multiplication trait that takes self by value, 
however then this is possible and indeed relatively trivial (see 
implementation here: 
https://gist.github.com/SiegeLord/11456760237781442cfe ). This code will 
act just like the C++ did: it will copy during the first move_mul call, 
and then move the temporary around:


let m = Matrix{ data: vec![1.0f32, 2.0, 3.0] };
let m2 = (&m).move_mul(2.0).move_mul(5.0).move_mul(10.0);

So there's nothing in Rust move semantics which prevents this useful 
pattern, and it'd be possible to do that with syntax sugar if the 
operator overload traits did not sabotage it. Pretty much all the 
existing users (e.g. num::BigInt and sebcrozet's nalgebra) of operator 
overloading traits take the inefficient route of creating a temporary 
copy for each operation (see 
https://github.com/mozilla/rust/blob/master/src/libnum/bigint.rs#L283 
and 
https://github.com/sebcrozet/nalgebra/blob/master/src/structs/dmat.rs#L593 
). If the operator overloading traits do not allow you to create 
efficient implementations of BigNums and linear algebra operations, the 
two use cases why you'd even *have* operator overloading as a language 
feature, why even have that feature?


I think this goes beyond just operator overloading, however, as these 
kinds of situations may arise in many other traits. By defining trait 
methods as taking &self and &mut self, we are preventing these useful 
optimizations.


Aside from somewhat more complicated impl's, are there any downsides to 
never using anything but by value 'self' in traits? If not, then I think 
that's what they should be using to allow people to create efficient 
APIs. In fact, this probably should extend to every member generic 
function argument: you should never force the user to tie their hands by 
using a reference. Rust has amazing move semantics, I just don't see 
what is gained by abandoning them whenever you use most traits.


Now, I did say there are complicated alternatives to this. First, you 
actually *can* move out through a borrowed pointer using 
RefCell>. You can see what this looks like here: 
https://gist.github.com/SiegeLord/e09c32b8cf2df72b2422 . I don't know 
how efficient that is, but it is certainly more fragile. With my 
by-value MoveMul implementation, the moves are checked by the 
compiler... in this case, they are not. It's easy to end up with a 
moved-out, dangling Matrix. This is what essentially has to be done, 
however, if you want to preserve the general semantic of the code.


Alternatively, you can use lazy evaluation/expression templates. This is 
the route I take in my linear algebra library. Essentially, each 
operation returns a struct (akin to what happens with many Iterator 
methods) that stores the arguments by reference. When it comes time to 
perform assignment, the chained operations are performed element-wise. 
There are no unnecessary copies and it optimizes well. The problem is 
that its a lot more complicated to implement and it pretty much forces 
you to use interior mutability (just Cell this time) if you don't want a 
crippled API. The latter bit introduces a whole slew of subtle bugs (in 
my opinion they are less common than the ones introduced by RefCell). 
Also, I don't think expression templates are the correct way to wrap, 
e.g., a LAPACK library. I.e. they only work well when you're 
implementing the math yourself which is not ideal for the more 
complicated algorithms. Along the same lines, it is not immediately 
obvious to me how to extend this lazy evaluation idea to something l

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

2014-06-11 Thread Noam Yorav-Raphael
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(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(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 
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


Re: [rust-dev] Porting a small DSP test from C++ to Rust: Comments and performance observations

2014-06-11 Thread Vladimir Matveev
Hi, Kevin!

> * What would be the replacement for a struct-scoped static constant, so I 
> could put a static inside a struct instead of making it a global?
It is not possible now. There are some suggestions on associated items, but I 
don’t think they are active. Currently Rust module system is used to control 
scopes of statics.

> * Rust doesn't have prefix/postfix increment? Or, I just didn't find the 
> right syntax of using it?
Yes, Rust doesn’t have it. You should use composite assignment: x += 1. It is 
not an expression, though.

> * My biggest problem was figuring out how to use arrays. Originally, things 
> just weren't working and I think it's because I was inadvertently copying an 
> array instead of referring to the original. t just couldn't figure out how to 
> create a mutable alias to an array passed into a function by reference.
Well, you have correctly figured out that it is done using slices :)

> * I understand the reasoning behind explicit integer conversions, but 
> depending on what one is doing, it can add to a lot of explicit conversions, 
> and I also didn't figure out a way to do an unsigned for loop.
Yes, explicit conversions may sometimes be too verbose. As for unsigned for 
loop, it is easy. Remember, Rust uses type inference to find out correct types 
of all local variables. `range()` function which creates range iterators is 
generic and looks like this:

fn range(from: T, until: T) -> Range { … }

(actual definition is different because T is not arbitrary but bounded with 
some traits)

The `T` type parameter is determined automatically from the use site of the 
function. In your case it is deduced as `int` because  of `length` variable 
(which is of `int` type). So you can just cast `length` to `uint`:

for i in range(0, length as uint) { … }

and `i` variable will be unsigned. BTW, why did you define `length` parameter 
as `int` at all? You can make it `uint` and you won’t need to do this cast.

> * When creating / using arrays, there is sometimes duplication of the size 
> parameter. Is there a way to reduce that?
I don’t think so. They are statically sized arrays, so they just need their 
size specified. When you don’t care about their size, you usually use slices 
anyway.

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev