Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-26 Thread SiegeLordEx

On 07/26/2014 12:56 PM, Patrick Walton wrote:

Well, part of the problem here is that people are going to want to write
generic functions that take addable values. If we start making `+` and
friends overloadable/ad-hoc, then people are going to be surprised when
they can't pass (say) bignums to functions that want addable things.


The current Rust doesn't allow a complete lack of surprise. Either you 
will be surprised by the traits not being supported by every numeric 
type, or you will be surprised by the terrible performance of most types 
that implement OpT, T. The core issue is that 'addable' (and other 
concepts/functions) cannot be expressed efficiently for all types in 
some unified way.


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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-26 Thread Daniel Micay
On 26/07/14 12:56 PM, Patrick Walton wrote:
 On 7/26/14 5:54 AM, SiegeLordEx wrote:
 While this doesn't matter for the pow function (the alternate function
 would just have a different path/name), it matters for the special
 syntaxes. When the Iterator is no longer enough for you (there was a
 case like this in IRC recently involving mutable windows), then you have
 to abandon the for loop which is a big syntactic change (right now it
 works because it is ad-hoc).
 
 As of last week it's not anymore.
 
 Similarly, when the operator overloading
 traits are insufficient, then you have to abandon that sugar as well.
 One might say well, don't use those traits then but that's not what
 happens in practice. In practice, people want the syntax sugar and
 therefore are guided into inefficiency. Some of BigNum's operator
 overloads shouldn't exist because they are so inefficient, and yet they
 do because people expect BigNum to act (on a syntactic level) just like
 any other number.

 So I think this is a real problem with real solutions that don't require
 going down the ad-hoc template black hole.
 
 Well, part of the problem here is that people are going to want to write
 generic functions that take addable values. If we start making `+` and
 friends overloadable/ad-hoc, then people are going to be surprised when
 they can't pass (say) bignums to functions that want addable things.
 
 Patrick

We can start out with efficient generic code for bignums (meaning stuff
like `op(mut tmp, a, b)` in a loop with a reused temporary variable)
and then add a static branch + other code for primitives as vector
iterators already do for zero-size types. Ideally there would be a way
of expressing it without relying on optimizations to remove a branch but
the language is expressive enough other than that.



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


[rust-dev] std::num::pow() is inadequate / language concepts

2014-07-26 Thread Ariel Ben-Yehuda
std::num::pow is not the most general exponentiation function but a
second-rate utility function in the standard library - you don't have to
use it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] std::num::pow() is inadequate / language concepts

2014-07-26 Thread Ariel Ben-Yehuda
[The previous message got sent accidentally by gmail]

However, for performance reasons, I think some kind of trait overloading
would be nice.

i.e., you should be able to do

  implT TraitT for Aφ { ... }

  overload impl Traitint for Aφ[int/T] {
//...
  }

And when using (x : Traitint) the items in the overload impl will be used
instead of the items in the base impl (note that, except for associated
types, overloaded traits won't participate in name resolution/type checking
- so probably force associated types in the overload to be the same as the
base).
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Opt-In Built-In Traits

2014-07-25 Thread David Henningsson



On 2014-07-24 16:30, Kevin Ballard wrote:

On Wed, Jul 23, 2014, at 12:52 PM, David Henningsson wrote:



On 2014-07-21 19:17, Patrick Walton wrote:

On 7/21/14 8:49 AM, Tobias Müller wrote:

Patrick Walton pcwal...@mozilla.com wrote:

On 7/20/14 8:12 PM, David Henningsson wrote:

   From a language design perspective, maybe it would be more
intuitive to
have different syntaxes for copy and move, like:


As a rust newbie, that aspect aways makes me a bit nervous. Two quite
different operations with the same syntax and and simply changing a
detail in the struct can be enough to switch between the two.


This is the reason for Opt-In Built-In Traits.

* Causing a move when you thought you were copying results in a compiler
error.

* Causing a copy when you thought you were moving is harmless, as any
implicit copy in Rust has *exactly the same runtime semantics* as a
move, except that the compiler prevents you from using the value again.

Again, we had that world before. It was extremely annoying to write
move all over the place. Be careful what you wish for.


I find these arguments compelling, but if what we want to accomplish is
a conscious choice between copy and move every time somebody makes a new
struct, maybe #[Deriving(Data)] struct Foo vs struct Foo is not
first-class enough.

Maybe the move vs copy should be done by using different keywords, a few
brainstorming examples:

   * datastruct for copy, struct for move
   * simplestruct for copy, complexstruct for move
   * struct for copy, class or object for move


What would this solve? Nobody who’s using a type is going to care about
the keyword used to introduce the type, they’re only going to care about
the behavior of the type. Using `datastruct` instead of `struct` will
have zero impact on the people writing

let x: Foo = y;

Actually, the whole notion of having to intentionally describe on every
struct whether you want it to be Copy is my biggest objection to opt-in
traits. The API Stability / documentation aspect is great, but it does
seem like a burden to people writing once-off structs.


Is it the typing or the decision that would be a burden? My idea was 
mostly to reduce the typing compared to writing Deriving(Data) all the 
time.



What I’d actually like to see is for private structs to infer things
like Copy and for public structs to then require it to be explicitly
stated. I don’t know how to do this in a way that’s not confusing
though.


That's actually an interesting idea. Maybe something like this?

struct foo1 {} /* Ok, copy or move is inferred */

#[Deriving(Data)]
pub struct foo2 {} /* Ok, copy behavior advertised */

#[Deriving(NoCopy)]
pub struct foo3 {} /* Ok, move behavior advertised */

pub struct foo4 {} /* Compile error, move or copy behavior must be 
explicitly stated */


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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Gregor Cramer
Hi Patrick,

 If the signature is wrong and we mistakenly freeze it, we can just introduce
 a new function with a different name.

But this is a severe design issue, to introduce new function names. This makes
generic programming impossible. Now the user has to distinguish between
the types, but this is the task of the compiler.

 Overloading only helps some simple cases, and adds more complexity than it's
 worth (IMO).

Overloading is the only way to specialize functions, and this is the only way
to allow generic programming. Without specializing we are back to the bad
old days, where the user has to call the appropriate function for a specific
object, but in a modern programming language the compiler is doing these
things.

 The problem with C++ isn't that it doesn't have enough features. Rust is
 deliberately omitting some features from C++ that don't pull their weight.
 Overloading is one of them.

I think that some weights are unavoidable. And I cannot see serious drawbacks
with function overloading, but I see serious drawbacks without:

As I saw Rust the first time, I was impressed, and I decided to overwork the
big integer module (I've already written a big integer library in C), because
the current impementation is much too slow, it suffers from:

1. too many memory allocations
2. some algorithms are a bit naive.

And at first I tried to specialize std::num::pow(), but I gave up immediately,
because I cannot specialize. And without specializing this function I cannot
realize a proper implementation and design, and I'm never doing half-baken
things. So I gave up at all.

The current design in Rust does not allow:

1. Generic programming, in current design of Rust the user has to know,
which function to call for a specific object, and has to use switch (or match)
statements to call it (and if he forget the right functions and uses
std::num::pow(), his program will suffer). This is a programming style 30 years
ago, as I started to write programs.

2. Uniform function signatures, currently the user has to decide about using a
reference or not, but the compiler should decide. If the compiler is deciding,
whether an argument is given by value or by reference, then the problem with
the signature will vanish. And the compiler is better to decide than the user.
One more advantage: the user must not know whether to use a reference
or not when calling a function/method. One exception: a mutable argument, in
this case a reference will be used explicitely by the user, when specifiying
the signature, and when calling the function.

One more drawbacks without overloading: The user defines two  print methods:

pub fn print(line : string) - bool;
pub fn print(line : string, max_line_length : uint) - bool;

Not possible, he has to use different names. An alternative definition would be:

pub fn print(line : string) - bool;
pub fn print_with_maxlen(line : string, len : uint) - bool;

30 years ago this was the normal way, but nowadays, it's a No-Go.

The current status of Rust is: it does not allow proper software design. And
that's bad, because a successor for C++ is needed. Of course, a successor
of C++ does not mean: a better C++. It means, a completely new language
conecept, like Rust. And it does not mean: avoid the good things of C++,
like specialization of functions.

Cheers,
Gregor___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread SiegeLordEx

On 07/24/2014 06:46 PM, Gregor Cramer wrote:

1. Overloading is not supported (even the archaic C++ is providing this).


I should note that Rust provides a limited form of overloading via the 
trait-double dispatch trick:


trait PowImplRes
{
fn pow(self, exp: uint) - Res;
}

fn powRes, T: PowImplRes(t: T, exp: uint) - Res
{
t.pow(exp)
}

impl PowImplint for int
{
fn pow(self, exp: uint) - int
{
...
}
}

impl'l PowImplBigInt for 'l BigInt
{
fn pow(self, exp: uint) - BigInt
{
...
}
}

Note that this is not suitable for generic code, which is kind of an 
under-appreciated problem. Currently Rust places running generic code 
above writing efficient code, which is not a trade-off it should be 
making imo. In my matrix library I opted for making my types useless for 
generic code in the quest for efficiency, and I find it unfortunate that 
I had to do that.




2. The footprint 'base: T' is not 100% suitable, for big integers the
function

definition

fn pow(base: BigInt, mut exp: uint) - BigInt

would be more appropriate, because the argument 'base' needs not to be

modified (or reassigned), and a call by reference (avoiding a superfluous

memory allocation) is more efficient in this case.



Yes, I concur on most of these points and I've brought up some related 
points before. The operator overloading technique used by Rust is 
antithetical to efficient generic code. The core numeric traits and 
functions are currently designed only with built-in types in mind, 
causing BigInt (and others, e.g. matrices) to suffer. I don't know how 
to fix these things, but perhaps auto-ref and ad-hoc operator 
overloading (it works for Haskell, why not for Rust?) would be part of 
the solution. Ultimately, I suspect that function overloading (the Rust 
trait double-dispatch trick above may be sufficient with auto-ref) will 
be of critical importance. This problem is very under-appreciated and I 
hope this aspect of the language is not stabilized by 1.0.


If the relevant operator overload is removed from BigInt, then one 
temporary solution will emerge: you won't be able to call this pow 
function at all, and will be forced to call a specialized version. As 
long as the core is designed for built-in types only, BigInt should stop 
pretending to be one. I think this is what should be done in the interim.


-SL

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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread ??????
Hi all,


I have an idea about data types here. 
We have two `product types` here, tuples and structs, but only one `sum types`, 
which is `enum`. 
The tuple's members have anonymous names. There is a missing type which is `sum 
type`with anonymous members. 


Why shouldn't we have another simpler `sum type` here. It can be defined like 
`type sum_type = int | str | (int, str)`.
It is like `enum`, but the members are anonymous.


Now, the function overloading is very obvious. `fn overload( arg : sum_type ) ` 
is just fine.


And, IMHO, this design is much clearer than traditional overloading, more 
explicit.


Apologize for my poor English. Feel free to ignore my proposal if it's silly.


Thanks,
Changchun


-- Original --
From:  Gregor Cramer;rema...@gmx.net;
Date:  Fri, Jul 25, 2014 06:47 PM
To:  rust-devrust-dev@mozilla.org; 

Subject:  Re: [rust-dev] std::num::pow() is inadequate / language concepts



 
Hi Patrick,
 
 
 
 If the signature is wrong and we mistakenly freeze it, we can just introduce
 
 a new function with a different name.
 
 
 
But this is a severe design issue, to introduce new function names. This makes
 
generic programming impossible. Now the user has to distinguish between
 
the types, but this is the task of the compiler.
 
 
 
 Overloading only helps some simple cases, and adds more complexity than it's
 
 worth (IMO).
 
 
 
Overloading is the only way to specialize functions, and this is the only way
 
to allow generic programming. Without specializing we are back to the bad
 
old days, where the user has to call the appropriate function for a specific
 
object, but in a modern programming language the compiler is doing these
 
things.
 
 
 
 The problem with C++ isn't that it doesn't have enough features. Rust is
 
 deliberately omitting some features from C++ that don't pull their weight.
 
 Overloading is one of them.
 
 
 
I think that some weights are unavoidable. And I cannot see serious drawbacks
 
with function overloading, but I see serious drawbacks without:
 
 
 
As I saw Rust the first time, I was impressed, and I decided to overwork the
 
big integer module (I've already written a big integer library in C), because
 
the current impementation is much too slow, it suffers from:
 
 
 
1. too many memory allocations
 
2. some algorithms are a bit naive.
 
 
 
And at first I tried to specialize std::num::pow(), but I gave up immediately,
 
because I cannot specialize. And without specializing this function I cannot
 
realize a proper implementation and design, and I'm never doing half-baken
 
things. So I gave up at all.
 
 
 
The current design in Rust does not allow:
 
 
 
1. Generic programming, in current design of Rust the user has to know,
 
which function to call for a specific object, and has to use switch (or match)
 
statements to call it (and if he forget the right functions and uses
 
std::num::pow(), his program will suffer). This is a programming style 30 years
 
ago, as I started to write programs.
 
 
 
2. Uniform function signatures, currently the user has to decide about using a
 
reference or not, but the compiler should decide. If the compiler is deciding,
 
whether an argument is given by value or by reference, then the problem with
 
the signature will vanish. And the compiler is better to decide than the user.
 
One more advantage: the user must not know whether to use a reference
 
or not when calling a function/method. One exception: a mutable argument, in
 
this case a reference will be used explicitely by the user, when specifiying
 
the signature, and when calling the function.
 
 
 
One more drawbacks without overloading: The user defines two  print methods:
 
 
 
pub fn print(line : string) - bool;
 
pub fn print(line : string, max_line_length : uint) - bool;
 
 
 
Not possible, he has to use different names. An alternative definition would be:
 
 
 
pub fn print(line : string) - bool;
 
pub fn print_with_maxlen(line : string, len : uint) - bool;
 
 
 
30 years ago this was the normal way, but nowadays, it's a No-Go.
 
 
 
The current status of Rust is: it does not allow proper software design. And
 
that's bad, because a successor for C++ is needed. Of course, a successor
 
of C++ does not mean: a better C++. It means, a completely new language
 
conecept, like Rust. And it does not mean: avoid the good things of C++,
 
like specialization of functions.
 
 
 
Cheers,
 
Gregor___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Gregor Cramer
Hi Marijn,

 Firstly, blanket statements like This makes generic programming
 impossible and it does not allow proper software design are
 unneccesary hyperbole, and do not help the discussion in any way.

You're not right, my statement wasn't blanket, it was my result
after I tried to overwork the big integer library, and I have mentioned this:
I gave up at all. (I'm doing software design and implementation since
more than 30 years, and I never accept compromises, this is the way
how to develop magnificient software).

 Traits provide a more well-defined, easier to reason about alternative
 to overloading. They do require the author of an algorithm to decide
 ahead of time whether this algorithm needs to be specializeable, which
 I guess C++-style overloading does not.

Yes, the traits are great, I'm impressed, as I said before, and in fact Rust
is really great, despite a few facts, otherwise I wouldn't subscribe to
this mailing list. And my goal is to be constructive, don't worry if I'm
a bit euphoric, such things happens. Nethertheless, it gave up to overwork
the big integer libary because I cannot specialize std::num::pow(). There is
no way to proceed with a proper design.

 Whether that is a good or a
 bad thing is debatable, but it is not true that Rust lacks a feature
 for specialization.

There is a lack in the current language concept, std::num::pow()
is inadequate due to this language concept, and std::num::pow() is
only one example for this fact.

I will repeat the problem with signatures. Currently pow() is declared
as following:

pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T;

That't 100% ok. The user will call this function in this way:

pow(a) // a is i32

Perfect. Now I need a specialized function for BigInt:

[#overload]
pub fn pow(base: BigInt, mut exp: uint) - T;

There's a problem (beside the missing overloading feature): the
specialized version requires a reference. Same problem if I'm
calling this function:

pow(a) // a is BigInt

The user has to know how to call a function, depending on the type.
But a proper function specialization would be:

[#overload]
pub fn pow(base: BigInt, mut exp: uint) - T;

And so the function call is as expected, like with other numeric types:

pow(a) // a is BigInt

But there is now a problem in this function definition, BigInt is given as
a copy, and this is a software design issue (superfluous memory allocation).
And this currently happens if the user is calling std::num::pow() with a
numeric type like BigInt (apart from other performance penalties in pow()).

That's what I've mentioned that the compiler should decide whether an
argument is given by reference or by value. In this way the latter approach
works. And in the case that a function willl modify an argument (in-out
value), for example:

fn mul_vec(acc : mut [BigDigit], base: mut [BigDigit], mut exp:uint)

the call of this function would be:

mul_vec(a, b, exp)

This concept will not change, because here it has to be clear that an argument
will be changed (furthermore the compiler should give a warning if a function
is not changing a mutable argument). I think that this approach is even
superior to the 'const' concept of C++, and it fit's with the great overall
concept of Rust (especially with the owner/borrower concept).

I try to show the problems if function specialization (overloading) is not
supported. A stable software design is problematic. Adding a new module,
which will use existing function declarations, is impossible in some cases.
Currently I cannot implement a specialized version of pow() for BigInt, adding
a new function for a different numeric type is only a hack, and moving this
function into a trait is not solving the general problem, because pow() is
only one example. (Beside: it's not my decision to move pow() into a trait.)

Cheers,
Gregor

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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Jason Fager
For the specific issue of exponentiation, you might be interested in
https://github.com/rust-lang/rfcs/pull/172



On Fri, Jul 25, 2014 at 9:26 AM, Gregor Cramer rema...@gmx.net wrote:

  Hi Marijn,



  Firstly, blanket statements like This makes generic programming

  impossible and it does not allow proper software design are

  unneccesary hyperbole, and do not help the discussion in any way.



 You're not right, my statement wasn't blanket, it was my result

 after I tried to overwork the big integer library, and I have mentioned
 this:

 I gave up at all. (I'm doing software design and implementation since

 more than 30 years, and I never accept compromises, this is the way

 how to develop magnificient software).



  Traits provide a more well-defined, easier to reason about alternative

  to overloading. They do require the author of an algorithm to decide

  ahead of time whether this algorithm needs to be specializeable, which

  I guess C++-style overloading does not.



 Yes, the traits are great, I'm impressed, as I said before, and in fact
 Rust

 is really great, despite a few facts, otherwise I wouldn't subscribe to

 this mailing list. And my goal is to be constructive, don't worry if I'm

 a bit euphoric, such things happens. Nethertheless, it gave up to overwork

 the big integer libary because I cannot specialize std::num::pow(). There
 is

 no way to proceed with a proper design.



  Whether that is a good or a

  bad thing is debatable, but it is not true that Rust lacks a feature

  for specialization.



 There is a lack in the current language concept, std::num::pow()

 is inadequate due to this language concept, and std::num::pow() is

 only one example for this fact.



 I will repeat the problem with signatures. Currently pow() is declared

 as following:



 pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T;



 That't 100% ok. The user will call this function in this way:



 pow(a) // a is i32



 Perfect. Now I need a specialized function for BigInt:



 [#overload]

 pub fn pow(base: BigInt, mut exp: uint) - T;



 There's a problem (beside the missing overloading feature): the

 specialized version requires a reference. Same problem if I'm

 calling this function:



 pow(a) // a is BigInt



 The user has to know how to call a function, depending on the type.

 But a proper function specialization would be:



 [#overload]

 pub fn pow(base: BigInt, mut exp: uint) - T;



 And so the function call is as expected, like with other numeric types:



 pow(a) // a is BigInt



 But there is now a problem in this function definition, BigInt is given as

 a copy, and this is a software design issue (superfluous memory
 allocation).

 And this currently happens if the user is calling std::num::pow() with a

 numeric type like BigInt (apart from other performance penalties in pow()).



 That's what I've mentioned that the compiler should decide whether an

 argument is given by reference or by value. In this way the latter approach

 works. And in the case that a function willl modify an argument (in-out

 value), for example:



 fn mul_vec(acc : mut [BigDigit], base: mut [BigDigit], mut exp:uint)



 the call of this function would be:



 mul_vec(a, b, exp)



 This concept will not change, because here it has to be clear that an
 argument

 will be changed (furthermore the compiler should give a warning if a
 function

 is not changing a mutable argument). I think that this approach is even

 superior to the 'const' concept of C++, and it fit's with the great overall

 concept of Rust (especially with the owner/borrower concept).



 I try to show the problems if function specialization (overloading) is not

 supported. A stable software design is problematic. Adding a new module,

 which will use existing function declarations, is impossible in some cases.

 Currently I cannot implement a specialized version of pow() for BigInt,
 adding

 a new function for a different numeric type is only a hack, and moving this

 function into a trait is not solving the general problem, because pow() is

 only one example. (Beside: it's not my decision to move pow() into a
 trait.)



 Cheers,

 Gregor


 ___
 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] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Christoph Husse
Sorry... I meant a^8 xD...

And overlaoding is not a great concept in general, IMO.
What Rust could do is copy template specialization. So that I can say:

pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T; //
uses the exponential trick

pub fn powi64(mut base: i64, mut exp: uint) - i64; // uses some
cool processor features if available

pub fn powBigInt(mut base: BigInt, mut exp: uint) - BigInt; //
uses some mighty algorithm that is not naive ;)

This avoids the horrible confusing of having functions acting totally
different depending on parameter count. Of course there should still
be the requirement in place that all specializations fulfill the
original template contraints. And in the best case also need to
fullfill some generic unitests that give a specification to ensure
that the user is not confused by this sort of overloading.


On Fri, Jul 25, 2014 at 6:47 PM, Christoph Husse
thesaint1...@googlemail.com wrote:
 I gave up at all. (I'm doing software design and implementation since
 more than 30 years, and I never accept compromises, this is the way
 how to develop magnificient software).

 Hum, I would almost strongly disagree. I would even go as far as
 saying that you won't develop any kind of reasonable software outside
 of academic environments without making a whole fairytale of
 compromises. In fact, everything is a compromise. Besides that, giving
 up just because you can't overload functions, in a language that is
 still evolving also sounds rather strange. More legit would be to
 mention the issue, ask how the designers of the language would solve
 it and maybe suggest what could be improved etc...

 the big integer libary because I cannot specialize std::num::pow(). There is
 no way to proceed with a proper design.

 Well, I guess you did nothing but C++ in the last 30 years then?
 Because I can't recall many languages that would allow this sort of
 thing. How would C# and Java's Math::Pow() would work out in this
 case? How would it work out in C? How would it work out in Python,
 JavaScript, etc... the list is ... quite long.

 The question is always about compromise. Shall rust include a language
 feature to make some things easier for the sake of introducing tons of
 problems as well?
 Java is about the least expressive language we have at the time
 (appears a bit like the greatest common denominator of all imperative
 languages) and I would say only few people are out there who would say
 that you can't do proper software design with it. It might not be a
 concise and pleasing as GOOD C++ design is, but then again GOOD C++
 design is very hard to archieve and thus begs the questions if it is
 even worth it to make a language that complicated so that magnificient
 (academic) design is possible at the cost of making the average
 (industrial) design horrible.

 pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T;

 I agree this definition appears to be very strange to me. In more than
 one way. First it implies that the existing implementation works by
 somehow multiplying types with the expontential trick  a * a = b, b *
 b = c, c * c = a^6 etc...
 This is an unacceptable restriction for me, as this kind of evaluation
 might not be the best in many cases and we are talking about a
 standard library function after all. It should always allow the BEST
 implementation, not just some implementation.

 Here we clearly need a better concept. And this concept needs to be
 designed  defined. And you could start by doing this, instead of just
 giving up ;).
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Patrick Walton

On 7/25/14 6:26 AM, Gregor Cramer wrote:

And so the function call is as expected, like with other numeric types:

pow(a) // a is BigInt

But there is now a problem in this function definition, BigInt is given as
a copy, and this is a software design issue (superfluous memory allocation).
And this currently happens if the user is calling std::num::pow() with a
numeric type like BigInt (apart from other performance penalties in pow()).


That solution doesn't work for generic code, because Rust doesn't do 
ad-hoc templates like C++. A function that is generic over the bigint 
and int pow functions has to have one signature for pow. Otherwise 
you could get errors during template instantiation time, which is 
something Rust strictly avoids.



That's what I've mentioned that the compiler should decide whether an
argument is given by reference or by value.


That doesn't work. It would have numerous problems with the borrow 
check, etc.



I try to show the problems if function specialization (overloading) is not
supported.


Sorry, but it's not convincing to me.

Patrick

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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Patrick Walton

On 7/25/14 4:43 AM, SiegeLordEx wrote:

Yes, I concur on most of these points and I've brought up some related
points before. The operator overloading technique used by Rust is
antithetical to efficient generic code. The core numeric traits and
functions are currently designed only with built-in types in mind,
causing BigInt (and others, e.g. matrices) to suffer. I don't know how
to fix these things, but perhaps auto-ref and ad-hoc operator
overloading (it works for Haskell, why not for Rust?) would be part of
the solution.


Neither auto-ref or ad-hoc operator overloading would let you write a 
generic function that calls `pow` and works optimally with both bigints 
and ints. I think the only thing that would work is something like C++ 
ad-hoc templates, which is a road I don't want to go down.



Ultimately, I suspect that function overloading (the Rust
trait double-dispatch trick above may be sufficient with auto-ref) will
be of critical importance. This problem is very under-appreciated and I
hope this aspect of the language is not stabilized by 1.0.


I don't think we should be trying to solve it.

Patrick

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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Josh Haberman
On Fri, Jul 25, 2014 at 10:04 AM, Patrick Walton pcwal...@mozilla.com wrote:
 Neither auto-ref or ad-hoc operator overloading
 would let you write a generic function that calls
 `pow` and works optimally with both bigints and
 ints. I think the only thing that would work is
 something like C++ ad-hoc templates, which is
 a road I don't want to go down.

Could you explain what you mean by ad-hoc templates, and how this
differs from Rust's templates?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Oscar Boykin
Did I miss a point in this thread where using a typeclass/trait to
implement exponentiation was dismissed?

This function could be changed to:

fn powT: HasPow(base: T, exp: uint) - T { base.pow(exp) }

trait HasPow {
  fn pow(self: Self, exp: uint) - Self
}

Or, just use HasPow in your code.

Why is this not a solution?


On Fri, Jul 25, 2014 at 6:53 AM, Christoph Husse 
thesaint1...@googlemail.com wrote:

 Sorry... I meant a^8 xD...

 And overlaoding is not a great concept in general, IMO.
 What Rust could do is copy template specialization. So that I can say:

 pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T; //
 uses the exponential trick

 pub fn powi64(mut base: i64, mut exp: uint) - i64; // uses some
 cool processor features if available

 pub fn powBigInt(mut base: BigInt, mut exp: uint) - BigInt; //
 uses some mighty algorithm that is not naive ;)

 This avoids the horrible confusing of having functions acting totally
 different depending on parameter count. Of course there should still
 be the requirement in place that all specializations fulfill the
 original template contraints. And in the best case also need to
 fullfill some generic unitests that give a specification to ensure
 that the user is not confused by this sort of overloading.


 On Fri, Jul 25, 2014 at 6:47 PM, Christoph Husse
 thesaint1...@googlemail.com wrote:
  I gave up at all. (I'm doing software design and implementation since
  more than 30 years, and I never accept compromises, this is the way
  how to develop magnificient software).
 
  Hum, I would almost strongly disagree. I would even go as far as
  saying that you won't develop any kind of reasonable software outside
  of academic environments without making a whole fairytale of
  compromises. In fact, everything is a compromise. Besides that, giving
  up just because you can't overload functions, in a language that is
  still evolving also sounds rather strange. More legit would be to
  mention the issue, ask how the designers of the language would solve
  it and maybe suggest what could be improved etc...
 
  the big integer libary because I cannot specialize std::num::pow().
 There is
  no way to proceed with a proper design.
 
  Well, I guess you did nothing but C++ in the last 30 years then?
  Because I can't recall many languages that would allow this sort of
  thing. How would C# and Java's Math::Pow() would work out in this
  case? How would it work out in C? How would it work out in Python,
  JavaScript, etc... the list is ... quite long.
 
  The question is always about compromise. Shall rust include a language
  feature to make some things easier for the sake of introducing tons of
  problems as well?
  Java is about the least expressive language we have at the time
  (appears a bit like the greatest common denominator of all imperative
  languages) and I would say only few people are out there who would say
  that you can't do proper software design with it. It might not be a
  concise and pleasing as GOOD C++ design is, but then again GOOD C++
  design is very hard to archieve and thus begs the questions if it is
  even worth it to make a language that complicated so that magnificient
  (academic) design is possible at the cost of making the average
  (industrial) design horrible.
 
  pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T;
 
  I agree this definition appears to be very strange to me. In more than
  one way. First it implies that the existing implementation works by
  somehow multiplying types with the expontential trick  a * a = b, b *
  b = c, c * c = a^6 etc...
  This is an unacceptable restriction for me, as this kind of evaluation
  might not be the best in many cases and we are talking about a
  standard library function after all. It should always allow the BEST
  implementation, not just some implementation.
 
  Here we clearly need a better concept. And this concept needs to be
  designed  defined. And you could start by doing this, instead of just
  giving up ;).
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Oscar Boykin :: @posco :: http://twitter.com/posco
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Patrick Walton

On 7/25/14 10:11 AM, Oscar Boykin wrote:

Did I miss a point in this thread where using a typeclass/trait to
implement exponentiation was dismissed?

This function could be changed to:

fn powT: HasPow(base: T, exp: uint) - T { base.pow(exp) }

trait HasPow {
   fn pow(self: Self, exp: uint) - Self
}

Or, just use HasPow in your code.

Why is this not a solution?


Yes, I was about to bring this up. You might want to conceivably have 
different types for the parameters, which Associated Types would solve 
nicely. For the maximum genericity:


trait Pow {
type This;
type Exp;
type Result;
fn pow(this: This, exp: Exp) - Result;
}

You can then write functions that take Powable things:

fn whateverP:Pow(p: P) - P {
p.pow(p, 1)
}

Now the only restriction that is left is that all instances of `Pow` 
must have the same number of arguments. Presumably this is not too 
onerous. :)


Patrick

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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Patrick Walton

On 7/25/14 10:10 AM, Josh Haberman wrote:

On Fri, Jul 25, 2014 at 10:04 AM, Patrick Walton pcwal...@mozilla.com wrote:

Neither auto-ref or ad-hoc operator overloading
would let you write a generic function that calls
`pow` and works optimally with both bigints and
ints. I think the only thing that would work is
something like C++ ad-hoc templates, which is
a road I don't want to go down.


Could you explain what you mean by ad-hoc templates, and how this
differs from Rust's templates?


In Rust you can never have type errors during template expansion. If a 
call to a generic/template typechecks properly, then the template is 
guaranteed to expand to valid Rust code with no type errors within it. 
This is done via the trait system, which is similar in spirit to the 
concept systems proposed for C++17 (the difference being that Rust 
*only* has concepts).


The primary benefit of this setup is that the infamous template error 
messages in C++ are eliminated. There are a bunch of other secondary 
benefits as well: there is no need for the ADL hack, you can do things 
like overload on the return type, etc.


Patrick

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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Gregor Cramer
 Did I miss a point in this thread where using a typeclass/trait to
 implement exponentiation was dismissed?

 This function could be changed to:

   fn powT: HasPow(base: T, exp: uint) - T { base.pow(exp) }

 trait HasPow {
   fn pow(self: Self, exp: uint) - Self
 }

 Or, just use HasPow in your code.

Yes, you missed a point, I've already pointed out in my initial mail that
moving pow() into a trait (that's what your code is finally doing) is solving
this special problem, but it is not solving a general problem with (other)
functions. A new module may cause that an older function (which you
cannot overload) is inadequate. This makes software instable. In the past
(with some older programming languages) you did not have solutions for
this, but Rust is 2014, programming and compiler techniques have evolved.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Gregor Cramer
  I gave up at all. (I'm doing software design and implementation since
  more than 30 years, and I never accept compromises, this is the way
  how to develop magnificient software).
 
 Hum, I would almost strongly disagree  I would even go as far as
 saying that you won't develop any kind ...

How can you disagree about what I'm doing?

 Well, I guess you did nothing but C++ in the last 30 years then?
 Because I can't recall many languages that would allow this sort of
 thing. How would C# and Java's Math::Pow() would work out in this
 case? How would it work out in C? How would it work out in Python,
 JavaScript, etc... the list is ... quite long.

I don't care about the capabilities of other languages, I don't use a
language if it is not appropriate.

 The question is always about compromise. Shall rust include a language
 feature to make some things easier for the sake of introducing tons of
 problems as well?

No. Everyone is talking about tons of problems, but which ones?
The most problematic language, with tons of problems, is C++.
But even in C++ not overloading is the problem - and I have about
20 years experience with C++ - it is for example, to name just one,
the implicit casting, because this makes overloading a bit problematic.

 Java is about the least expressive language we have at the time
 (appears a bit like the greatest common denominator of all imperative
 languages) and I would say only few people are out there who would say
 that you can't do proper software design with it.

This depends on how your are doing software design. Impossible
for me to use Java.

 It might not be a
 concise and pleasing as GOOD C++ design is, but then again GOOD C++
 design is very hard to archieve and thus begs the questions if it is
 even worth it to make a language that complicated so that magnificient
 (academic) design is possible at the cost of making the average
 (industrial) design horrible.

I cannot see that overloading is horrible or complicated. It's another
point that C++ is horrible and complicated. We have 2014, as I started
with C++ it was the superior language, but software design has evolved,
nowadays object oriented design is obscure, and that's in fact
my own experience. But C++ already supported one ingenious feature:
generic programming (but very low level).

  pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T;
 
 I agree this definition appears to be very strange to me. In more than
 one way. First it implies that the existing implementation works by
 somehow multiplying types with the expontential trick  a * a = b, b *
 b = c, c * c = a^6 etc...
 This is an unacceptable restriction for me, as this kind of evaluation
 might not be the best in many cases and we are talking about a
 standard library function after all. It should always allow the BEST
 implementation, not just some implementation.

 Here we clearly need a better concept. And this concept needs to be
 designed  defined. And you could start by doing this, instead of just
 giving up ;).

This means that I have to design at a lower level, before I start to implement
the big number library. Probably I'll try it, I don't know yet. I don't know
yet whether I will really use Rust. (BTW: I gave up at all does not mean
forever, please be aware that I'm not a native English speaker.)
In fact I'm looking for an alternative to C++, and Rust is still the most
promising one, but Rust is not yet elaborated (I know that Rust is still
pre-alpha).

 And overlaoding is not a great concept in general, IMO.
 What Rust could do is copy template specialization. So that I can say:

 pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T; //
 uses the exponential trick

 pub fn powi64(mut base: i64, mut exp: uint) - i64; // uses some
 cool processor features if available

 pub fn powBigInt(mut base: BigInt, mut exp: uint) - BigInt; //
 uses some mighty algorithm that is not naive 

Yes, that would possibly be one solution for overloading, Unfortunately
the problem with the signature remains. It's absolutely clear for me
that an overloading feature should not cause problems, this means
that a design is required which suits perfectly with the principle design
of Rust.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread comex
On Fri, Jul 25, 2014 at 3:36 PM, Gregor Cramer rema...@gmx.net wrote:
 I don't care about the capabilities of other languages, I don't use a
 language if it is not appropriate.

Appropriate for what?  You seem to be claiming that stable code in
general needs this feature, so that's consigning all of the languages
listed to be inappropriate for virtually anything.  But they're not,
so their design decisions should be considered, although of course
they're not necessarily right.

 No. Everyone is talking about tons of problems, but which ones?
 The most problematic language, with tons of problems, is C++.
 But even in C++ not overloading is the problem - and I have about
 20 years experience with C++ - it is for example, to name just one,
 the implicit casting, because this makes overloading a bit problematic.

A few months ago I posted in a similar thread why I don't like overloading:

https://mail.mozilla.org/pipermail/rust-dev/2014-May/009982.html

Buy it or not, I don't think overloading is necessary, since most of
the time operations with room for such efficiency improvements should
be implemented either in traits or as ad-hoc methods.  That is, I'd
call this a bug in std::num::pow.

And of course it's possible to change something to a trait after the
fact without breaking API compatibility.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Christoph Husse
 How can you disagree about what I'm doing?

I don't. I disagree with that:  I never accept compromises, this is
the way how to develop magnificient software
Because it's not. Unless you use magnificient only in academic context.

 I don't care about the capabilities of other languages, I don't use a 
 language if it is not appropriate.

C++ is not appropiate for almost any task there is. I am using C++
quite a lot, because at my work, C++ is the right tool for the job.
But there aren't many jobs for which this is true.

 No. Everyone is talking about tons of problems, but which ones?

I am sure some language designers can give you more insight. I lack
the convincing arguments.

 But even in C++ not overloading is the problem - and I have about

It's not so much about wether or not overloading could be used in rust
without causing really painful issues. The question is if overlaoding
fits into the language's design principles. Overloading is not
necessary. It's just one of many ways that lead to Rome.

 This depends on how your are doing software design. Impossible for me to use 
 Java.

Some of the greatest minds in the industry use Java for excellent
software design.
People read code, most of the time. People need to work with code
other people wrote most of the time. Agile projects need good tooling,
speaking of refactoring, code coverage, code formatting, coding
standards, build tools, packaging, dependency managment in particular.
C++ gives you almost nothing in any of those. C++ is a huge pain in
the ass in most regards. Unless you really need it to get the job
done, it's the worst choice there is.
A language is about more than just what you consider beautiful,
etc It's about wether it allows agile, fast paced development
across diverse teams and average programmers can produce code anyone
else can read without getting eye cancer. That does not apply to C++
at all.

 I cannot see that overloading is horrible or complicated. It's another

No, but it might be unnecessary.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Gregor Cramer
 And of course it's possible to change something to a trait after the
 fact without breaking API compatibility.

How you are doing this? I'm in fact a newbie in Rust, and it's interesting
that this can be done. std::num::pow() is a good example, I think.
Suppose I already have a program which is using std::num::pow() with a
self defined integer type. Now you are changing std::num::pow(), moving
the functionality into a trait. And my program will still compile and work
as before?___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Sean McArthur
On Fri, Jul 25, 2014 at 1:45 PM, Gregor Cramer rema...@gmx.net wrote:

  How you are doing this? I'm in fact a newbie in Rust, and it's
 interesting

 that this can be done. std::num::pow() is a good example, I think.

 Suppose I already have a program which is using std::num::pow() with a

 self defined integer type. Now you are changing std::num::pow(), moving

 the functionality into a trait. And my program will still compile and work

 as before?


I'd expect that std::num::pow() would gain a #[deprecated = Use Pow
trait] attribute, and be removed after Rust's deprecation period (which
pre-1.0 is pretty much a few commits later).
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Gregor Cramer
 I disagree with that:  I never accept compromises, this is
 the way how to develop magnificient software
 Because it's not. Unless you use magnificient only in academic context.

? I'm not doing academic things.

 It's not so much about wether or not overloading could be used in rust
 without causing really painful issues. The question is if overlaoding
 fits into the language's design principles.

I agree, if overloading does not fit at all, then it should not be done.

 Overloading is not necessary. It's just one of many ways that lead to Rome.

Yes, many ways are leading to Rome. One of the ways is easy to go,
and is a joy. Another way is tedious or cumbersome.

 A language is about more than just what you consider beautiful,
 etc It's about wether it allows agile, fast paced development
 across diverse teams and average programmers can produce code anyone
 else can read without getting eye cancer.

Fast-paced development without generic programming? And overloading
is supporting generic programming.

  I cannot see that overloading is horrible or complicated. It's another
 
 No, but it might be unnecessary.

Possibly I'm wrong that overloading is neccessary in Rust, that's why
I'm talking, I'm not a master in Rust programming. But fact is: as I
stumbled over std::num::pow() I could see problems if not
having overloading. And I repeat: std::num::pow() is only an
example for a general problem.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Josh Haberman
On Fri, Jul 25, 2014 at 10:34 AM, Patrick Walton pcwal...@mozilla.com
wrote:

 On 7/25/14 10:10 AM, Josh Haberman wrote:

 On Fri, Jul 25, 2014 at 10:04 AM, Patrick Walton pcwal...@mozilla.com
 wrote:

 Neither auto-ref or ad-hoc operator overloading
 would let you write a generic function that calls
 `pow` and works optimally with both bigints and
 ints. I think the only thing that would work is
 something like C++ ad-hoc templates, which is
 a road I don't want to go down.


 Could you explain what you mean by ad-hoc templates, and how this
 differs from Rust's templates?


 In Rust you can never have type errors during template expansion. If a
 call to a generic/template typechecks properly, then the template is
 guaranteed to expand to valid Rust code with no type errors within it. This
 is done via the trait system, which is similar in spirit to the concept
 systems proposed for C++17 (the difference being that Rust *only* has
 concepts).


Got it. So the ad hoc part refers to having a template parameter, but not
being able to check its capabilities/interface at template
parsing/typechecking time, it sounds like?

How does the trait/concept approach preclude template specialization? Each
template specialization could be independently type-checked, but the most
specialized one could be selected at instantiation time. Or is this
considered overloading and discarded because of the extra complexity? I
guess it could be complicated to define which was most specialized.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Patrick Walton

On 7/25/14 3:20 PM, Josh Haberman wrote:

Got it. So the ad hoc part refers to having a template parameter, but
not being able to check its capabilities/interface at template
parsing/typechecking time, it sounds like?


Right. (The term comes from Making Ad-Hoc Polymorphism Less Ad-Hoc, 
which is the seminal paper on typeclasses.)



How does the trait/concept approach preclude template specialization?
Each template specialization could be independently type-checked, but
the most specialized one could be selected at instantiation time. Or is
this considered overloading and discarded because of the extra
complexity? I guess it could be complicated to define which was most
specialized.


Yeah, that's the complexity. Some GHC language extensions do allow 
something like template specialization, but it's considered very 
experimental. I'd like to see if things like associated types get us 
most of the way there without the difficulties of specialization.


Patrick

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


Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?

2014-07-25 Thread Patrick Walton

On 7/25/14 8:26 PM, Patrick Walton wrote:

Uniform value representations work well too (as
OCaml shows), but of course you'll pay a performance cost for that.


Oh, note that Greg's notes are a little bit out of date when discussing 
the performance tradeoffs of uniform value representation. On 64 bit 
(and even on 32 bit) you can do NaN-boxed fatvals [1] (scroll down to 
Mozilla's New JavaScript Value Representation) which avoid having to 
box every floating point value.


Patrick

[1] http://evilpie.github.io/sayrer-fatval-backup/cache.aspx.htm

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


Re: [rust-dev] Announcing the Rust Community Calendar

2014-07-24 Thread Erick Tryzelaar
Added it to the calendar, and gave you write access so you can add future
events yourself :)


On Wed, Jul 23, 2014 at 10:44 PM, Paul Nathan pnathan.softw...@gmail.com
wrote:

 Seattle has a Rust meetup Monthly.  Second Monday of the month, 7pm.

 There's a event signup on Eventbrite.

 In August there will be pizza. :)
 On Jul 23, 2014 2:22 PM, Erick Tryzelaar erick.tryzel...@gmail.com
 wrote:

 Good afternoon Rustaceans!

 I just created a community calender for all the Rust events happening
 throughout the Rust community around the world. You can find it at:


 https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.comctz=America/Los_Angeles

 It's pretty bare bones at the moment, so if you have something you would
 like added to the list, please let me know and I'll get it on the calendar.
 I'll also see if we can get this embedded on http://www.rust-lang.org/.

 Thanks,
 Erick

 ___
 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] London Rust meetup: 2014-08-14

2014-07-24 Thread Simon Sapin

Hello Rustaceans,

The next London meetup is on August 14. Come and say hi! Nick Cameron 
a.k.a nrc will be giving a talk on DST.


http://www.meetup.com/Rust-London-User-Group/events/196222722/

We’re also looking for speakers for this or future events. Let me know 
if you’re interested!


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


Re: [rust-dev] London Rust meetup: 2014-08-14

2014-07-24 Thread Ilya Dmitrichenko
Hi Simon,

I and @farcaller where thinking to prepare a talk on Zinc project
(http://zinc.rs/).

What length of the talks you guys do?

Cheers,
-- 
Ilya


On 24 July 2014 09:00, Simon Sapin simon.sa...@exyr.org wrote:
 Hello Rustaceans,

 The next London meetup is on August 14. Come and say hi! Nick Cameron a.k.a
 nrc will be giving a talk on DST.

 http://www.meetup.com/Rust-London-User-Group/events/196222722/

 We're also looking for speakers for this or future events. Let me know if
 you're interested!

 Cheers,
 --
 Simon Sapin
 ___
 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] London Rust meetup: 2014-08-14

2014-07-24 Thread Simon Sapin

On 24/07/14 10:18, Ilya Dmitrichenko wrote:

Hi Simon,

I and @farcaller where thinking to prepare a talk on Zinc project
(http://zinc.rs/).


That looks cool. Do you want to present on August 14?



What length of the talks you guys do?


The length is flexible, this is only the second time we’re doing in this 
in London so we’re still figuring it all out. Just remember that the 
event is in the evening and that there may be another talk in the same 
event. To give a number that I totally just made up, anything up to 30 
minutes sounds good.


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


Re: [rust-dev] Opt-In Built-In Traits (was: Mutable files)

2014-07-24 Thread Kevin Ballard
On Wed, Jul 23, 2014, at 12:52 PM, David Henningsson wrote:
 
 
 On 2014-07-21 19:17, Patrick Walton wrote:
  On 7/21/14 8:49 AM, Tobias Müller wrote:
  Patrick Walton pcwal...@mozilla.com wrote:
  On 7/20/14 8:12 PM, David Henningsson wrote:
From a language design perspective, maybe it would be more
  intuitive to
  have different syntaxes for copy and move, like:
 
  As a rust newbie, that aspect aways makes me a bit nervous. Two quite
  different operations with the same syntax and and simply changing a
  detail in the struct can be enough to switch between the two.
 
  This is the reason for Opt-In Built-In Traits.
 
  * Causing a move when you thought you were copying results in a compiler
  error.
 
  * Causing a copy when you thought you were moving is harmless, as any
  implicit copy in Rust has *exactly the same runtime semantics* as a
  move, except that the compiler prevents you from using the value again.
 
  Again, we had that world before. It was extremely annoying to write
  move all over the place. Be careful what you wish for.
 
 I find these arguments compelling, but if what we want to accomplish is 
 a conscious choice between copy and move every time somebody makes a new 
 struct, maybe #[Deriving(Data)] struct Foo vs struct Foo is not 
 first-class enough.
 
 Maybe the move vs copy should be done by using different keywords, a few 
 brainstorming examples:
 
   * datastruct for copy, struct for move
   * simplestruct for copy, complexstruct for move
   * struct for copy, class or object for move

What would this solve? Nobody who’s using a type is going to care about
the keyword used to introduce the type, they’re only going to care about
the behavior of the type. Using `datastruct` instead of `struct` will
have zero impact on the people writing

let x: Foo = y;

Actually, the whole notion of having to intentionally describe on every
struct whether you want it to be Copy is my biggest objection to opt-in
traits. The API Stability / documentation aspect is great, but it does
seem like a burden to people writing once-off structs.

What I’d actually like to see is for private structs to infer things
like Copy and for public structs to then require it to be explicitly
stated. I don’t know how to do this in a way that’s not confusing
though.

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


Re: [rust-dev] London Rust meetup: 2014-08-14

2014-07-24 Thread T.Ikonomou
Hey all,

Sounds good ! If you wish to present at the event on August 14, then could
you please let us know a title of the presentation and a brief description
of what it will involve so as to let attenders know.

Thank you,
Theo


On Thu, Jul 24, 2014 at 3:05 PM, Simon Sapin simon.sa...@exyr.org wrote:

 On 24/07/14 10:18, Ilya Dmitrichenko wrote:

 Hi Simon,

 I and @farcaller where thinking to prepare a talk on Zinc project
 (http://zinc.rs/).


 That looks cool. Do you want to present on August 14?


  What length of the talks you guys do?


 The length is flexible, this is only the second time we’re doing in this
 in London so we’re still figuring it all out. Just remember that the event
 is in the evening and that there may be another talk in the same event. To
 give a number that I totally just made up, anything up to 30 minutes sounds
 good.

 --
 Simon Sapin

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


Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?

2014-07-24 Thread Lionel Parreaux
Hi,

Could you provide a link to Patrick's description of size/alignment-passing
implementation? I'm interested in these things.

Well, there could be a warning if the compiler switches to such an
implementation. It's arguably still better than not compiling at all.
However, I don't have enough experience with type classes to know whether
such situations actually happen in the real world. But didn't Nawfel BGH
give an example of that?

I'm not an expert in embedded systems, but I know that in some embedded
systems, especially when memory is scarce or when the instruction cache is
small, code size does matter more than the number of instructions executed
per function call. It would probably be useful to be able to use generic
libraries but still tweak the amount of monomoprhization in order to
control the size of the generated executable.
I don't know if this is the case for Rust, but executable size is an
endemic problem in C++ because of wild template instantiation.

I can't pronounce myself about the suitability of features in the Rust
language, but it may be worth noting that some convenient high-level
features are already present in the language, like garbage collection.
Also, even C compilers output code with dramatically varying efficiency
depending on the chosen levels of optimization -- and sometimes small
details can disable optimization opportunities.

Cheers,
LP.



2014-07-23 4:13 GMT+02:00 Cameron Zwarich zwar...@mozilla.com:

 Even if we could do a size/alignment-passing implementation like Patrick
 describes, would be it even be appropriate? It wouldn’t make sense for a
 systems language to transparently switch to a dramatically less efficient
 implementation mechanism without the programmer’s involvement.

 Is there any place where an unbounded number of dictionaries at runtime is
 actually appropriate for solving a real problem in Rust?

 Cameron

 On Jul 22, 2014, at 10:16 AM, Lionel Parreaux lionel.parre...@gmail.com
 wrote:

 Hi,

 So traits seem to be quite similar to Haskell's classes, being also used
 for parametric polymorphism. Now, Haskell classes are usually implemented
 using runtime dictionary passing. In general, code cannot be specialized
 for every function call, since there may be an unbounded number of
 instances generated for it, as is explained in this reddit answer:
 http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju

 Knowing that Rust implements traits using monomorphization of code (much
 like C++ templates), I was curious about how it handled such cases, and
 tried this:

 struct WT {
 f: T
 }

 trait Show {
 fn show(self) - int;
 }

 impl Show for int {
 fn show(self) - int { 666 }
 }
 implT:Show Show for WT {
 fn show(self) - int { self.f.show()+1 }
 }
 implT:Clone Clone for WT {
 fn clone(self) - WT { W{f:self.f.clone()} }
 }

 fn fooS:Show+Clone(s: S, n: int) {
 let w = W{f:s.clone()};
 if n  0 { foo(w, n-1); }
 }

 fn main() {
   foo(W{f:42i},42);
 }


 It gave me an error: reached the recursion limit during
 monomorphization, which... well, that's a possible solution :)

 I'm not sure whether this is a big problem in practice, but I was
 wondering if it would be possible to switch to some runtime mechanism in
 cases like this. Maybe we could make a special version of every generic
 functions, that takes a dictionary at runtime and that would be able to
 handle types unknown at compile-time. We would switch to this version when
 monomorphization does not work. It could also allow dynamic linking of
 libraries with generic functions, or it could be a way to compile some
 programs (or some parts of programs) much faster.
 I was thinking about, for example, an IDE where generic function calls to
 types defined inside the files currently being edited use their dynamic
 version, so that recompile times can be virtually inexistent (like Java).
 On the other hand, the release build would of course monomorphize as much
 as possible to make the perf optimal.

 Now the question is: would this conform to the current semantic of
 monomorphization? Do special things happen during monomorphization that
 cannot be reproduced at runtime?
 This is the case in C++ (and one of the reasons why C++ templates are so
 bad). Is it the case in Rust, which should already have all the required
 info (type bounds) before monomorphization?

 I apologize if this has already been discussed. I could not find many
 satisfying answers by googling.

 Cheers,
 LP.


 ___
 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] Implementation of traits in Rust: could it be dynamic?

2014-07-24 Thread Daniel Micay
On 24/07/14 11:59 AM, Lionel Parreaux wrote:

 I can't pronounce myself about the suitability of features in the Rust
 language, but it may be worth noting that some convenient high-level
 features are already present in the language, like garbage collection.

There isn't an implementation of garbage collection.



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


Re: [rust-dev] London Rust meetup: 2014-08-14

2014-07-24 Thread Brian Anderson

I'm really looking forward to this!

On 07/24/2014 02:18 AM, Ilya Dmitrichenko wrote:

Hi Simon,

I and @farcaller where thinking to prepare a talk on Zinc project
(http://zinc.rs/).

What length of the talks you guys do?

Cheers,


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


[rust-dev] std::num::pow() is inadequate / language concepts

2014-07-24 Thread Gregor Cramer
Hello Rust folk!

I am new to Rust, and I have doubts concerning current language concepts.

One example: in module ::std::num function pow() is defined:

pub fn powT: One + MulT, T(mut base: T, mut exp: uint) - T {
if exp == 1 { base }
else {
let mut acc = one::T();
while exp  0 {
if (exp  1) == 1 {
acc = acc * base;
}
base = base * base;
exp = exp  1;
}
acc
}
}

In general this implementation is ok, but not really usable with BigInt. Of
course, the call ':.std::num::pow(a, 1000)', 'a' is a BigInt, works. But this
implementation is not adequate for big integers. Firstly, too many memory
allocations during the computation (a specialized version can avoid these
memory allocations), secondly, for big integers a specialized function for
squaring (base * base) has to be used, because squaring can be done quite
more efficient than multiplication (with big integers). So this function is much
too slow and has to be overloaded, but:

1. Overloading is not supported (even the archaic C++ is providing this).

2. The footprint 'base: T' is not 100% suitable, for big integers the function
definition
 fn pow(base: BigInt, mut exp: uint) - BigInt
would be more appropriate, because the argument 'base' needs not to be
modified (or reassigned), and a call by reference (avoiding a superfluous
memory allocation) is more efficient in this case.

Of cource, a specialized version of pow() could be implemented in trait
BigInt, but this is only a workaround. And if a user only knows
::std::num::pow(), he will use an inappropriate implementation without
being aware of this.

Probably in this case it might be a solution  to move pow() into a trait, but
I'm speaking about a general problem. Rust 1.0 will be released, and someone
is developing a new module for version 1.1. But some of the functions in 1.0
are inadequate for the new module, how to solve this without changing the API
in 1.1? I think that function overloading may  help in some cases, but the
problem with inappropriate footprints remains. In my opinion this
thing with the footprints (reference or not if the real type is unknown -
that's why the concept with 'const' in C++ exists) is a conceptual design
issue, but probably I do not yet fully understand Rust.

BTW: the functions next_power_of_two(), and checked_next_power_of_two()
are only defined for primitives (trait Primitive), but should also be 
applicable for big integers, I think .

C heers,
Gregor___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-24 Thread Huon Wilson

On 25/07/14 08:46, Gregor Cramer wrote:


Probably in this case it might be a solution to move pow() into a 
trait, but


I'm speaking about a general problem. Rust 1.0 will be released, and 
someone


is developing a new module for version 1.1. But some of the functions 
in 1.0


are inadequate for the new module, how to solve this without changing 
the API


in 1.1?



1.0 will not stabilise every function in every library; we have precise 
stability attributes[1] so that the compiler can warn or error if you 
are using functionality that is subject to change. The goal is to have 
the entirety of the standard library classified and marked appropriately 
for 1.0.



[1]: http://doc.rust-lang.org/master/rust.html#stability


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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-24 Thread Tommy M. McGuire
On 07/24/2014 05:55 PM, Huon Wilson wrote:
 1.0 will not stabilise every function in every library; we have precise
 stability attributes[1] so that the compiler can warn or error if you
 are using functionality that is subject to change. The goal is to have
 the entirety of the standard library classified and marked appropriately
 for 1.0.
 
 
 [1]: http://doc.rust-lang.org/master/rust.html#stability

How would that solve the general problem? What would the stability of
pow() be if Gregor had not brought up the issue now?


-- 
Tommy M. McGuire
mcgu...@crsr.net
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-24 Thread Patrick Walton
On 7/24/14 3:46 PM, Gregor Cramer wrote:
 Probably in this case it might be a solution to move pow() into a trait, but
 I'm speaking about a general problem. Rust 1.0 will be released, and someone
 is developing a new module for version 1.1. But some of the functions in 1.0
 are inadequate for the new module, how to solve this without changing 
 the API

If the signature is wrong and we mistakenly freeze it, we can just introduce a 
new function with a different name.

 in 1.1? I think that function overloading may help in some cases, but the
 problem with inappropriate footprints remains. In my opinion this
 thing with the footprints (reference or not if the real type is unknown -
 that's why the concept with 'const' in C++ exists) is a conceptual design
 issue, but probably I do not yet fully understand Rust.

Overloading only helps some simple cases, and adds more complexity than it's 
worth (IMO).

The problem with C++ isn't that it doesn't have enough features. Rust is 
deliberately omitting some features from C++ that don't pull their weight. 
Overloading is one of them.

Patrick

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


Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-24 Thread Huon Wilson

On 25/07/14 09:21, Tommy M. McGuire wrote:

On 07/24/2014 05:55 PM, Huon Wilson wrote:

1.0 will not stabilise every function in every library; we have precise
stability attributes[1] so that the compiler can warn or error if you
are using functionality that is subject to change. The goal is to have
the entirety of the standard library classified and marked appropriately
for 1.0.


[1]: http://doc.rust-lang.org/master/rust.html#stability

How would that solve the general problem? What would the stability of
pow() be if Gregor had not brought up the issue now?




I was just pointing out that we aren't required to solve any/every 
library issue before 1.0 (since the text I was quoting was rightfully 
concerned about backwards incompatible API changes), not that this isn't 
an issue.




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


[rust-dev] Artisan Assitant Launch: Please Confirm Subscription

2014-07-24 Thread Steve
** Please Confirm Subscription

Yes, subscribe me to this list. 
(http://steveklabnik.us2.list-manage.com/subscribe/confirm?u=31556dd6d5e1f7d449288b7d9id=3bc3472c3ee=4b68f345fe)
If you received this email by mistake, simply delete it. You won't be 
subscribed if you don't click the confirmation link above.

For questions about this list, please contact:
st...@steveklabnik.com (mailto:st...@steveklabnik.com)


attachment: Artisan_Assitant_Launch.vcf___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Artisan Assitant Launch: Subscription Confirmed

2014-07-24 Thread Steve
Your subscription to our list has been confirmed.

For your records, here is a copy of the information you submitted to us...
 
* Email Address: rust-dev@mozilla.org   
* First Name:
* Last Name:

If at any time you wish to stop receiving our emails, you can:
unsubscribe here 
(http://steveklabnik.us2.list-manage1.com/unsubscribe?u=31556dd6d5e1f7d449288b7d9id=3bc3472c3ee=4b68f345fe)
You may also contact us at:
st...@steveklabnik.com (mailto:st...@steveklabnik.com)


attachment: Artisan_Assitant_Launch.vcf___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Artisan Assitant Launch: Subscription Confirmed

2014-07-24 Thread Steve Klabnik
Sorry, all. I have a weekend project which has a mailchimp email signup on
the home page, and apparently someone went and signed up rust-dev.

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


[rust-dev] Debugging rust for a newbie

2014-07-23 Thread Urban Hafner
Hey there,

I'm still quite new to Rust. Until now I was able to fix all my bugs by
writing tests and/or randomly adding lifetime parameters to keep the
compiler happy. Now I've hit my first stack overflow. I assume it's due to
the fact that I've screwed up the lifetimes and the objects live too long
although I'm not even sure about that. Now my question is: How do I debug
this? Is there a way to figure out how long objects live? Or how would one
go about debugging this?

Oh, if you're interested in the failing code:
https://github.com/ujh/iomrascalai/pull/46

Cheers,

Urban
-- 
Freelancer

Available for hire for Ruby, Ruby on Rails, and JavaScript projects

More at http://urbanhafner.com
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Debugging rust for a newbie

2014-07-23 Thread Huon Wilson
It is unlikely to be a lifetimes thing; far, far more likely to be a 
normal infinite recursion. The size of the stack frame of each 
function is fixed at compile time, so the way to blow the stack is by 
calling a lot of functions deeply, e.g. it's not possible to write a 
loop that places more and more objects on the stack (not in safe code, 
anyway).


You can get a backtrace by running the test in a conventional debugger, 
e.g. `gdb --args ./tester produces_a_move`, then type `run`. When it 
hits the abort, gdb will freeze execution and you can run `backtrace` to 
see the function call stack, to see what is recursing deeply.


You can make rustc emit debug info which makes gdb far more useful, by 
compiling with `-g` or, equivalently, `--debuginfo=2`. (Depending on 
your platform, 'lldb' may be better.)



If all else fails, you can fall back to println debugging, e.g.

fn gen_move(self, ...) - Move {
println!(calling gen_move);

// ...
}

---

Just glancing over your code, it looks like there's mutual recursion 
between Playout::run and McEngine::gen_move:


- McEngine::gen_move calls Playout::run 
https://github.com/ujh/iomrascalai/blob/88e09fdd/src/engine/mc/mod.rs#L82
- Playout::run calls Playout::gen_move 
https://github.com/ujh/iomrascalai/blob/88e09fdd/src/playout/mod.rs#L42
- Playout::gen_move calls McEngine::gen_move 
https://github.com/ujh/iomrascalai/blob/88e09fdd/src/playout/mod.rs#L49



Huon


On 23/07/14 17:42, Urban Hafner wrote:

Hey there,

I'm still quite new to Rust. Until now I was able to fix all my bugs 
by writing tests and/or randomly adding lifetime parameters to keep 
the compiler happy. Now I've hit my first stack overflow. I assume 
it's due to the fact that I've screwed up the lifetimes and the 
objects live too long although I'm not even sure about that. Now my 
question is: How do I debug this? Is there a way to figure out how 
long objects live? Or how would one go about debugging this?


Oh, if you're interested in the failing code: 
https://github.com/ujh/iomrascalai/pull/46


Cheers,

Urban
--
Freelancer

Available for hire for Ruby, Ruby on Rails, and JavaScript projects

More at http://urbanhafner.com


___
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] Debugging rust for a newbie

2014-07-23 Thread Urban Hafner
Hey Huon,

thanks for the help. The problem is really obvious now that you mention it!
Thanks for the debugging tips however. Coming from Ruby all I ever use are
print statements. So it's good to know how to do it!

Urban


On Wed, Jul 23, 2014 at 10:02 AM, Huon Wilson dbau...@gmail.com wrote:

  It is unlikely to be a lifetimes thing; far, far more likely to be a
 normal infinite recursion. The size of the stack frame of each function
 is fixed at compile time, so the way to blow the stack is by calling a lot
 of functions deeply, e.g. it's not possible to write a loop that places
 more and more objects on the stack (not in safe code, anyway).

 You can get a backtrace by running the test in a conventional debugger,
 e.g. `gdb --args ./tester produces_a_move`, then type `run`. When it hits
 the abort, gdb will freeze execution and you can run `backtrace` to see the
 function call stack, to see what is recursing deeply.

 You can make rustc emit debug info which makes gdb far more useful, by
 compiling with `-g` or, equivalently, `--debuginfo=2`. (Depending on your
 platform, 'lldb' may be better.)


 If all else fails, you can fall back to println debugging, e.g.

 fn gen_move(self, ...) - Move {
 println!(calling gen_move);

 // ...
 }

 ---

 Just glancing over your code, it looks like there's mutual recursion
 between Playout::run and McEngine::gen_move:

 - McEngine::gen_move calls Playout::run
 https://github.com/ujh/iomrascalai/blob/88e09fdd/src/engine/mc/mod.rs#L82
 - Playout::run calls Playout::gen_move
 https://github.com/ujh/iomrascalai/blob/88e09fdd/src/playout/mod.rs#L42
 - Playout::gen_move calls McEngine::gen_move
 https://github.com/ujh/iomrascalai/blob/88e09fdd/src/playout/mod.rs#L49


 Huon



 On 23/07/14 17:42, Urban Hafner wrote:

 Hey there,

  I'm still quite new to Rust. Until now I was able to fix all my bugs by
 writing tests and/or randomly adding lifetime parameters to keep the
 compiler happy. Now I've hit my first stack overflow. I assume it's due to
 the fact that I've screwed up the lifetimes and the objects live too long
 although I'm not even sure about that. Now my question is: How do I debug
 this? Is there a way to figure out how long objects live? Or how would one
 go about debugging this?

  Oh, if you're interested in the failing code:
 https://github.com/ujh/iomrascalai/pull/46

  Cheers,

  Urban
 --
 Freelancer

 Available for hire for Ruby, Ruby on Rails, and JavaScript projects

 More at http://urbanhafner.com


 ___
 Rust-dev mailing 
 listRust-dev@mozilla.orghttps://mail.mozilla.org/listinfo/rust-dev



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




-- 
Freelancer

Available for hire for Ruby, Ruby on Rails, and JavaScript projects

More at http://urbanhafner.com
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A shiny test framework

2014-07-23 Thread Nat Pryce
Could you use RAII to call a lambda?


On 22 July 2014 20:31, Vladimir Pouzanov farcal...@gmail.com wrote:

 One note on why there's no after_each:

 You cannot really make sure that the epilogue is being called, so if you
 need to do anything after your test case, use RAII in before_each.


 On Tue, Jul 22, 2014 at 8:10 PM, Benjamin Gudehus hasteb...@gmail.com
 wrote:

 Nice to see an RSpec-like test framework and Hamcrest assertions/matchers
 for Rust!


 On Tue, Jul 22, 2014 at 9:09 PM, Ilya Dmitrichenko 
 errordevelo...@gmail.com wrote:

 Dude, that's pretty much rspec ;) sweet!
 On 22 Jul 2014 20:07, Vladimir Pouzanov farcal...@gmail.com wrote:

 I've just published a tiny test framework: shiny at
 https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

 This library exists because I find it ugly to redefine all the
 initialisation code in every test case and I can't simply move it to a
 function due to problems with moving [T] out.

 Here's how shiny looks:

 #[cfg(test)]
 mod test {
   describe!(
 before_each {
   let awesome = true;
 }

 it is awesome {
   assert!(awesome);
 }

 it injects before_each into all test cases {
   let still_awesome = awesome;
   assert!(still_awesome);
 }
   )
 }

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

 ___
 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





 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

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




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


Re: [rust-dev] A shiny test framework

2014-07-23 Thread Nat Pryce
It's great to see Hamcrest ported to Rust.


On 22 July 2014 20:06, Vladimir Pouzanov farcal...@gmail.com wrote:

 I've just published a tiny test framework: shiny at
 https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

 This library exists because I find it ugly to redefine all the
 initialisation code in every test case and I can't simply move it to a
 function due to problems with moving [T] out.

 Here's how shiny looks:

 #[cfg(test)]
 mod test {
   describe!(
 before_each {
   let awesome = true;
 }

 it is awesome {
   assert!(awesome);
 }

 it injects before_each into all test cases {
   let still_awesome = awesome;
   assert!(still_awesome);
 }
   )
 }

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

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




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


[rust-dev] Using 'mod' for test code

2014-07-23 Thread Allen Welkie
I'm having an issue with creating a separate testing file for a program I'm
writing. I have a file called 'myprogram.rs', which imports complex numbers
with the following

  extern crate num;
  use num::complex::Complex;

and then defines a bunch of functions. I want to test these functions in a
separate file. So I created 'testprogram.rs' and import the myprogram
functions using the 'mod' keyword:

  mod myprogram;

But when I try to compile test.rs with the --test flag, I get the following
error for myprogram.rs:

  unresolved import 'num::complex::Complex'. Did you mean
'self::num::complex'?

What's going on here? How can I import my program to create a test suite.
Also, is this the preferred way of creating a test suite (using the 'mod'
keyword)? Or should I compile 'myprogram.rs' into a crate and import the
crate into 'test.rs'?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Opt-In Built-In Traits (was: Mutable files)

2014-07-23 Thread David Henningsson



On 2014-07-21 19:17, Patrick Walton wrote:

On 7/21/14 8:49 AM, Tobias Müller wrote:

Patrick Walton pcwal...@mozilla.com wrote:

On 7/20/14 8:12 PM, David Henningsson wrote:

  From a language design perspective, maybe it would be more
intuitive to
have different syntaxes for copy and move, like:


As a rust newbie, that aspect aways makes me a bit nervous. Two quite
different operations with the same syntax and and simply changing a
detail in the struct can be enough to switch between the two.


This is the reason for Opt-In Built-In Traits.

* Causing a move when you thought you were copying results in a compiler
error.

* Causing a copy when you thought you were moving is harmless, as any
implicit copy in Rust has *exactly the same runtime semantics* as a
move, except that the compiler prevents you from using the value again.

Again, we had that world before. It was extremely annoying to write
move all over the place. Be careful what you wish for.


I find these arguments compelling, but if what we want to accomplish is 
a conscious choice between copy and move every time somebody makes a new 
struct, maybe #[Deriving(Data)] struct Foo vs struct Foo is not 
first-class enough.


Maybe the move vs copy should be done by using different keywords, a few 
brainstorming examples:


 * datastruct for copy, struct for move
 * simplestruct for copy, complexstruct for move
 * struct for copy, class or object for move

...etc.

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


Re: [rust-dev] Announcing the Rust Community Calendar

2014-07-23 Thread Paul Nathan
Seattle has a Rust meetup Monthly.  Second Monday of the month, 7pm.

There's a event signup on Eventbrite.

In August there will be pizza. :)
On Jul 23, 2014 2:22 PM, Erick Tryzelaar erick.tryzel...@gmail.com
wrote:

 Good afternoon Rustaceans!

 I just created a community calender for all the Rust events happening
 throughout the Rust community around the world. You can find it at:


 https://www.google.com/calendar/embed?src=apd9vmbc22egenmtu5l6c5jbfc%40group.calendar.google.comctz=America/Los_Angeles

 It's pretty bare bones at the moment, so if you have something you would
 like added to the list, please let me know and I'll get it on the calendar.
 I'll also see if we can get this embedded on http://www.rust-lang.org/.

 Thanks,
 Erick

 ___
 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] moving out few odd libraries from the main tree

2014-07-22 Thread Zach Mertes
I'd also like to see semver stay in the language.
 On Jul 21, 2014 7:43 PM, Steve Klabnik st...@steveklabnik.com wrote:

I like the idea of SemVer being in the language itself, personally.
___
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] Conflicting implementations of a trait

2014-07-22 Thread Allen Welkie
Can there be two simultaneous implementations of a generic trait? I ask
because I want to extend the Complex class to allow for multiplication by
scalars, so that you can use a * b where a and b can be either
scalars or Complex.

The Complex struct already has an implementation of the Mul trait. I wanted
to add another, so I added the implementation of MulT, ComplexT for
ComplexT, and used the scale() function. But I get a compiler error
saying that there are conflicting implementations for trait
'core::ops::Mul'.

Is it possible to simultaneously overload the Complex (*) operator scalars
and complex numbers?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Conflicting implementations of a trait

2014-07-22 Thread Corey Richardson
Not right now. Extending the language to allow this is the subject of
RFC 24: https://github.com/rust-lang/rfcs/blob/master/active/0024-traits.md

On Tue, Jul 22, 2014 at 9:50 AM, Allen Welkie allen.wel...@gmail.com wrote:
 Can there be two simultaneous implementations of a generic trait? I ask
 because I want to extend the Complex class to allow for multiplication by
 scalars, so that you can use a * b where a and b can be either scalars
 or Complex.

 The Complex struct already has an implementation of the Mul trait. I wanted
 to add another, so I added the implementation of MulT, ComplexT for
 ComplexT, and used the scale() function. But I get a compiler error saying
 that there are conflicting implementations for trait 'core::ops::Mul'.

 Is it possible to simultaneously overload the Complex (*) operator scalars
 and complex numbers?

 ___
 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] How to write Generic traits for enums

2014-07-22 Thread Aravinda VK
Hi Felix,

Just now got a doubt. Since we know the type of enum during compile time,
is it not possible to get the value from enum. Something like this..

enum MyTypes{
MyBool(bool),
MyStr(String),
MyInt(int)
}

let a = MyBool(true);
a.get_value();  // trait for enum

let b = MyInt(100);
b.get_value();

Do you think it is possible to implement?



On Tue, Jul 22, 2014 at 9:37 PM, Aravinda VK hallimanearav...@gmail.com
wrote:

 Hi Felix,

 Thanks a lot for the detailed explanation.


 On Tue, Jul 22, 2014 at 7:08 PM, Felix S. Klock II pnkfe...@mozilla.com
 wrote:

 Aravinda (cc’ing rust-dev)-

 It seems like you are trying to program in Rust as if it were a
 dynamically-typed language, or one with runtime-type reflection (i.e. like
 Java).  At least, that is my best guess at where your misunderstanding lies.

 All functions in Rust, even generic ones, need to have their types
 resolved at compile-time.  A generic function can have different concrete
 types substituted in for its type parameters at different call-sites, but
 in the end, a particular call-site needs to resolve to a single type at
 compile-time; the type cannot be left for later resolution at program
 runtime.

 In a signature like your:

 fn get_value(settings:HashMapString, MyTypes, key: 'static str) -
 T;

 the particular instance of `MyTypes` that is returned will depend on
 which `key` is passed in; therefore, the `T` above could only be
 dynamically determined based on the runtime computation.  It inherently
 cannot be resolved at compile-time, and therefore it is not statically
 typed.

 

 Rust is not alone in offering this kind of generic types; many
 programming languages use a similar logic for determining types at compile
 time.  It just gets fuzzy if one is used to languages that maintain types
 at runtime and do not enforce restrictions like the one I outlined above.

 These type systems are often said to offer “parametric polymorphism”; I
 mention that solely to give you some guidance for a term to search for when
 goggling this subject.  (Though I will say up front that a lot of the
 results you get on this topic can be very academic and language
 research-oriented.)

 Here is a tutorial that may help you get a handle on the concepts here:

   http://lucacardelli.name/Papers/BasicTypechecking.pdf

 (Yes, it is from 1987.  I think that is why it probably one of the better
 descriptions I was able to find quickly: At that time, these ideas were not
 as widely popularized as they were today, so Cardelli took his time
 explaining the notions and assumed little about the audience.)

 rust-dev members: If others know of freely available introductions to
 this topic, I’m all ears; I just didn’t see any obvious winners in my
 searches.

 Cheers,
 -Felix


 On 22 Jul 2014, at 14:24, Aravinda VK hallimanearav...@gmail.com wrote:

 Sorry for the incomplete mail.

 What I wanted is,
 get_value(MyStr(Rust.to_str())) returns String,
 get_value(MyBool(true)) returns bool and,
 get_value(MyInt(100)) returns int

 I was trying to store generic value in hashmap, as in the example below,

 use std::collections::hashmap::HashMap;

 #[deriving(Show)]
 enum MyTypes{
 MyBool(bool),
 MyStr(String),
 MyInt(int)
 }

 fn main(){
 let mut settings:HashMapString, MyTypes = HashMap::new();

 settings.insert(port.to_str(), MyInt(8000));
 settings.insert(name.to_str(), MyStr(Rust.to_str()));
 settings.insert(enabled.to_str(), MyBool(true));

 println!({}, settings);
 }

 So to get the value out of hashmap, I need a generic function which
 checks the respective type and returns value. Some thing like

 fn get_value(settings:HashMapString, MyTypes, key: 'static str) - T{
 match settings.get(key) {
 MyBool(x) = x,
 MyStr(x) = x,
 MyInt(x) = x
 }
 }

 But I don't know how to make this work.

 Thanks.



 On Tue, Jul 22, 2014 at 4:55 PM, Felix S. Klock II pnkfe...@mozilla.com
 wrote:

 Aravinda (cc’ing rust-dev)-

 You didn’t show us exactly what you had tried to do to get your code to
 work, nor did you really describe what it is you want here.

 E.g. you seem to want `get_value(MyBool(true))` to return a boolean, but
 since `MyBool` belongs to the `MyTypes` enum, that implies that `get_value`
 when applied to any variant of `MyTypes` (including `MyInt` or `MyStr`)
 should also return a boolean … does that seem right to you?

 In any case, I suspect the missing piece of the puzzle for you is that
 you need to write an `impl` for the type in question.  I.e. something along
 the lines of:

 impl MyTypes {
 fn render(self) - String {
 match *self {
 MyBool(x) = format!({:b}, x),
 MyStr(ref x) = x.clone(),
 MyInt(x) = format!({:d}, x),
 }
 }
 }

 (except revised from an Impl for the type to being an impl of some trait
 for the type).

 Here is a link to a playpen with your code, and with a couple of example
 `impl`s for 

[rust-dev] Implementation of traits in Rust: could it be dynamic?

2014-07-22 Thread Lionel Parreaux
Hi,

So traits seem to be quite similar to Haskell's classes, being also used
for parametric polymorphism. Now, Haskell classes are usually implemented
using runtime dictionary passing. In general, code cannot be specialized
for every function call, since there may be an unbounded number of
instances generated for it, as is explained in this reddit answer:
http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju

Knowing that Rust implements traits using monomorphization of code (much
like C++ templates), I was curious about how it handled such cases, and
tried this:

struct WT {
f: T
}

trait Show {
fn show(self) - int;
}

impl Show for int {
fn show(self) - int { 666 }
}
implT:Show Show for WT {
fn show(self) - int { self.f.show()+1 }
}
implT:Clone Clone for WT {
fn clone(self) - WT { W{f:self.f.clone()} }
}

fn fooS:Show+Clone(s: S, n: int) {
let w = W{f:s.clone()};
if n  0 { foo(w, n-1); }
}

fn main() {
  foo(W{f:42i},42);
}


It gave me an error: reached the recursion limit during monomorphization,
which... well, that's a possible solution :)

I'm not sure whether this is a big problem in practice, but I was wondering
if it would be possible to switch to some runtime mechanism in cases like
this. Maybe we could make a special version of every generic functions,
that takes a dictionary at runtime and that would be able to handle types
unknown at compile-time. We would switch to this version when
monomorphization does not work. It could also allow dynamic linking of
libraries with generic functions, or it could be a way to compile some
programs (or some parts of programs) much faster.
I was thinking about, for example, an IDE where generic function calls to
types defined inside the files currently being edited use their dynamic
version, so that recompile times can be virtually inexistent (like Java).
On the other hand, the release build would of course monomorphize as much
as possible to make the perf optimal.

Now the question is: would this conform to the current semantic of
monomorphization? Do special things happen during monomorphization that
cannot be reproduced at runtime?
This is the case in C++ (and one of the reasons why C++ templates are so
bad). Is it the case in Rust, which should already have all the required
info (type bounds) before monomorphization?

I apologize if this has already been discussed. I could not find many
satisfying answers by googling.

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


Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?

2014-07-22 Thread Corey Richardson
You can avoid monomorphization by using trait objects, which erase
the precise implementing type through a vtable + pointer.
http://doc.rust-lang.org/tutorial.html#trait-objects-and-dynamic-method-dispatch
has some documentation.

On Tue, Jul 22, 2014 at 10:16 AM, Lionel Parreaux
lionel.parre...@gmail.com wrote:
 Hi,

 So traits seem to be quite similar to Haskell's classes, being also used for
 parametric polymorphism. Now, Haskell classes are usually implemented using
 runtime dictionary passing. In general, code cannot be specialized for every
 function call, since there may be an unbounded number of instances generated
 for it, as is explained in this reddit answer:
 http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju

 Knowing that Rust implements traits using monomorphization of code (much
 like C++ templates), I was curious about how it handled such cases, and
 tried this:

 struct WT {
 f: T
 }

 trait Show {
 fn show(self) - int;
 }

 impl Show for int {
 fn show(self) - int { 666 }
 }
 implT:Show Show for WT {
 fn show(self) - int { self.f.show()+1 }
 }
 implT:Clone Clone for WT {
 fn clone(self) - WT { W{f:self.f.clone()} }
 }

 fn fooS:Show+Clone(s: S, n: int) {
 let w = W{f:s.clone()};
 if n  0 { foo(w, n-1); }
 }

 fn main() {
   foo(W{f:42i},42);
 }


 It gave me an error: reached the recursion limit during monomorphization,
 which... well, that's a possible solution :)

 I'm not sure whether this is a big problem in practice, but I was wondering
 if it would be possible to switch to some runtime mechanism in cases like
 this. Maybe we could make a special version of every generic functions, that
 takes a dictionary at runtime and that would be able to handle types unknown
 at compile-time. We would switch to this version when monomorphization does
 not work. It could also allow dynamic linking of libraries with generic
 functions, or it could be a way to compile some programs (or some parts of
 programs) much faster.
 I was thinking about, for example, an IDE where generic function calls to
 types defined inside the files currently being edited use their dynamic
 version, so that recompile times can be virtually inexistent (like Java). On
 the other hand, the release build would of course monomorphize as much as
 possible to make the perf optimal.

 Now the question is: would this conform to the current semantic of
 monomorphization? Do special things happen during monomorphization that
 cannot be reproduced at runtime?
 This is the case in C++ (and one of the reasons why C++ templates are so
 bad). Is it the case in Rust, which should already have all the required
 info (type bounds) before monomorphization?

 I apologize if this has already been discussed. I could not find many
 satisfying answers by googling.

 Cheers,
 LP.



 ___
 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] Conflicting implementations of a trait

2014-07-22 Thread Sebastian Gesemann
Am 22.07.2014 18:50, schrieb Allen Welkie:
 Can there be two simultaneous implementations of a generic trait? I ask
 because I want to extend the Complex class to allow for multiplication by
 scalars, so that you can use a * b where a and b can be either
 scalars or Complex.

[snip]

Something like this was my first attempt in Rust. I was able to define
two own types (complex and imaginary) which I could mix with f64 for
multiplication, addition, etc.

But it required a kind of double dispatch. Niko explained it here:
http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/

Unfortunately, given how these traits are defined now, design requires a
bit of foresight. If you want to mix types like this for binary
operations eventually, you should probably start this kind of
dispatching early on. You can't do that with num's complex struct now.
Its Add/Mul/etc impls weren't designed with double-dispatch in mind. For
now, you would have to define your own types like I did.

But there is a chance that the binary operator traits change. For a
binary operator like + and * there is no clear receiver (an object you
call an add function on). IMHO the operands should be treated equally.
One approach that I saw mentioned by Niko (in another blog post I
believe) was to use tuples for that:

trait AddOut {
fn add(self) - Out;
}

impl AddComplexf64 for (f64,Compexf64) {
fn add((lhs, rhs) : (f64, Complexf64)) - Complexf64 {
...
}
}

And this makes it much easier to extend the interface of certain types
together.

On the other hand, there still needs to go some thought into this with
respect to passing operands by value or reference. You don't want
unnecessary clones. And you probably don't want operands to be
moved-from in some cases. And the way these kinds of traits are refined
should work well together with generic code:

fn fooT,U,O(x: T, y: U) - O
where ???: MulO
{
x * y
}

Ideally, this should work for every type T and U that can be multiplied
somehow. The question however is, how to write down the type bound?
Should we write

(T,U): AddO

to avoid moving? Should we write

(T,U): AddO

for a nicer, more intuitive syntax perhaps? I don't know. If you have a
good idea how to do that, I'm all ears. I'm very much interested in
getting easily overloadable operators without the pain of
double-dispatch and without the pain of clumsly type bounds for generic
functions that only work for half the cases due to references and such.

Cheers!
sg

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


Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?

2014-07-22 Thread Nawfel BGH
this remindes me of the issue i got when trying to implement finger
trees in Rust so long ago

https://github.com/rust-lang/rust/issues/8613

I suggested to let add a way to specify (in the code) how match
functions do we want to generate and failing at runtime when the limit
is reached. This made sense in my situation.

2014-07-22 18:23 UTC+01:00, Corey Richardson co...@octayn.net:
 You can avoid monomorphization by using trait objects, which erase
 the precise implementing type through a vtable + pointer.
 http://doc.rust-lang.org/tutorial.html#trait-objects-and-dynamic-method-dispatch
 has some documentation.

 On Tue, Jul 22, 2014 at 10:16 AM, Lionel Parreaux
 lionel.parre...@gmail.com wrote:
 Hi,

 So traits seem to be quite similar to Haskell's classes, being also used
 for
 parametric polymorphism. Now, Haskell classes are usually implemented
 using
 runtime dictionary passing. In general, code cannot be specialized for
 every
 function call, since there may be an unbounded number of instances
 generated
 for it, as is explained in this reddit answer:
 http://www.reddit.com/r/haskell/comments/1ar642/what_type_of_binding_does_haskell_use/c94o2ju

 Knowing that Rust implements traits using monomorphization of code (much
 like C++ templates), I was curious about how it handled such cases, and
 tried this:

 struct WT {
 f: T
 }

 trait Show {
 fn show(self) - int;
 }

 impl Show for int {
 fn show(self) - int { 666 }
 }
 implT:Show Show for WT {
 fn show(self) - int { self.f.show()+1 }
 }
 implT:Clone Clone for WT {
 fn clone(self) - WT { W{f:self.f.clone()} }
 }

 fn fooS:Show+Clone(s: S, n: int) {
 let w = W{f:s.clone()};
 if n  0 { foo(w, n-1); }
 }

 fn main() {
   foo(W{f:42i},42);
 }


 It gave me an error: reached the recursion limit during
 monomorphization,
 which... well, that's a possible solution :)

 I'm not sure whether this is a big problem in practice, but I was
 wondering
 if it would be possible to switch to some runtime mechanism in cases like
 this. Maybe we could make a special version of every generic functions,
 that
 takes a dictionary at runtime and that would be able to handle types
 unknown
 at compile-time. We would switch to this version when monomorphization
 does
 not work. It could also allow dynamic linking of libraries with generic
 functions, or it could be a way to compile some programs (or some parts
 of
 programs) much faster.
 I was thinking about, for example, an IDE where generic function calls to
 types defined inside the files currently being edited use their dynamic
 version, so that recompile times can be virtually inexistent (like Java).
 On
 the other hand, the release build would of course monomorphize as much as
 possible to make the perf optimal.

 Now the question is: would this conform to the current semantic of
 monomorphization? Do special things happen during monomorphization that
 cannot be reproduced at runtime?
 This is the case in C++ (and one of the reasons why C++ templates are so
 bad). Is it the case in Rust, which should already have all the
 required
 info (type bounds) before monomorphization?

 I apologize if this has already been discussed. I could not find many
 satisfying answers by googling.

 Cheers,
 LP.



 ___
 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

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


Re: [rust-dev] Implementation of traits in Rust: could it be dynamic?

2014-07-22 Thread Patrick Walton

On 7/22/14 10:16 AM, Lionel Parreaux wrote:

I'm not sure whether this is a big problem in practice, but I was
wondering if it would be possible to switch to some runtime mechanism in
cases like this. Maybe we could make a special version of every generic
functions, that takes a dictionary at runtime and that would be able to
handle types unknown at compile-time. We would switch to this version
when monomorphization does not work. It could also allow dynamic linking
of libraries with generic functions, or it could be a way to compile
some programs (or some parts of programs) much faster.


The hard part about doing that is not the dictionary passing. The hard 
part is that generic types may have unknown size or alignment. In 
Haskell this is not a problem because the language is garbage-collected 
and lazy so values have a uniform representation. But in Rust this is 
not true.


Old Rust used to try to use runtime dictionary passing, where the 
dictionary contained size and alignment information, and all 
size/alignment info was computed at runtime for generics. I cannot 
overstate how *fiendishly* complex this was. We never got all the bugs 
out. In many cases, the amount of runtime code generated to compute size 
and alignment outweighed the cost of just monomorphizing.


I strongly feel that the current system, where you can use generic type 
parameters to get monomorphization or trait objects to get dictionary 
passing, is the sweet spot.


Patrick

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


[rust-dev] A shiny test framework

2014-07-22 Thread Vladimir Pouzanov
I've just published a tiny test framework: shiny at
https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

This library exists because I find it ugly to redefine all the
initialisation code in every test case and I can't simply move it to a
function due to problems with moving [T] out.

Here's how shiny looks:

#[cfg(test)]
mod test {
  describe!(
before_each {
  let awesome = true;
}

it is awesome {
  assert!(awesome);
}

it injects before_each into all test cases {
  let still_awesome = awesome;
  assert!(still_awesome);
}
  )
}

-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A shiny test framework

2014-07-22 Thread Ilya Dmitrichenko
Dude, that's pretty much rspec ;) sweet!
On 22 Jul 2014 20:07, Vladimir Pouzanov farcal...@gmail.com wrote:

 I've just published a tiny test framework: shiny at
 https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

 This library exists because I find it ugly to redefine all the
 initialisation code in every test case and I can't simply move it to a
 function due to problems with moving [T] out.

 Here's how shiny looks:

 #[cfg(test)]
 mod test {
   describe!(
 before_each {
   let awesome = true;
 }

 it is awesome {
   assert!(awesome);
 }

 it injects before_each into all test cases {
   let still_awesome = awesome;
   assert!(still_awesome);
 }
   )
 }

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

 ___
 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] A shiny test framework

2014-07-22 Thread Benjamin Gudehus
Nice to see an RSpec-like test framework and Hamcrest assertions/matchers
for Rust!


On Tue, Jul 22, 2014 at 9:09 PM, Ilya Dmitrichenko errordevelo...@gmail.com
 wrote:

 Dude, that's pretty much rspec ;) sweet!
 On 22 Jul 2014 20:07, Vladimir Pouzanov farcal...@gmail.com wrote:

 I've just published a tiny test framework: shiny at
 https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

 This library exists because I find it ugly to redefine all the
 initialisation code in every test case and I can't simply move it to a
 function due to problems with moving [T] out.

 Here's how shiny looks:

 #[cfg(test)]
 mod test {
   describe!(
 before_each {
   let awesome = true;
 }

 it is awesome {
   assert!(awesome);
 }

 it injects before_each into all test cases {
   let still_awesome = awesome;
   assert!(still_awesome);
 }
   )
 }

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

 ___
 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] A shiny test framework

2014-07-22 Thread Vladimir Pouzanov
One note on why there's no after_each:

You cannot really make sure that the epilogue is being called, so if you
need to do anything after your test case, use RAII in before_each.


On Tue, Jul 22, 2014 at 8:10 PM, Benjamin Gudehus hasteb...@gmail.com
wrote:

 Nice to see an RSpec-like test framework and Hamcrest assertions/matchers
 for Rust!


 On Tue, Jul 22, 2014 at 9:09 PM, Ilya Dmitrichenko 
 errordevelo...@gmail.com wrote:

 Dude, that's pretty much rspec ;) sweet!
 On 22 Jul 2014 20:07, Vladimir Pouzanov farcal...@gmail.com wrote:

 I've just published a tiny test framework: shiny at
 https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

 This library exists because I find it ugly to redefine all the
 initialisation code in every test case and I can't simply move it to a
 function due to problems with moving [T] out.

 Here's how shiny looks:

 #[cfg(test)]
 mod test {
   describe!(
 before_each {
   let awesome = true;
 }

 it is awesome {
   assert!(awesome);
 }

 it injects before_each into all test cases {
   let still_awesome = awesome;
   assert!(still_awesome);
 }
   )
 }

 --
 Sincerely,
 Vladimir Farcaller Pouzanov
 http://farcaller.net/

 ___
 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





-- 
Sincerely,
Vladimir Farcaller Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Mutable files

2014-07-22 Thread Tobias Müller
Patrick Walton pcwal...@mozilla.com wrote:
 On 7/21/14 2:22 PM, Tobias Müller wrote:
 We discussed this with Bartosz literally for weeks (him being a fan of
 auto_ptr for too long, later completely converted against it and I take
 credit for that :o)). With auto_ptr this was possible:
 
 auto_ptrint a(new int);
 auto_ptrint b = a;
 
 It would nullify a with copy syntax. That code won't compile with
 unique_ptr; you'd need an explicit move(a).
 
 It only got worse from there: passing into functions, member variables...
 
 MOVING WITH COPY SYNTAX DOES NOT WORK.
 
 It's cut and dried.

Please don't snip the attribution, that was a quote!

 ... in C++. Not in Rust. That's because, unlike C++, Rust is designed 
 from the ground up to support moves and copies in a first class way.
 
 It's just strange that you can change the semantic of an already existing
 operation just by adding new capabilities. Adding traits should define new
 operations with new semantics, not changing the semantics of existing
 operations. At least that's how it works for all other traits, and
 deviating from that is at least surprising.
 
 Hence the Opt-In Built-In Traits proposal

Opt-In built-In traits makes things a bit better but my point is still
valid. By adding Copy (implicitly or explicitly) you remove the possibility
of move semantics from the type.
Usually you don't work alone on a project and some coworker adding Copy to
a type that I expected to be Move may be fatal.

No other trait removed works like that.

 Maybe the syntax was just too heavy?
 
 Any syntax at all is too much. I am convinced of that.

I'm still not convinced but maybe my fear is unjustified. Time will tell.

Tobi

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


Re: [rust-dev] Mutable files

2014-07-22 Thread Val Markovic
On Mon, Jul 21, 2014 at 2:45 PM, Patrick Walton pcwal...@mozilla.com
wrote:


  ... in C++. Not in Rust. That's because, unlike C++, Rust is designed
 from the ground up to support moves and copies in a first class way.


As a C++ dev, I feel the need to say THANK YOU for that. Rust being
designed with first-class move support is a major feature for me; it's
something I highlight when I talk about Rust with other C++ devs and it's
universally applauded.




  It's just strange that you can change the semantic of an already existing
 operation just by adding new capabilities. Adding traits should define new
 operations with new semantics, not changing the semantics of existing
 operations. At least that's how it works for all other traits, and
 deviating from that is at least surprising.


 Hence the Opt-In Built-In Traits proposal


  Maybe the syntax was just too heavy?


 Any syntax at all is too much. I am convinced of that.

 Patrick


 ___
 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] Mutable files

2014-07-22 Thread Huon Wilson

On 23/07/14 07:10, Tobias Müller wrote:



... in C++. Not in Rust. That's because, unlike C++, Rust is designed
from the ground up to support moves and copies in a first class way.


It's just strange that you can change the semantic of an already existing
operation just by adding new capabilities. Adding traits should define new
operations with new semantics, not changing the semantics of existing
operations. At least that's how it works for all other traits, and
deviating from that is at least surprising.

Hence the Opt-In Built-In Traits proposal

Opt-In built-In traits makes things a bit better but my point is still
valid. By adding Copy (implicitly or explicitly) you remove the possibility
of move semantics from the type.
Usually you don't work alone on a project and some coworker adding Copy to
a type that I expected to be Move may be fatal.

No other trait removed works like that.


You can't just add Copy to anything: the contents has to be Copy itself, 
and, you can't have a destructor on your type (i.e. a Drop 
implementation removes the possibility to be Copy). Thus, almost all 
types for which by-value uses *should* invalidate the source (i.e. move 
semantics) are automatically not Copy anyway.


The only way one can get a fatal error due to an incorrect Copy 
implementation is if the type with the impl is using `unsafe` code 
internally. In this case, that whole API needs to be considered very 
carefully anyway, ensuring correctness by avoiding Copy is just part of it.



I'll also note that an implementation of Copy just states the a 
byte-copy of a value is also a semantic copy, it doesn't offer any 
control over how the copy is performed. At runtime, by-value use of a 
Copy type is essentially identical to a by-value use of a non-Copy type 
(both are memcpy's of the bytes), the only major difference is the 
compiler statically prevents further uses of the source for non-Copy ones.



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


Re: [rust-dev] Mutable files

2014-07-21 Thread David Henningsson



On 2014-07-21 06:06, Patrick Walton wrote:

On 7/20/14 9:04 PM, Patrick Walton wrote:

On 7/20/14 8:12 PM, David Henningsson wrote:

Cool, thanks for the answer. These restrictions seem somewhat complex.


They are required. Otherwise we would end up with a C++-like situation
where copies end up happening too frequently.


Also note that these rules, far from being complex, end up making the
language much simpler than C++, as copy (or D-like postblit)
constructors are not required. All Rust types, if they are copyable at
all, can be copied by simply moving bits around.


Fair enough. I just guess it takes a while getting used to, that you 
sometimes can't use a variable after you've sent it as a parameter to a 
function.


Also now having read the RFC for Opt-in builtin traits which you 
mentioned earlier, I think this RFC makes a lot of sense. Especially the 
API Stability and Pedagogy points would have been helpful here.


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


Re: [rust-dev] Mutable files

2014-07-21 Thread Patrick Walton

On 7/21/14 8:49 AM, Tobias Müller wrote:

Patrick Walton pcwal...@mozilla.com wrote:

On 7/20/14 8:12 PM, David Henningsson wrote:

  From a language design perspective, maybe it would be more intuitive to
have different syntaxes for copy and move, like:


As a rust newbie, that aspect aways makes me a bit nervous. Two quite
different operations with the same syntax and and simply changing a detail
in the struct can be enough to switch between the two.


This is the reason for Opt-In Built-In Traits.


AFAIK this also was one of the reasons (if not _the_ reason) why
std::auto_ptr was deprecated in C++.


No, `auto_ptr` was deprecated because it copies, not moves, making it 
hard to sensibly use in containers (among other things).


Comparisons between C++ aren't really relevant anyway because the 
compiler catches any use-after-move at *compile time*, rather than at 
runtime. This means that mistaking the two doesn't cause any harm:


* Causing a move when you thought you were copying results in a compiler 
error.


* Causing a copy when you thought you were moving is harmless, as any 
implicit copy in Rust has *exactly the same runtime semantics* as a 
move, except that the compiler prevents you from using the value again.


Again, we had that world before. It was extremely annoying to write 
move all over the place. Be careful what you wish for.


Patrick

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


Re: [rust-dev] Mutable files

2014-07-21 Thread Tobias Müller
Patrick Walton pcwal...@mozilla.com wrote:
 On 7/21/14 8:49 AM, Tobias Müller wrote:
 As a rust newbie, that aspect aways makes me a bit nervous. Two quite
 different operations with the same syntax and and simply changing a detail
 in the struct can be enough to switch between the two.
 
 This is the reason for Opt-In Built-In Traits.
 
 AFAIK this also was one of the reasons (if not _the_ reason) why
 std::auto_ptr was deprecated in C++.
 
 No, `auto_ptr` was deprecated because it copies, not moves, making it 
 hard to sensibly use in containers (among other things).

Quoting Andrei Alexandrescu on digitalmars.d:

We discussed this with Bartosz literally for weeks (him being a fan of
auto_ptr for too long, later completely converted against it and I take
credit for that :o)). With auto_ptr this was possible:

auto_ptrint a(new int); 
auto_ptrint b = a;

It would nullify a with copy syntax. That code won't compile with
unique_ptr; you'd need an explicit move(a).

It only got worse from there: passing into functions, member variables...

MOVING WITH COPY SYNTAX DOES NOT WORK.

It's cut and dried.

Andrei
-

But you are right, Rust is not C++, it's actually the other way round that
makes me nervous.

 Comparisons between C++ aren't really relevant anyway because the 
 compiler catches any use-after-move at *compile time*, rather than at 
 runtime. This means that mistaking the two doesn't cause any harm:
 
 * Causing a move when you thought you were copying results in a compiler 
 error.

 * Causing a copy when you thought you were moving is harmless, as any 
 implicit copy in Rust has *exactly the same runtime semantics* as a 
 move, except that the compiler prevents you from using the value again.

From a performance point of view that may be true, but you may lose desired
semantics.

If you want an instance of a type to be move-only, but later decide that
copying that type is still useful in another place, then you lose the
guarantee in the first place.

It's just strange that you can change the semantic of an already existing
operation just by adding new capabilities. Adding traits should define new
operations with new semantics, not changing the semantics of existing
operations. At least that's how it works for all other traits, and
deviating from that is at least surprising.

 Again, we had that world before. It was extremely annoying to write 
 move all over the place. Be careful what you wish for.

Maybe the syntax was just too heavy?

Tobi

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


[rust-dev] moving out few odd libraries from the main tree

2014-07-21 Thread Ilya Dmitrichenko
It would be great to discuss which libraries can be removed from the
main tree, I can see that there had been some progress with liburl
[1], but there appear to be a few other very dubious libraries that
can easily leave outside of the main tree.

The ones I was able to spot so far, would be:

- libfourcc
- libsemver

The main question would be where would these live on github? Should it
be under the main (`github.com/rust`) organisation or actually we
could consider creating `github.com/rust-libs`?

[1]: https://github.com/rust-lang/rust/issues/10707

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


Re: [rust-dev] moving out few odd libraries from the main tree

2014-07-21 Thread Corey Richardson
I believe it has long been the goal that once we have a robust package
manager, we would start moving everything we could get away with out
of the tree. Cargo is pretty awesome now, and I think we could get
away with moving those out, with the caveat that cargo depends on
semver..

On Mon, Jul 21, 2014 at 2:28 PM, Ilya Dmitrichenko
errordevelo...@gmail.com wrote:
 It would be great to discuss which libraries can be removed from the
 main tree, I can see that there had been some progress with liburl
 [1], but there appear to be a few other very dubious libraries that
 can easily leave outside of the main tree.

 The ones I was able to spot so far, would be:

 - libfourcc
 - libsemver

 The main question would be where would these live on github? Should it
 be under the main (`github.com/rust`) organisation or actually we
 could consider creating `github.com/rust-libs`?

 [1]: https://github.com/rust-lang/rust/issues/10707

 Cheers,
 --
 Ilya
 ___
 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] Mutable files

2014-07-21 Thread Patrick Walton

On 7/21/14 2:22 PM, Tobias Müller wrote:

We discussed this with Bartosz literally for weeks (him being a fan of
auto_ptr for too long, later completely converted against it and I take
credit for that :o)). With auto_ptr this was possible:

auto_ptrint a(new int);
auto_ptrint b = a;

It would nullify a with copy syntax. That code won't compile with
unique_ptr; you'd need an explicit move(a).

It only got worse from there: passing into functions, member variables...

MOVING WITH COPY SYNTAX DOES NOT WORK.

It's cut and dried.


... in C++. Not in Rust. That's because, unlike C++, Rust is designed 
from the ground up to support moves and copies in a first class way.



It's just strange that you can change the semantic of an already existing
operation just by adding new capabilities. Adding traits should define new
operations with new semantics, not changing the semantics of existing
operations. At least that's how it works for all other traits, and
deviating from that is at least surprising.


Hence the Opt-In Built-In Traits proposal


Maybe the syntax was just too heavy?


Any syntax at all is too much. I am convinced of that.

Patrick

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


Re: [rust-dev] moving out few odd libraries from the main tree

2014-07-21 Thread Ilya Dmitrichenko
On 21 July 2014 22:46, Corey Richardson co...@octayn.net wrote:
 Cargo is pretty awesome now, and I think we could get away with moving those 
 out, with the caveat that cargo depends on semver..

It does have a bunch of things as submodules already. I wouldn't find
it unreasonable to just make libsemver part of cargo, as I doubt there
would be much use for it outside of cargo in the near feature.

Any suggestions on where misc libs should live? If someone create
repos, I'll be happy to pull these two out and push into a given repo.
In regards to CI, I'm not sure if these will really need
buildbot+bors, Travis should be pretty sufficient, I think.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] moving out few odd libraries from the main tree

2014-07-21 Thread Brian Anderson
Doing this is a goal, but we're going to need a complete strategy - 
let's please not start doing this too hastily. Maintaining crates out of 
tree is not easy, and we need to have the systems in place that will let 
us succeed (particularly around integration). acrichto will need to be 
involved because he's the most familiar with all the systems this will 
touch.


On 07/21/2014 02:28 PM, Ilya Dmitrichenko wrote:

It would be great to discuss which libraries can be removed from the
main tree, I can see that there had been some progress with liburl
[1], but there appear to be a few other very dubious libraries that
can easily leave outside of the main tree.

The ones I was able to spot so far, would be:

- libfourcc
- libsemver

The main question would be where would these live on github? Should it
be under the main (`github.com/rust`) organisation or actually we
could consider creating `github.com/rust-libs`?

[1]: https://github.com/rust-lang/rust/issues/10707

Cheers,


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


Re: [rust-dev] moving out few odd libraries from the main tree

2014-07-21 Thread Brian Anderson
I expect moving crates out of the main tree to be important for reducing 
build cycle time.


On 07/21/2014 02:28 PM, Ilya Dmitrichenko wrote:

It would be great to discuss which libraries can be removed from the
main tree, I can see that there had been some progress with liburl
[1], but there appear to be a few other very dubious libraries that
can easily leave outside of the main tree.

The ones I was able to spot so far, would be:

- libfourcc
- libsemver

The main question would be where would these live on github? Should it
be under the main (`github.com/rust`) organisation or actually we
could consider creating `github.com/rust-libs`?

[1]: https://github.com/rust-lang/rust/issues/10707

Cheers,


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


Re: [rust-dev] moving out few odd libraries from the main tree

2014-07-21 Thread Brian Anderson

As to your original question about candidate libs, here are mine:

arena
fourcc
glob
graphviz (with some rustc refactoring)
hexfloat
regex
url
uuid


On 07/21/2014 02:28 PM, Ilya Dmitrichenko wrote:

It would be great to discuss which libraries can be removed from the
main tree, I can see that there had been some progress with liburl
[1], but there appear to be a few other very dubious libraries that
can easily leave outside of the main tree.

The ones I was able to spot so far, would be:

- libfourcc
- libsemver

The main question would be where would these live on github? Should it
be under the main (`github.com/rust`) organisation or actually we
could consider creating `github.com/rust-libs`?

[1]: https://github.com/rust-lang/rust/issues/10707

Cheers,


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


Re: [rust-dev] moving out few odd libraries from the main tree

2014-07-21 Thread Steve Klabnik
I like the idea of SemVer being in the language itself, personally.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] adding a new cross-compile target

2014-07-20 Thread Rob Latham
I probably picked the exact wrong project for diving into rust, but
I'd like to teach rust how to build powerpc64-bgq-linux binaries.

I've got a powerpc64-bgq-linux toolchain.   I added this stanza to
mk/platforms.mk, but cribbed from other platforms.  Did I leave out
any important settings?

% git diff
diff --git a/mk/platform.mk b/mk/platform.mk
index d1ec7c65..f1272eaa 100644
--- a/mk/platform.mk
+++ b/mk/platform.mk
@@ -580,6 +580,19 @@ CFG_LDPATH_x86_64-unknown-freebsd :=
 CFG_RUN_x86_64-unknown-freebsd=$(2)
 CFG_RUN_TARG_x86_64-unknown-freebsd=$(call
CFG_RUN_x86_64-unknown-freebsd,,$(2))

+# powerpc64-bgq-linux configuration
+CC_powerpc64-bgq-linux=powerpc64-bgq-linux-gcc
+CXX_powerpc64-bgq-linux=powerpc64-bgq-linux-g++
+CPP_powerpc64-bgq-linux=powerpc64-bgq-linux-cpp
+AR_powerpc64-bgq-linux=powerpc64-bgq-linux-ar
+CFG_LIB_NAME_powerpc64-bgq-linux=libs$(1).so
+CFG_STATIC_LIB_NAME_powerpc64-bgq-linux=libs$(1).a
+CFG_LIB_GLOB_powerpc64-bgq-linux=lib$(1)-*.so
+CFG_CFLAGS_powerpc64-bgq-linux := $(CFLAGS)
+CFG_GCCISH_CFLAGS_powerpc64-bgq-linux := -Wall -Werror -g -fPIC $(CFLAGS)
+CFG_UNIXY_powerpc64-bgq-linux := 1
+CFG_RUN_powerpc64-bgq-linux =
+CFG_RUN_TARG_powerpc64-bgq-linux =

I can configure ok:

 ../configure --target=powerpc64-bgq-linux --prefix=/sandbox/robl/rust-master

But  build progresses pretty far, hanging up here:

[...]
rustc: 
x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustdoc
rustc: 
x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libfourcc
rustc: 
x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhexfloat
rustc: 
x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libregex_macros
make: *** No rule to make target
`powerpc64-bgq-linux/rt/arch/powerpc64/morestack.o', needed by
`powerpc64-bgq-linux/rt/libsmorestack.a'.  Stop.

I don't know how to go about debugging this.   Any ideas?

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


Re: [rust-dev] adding a new cross-compile target

2014-07-20 Thread Ilya Dmitrichenko
Hi Rob!

It's probably best to way until porting had been simplified.

Here is a ongoing discussion of this matter:

https://github.com/rust-lang/rfcs/pull/131


Cheers,

-- 

Ilya
On 20 Jul 2014 15:35, Rob Latham rlat...@gmail.com wrote:

 I probably picked the exact wrong project for diving into rust, but
 I'd like to teach rust how to build powerpc64-bgq-linux binaries.

 I've got a powerpc64-bgq-linux toolchain.   I added this stanza to
 mk/platforms.mk, but cribbed from other platforms.  Did I leave out
 any important settings?

 % git diff
 diff --git a/mk/platform.mk b/mk/platform.mk
 index d1ec7c65..f1272eaa 100644
 --- a/mk/platform.mk
 +++ b/mk/platform.mk
 @@ -580,6 +580,19 @@ CFG_LDPATH_x86_64-unknown-freebsd :=
  CFG_RUN_x86_64-unknown-freebsd=$(2)
  CFG_RUN_TARG_x86_64-unknown-freebsd=$(call
 CFG_RUN_x86_64-unknown-freebsd,,$(2))

 +# powerpc64-bgq-linux configuration
 +CC_powerpc64-bgq-linux=powerpc64-bgq-linux-gcc
 +CXX_powerpc64-bgq-linux=powerpc64-bgq-linux-g++
 +CPP_powerpc64-bgq-linux=powerpc64-bgq-linux-cpp
 +AR_powerpc64-bgq-linux=powerpc64-bgq-linux-ar
 +CFG_LIB_NAME_powerpc64-bgq-linux=libs$(1).so
 +CFG_STATIC_LIB_NAME_powerpc64-bgq-linux=libs$(1).a
 +CFG_LIB_GLOB_powerpc64-bgq-linux=lib$(1)-*.so
 +CFG_CFLAGS_powerpc64-bgq-linux := $(CFLAGS)
 +CFG_GCCISH_CFLAGS_powerpc64-bgq-linux := -Wall -Werror -g -fPIC $(CFLAGS)
 +CFG_UNIXY_powerpc64-bgq-linux := 1
 +CFG_RUN_powerpc64-bgq-linux =
 +CFG_RUN_TARG_powerpc64-bgq-linux =

 I can configure ok:

  ../configure --target=powerpc64-bgq-linux
 --prefix=/sandbox/robl/rust-master

 But  build progresses pretty far, hanging up here:

 [...]
 rustc:
 x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustdoc
 rustc:
 x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libfourcc
 rustc:
 x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhexfloat
 rustc:
 x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib/libregex_macros
 make: *** No rule to make target
 `powerpc64-bgq-linux/rt/arch/powerpc64/morestack.o', needed by
 `powerpc64-bgq-linux/rt/libsmorestack.a'.  Stop.

 I don't know how to go about debugging this.   Any ideas?

 thanks
 ==rob
 ___
 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] adding a new cross-compile target

2014-07-20 Thread Valerii Hiora
Hi Rob,

 make: *** No rule to make target 
 `powerpc64-bgq-linux/rt/arch/powerpc64/morestack.o', needed by 
 `powerpc64-bgq-linux/rt/libsmorestack.a'.  Stop.

 I don't know how to go about debugging this.   Any ideas?

  There is no way to debug this - you have to implement a couple of
functions which are required by Rust runtime and are
architecture-dependent. They live in src/rt/arch/$ARCH_NAME$

  Functions (files) are:

  morestack (morestack.S) - it is a vestige from segmented stack time.
Back then it allocated a new stack segment once were wasn't enough space
in the current one. Nowadays it just calls rust_stack_exhausted function.

  record_sp_limit (record_sp.S) - should store stack limit for current
task (usually it uses platform specific thread local storage).

  get_sp_limit (record_sp.S) - should return stack limit for current
task (reads from the same platform-specific thread local storage)

  rust_swap_registers (_context.S) - I'm not sure about this one, but I
assume it allows correct register restoration in case of green task
switches.

  rust_bootstrap_green_task (_context.S) - again, not sure, but I assume
it initializes green task.

  Note, that all stack-related functions (morestack, record_sp_limit,
get_sp_limit) should be actually compatible with LLVM segmented stack
prologue (in your case consult
$LLVM/lib/target/PowerPC/PPCFrameLowering.cpp, emitPrologue and
emitEpilogue methods, may be a couple of others).

  For a reference implementations (and much more additional comments)
see src/rt/arch/i386/*.S

-- 

  Valerii




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


Re: [rust-dev] Next week's older RFCs

2014-07-20 Thread Gábor Lehel
On Sun, Jul 13, 2014 at 10:37 PM, Nick Cameron li...@ncameron.org wrote:

 Yes, this is the right place for meta-discussion.

 I'll make sure to be stricter about commenting on the PRs in the future.
 The aim of this email is only to summarise the discussion so far, it
 shouldn't add new opinions or comments beyond applying our 'rules' for
 accepting PRs in the most uncontroversial manner. Obviously that is kind of
 a fuzzy statement, but I think you are right that here I didn't quite stick
 to that. Sorry.


Yes, this sounds sensible to me. Thanks for explaining.



 In general, I agree with your last point, but it takes considerable time
 and energy to have an active role and that is in limited supply, so it is
 always a trade off on whether any particular person gets involved with a
 particular RFC. Having said that, the vast majority of the discussion for
 an RFC should always be happening on the RFC.


I can really, really sympathize with the limited time and energy problem,
because I have it as well. Following that line of thought, we should
consider the fact that most contributors have even less time and energy,
and aren't compensated for it. As such, any steps, even incremental, in the
direction of a more engaged and collaborative process, as opposed to just
an ultimate accept/postpone/reject decision, would be very much appreciated.

Cheers



 Cheers, Nick


 On Mon, Jul 14, 2014 at 2:29 AM, Gábor Lehel glaebho...@gmail.com wrote:

 On Fri, Jul 11, 2014 at 2:48 AM, Nick Cameron li...@ncameron.org wrote:

 https://github.com/rust-lang/rfcs/pull/157 - Use `for` to introduce
 universal quantification - glaebhoerl
 Use `for` rather than `...` syntax for type-parametric items.
 Not much feedback, some discussion.
 Recommend close - we're not up for changing the syntax of Rust in
 such a fundamental way at this stage and want to keep with the
 curly-brace-language heritage.


 (Thank you for sending these e-mails. I've responded to the substantive
 aspects of this at the PR, as requested, but for the meta aspects
 pertaining to process, I hope that replying to the e-mail is acceptable.)

 If I may file a small protest: It feels wrong to me that the first time I
 hear of this concern is in a recommendation to the meeting group to close
 the PR because of it. (Which is not to mention that it's based on a basic
 misunderstanding of the proposal.) Would it be possible to always raise a
 particular concern in the comments on a PR before using it as justification
 to close, or recommend closing, that PR?

 (In general, I think it would be beneficial if the people who get to
 decide the fate of PRs took a more active role in discussing and shaping
 them, instead of staying aloof before handing down an opinion at some
 point.)



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


[rust-dev] Mutable files

2014-07-20 Thread David Henningsson

Hi,

Consider these two examples:

1)

let mut file = File::open(filename);
file.read(buf);

2)

let file = File::open(filename);
let mut reader = BufferedReader::new(file);
reader.read(buf);

My question is: in example 2, why doesn't BufferedReader need file to 
be mutable? After all, BufferedReader ends up calling file.read(), which 
needs a mutable reference to the file.


It looks like I'm able to bypass the mutability requirement, just 
because I wrap the file inside a BufferedReader?


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


Re: [rust-dev] Mutable files

2014-07-20 Thread Corey Richardson
That's right. `BufferedReader` takes the `Reader` it wraps by-value,
but the `read` method takes `mut self`. Moving something doesn't
require it to be stored in a mutable variable, but taking a `mut` to
it does.

On Sun, Jul 20, 2014 at 6:29 PM, David Henningsson di...@ubuntu.com wrote:
 Hi,

 Consider these two examples:

 1)

 let mut file = File::open(filename);
 file.read(buf);

 2)

 let file = File::open(filename);
 let mut reader = BufferedReader::new(file);
 reader.read(buf);

 My question is: in example 2, why doesn't BufferedReader need file to be
 mutable? After all, BufferedReader ends up calling file.read(), which needs
 a mutable reference to the file.

 It looks like I'm able to bypass the mutability requirement, just because
 I wrap the file inside a BufferedReader?

 // David
 ___
 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] Mutable files

2014-07-20 Thread Patrick Walton

On 7/20/14 6:29 PM, David Henningsson wrote:

Hi,

Consider these two examples:

1)

let mut file = File::open(filename);
file.read(buf);

2)

let file = File::open(filename);
let mut reader = BufferedReader::new(file);
reader.read(buf);

My question is: in example 2, why doesn't BufferedReader need file to
be mutable? After all, BufferedReader ends up calling file.read(), which
needs a mutable reference to the file.

It looks like I'm able to bypass the mutability requirement, just
because I wrap the file inside a BufferedReader?


Because `BufferedReader::new` moves `file` and takes ownership of it. 
(You can see this if you try to use `file` again: the compiler will 
prevent you.) Mutability is inherited through ownership in Rust: that 
is, the current owner determines the mutability of a piece of data. So, 
the mutability of `reader` determines the mutability of the `File` 
object at the time you try to read, and the mutability restriction is 
satisfied.


Patrick

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


Re: [rust-dev] Mutable files

2014-07-20 Thread David Henningsson



On 2014-07-21 03:33, Patrick Walton wrote:

On 7/20/14 6:29 PM, David Henningsson wrote:

Hi,

Consider these two examples:

1)

let mut file = File::open(filename);
file.read(buf);

2)

let file = File::open(filename);
let mut reader = BufferedReader::new(file);
reader.read(buf);

My question is: in example 2, why doesn't BufferedReader need file to
be mutable? After all, BufferedReader ends up calling file.read(), which
needs a mutable reference to the file.

It looks like I'm able to bypass the mutability requirement, just
because I wrap the file inside a BufferedReader?


Because `BufferedReader::new` moves `file` and takes ownership of it.
(You can see this if you try to use `file` again: the compiler will
prevent you.) Mutability is inherited through ownership in Rust: that
is, the current owner determines the mutability of a piece of data. So,
the mutability of `reader` determines the mutability of the `File`
object at the time you try to read, and the mutability restriction is
satisfied.


Thanks for the quick answer!

I did two more examples to try to understand when things are moved:

3)
struct Dummy {
  foo: int,
  bar: int
}

let f = Dummy {foo: 10, bar: 5};
let mut g = f; // Here the assignment copies..?
println!({}, f.foo + g.foo); // Ok

4)

let f = File::open(filename);
let mut g = f; // Here the assignment moves..?
f.tell(); // Fails - use of moved value

How come that the assignment moves in example 4), and copies in example 3)?

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


Re: [rust-dev] Mutable files

2014-07-20 Thread Patrick Walton
Because Foo is a POD type (implements the Copy trait). Essentially, types that 
can be copied by copying bits only (not allocating) are POD types, and all 
others move.

This may be changed with the Opt-In Built-in Traits proposal so that POD types 
must be specially declared to implement Copy before they will copy.

Patrick

On July 20, 2014 7:39:35 PM PDT, David Henningsson di...@ubuntu.com wrote:


On 2014-07-21 03:33, Patrick Walton wrote:
 On 7/20/14 6:29 PM, David Henningsson wrote:
 Hi,

 Consider these two examples:

 1)

 let mut file = File::open(filename);
 file.read(buf);

 2)

 let file = File::open(filename);
 let mut reader = BufferedReader::new(file);
 reader.read(buf);

 My question is: in example 2, why doesn't BufferedReader need file
to
 be mutable? After all, BufferedReader ends up calling file.read(),
which
 needs a mutable reference to the file.

 It looks like I'm able to bypass the mutability requirement, just
 because I wrap the file inside a BufferedReader?

 Because `BufferedReader::new` moves `file` and takes ownership of it.
 (You can see this if you try to use `file` again: the compiler will
 prevent you.) Mutability is inherited through ownership in Rust: that
 is, the current owner determines the mutability of a piece of data.
So,
 the mutability of `reader` determines the mutability of the `File`
 object at the time you try to read, and the mutability restriction is
 satisfied.

Thanks for the quick answer!

I did two more examples to try to understand when things are moved:

3)
struct Dummy {
   foo: int,
   bar: int
}

let f = Dummy {foo: 10, bar: 5};
let mut g = f; // Here the assignment copies..?
println!({}, f.foo + g.foo); // Ok

4)

let f = File::open(filename);
let mut g = f; // Here the assignment moves..?
f.tell(); // Fails - use of moved value

How come that the assignment moves in example 4), and copies in example
3)?

// David

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Mutable files

2014-07-20 Thread Steven Fackler
Some types are implicitly copyable. They implement the built-in trait Copy.
A type is Copy if it is

a) numeric primitive (e.g. f32 or uint), or
b) an immutable reference (e.g. Foo or str), or
c) a raw pointer (e.g. *const Foo or *mut Foo), or
d) a collection of Copy types (e.g. struct Foo { a: int, b: 'static str }).

In addition, if a type implements Drop, it is no longer Copy.

Steven Fackler


On Sun, Jul 20, 2014 at 7:39 PM, David Henningsson di...@ubuntu.com wrote:



 On 2014-07-21 03:33, Patrick Walton wrote:

 On 7/20/14 6:29 PM, David Henningsson wrote:

 Hi,

 Consider these two examples:

 1)

 let mut file = File::open(filename);
 file.read(buf);

 2)

 let file = File::open(filename);
 let mut reader = BufferedReader::new(file);
 reader.read(buf);

 My question is: in example 2, why doesn't BufferedReader need file to
 be mutable? After all, BufferedReader ends up calling file.read(), which
 needs a mutable reference to the file.

 It looks like I'm able to bypass the mutability requirement, just
 because I wrap the file inside a BufferedReader?


 Because `BufferedReader::new` moves `file` and takes ownership of it.
 (You can see this if you try to use `file` again: the compiler will
 prevent you.) Mutability is inherited through ownership in Rust: that
 is, the current owner determines the mutability of a piece of data. So,
 the mutability of `reader` determines the mutability of the `File`
 object at the time you try to read, and the mutability restriction is
 satisfied.


 Thanks for the quick answer!

 I did two more examples to try to understand when things are moved:

 3)
 struct Dummy {
   foo: int,
   bar: int
 }

 let f = Dummy {foo: 10, bar: 5};
 let mut g = f; // Here the assignment copies..?
 println!({}, f.foo + g.foo); // Ok

 4)

 let f = File::open(filename);
 let mut g = f; // Here the assignment moves..?
 f.tell(); // Fails - use of moved value

 How come that the assignment moves in example 4), and copies in example 3)?

 // David

 ___
 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] Mutable files

2014-07-20 Thread David Henningsson



On 2014-07-21 04:43, Steven Fackler wrote:

Some types are implicitly copyable. They implement the built-in trait
Copy. A type is Copy if it is

a) numeric primitive (e.g. f32 or uint), or
b) an immutable reference (e.g. Foo or str), or
c) a raw pointer (e.g. *const Foo or *mut Foo), or
d) a collection of Copy types (e.g. struct Foo { a: int, b: 'static str }).

In addition, if a type implements Drop, it is no longer Copy.

Steven Fackler


Cool, thanks for the answer. These restrictions seem somewhat complex.

This wasn't very intuitive for me, so just throwing this out (feel free 
to ignore if it has already been discussed :-) )


From a language design perspective, maybe it would be more intuitive to 
have different syntaxes for copy and move, like:


let mut g = f; /* Copies from f to g, error if f is a non-Copy type */

let mut g - f; /* Moves from f to g, error if trying to use f afterwards */

Or in the File/BufferedReader example, this would be something like:

let f = File::open(filename);
let mut reader = BufferedReader::new(- f); /* Bye bye f! */

I'm also afraid that if a library struct decides to change between a 
copy and non-copy type, this would cause subtle errors in users of that 
library that expected the other type. But if the compiler is guaranteed 
to catch all such errors even with today's handling, maybe that is not 
too much to worry about.






On Sun, Jul 20, 2014 at 7:39 PM, David Henningsson di...@ubuntu.com
mailto:di...@ubuntu.com wrote:



On 2014-07-21 03:33, Patrick Walton wrote:

On 7/20/14 6:29 PM, David Henningsson wrote:

Hi,

Consider these two examples:

1)

let mut file = File::open(filename);
file.read(buf);

2)

let file = File::open(filename);
let mut reader = BufferedReader::new(file);
reader.read(buf);

My question is: in example 2, why doesn't BufferedReader
need file to
be mutable? After all, BufferedReader ends up calling
file.read(), which
needs a mutable reference to the file.

It looks like I'm able to bypass the mutability
requirement, just
because I wrap the file inside a BufferedReader?


Because `BufferedReader::new` moves `file` and takes ownership
of it.
(You can see this if you try to use `file` again: the compiler will
prevent you.) Mutability is inherited through ownership in Rust:
that
is, the current owner determines the mutability of a piece of
data. So,
the mutability of `reader` determines the mutability of the `File`
object at the time you try to read, and the mutability
restriction is
satisfied.


Thanks for the quick answer!

I did two more examples to try to understand when things are moved:

3)
struct Dummy {
   foo: int,
   bar: int
}

let f = Dummy {foo: 10, bar: 5};
let mut g = f; // Here the assignment copies..?
println!({}, f.foo + g.foo); // Ok

4)

let f = File::open(filename);
let mut g = f; // Here the assignment moves..?
f.tell(); // Fails - use of moved value

How come that the assignment moves in example 4), and copies in
example 3)?

// David

_
Rust-dev mailing list
Rust-dev@mozilla.org mailto:Rust-dev@mozilla.org
https://mail.mozilla.org/__listinfo/rust-dev
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] Mutable files

2014-07-20 Thread Patrick Walton

On 7/20/14 8:12 PM, David Henningsson wrote:

Cool, thanks for the answer. These restrictions seem somewhat complex.


They are required. Otherwise we would end up with a C++-like situation 
where copies end up happening too frequently.



This wasn't very intuitive for me, so just throwing this out (feel free
to ignore if it has already been discussed :-) )

 From a language design perspective, maybe it would be more intuitive to
have different syntaxes for copy and move, like:


There used to be a unary move operator. This was a huge pain.

match move x {
Some(move y) = foo(move z);
}

And so on. I don't want to go back to that world.

Patrick

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


Re: [rust-dev] Mutable files

2014-07-20 Thread Patrick Walton

On 7/20/14 9:04 PM, Patrick Walton wrote:

On 7/20/14 8:12 PM, David Henningsson wrote:

Cool, thanks for the answer. These restrictions seem somewhat complex.


They are required. Otherwise we would end up with a C++-like situation
where copies end up happening too frequently.


Also note that these rules, far from being complex, end up making the 
language much simpler than C++, as copy (or D-like postblit) 
constructors are not required. All Rust types, if they are copyable at 
all, can be copied by simply moving bits around.


Patrick

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


[rust-dev] compiling Rust to C?

2014-07-18 Thread Josh Haberman
Is there any prospect of compiling Rust to C anytime in the mid to near future?

This would be a really attractive option for anyone who wants to write
in Rust, but wants the extreme portability of C.

Actually maybe I should first ask if this is actually a tractable
problem. Are there technical reasons that would prevent compiling Rust
into portable C?

LLVM's C Backend seems to have fallen out of maintenance -- would this
provide the solution I am looking for, if it were maintained?

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


Re: [rust-dev] compiling Rust to C?

2014-07-18 Thread Cameron Zwarich
The biggest problem would be probably be handling stack unwinding (IIRC the 
LLVM C backend never tried to handle this either). The only option when 
targeting C is to use setjmp / longjmp, but that is going to be pretty 
inefficient. Alternatively you could just abort instead of unwinding.

Cameron

On Jul 18, 2014, at 12:29 AM, Josh Haberman jhaber...@gmail.com wrote:

 Is there any prospect of compiling Rust to C anytime in the mid to near 
 future?
 
 This would be a really attractive option for anyone who wants to write
 in Rust, but wants the extreme portability of C.
 
 Actually maybe I should first ask if this is actually a tractable
 problem. Are there technical reasons that would prevent compiling Rust
 into portable C?
 
 LLVM's C Backend seems to have fallen out of maintenance -- would this
 provide the solution I am looking for, if it were maintained?
 
 Thanks,
 Josh
 ___
 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] Requesting information (about globs, macros, subtyping)

2014-07-18 Thread Cameron Zwarich
On Jul 16, 2014, at 10:54 AM, Gábor Lehel glaebho...@gmail.com wrote:

 3. As far as I'm aware, subtyping in the current language arises only from 
 subtyping of lifetimes. Where is this important? One example was mentioned in 
 [Niko's recent blog 
 post](http://smallcultfollowing.com/babysteps/blog/2014/07/06/implied-bounds/).
  Where else? Without this subtyping of lifetimes, what would break? How 
 burdensome would it be if one had to use explicit casts in those 
 circumstances?

I’ve been thinking about this a bit recently, so I might as well post my 
thoughts in this thread rather than following up privately with people.

All subtyping in Rust is ultimately derived from the inclusion of lifetimes and 
the contravariance of the /mut type constructors in their lifetime parameter: 
a pointer to something that lives longer than ‘a is usable in any place where 
we are using a pointer to something with lifetime ‘a. As far as I know, there 
are only 3 original sources of bounds ‘a = ‘b for lifetimes ‘a and ‘b:

1) Inclusion of concrete lifetimes, i.e. control-flow regions (currently 
lexical scopes, but soon to be extended to arbitrary single-entry / multiple 
exit regions), in the same function.

2) That if a function is parameterized in lifetime ‘b and lifetime ‘a is a 
concrete lifetime in that function, then ‘a = ‘b.

3) That the scope of a borrow is always included in the lifetime of its 
referent, e.g. that ‘a = ‘b in ’a ’b T. This is described by Niko in his 
blog post 
http://smallcultfollowing.com/babysteps/blog/2013/04/04/nested-lifetimes/. This 
rule is different than the first two because it is the only way that a bound 
can be propagated on two lifetime *parameters*, whereas the first two involve a 
concrete lifetime in one of the positions.

This is handwaving a bit, since the specifics of 1) and how these all interact 
in the current lifetime inference (and Niko’s proposed simplification) are all 
relevant in practice, but I hope this is a correct abstraction of the situation.

The simplest question to ask is whether it is possible to remove lifetime 
subtyping entirely from Rust. Unfortunately, this is not possible, because if 
you try to do this (see the Tofte-Talpin region system, which is probably the 
closest thing to pure Hindley-Milner type inference for a region system) then 
you have lifetime variables for local variables in a function caller and callee 
unified, so that a called function is allocating local variables in the 
caller’s lifetime. This means that lifetimes no longer correspond to nested 
stack frames, and you also can’t implement destructors properly (at least in 
any trivial way that I can think of). This is not suitable for a systems 
language.

The next logical question to ask is whether you can eliminate the 
non-invariance of type constructors, since that is how subtyping infects the 
rest of the language.

Since /mut are contravariant in their lifetime parameter, the vast majority 
of type constructors get their variance inferred as contravariant in lifetime 
parameters. Most examples of contravariance come from something like this:

struct A‘a {
x: ’a int,
y: ’a int,
}

If I have two distinct int borrows with concrete lifetimes (meaning an actual 
control-flow region in the calling function, rather than a lifetime parameter) 
being used at a construction of A‘a, then one of the lifetimes is nested in 
the other. Hence I if ‘a is the inner lifetime and ‘b is the outer lifetime, I 
can coerce the ’b to an ’a and construct an A‘a.

What do I lose by this? Well, it only works at the first level, so that 
something like this will fail to type-check:

struct A'a { x: 'a int }

fn foo(i: int) {
let a = A { x: i };
if i  1 {
let j  = 2;
let b = if i  10 {
a
} else {
A { x: j }
};
}
}

There are obvious workarounds here, but in more complex examples they could 
possibly hurt the readability / performance of the program. However, the 
fallout is internal to a single function, since there is no way to directly 
propagate the knowledge that one concrete lifetime is included in another to 
another function (beside the 3rd source of bounds mentioned above. which I will 
talk about below).

You can do similar coercions with the sources of bounds 2) and 3). In 2) one of 
the lifetimes is a concrete lifetime again, so again all of the fallout is 
internal to a single function. However, in 3) there is a new complication. 
since knowledge of the relationship between two lifetimes can actually leak 
outside of the functions where they originate. Here is the example in Niko’s 
blog post on 3):

struct BorrowedCursor'b, T {
buffer: 'b [T],
position: uint
}

impl'b, T CursorT for BorrowedCursor'b, T {
fn get'c('c self) - 'c T {
self.buffer[self.position]
}

...
}

This would still work, because we’re dealing directly with the  type 
constructor, and we could still coerce an ’b [] to 

[rust-dev] Sendable References for data-parallel fork/join-style algorithms

2014-07-18 Thread Sebastian Gesemann
Hi!

I was thinking about fork/join-style parallelism and about whether
this can be made to work including the possibility to pass references
(or something similar to references) across task boundaries. So far, I
came up with a little low-level building block that could be of
interest to the community. This basically allows to send
reference-like things across task boundaries without any dangling
pointer issues (I believe).

A use case I had in mind was a divide-and-conquer algorithm where the
recursion could benefit from concurrency because the division produces
independent problems operating on non-overlapping mut slices. In my
case, I tried to parallelize a multibody simulation with this. But you
could also think about a parallelized quicksort if you want. After
partitioning, sorting the two halves can be done independently and
concurrently. But you may wish to avoid splitting one vector into two
and joining them together. Instead you may want different tasks to
work on the same vector but restricted to their non-overlapping
sub-slices.

The basic idea is to erase the lifetime parameter (to make the
reference-like objects sendable) and to keep it safe w.r.t. to
lifetimes by creating a new scope that won't be left by execution
until all the borrowed and life-time erased pseudo-references are
gone. This is done by reference counting and signal/wait on a mutex.

Let me just show you for now how this can be used:

trait IntoSendBorrowOut {
unsafe fn into_sendable(self) - Out;
fn sendableU(self, func:|Out|-U) - U { ... }
}

fn partition_inplace'a(s: 'a mut[int]) - ('a mut[int],'a mut[int]) {
...
}

fn main() {
let mut vec = Vec::from_fn(10,|u|-(u as int));

partition_inplace(vec.as_mut_slice()).sendable(|(left,right)|{
// Here, left and right are sendable slices: SendMutSliceint
// A sendable reference internally refers to a reference counter
// stored in a mutex and increases/decreases it on clone/drop.
// If the counter reaches zero, it will send a signal.
spawn(proc() {
let mut left = left; // needed for unique borrowing
left.as_mut_slice().sort();
});
let mut right = right; // needed for unique borrowing
right.as_mut_slice().sort();

}); // -- in case the reference counter is not null, sendable waits
// for the signal and blocks until until it reaches zero.
// This is done within a destructor of a function-local object
// that carries the reference counter as a member.

for i in vec.iter() {
println!({}, i)
}
}

IntoSendBorrow is simply implemented for all reference-like things
(T, mut T, [T], mut[T] and tuples of these).

I'm planning on putting the whole source code online on github. Feel
free to comment -- especially if you find this useful. :)

One thing I learned is that it does not seem to be possible to emulate
the behaviour of mutable references and mutable slices perfectly in
the sense that they could be uniquely borrowed without being mutable.
I think, I would have to write something like this:

implT SendMutSliceT {
...
fn get'a('a uniq self, index: uint) - 'a mut T
...
}

where self is only uniquely borrowed but does not have to be mutable.
At least a unique borrow is needed to avoid returning mutable aliases.
Since this is not possible right now, I have to put a mut there
instead and that's why I need the lines

let mut left = left;
let mut right = right;

in the above example.

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


Re: [rust-dev] compiling Rust to C?

2014-07-18 Thread Josh Haberman
On Fri, Jul 18, 2014 at 12:35 AM, Cameron Zwarich zwar...@mozilla.com wrote:
 The biggest problem would be probably be handling stack
 unwinding (IIRC the LLVM C backend never tried to handle
 this either).

Interesting, I can see what that would be a challenge.

 The only option when targeting C is to use
 setjmp / longjmp, but that is going to be pretty inefficient.

Why do you think of setjmp/longjmp as inefficient? If you use the
_setjmp/_longjmp variants that don't fiddle with the signal mask, they
seem pretty efficient to me.

The bigger problem with setjmp/longjmp to me is that they don't let
you clean up variables sitting on the stack, as Rust language
semantics do I believe?

I can think of a way to do this portably, but it costs two extra
pointers every time you declare any stack variables. Basically you
could, every time you declare local variables, make them part of a
struct that has a pointer to the enclosing local var struct, and a
pointer to an unwind function. Then when a task fails, traverse this
list of frames and run the unwind function for each one before calling
longjmp().

It's wasteful of stack space (since this is basically duplicating
unwind info that exists at the system level, like in .eh_frame), but
it is portable.

In any case, it sounds like no one is working on this, so it's
probably unlikely to happen unless someone takes it up. Thanks for the
info!

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


Re: [rust-dev] compiling Rust to C?

2014-07-18 Thread Cameron Zwarich
On Jul 18, 2014, at 9:52 AM, Josh Haberman jhaber...@gmail.com wrote:
 
 The only option when targeting C is to use
 setjmp / longjmp, but that is going to be pretty inefficient.
 
 Why do you think of setjmp/longjmp as inefficient? If you use the
 _setjmp/_longjmp variants that don't fiddle with the signal mask, they
 seem pretty efficient to me.
 
 The bigger problem with setjmp/longjmp to me is that they don't let
 you clean up variables sitting on the stack, as Rust language
 semantics do I believe?
 
 I can think of a way to do this portably, but it costs two extra
 pointers every time you declare any stack variables. Basically you
 could, every time you declare local variables, make them part of a
 struct that has a pointer to the enclosing local var struct, and a
 pointer to an unwind function. Then when a task fails, traverse this
 list of frames and run the unwind function for each one before calling
 longjmp().
 
 It's wasteful of stack space (since this is basically duplicating
 unwind info that exists at the system level, like in .eh_frame), but
 it is portable.

This is more along the lines of what I meant. The 32-bit ARM Darwin ABI 
actually uses this form of exception handling, and LLVM has some support for 
it. Unlike DWARF unwinding you incur a cost for every cleanup that you 
register, so it can be quite expensive. Having had to debug issues with it in 
the past in LLVM, I'm not sure I would really trust the codegen to be correct.

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


Re: [rust-dev] compiling Rust to C?

2014-07-18 Thread Eric Christopher
On Fri, Jul 18, 2014 at 12:29 AM, Josh Haberman jhaber...@gmail.com wrote:
 Is there any prospect of compiling Rust to C anytime in the mid to near 
 future?

 This would be a really attractive option for anyone who wants to write
 in Rust, but wants the extreme portability of C.

 Actually maybe I should first ask if this is actually a tractable
 problem. Are there technical reasons that would prevent compiling Rust
 into portable C?

 LLVM's C Backend seems to have fallen out of maintenance -- would this
 provide the solution I am looking for, if it were maintained?


FWIW I removed the C Backend a few years ago because it was largely
unmaintained. It would likely need to be rewritten from scratch to do
this. If you're curious about it, let me know.

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


Re: [rust-dev] Rust universal build issues

2014-07-18 Thread Aljaž Srebrnič
On 17/lug/2014, at 20:08, Brian Anderson bander...@mozilla.com wrote:

 Thanks for your work on MacPorts. Did you use any flags to configure or 
 arguments to make? What version of OS X, clang/gcc?

Yes, sorry, I’m building this on OS X 10.9.4 with system clang (5.1). After 
further inspection, I can build it with target and host set to 
x86_64-apple-darwin, but when I try to add i686-apple-darwin to the target 
list, the build fails. Is compiling for 32 bit on 64 bit host still supported?

 
 On 07/17/2014 01:17 AM, Aljaž Srebrnič wrote:
 Hello list,
 I’m ono of the maintainers of rust on MacPorts, and I found some issues with 
 the build. The script in src/compiler-rt/make/platform/clang_darwin.mk has a 
 comment on line 135:
 
 # Forcibly strip off any -arch, as that totally breaks our universal support.
 
 Now, it looks like that script strips any -arch flags and adds -arch flags 
 for *all* the supported architectures by the host compiler. As a result, 
 some of the files are compiled as x86_64 only (the original arch flags) and 
 some as a fat binary (i386 and x86_64). In stage3, linking fails:
 
 I don't believe the build system is supposed to build stage3 on OS X. Seems 
 suspicious.

I could be wrong about the stage number, I just inferred because the stage3 
directory had no files in it.

 
 
 […]
 error: ar 'x' 
 '/opt/local/var/macports/build/_opt_local_var_macports_sources_svn.macports.org_dports_lang_rust/rust/work/rust-0.11.0/i686-apple-darwin/rt/libjemalloc.a'
  failed with: exit code: 1
 note: stdout ---
 
 note: stderr ---
 ar: 
 /opt/local/var/macports/build/_opt_local_var_macports_sources_svn.macports.org_dports_lang_rust/rust/work/rust-0.11.0/i686-apple-darwin/rt/libjemalloc.a
  is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
 ar: 
 /opt/local/var/macports/build/_opt_local_var_macports_sources_svn.macports.org_dports_lang_rust/rust/work/rust-0.11.0/i686-apple-darwin/rt/libjemalloc.a:
  Inappropriate file type or format
 […]
 
 I saw a env variable, $RC_SUPPORTED_ARCHS and tried to set 
 RC_SUPPORTED_ARCHS=“x86_64”, but to no avail. How can I instruct compiler-rt 
 to build for my architecture only?
 
 Thanks,
 Aljaž
 
 --
 Aljaž Srebrnič a.k.a g5pw
 My public key:  http://bit.ly/g5pw_pubkey
 
 ___
 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


--
Aljaž Srebrnič a.k.a g5pw
My public key:  http://bit.ly/g5pw_pubkey

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


<    2   3   4   5   6   7   8   9   10   11   >