Re: [rust-dev] rustpkg use scenarios
Graydon answered this pretty thoroughly, but just to add: On Thu, Jun 27, 2013 at 2:39 PM, SiegeLord slab...@aim.com wrote: Scenario 4: Fetching/building without installation Building without installing: rustpkg build URI If you then run `rustpkg install URI` or `rustpkg install --package bar`, then it'll use that pre-built copy without fetching the sources and building This is the intended behavior, though currently it will rebuild, because https://github.com/mozilla/rust/issues/7075 isn't implemented yet. them again. Speaking of fetching, this would just fetch the sources: rustpkg fetch URI Planned -- see https://github.com/mozilla/rust/issues/7242 Also, I opened https://github.com/mozilla/rust/issues/7447 for Zack's suggestions about versions. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt Not a riot, it's a rebellion. -- Boots Riley Attention Bros and Trolls: When I call out your spew, I'm not angry, I'm defiant. -- Reg Braithwaite ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Language support for external iterators (new for loop)
Specificity is the cost of non-virtual dispatch. However, if it is truly undesirable in some cases, we can eventually permit you to return `~Iteratorint`, once ~-objects work properly. Niko On Wed, Jun 26, 2013 at 11:49:07PM +0100, Gareth Smith wrote: One downside of external iterators is that they produce function signatures that expose implementation details and are harder to understand. For example, an internal iterator function that loops over odd numbers would have a signature like this: fn each_odd(ints: [int], fn(int) - bool) - bool; The same function written to produce an external iterator would have a signature more like this: fn iter_odds'a(ints: 'a [int]) - iterator::FilterMapIterator'a, int, int, vec::VecIterator'a, int; This signature is more complicated. It is also likely to change if the implementation of iter_odds changes (e.g. to no longer use filter_map). Gareth On 26/06/13 04:44, Daniel Micay wrote: This is a followup from the previous discussion on internal vs. external iterators.[1] Since then, most iterators in the standard library have been converted to external ones. Almost all uses of the `for` loop are now using the `.advance` wrapper, and I don't think there will be any use cases left for the old internal iteration protocol. # External iterators To reiterate the benefits of the external iteration protocol: * It's generic and works well with traits, so functions can be written to work on any arbitrary `IteratorA`. Most adaptors can work for any type `A`, whether it's a value, reference or mutable reference. * Iteration state is an object, so iterators can be interleaved. This is required for a generic zip, merge, union, intersect, etc. and is often useful in an ad-hoc fashion to consume only some of an iterator without losing it. * In the future, Rust can have generators using a `yield` statement like C#, compiling down to a fast state machine without requiring context switches, virtual functions or even closures. This would eliminate the difficulty of coding recursive traversals by-hand with external iterators. # Alternatives The iteration protocol can't be based on anything requiring virtual method calls, heap allocations or context switches without the performance becoming significantly worse. There have been some suggestions about following the lead of Clojure and using reducers[2], but the implementation suffers from the same limitations of not having an external state. Rust doesn't yet have a way to write data-parallel code, but when it does gain that, containers can just support partitioning themselves into ranges via `Iterator`. It will work for in-place mutation in parallel too. # A new loop I think it's a foregone conclusion that we'll be replacing `for`, so I suggest that we just reuse the current syntax and change the semantics: for iterator |pattern| { body } This can just be compiled as the following would be: let mut it = iterator; loop { match it.next() { Some(pattern) = { body } None = break } } A lang item can be added for the Iterator trait requirement. This would avoid the `.advance` tacked onto almost every `for` loop at the moment, and rid us of the problems associated with the current `for`: * The `break` and `return` statements can fail to work, so borrow/liveness checking can't trust them. A loop body can't take an `mut` reference and return it because it could result in grabbing the reference again. This also seems to be why we forbid `return` inside closures and do statements, since it would be confusing to have to act differently than `for`. * The function's local variables are upvars in the closure, so using them is very restricted. It's very obvious that it's not just another block because of this. * Compiling closures is slow, as they have to broken down by SROA and involve inlining a function after proving the function pointer is constant. If we were marking the function pointers as `llvm.invariant` it might stop being a performance hit, but it would remain a compile time issue. # Iterables The `for` loop above can also be extended to work for *any* `Iterable` in the future, not just iterators themselves. for iterable |x| { ... } // use the default iterator for iterable.rev_iter |x| { ... } // use another iterator At the moment, the `Iterable` trait cannot be defined/used because the compiler ignores bounds on trait type parameters, but it would be something like the following: #[lang = iterable] trait IterableA, T: IteratorA { fn iter(self) - T; } trait ReverseIterableA, T: IteratorA { fn rev_iter(self) - T; } trait MutableIterableA, T: IteratorA { fn mut_iter(mut self) - T; }
Re: [rust-dev] Language support for external iterators (new for loop)
On 6/28/13 11:23 AM, Niko Matsakis wrote: Specificity is the cost of non-virtual dispatch. However, if it is truly undesirable in some cases, we can eventually permit you to return `~Iteratorint`, once ~-objects work properly. They basically do now (in master), no? Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Language support for external iterators (new for loop)
On Tue, Jun 25, 2013 at 11:44:10PM -0400, Daniel Micay wrote: Rust doesn't yet have a way to write data-parallel code, but when it does gain that, containers can just support partitioning themselves into ranges via `Iterator`. It will work for in-place mutation in parallel too. I do not follow what you mean by support partitioning themselves into ranges via `Iterator`. That said, I don't think the optimal sequential protocol will necessarily be the optimal parallel protocol, and it's not clear to me how general it will be to have a protocol that yields slices. It'd work ok for vectors and btrees but perhaps not that much else? I suspect the best thing will be to have the iterable trait optimized for sequential access, and provide a second trait to be used for optimal parallel access, probably some kind of divide-and-conquer-like trait that can split an iterator into two other iterators. For types that lack the DivideAndConquer trait, you could also have a poor man's DC that is implemented in terms of an iterator, or just serialize to a vec. Niko ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] mk_t() and interning in middle/ty.rs
Ah, thanks for clearing that up. That makes much more sense now :) On Jun 28, 2013 10:04 PM, Björn Steinbrink bstei...@gmail.com wrote: Hi, On 2013.06.28 13:27:57 +0200, Michael Woerister wrote: I hope this question is not too specific for the mailing list, but I stumbled upon something I don't understand today and thought I'd better ask. In librustc/middle/ty.rs there is the mk_t() function which creates and caches objects of type t from values of type sty. However, the way it uses the cache seems kind of strange, especially the key creation at the beginning: fn mk_t(cx: ctxt, st: sty) - t { // Check for primitive types. // ... omitted here ... let key = intern_key { sty: to_unsafe_ptr(st) }; match cx.interner.find(key) { Some(t) = unsafe { return cast::transmute(t.sty); }, _ = () } The intern_key is created by taking a pointer to st, which in effect is the address of the argument slot on the stack. That can't be right, can it? The IterBytes implementation for intern_key, which is used to generate the key for the hashmap, derefs the stored pointer, so it's using the actual value on the stack. And when actually interning, the interned value has a sty field, which is referenced by the key for that value, so the pointer in the intern_key stays valid as long as the value is in the interner. HTH Björn ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Language support for external iterators (new for loop)
On 13-06-28 11:23 AM, Niko Matsakis wrote: Specificity is the cost of non-virtual dispatch. However, if it is truly undesirable in some cases, we can eventually permit you to return `~Iteratorint`, once ~-objects work properly. This is interesting. I assume we'd want these to be Iterator cast to Iterator, no? But we can't really do that in a return value; we'd have to return the Iterator and have the caller cast it to Iterator. ~-allocating here seems a bit much.. -Graydon ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev