Re: [rust-dev] issue numbers in commit messages
Maybe I'm misunderstanding? This would require that all commits be specifically associated with an issue. I don't have actual stats, but briefly skimming recent commits and looking at the issue tracker, a lot of commits can't be reasonably associated with an issue. This requirement would either force people to create fake issues for each commit, or to reference tangentially-related or overly-broad issues in commit messages, neither of which is very useful. Referencing any conversation that leads to or influences a commit is a good idea, but something this inflexible doesn't seem right. My 1.5ยข. On Tue, 18 Feb 2014, Nick Cameron wrote: How would people feel about a requirement for all commit messages to have an issue number in them? And could we make bors enforce that? The reason is that GitHub is very bad at being able to trace back a commit to the issue it fixes (sometimes it manages, but not always). Not being able to find the discussion around a commit is extremely annoying. Cheers, Nick -- Scott Lawrence___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] issue numbers in commit messages
What about having bors place the hash of each commit merged into the auto-merge message? Then finding the PR, and any closed issues, consists of backwards-searching in git-log. (Having bors modify commit messages would probably cause major problems with hashes changing.) On Tue, 18 Feb 2014, Nick Cameron wrote: Adding a few chars to a commit is not onerous and it is useful. You may not want it now, but perhaps you would if you had it to use. _I_ certainly want it, and I think others would find it useful if it was there to use. On Tue, Feb 18, 2014 at 1:37 PM, Steve Klabnik st...@steveklabnik.comwrote: Yeah, I'm not into modifying every single commit, I basically only want what bors already (apparently) already does. -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax
May as well throw my 2 cents in. This is a pretty nice idea (I've always found 'implT' to be particularly confusing anyway). It does loose a nice property, though. Previously, there was a nice parallelism between struct FooT and let foo: FooT and so the syntax was quite obvious for beginners. The extra complexity of forall kills this. Of course, one could write forallT:K,L struct FooT { but that's just ugly. On Sat, 1 Feb 2014, Corey Richardson wrote: Hey all, bjz and I have worked out a nice proposal[0] for a slight syntax change, reproduced here. It is a breaking change to the syntax, but it is one that I think brings many benefits. Summary === Change the following syntax: ``` struct FooT, U { ... } implT, U TraitT for FooT, U { ... } fn fooT, U(...) { ... } ``` to: ``` forallT, U struct Foo { ... } forallT, U impl TraitT for FooT, U { ... } forallT, U fn foo(...) { ... } ``` The Problem === The immediate, and most pragmatic, problem is that in today's Rust one cannot easily search for implementations of a trait. Why? `grep 'impl Clone'` is itself not sufficient, since many types have parametric polymorphism. Now I need to come up with some sort of regex that can handle this. An easy first-attempt is `grep 'impl(.*?)? Clone'` but that is quite inconvenient to type and remember. (Here I ignore the issue of tooling, as I do not find the argument of But a tool can do it! valid in language design.) A deeper, more pedagogical problem, is the mismatch between how `struct Foo... { ... }` is read and how it is actually treated. The straightforward, left-to-right reading says There is a struct Foo which, given the types ... has the members This might lead one to believe that `Foo` is a single type, but it is not. `Fooint` (that is, type `Foo` instantiated with type `int`) is not the same type as `Foounit` (that is, type `Foo` instantiated with type `uint`). Of course, with a small amount of experience or a very simple explanation, that becomes obvious. Something less obvious is the treatment of functions. What does `fn foo...(...) { ... }` say? There is a function foo which, given types ... and arguments ..., does the following computation: ... is not very adequate. It leads one to believe there is a *single* function `foo`, whereas there is actually a single `foo` for every substitution of type parameters! This also holds for implementations (both of traits and of inherent methods). Another minor problem is that nicely formatting long lists of type parameters or type parameters with many bounds is difficult. Proposed Solution = Introduce a new keyword, `forall`. This choice of keyword reads very well and will not conflict with any identifiers in code which follows the [style guide](https://github.com/mozilla/rust/wiki/Note-style-guide). Change the following declarations from ``` struct FooT, U { ... } implT, U TraitT for FooT, U { ... } fn fooT, U(...) { ... } ``` to: ``` forallT, U struct Foo { ... } forallT, U impl TraitT for FooT, U { ... } forallT, U fn foo(...) { ... } ``` These read very well. for all types T and U, there is a struct Foo ..., for all types T and U, there is a function foo ..., etc. These reflect that there are in fact multiple functions `foo` and structs `Foo` and implementations of `Trait`, due to monomorphization. [0]: http://cmr.github.io/blog/2014/02/01/polymorphic-declaration-syntax-in-rust/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax
It seems to use a '+' instead of ','. On Sat, 1 Feb 2014, Benjamin Striegel wrote: How about supporting type aliases as Scala does? In theory I think that should be achievable today, using trait inheritance: trait MyT : Clone, Eq {} ...at least, I *think* we allow multiple trait inheritance. Not sure what the syntax is! On Sat, Feb 1, 2014 at 6:12 PM, Vladimir Lushnikov vladi...@slate-project.org wrote: Placing type bounds before the name of the thing you are trying to declare feels unnatural to me. And the generic block is far too much boilerplate! How about supporting type aliases as Scala does? So you write: type MyT = Clone + Eq fn fooMyT, U(t: T, u: U) - ... and the 'type' is just an alias for any type that has Clone + Eq? Obviously the above only solves repeating yourself for complex type constraints. Also, reusing 'for' would be confusing as well, because you expect a loop there, not a generic type bound. How about 'any': any T: Clone + Eq, U fn foo (t: T, u: U) - ... ? On Sat, Feb 1, 2014 at 11:06 PM, Benjamin Striegel ben.strie...@gmail.com wrote: Another point in favor of this plan is that it would eliminate the need to put type parameters directly after the `impl`, which to be honest *is* pretty weird and inconsistent with the rest of the language. But I'm still not sure how I feel about the look of it: for T: Clone+Eq, U fn foo(t: T, u: U) - (T, U) { If you choose *not* to wrap after the type parameters there, you're really obscuring what the heck you're trying to declare. Heck, maybe what we're really asking for is for the ability to have generic blocks within which type parameters can be declared once: for T: Clone+Eq, U { fn foo(t: T, u: U) - (T, U) { ...but that's even *more* boilerplate! On Sat, Feb 1, 2014 at 5:59 PM, Benjamin Striegel ben.strie...@gmail.com wrote: Yes, and I don't have a solution for that. Well, it's not like we don't already stumble here a bit, what with requiring :: instead of just . Not sure how much other people value the consistency here. On Sat, Feb 1, 2014 at 5:58 PM, Corey Richardson co...@octayn.netwrote: On Sat, Feb 1, 2014 at 5:55 PM, Benjamin Striegel ben.strie...@gmail.com wrote: First of all, why a new keyword? Reusing `for` here would be totally unambiguous. :P And also save us from creating the precedent of multi-word keywords. I'd be equally happy with for instead of forall. Secondly, currently Rust has a philosophy of use-follows-declaration (i.e. the syntax for using something mirrors the syntax for declaring it). This would eliminate that. Yes, and I don't have a solution for that. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Lifetime required to outlive itself
This code compiles successfully: http://ix.io/a34 . I believe this behavior is correct. Just so it's clear what this code does: f() takes a `mut int` and adds it to an array - the idea is that all of the `mut int` can be changed at some later time. Naturally, there's some fancy lifetime juggling involved in this (which I may have gotten wrong). Uncommenting the commented parts (the method f() in the impl A, in particular) yields the error message shown at the bottom, which appears to say that the lifetime created in the second parameter of f() does not necessarily outlive itself. Is there some especially complicated aspect of lifetimes as they interact with self, or is this indeed a bug? -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Lifetime required to outlive itself
Yup, that was pretty much it. (I suspected something like that might be happening.) Thanks! To future generations of confused souls: when the impl is parameterized, the function probably doesn't need to be. On Wed, 22 Jan 2014, Huon Wilson wrote: On 22/01/14 12:41, Scott Lawrence wrote: This code compiles successfully: http://ix.io/a34 . I believe this behavior is correct. Just so it's clear what this code does: f() takes a `mut int` and adds it to an array - the idea is that all of the `mut int` can be changed at some later time. Naturally, there's some fancy lifetime juggling involved in this (which I may have gotten wrong). Uncommenting the commented parts (the method f() in the impl A, in particular) yields the error message shown at the bottom, which appears to say that the lifetime created in the second parameter of f() does not necessarily outlive itself. Is there some especially complicated aspect of lifetimes as they interact with self, or is this indeed a bug? I think it's the compiler tricking you: the 'a in `fn f'a(mut self, ...)` is shadowing the `impl'a A'a` i.e. they are different lifetimes that happen to have the same identifier. Changing it to `fn f(mut self, 'a mut int)` should work. There's a bug open about warning on shadowed generics, because, as this demonstrates, you end up with hard-to-diagnose error messages: https://github.com/mozilla/rust/issues/11658 Huon ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] sandboxing Rust?
On Sat, 18 Jan 2014, Corey Richardson wrote: Rust's safety model is not intended to prevent untrusted code from doing evil things. Doesn't it succesfully do that, though? Or at least with only a small amount of extra logic? For example, suppose I accept, compile, and run arbitrary rust code, with only the requirement that there be no unsafe blocks (ignore for a moment the fact that libstd uses unsafe). Barring compiler bugs, I think it's then guaranteed nothing bad can happen. It seems to me that (as usual with languages like Rust) it's simply a mildly arduous task of maintaining a parallel libstd implementation to be used for sandboxing, which either lacks implementations for dangerous functionality, or has them replaced with special versions that perform correct permissions checking. That, coupled with forbidding unsafe blocks in submitted code, should solve the problem. I could be completely wrong. (Is there some black magic I don't know?) On Sat, Jan 18, 2014 at 10:18 PM, Josh Haberman jhaber...@gmail.com wrote: Is it a design goal of Rust that you will be able to run untrusted code in-process safely? In other words, by whitelisting the set of available APIs and prohibiting unsafe blocks, would you be able to (eventually, once Rust is stable and hardened) run untrusted code in the same address space without it intentionally or unintentionally escaping its sandbox? (Sorry if this a FAQ, I couldn't find any info about it). 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 -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] typing in rust
I would think that `test()` (the function) is in scope for the duration of `let test =`, and then the new definition masks the old one. Similarly, let x = 2; let x = x + 2; If you change the last line to /call/ test(), you should get an error. On Wed, 13 Nov 2013, Philip Herron wrote: Hey all I am still learning but i just tried something which i expected to give an error but works: fn test () - int { 1 } fn main () { let test = test (); println (format! ({}, test)); } I guess on compilation the names are mangled against their types or something so you can differentiate between test the function and test the variable. Not sure would be nice to get some clarification what this behavior is. Thanks --Phil -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How would you map one vector to a vector of a different element type?
I would think: let ports = do myvect.iter().map { |e| something(e) } On Sat, 2 Nov 2013, Leah Hanson wrote: Hi, I have a ~[~str]. I have code that will turn a ~str into a Portuint. I want to end up with a [Portuint]. (or ~ or @ or whatever. I just want to be able to iterate over the Ports later.) Since I'm not sure what looping construct to use, I tried with a for-each loop. ~~~ let ports = for s in myvect.iter() { let (pport, cchan) = stream(); do spawn { cchan.send(fun(*s)) } pport }; ~~~ As you might, expect I got an error: error: mismatched types: expected `()` but found `std::comm::Portuint` (expected () but found struct std::comm::Port) From this, I take it that for loops must return `()`, rather than an actual value. When I searched for a map function in the documentation, I only found a Map type. How would you map one vector to a vector of a different element type? Thanks, Leah -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] average function
Use NumCast::from(count). You'll also want to be sure to initialize sum. I'd use the Zero instance. use std::num::Zero; fn averageT:Int(values:[T]) - T { let count = values.len(); let mut sum:T = Zero::zero(); for v in values.iter() { sum = sum.add(v); } return sum / NumCast::from(count); } fn main() { println(fmt!(%d, average([1,2,3]))) } On Wed, 25 Sep 2013, Andreas Zwinkau wrote: I tried to write an average function, but so far failed to convince the type checker. fn averageT:Int(values:[T]) - T { let count = values.len(); let mut sum:T; for v in values.iter() { sum = sum.add(v); } return sum / count; } error: mismatched types: expected `T` but found `uint` (expected type parameter but found uint) The problem is that sum is the generic type T, but count is uint due to the definition of the len function. Casting count as T should work, i thought, but rustc seems to have another opinion? -- Andreas Zwinkau work email: zwin...@kit.edu private email: q...@web.de homepage: http://beza1e1.tuxen.de ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- Scott Lawrence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev