From ivan.ristic at gmail.com Fri Aug 2 01:10:15 2013 From: ivan.ristic at gmail.com (=?UTF-8?B?SXZhbiBSaXN0acSH?=) Date: Fri, 02 Aug 2013 09:10:15 +0100 Subject: [rust-dev] Help with a trivial TCP client example needed Message-ID: <51FB6967.4050401@gmail.com> I am starting to play with Rust, but I got stuck early on with a trivial TCP client example. (There's a few server examples out there, but I couldn't find a single working client anywhere. I tried the archives, the tests, etc.) My naive approach sends some data to the server and then attempts to read, but socket.read() always times out. I have verified that the server is receiving the request and responding to it. I came across a couple of tickets that suggest that I might be handling the event loop incorrectly, but I don't know enough to fix the code. Your help is appreciated. Thanks. extern mod extra; use extra::net::{ip, tcp}; use extra::uv; use std::str; fn main() { let ip_addr = ip::v4::parse_addr("204.232.212.130"); let iotask = &uv::global_loop::get(); let r = tcp::connect(ip_addr, 80, iotask); match(r) { Err(err) => { println(fmt!("Connection failed: %?", err)) } Ok(socket) => { let r = socket.write(bytes!("GET / HTTP/1.0\r\n\r\n").to_owned()); if (r.is_err()) { println(fmt!("Write error: %?", r.get_err())) } else { let r = socket.read(2000); if (r.is_err()) { println(fmt!("Read error: %?", r.get_err())) } else { let bytes = r.get(); println(str::from_bytes(bytes)); } } } } } -- Ivan From vladimir at slate-project.org Fri Aug 2 13:47:57 2013 From: vladimir at slate-project.org (Vladimir Lushnikov) Date: Fri, 2 Aug 2013 21:47:57 +0100 Subject: [rust-dev] Function definition syntax In-Reply-To: <20130801060322.GI2529@Mr-Bennet> References: <51F76C0D.20802@mozilla.com> <84B1C957-0038-4514-80DF-E906EE6553A6@mpi-sws.org> <51F7F268.8060701@mozilla.com> <66765CB4-6AE3-45A5-980B-0A6FD04E683A@mpi-sws.org> <51F83046.1010003@mozilla.com> <37281313-D300-4BC6-B784-CE3C61536C15@yahoo.com.au> <20130801060322.GI2529@Mr-Bennet> Message-ID: +1 for keeping the syntax as is i.e. the -> as part of the return signature. It's more readable and it does not mislead people into the fact that there is no partial function application in rust (which IMHO is one of the main reasons to keep the syntax the same between argument and return types). On Thu, Aug 1, 2013 at 7:03 AM, Niko Matsakis wrote: > On Wed, Jul 31, 2013 at 08:59:07AM +1000, Brendan Zabarauskas wrote: > > On 31/07/2013, at 7:29 AM, Graydon Hoare wrote: > > > > > we used to use [T,U,V] like Scala, but user feedback decisively > rejected it. My kingdom > > > for a few extra bracket characters! > > > > > > Maybe I should be more dictatorial and less democratic when it comes to > > > such things; I'm a bit of a pushover. > > > > Damn, that's a shame. Feel free to use your Benevolent Dictator For Life > role in future! The users will thank you in the end :) > > > > *shudders at the issues caused by <> delimeters* > > While I tend to prefer `[]` visually, I don't see how it solves any of > the ambiguities that arise in parsing, if that's what you're referring > to. At least not in our case. > > > Niko > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Fri Aug 2 18:28:59 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 02 Aug 2013 18:28:59 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names Message-ID: <51FC5CDB.6000902@mozilla.com> Hi everyone, Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I think now is as good a time as any to have the bikeshedding debate :) I've noticed two styles for acronyms in type names: Java style (HTTPServer) versus .NET style (HttpServer). Currently we are usually using .NET style, but inconsistently (e.g. ARC). We never really decided. Here are a few examples of types in each style: * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. I slightly prefer Java style myself because I think "GC" looks better than "Gc", because Web APIs use Java style, and because Python does (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But I don't feel strongly on this issue. Thoughts/straw poll? Patrick From corey at octayn.net Fri Aug 2 18:30:07 2013 From: corey at octayn.net (Corey Richardson) Date: Fri, 2 Aug 2013 21:30:07 -0400 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: I prefer .NET style for no particular reason at all. On Fri, Aug 2, 2013 at 9:28 PM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I > think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style (HTTPServer) > versus .NET style (HttpServer). Currently we are usually using .NET style, > but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than > "Gc", because Web APIs use Java style, and because Python does (e.g. > SimpleHTTPServer) and in general we've been following PEP 8. But I don't > feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From danielmicay at gmail.com Fri Aug 2 18:30:37 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 2 Aug 2013 21:30:37 -0400 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: On Fri, Aug 2, 2013 at 9:28 PM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I > think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style (HTTPServer) > versus .NET style (HttpServer). Currently we are usually using .NET style, > but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than > "Gc", because Web APIs use Java style, and because Python does (e.g. > SimpleHTTPServer) and in general we've been following PEP 8. But I don't > feel strongly on this issue. > > Thoughts/straw poll? > > Patrick I slightly prefer the Java naming style here. Otherwise, it's not obvious something is an acronym. From banderson at mozilla.com Fri Aug 2 18:31:16 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 02 Aug 2013 18:31:16 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: <51FC5D64.7090908@mozilla.com> On 08/02/2013 06:28 PM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over > `Gc<>`. I think now is as good a time as any to have the bikeshedding > debate :) > > I've noticed two styles for acronyms in type names: Java style > (HTTPServer) versus .NET style (HttpServer). Currently we are usually > using .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better > than "Gc", because Web APIs use Java style, and because Python does > (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But > I don't feel strongly on this issue. > > Thoughts/straw poll? I prefer .NET style and have thus far been on a crusade to convert the standard libraries to this convention. From pnathan at vandals.uidaho.edu Fri Aug 2 18:42:59 2013 From: pnathan at vandals.uidaho.edu (Paul Nathan) Date: Fri, 2 Aug 2013 18:42:59 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: <5E7BFDBD-6BA9-431E-8503-4E0CC6C24171@vandals.uidaho.edu> Java style. My eyeballs like it better and it 'flows' better visually. The .net humps look ugly. -- my 2? Regards, Paul Nathan Sent from my iPhone On Aug 2, 2013, at 6:28 PM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style (HTTPServer) versus .NET style (HttpServer). Currently we are usually using .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than "Gc", because Web APIs use Java style, and because Python does (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But I don't feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From me at kevincantu.org Fri Aug 2 18:45:19 2013 From: me at kevincantu.org (Kevin Cantu) Date: Fri, 2 Aug 2013 18:45:19 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5D64.7090908@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> <51FC5D64.7090908@mozilla.com> Message-ID: COBOL style. People will have an easier time reading XML-HTTP-REQUEST than either of the alternatives listed above. Kevin On Fri, Aug 2, 2013 at 6:31 PM, Brian Anderson wrote: > On 08/02/2013 06:28 PM, Patrick Walton wrote: > >> Hi everyone, >> >> Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I >> think now is as good a time as any to have the bikeshedding debate :) >> >> I've noticed two styles for acronyms in type names: Java style >> (HTTPServer) versus .NET style (HttpServer). Currently we are usually using >> .NET style, but inconsistently (e.g. ARC). We never really decided. >> >> Here are a few examples of types in each style: >> >> * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. >> >> * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. >> >> I slightly prefer Java style myself because I think "GC" looks better >> than "Gc", because Web APIs use Java style, and because Python does (e.g. >> SimpleHTTPServer) and in general we've been following PEP 8. But I don't >> feel strongly on this issue. >> >> Thoughts/straw poll? >> > > I prefer .NET style and have thus far been on a crusade to convert the > standard libraries to this convention. > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From aaron.dandy at live.com Fri Aug 2 18:50:27 2013 From: aaron.dandy at live.com (Aaron Dandy) Date: Fri, 2 Aug 2013 19:50:27 -0600 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <5E7BFDBD-6BA9-431E-8503-4E0CC6C24171@vandals.uidaho.edu> References: <51FC5CDB.6000902@mozilla.com>, <5E7BFDBD-6BA9-431E-8503-4E0CC6C24171@vandals.uidaho.edu> Message-ID: I prefer mostly the C# style (http://msdn.microsoft.com/en-us/library/ms229043.aspx) but _without_ the stupid special case> A special case is made for two-letter acronyms in which both letters are capitalized, as shown in the following identifier:IOStream It would be weird to allow for both IoStream and IOStream for example. There are 2 reasons I prefer the .NET style.1) I bind shift to crouch in games and it is well worn, so holding it down for HTTP kind of sucks.2) I sometimes have trouble when there are multiple accronyms:HTTPOGCWFSService vs HttpOgcWgsService I don't care what looks better. I just simply have no idea what a helpful tongue twisting potato on good conditional wind farm subsidies service is. > From: pnathan at vandals.uidaho.edu > Date: Fri, 2 Aug 2013 18:42:59 -0700 > To: pwalton at mozilla.com > CC: rust-dev at mozilla.org > Subject: Re: [rust-dev] Java versus .NET style for acronyms in type names > > Java style. My eyeballs like it better and it 'flows' better visually. The .net humps look ugly. > > -- my 2? > > Regards, > Paul Nathan > > Sent from my iPhone > > On Aug 2, 2013, at 6:28 PM, Patrick Walton wrote: > > > Hi everyone, > > > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I think now is as good a time as any to have the bikeshedding debate :) > > > > I've noticed two styles for acronyms in type names: Java style (HTTPServer) versus .NET style (HttpServer). Currently we are usually using .NET style, but inconsistently (e.g. ARC). We never really decided. > > > > Here are a few examples of types in each style: > > > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > > > I slightly prefer Java style myself because I think "GC" looks better than "Gc", because Web APIs use Java style, and because Python does (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But I don't feel strongly on this issue. > > > > Thoughts/straw poll? > > > > Patrick > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.boggiano at seld.be Fri Aug 2 18:50:20 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Sat, 03 Aug 2013 03:50:20 +0200 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: <51FC61DC.2000509@seld.be> On 03.08.2013 03:28, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. > I think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style > (HTTPServer) versus .NET style (HttpServer). Currently we are usually > using .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better > than "Gc", because Web APIs use Java style, and because Python does > (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But I > don't feel strongly on this issue. > > Thoughts/straw poll? I prefer Java style visually (mostly, more below), but I prefer .NET for the consistency that it brings, and the simplicity of the rule. Just studly-caps on words, no matter what they are. It makes things less ambiguous, for HTTP it's obvious, but for ARC if someone tells you to use that and pronounces it "arc" and not A R C you might not know it's an acronym and just write Arc and waste time. I can't think of a more valid example right now but I think they're out there. Also XMLHTTPRequest is frankly nasty, it's as readable as German word-combination to the uninitiated. If you don't know what XML and HTTP are, good luck finding out there are two different words in there (again just an example). So I'd say better keep heading towards .NET (BTW Arc has been renamed to that already I think?) and standardize on that. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From jack at metajack.im Fri Aug 2 19:03:44 2013 From: jack at metajack.im (Jack Moffitt) Date: Fri, 2 Aug 2013 20:03:44 -0600 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5D64.7090908@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> <51FC5D64.7090908@mozilla.com> Message-ID: >> Thoughts/straw poll? > > I prefer .NET style and have thus far been on a crusade to convert the > standard libraries to this convention. +1 for .NET style. There are often multiple acronyms in a row, and then it's really hard to parse. Also with .NET style, you get working M-f and M-b in emacs, if you have subword mode on. I use this a lot. jack. From jeaye at arrownext.com Fri Aug 2 19:25:48 2013 From: jeaye at arrownext.com (Jeaye) Date: Fri, 02 Aug 2013 19:25:48 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: <51FC6A2C.7020500@arrownext.com> > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over > `Gc<>`. I think now is as good a time as any to have the bikeshedding > debate :) To be fair, and I like being fair, both of these are inconsistent within Rust. If functions_are_like_this then types Should_Be_Like_This or Maybe_like_this. You know, to be fair. As for .NET vs. Java... let acronyms be acronyms; choose the Java approach. Cheers, Jeaye From zack.slayton at gmail.com Fri Aug 2 19:31:33 2013 From: zack.slayton at gmail.com (Zack Slayton) Date: Fri, 2 Aug 2013 22:31:33 -0400 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC6A2C.7020500@arrownext.com> References: <51FC5CDB.6000902@mozilla.com> <51FC6A2C.7020500@arrownext.com> Message-ID: +1 for .NET style (maybe it should be '.Net'?). I find it makes consecutive acronyms easier to read. At any rate, I'd like to avoid mixing the two styles ? la Javascript's XMLHttpRequest. On Fri, Aug 2, 2013 at 10:25 PM, Jeaye wrote: > Hi everyone, >> >> Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I >> think now is as good a time as any to have the bikeshedding debate :) >> > > To be fair, and I like being fair, both of these are inconsistent within > Rust. If functions_are_like_this then types Should_Be_Like_This or > Maybe_like_this. You know, to be fair. As for .NET vs. Java... let acronyms > be acronyms; choose the Java approach. > > Cheers, > Jeaye > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rust-dev at tomlee.co Fri Aug 2 19:38:44 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Fri, 2 Aug 2013 19:38:44 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: Bikeshedding is right ;) I'm probably a weirdo but I like the Java style when the type name is the acronym in its entirety, but the .NET style when you mix it up with other stuff. e.g. I prefer GC<> to Gc<>, but then I prefer SimpleHttpServer to SimpleHTTPServer :P Guess I'm +0.5 on both? On Fri, Aug 2, 2013 at 6:28 PM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I > think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style > (HTTPServer) versus .NET style (HttpServer). Currently we are usually using > .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than > "Gc", because Web APIs use Java style, and because Python does (e.g. > SimpleHTTPServer) and in general we've been following PEP 8. But I don't > feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From aaron.dandy at live.com Fri Aug 2 19:47:48 2013 From: aaron.dandy at live.com (Aaron Dandy) Date: Fri, 2 Aug 2013 20:47:48 -0600 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com>, Message-ID: That is an interesting but complicated idea. Ogre caps when an acronym is alone, camel when acronyms are adjacent. GC<>BFG<>BfgGc<> I feel like this is the sort of thing we should not decide collaboratively but instead should have beaten into us by a glorious dictator. I'm not sure this discussion will get us far as we are not the first to discuss it. Date: Fri, 2 Aug 2013 19:38:44 -0700 From: rust-dev at tomlee.co To: rust-dev at mozilla.org Subject: Re: [rust-dev] Java versus .NET style for acronyms in type names Bikeshedding is right ;) I'm probably a weirdo but I like the Java style when the type name is the acronym in its entirety, but the .NET style when you mix it up with other stuff. e.g. I prefer GC<> to Gc<>, but then I prefer SimpleHttpServer to SimpleHTTPServer :P Guess I'm +0.5 on both? On Fri, Aug 2, 2013 at 6:28 PM, Patrick Walton wrote: Hi everyone, Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I think now is as good a time as any to have the bikeshedding debate :) I've noticed two styles for acronyms in type names: Java style (HTTPServer) versus .NET style (HttpServer). Currently we are usually using .NET style, but inconsistently (e.g. ARC). We never really decided. Here are a few examples of types in each style: * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. I slightly prefer Java style myself because I think "GC" looks better than "Gc", because Web APIs use Java style, and because Python does (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But I don't feel strongly on this issue. Thoughts/straw poll? Patrick _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- Tom Lee / http://tomlee.co / @tglee _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at timryan.org Fri Aug 2 19:55:07 2013 From: tim at timryan.org (Tim Cameron Ryan) Date: Fri, 2 Aug 2013 22:55:07 -0400 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: <0D9BA5FE-42DD-4C4C-B582-4CBF201E285A@timryan.org> Straw polling: +1 for Java style. It works in the favor of the audience. Arc looks like it may represent an actual Arc trait, ARC is an indicator I don't understand some component and should be going straight to wikipedia. Being clever about capitalization limits intuition. Tim On Aug 2, 2013, at 10:38 PM, Tom Lee wrote: > Bikeshedding is right ;) > > I'm probably a weirdo but I like the Java style when the type name is the acronym in its entirety, but the .NET style when you mix it up with other stuff. > > e.g. I prefer GC<> to Gc<>, but then I prefer SimpleHttpServer to SimpleHTTPServer :P > > Guess I'm +0.5 on both? > > > > On Fri, Aug 2, 2013 at 6:28 PM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style (HTTPServer) versus .NET style (HttpServer). Currently we are usually using .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than "Gc", because Web APIs use Java style, and because Python does (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But I don't feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > -- > Tom Lee / http://tomlee.co / @tglee > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Fri Aug 2 20:01:39 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 02 Aug 2013 20:01:39 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: <51FC7293.4060809@mozilla.com> On 8/2/13 7:38 PM, Tom Lee wrote: > Bikeshedding is right ;) > > I'm probably a weirdo but I like the Java style when the type name is > the acronym in its entirety, but the .NET style when you mix it up with > other stuff. > > e.g. I prefer GC<> to Gc<>, but then I prefer SimpleHttpServer to > SimpleHTTPServer :P > > Guess I'm +0.5 on both? Yes, I meant to mention this as a possible option but forgot to. I like this better than the .NET style alone. Patrick From jfager at gmail.com Fri Aug 2 20:03:18 2013 From: jfager at gmail.com (Jason Fager) Date: Fri, 2 Aug 2013 23:03:18 -0400 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <0D9BA5FE-42DD-4C4C-B582-4CBF201E285A@timryan.org> References: <51FC5CDB.6000902@mozilla.com> <0D9BA5FE-42DD-4C4C-B582-4CBF201E285A@timryan.org> Message-ID: +1 for benevolent dictator tossing a coin. On Friday, August 2, 2013, Tim Cameron Ryan wrote: > Straw polling: +1 for Java style. > > It works in the favor of the audience. Arc looks like it may > represent an actual Arc trait, ARC is an indicator I don't understand > some component and should be going straight to wikipedia. Being clever > about capitalization limits intuition. > > Tim > > On Aug 2, 2013, at 10:38 PM, Tom Lee > > wrote: > > Bikeshedding is right ;) > > I'm probably a weirdo but I like the Java style when the type name is the > acronym in its entirety, but the .NET style when you mix it up with other > stuff. > > e.g. I prefer GC<> to Gc<>, but then I prefer SimpleHttpServer to > SimpleHTTPServer :P > > Guess I'm +0.5 on both? > > > > On Fri, Aug 2, 2013 at 6:28 PM, Patrick Walton > > wrote: > >> Hi everyone, >> >> Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I >> think now is as good a time as any to have the bikeshedding debate :) >> >> I've noticed two styles for acronyms in type names: Java style >> (HTTPServer) versus .NET style (HttpServer). Currently we are usually using >> .NET style, but inconsistently (e.g. ARC). We never really decided. >> >> Here are a few examples of types in each style: >> >> * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. >> >> * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. >> >> I slightly prefer Java style myself because I think "GC" looks better >> than "Gc", because Web APIs use Java style, and because Python does (e.g. >> SimpleHTTPServer) and in general we've been following PEP 8. But I don't >> feel strongly on this issue. >> >> Thoughts/straw poll? >> >> Patrick >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > > > -- > *Tom Lee */ http://tomlee.co / @tglee > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rust-dev at tomlee.co Fri Aug 2 20:03:50 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Fri, 2 Aug 2013 20:03:50 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: Agreed -- I don't particularly care, so long as it's consistent. I guess wrt camel-casing acronyms, it'd be nice to avoid stuff like HttpURLConnectionwhich uses some bastardry of capitalization to avoid the unfortunate situation where there are two acronyms are side-by-side. Anyway. Bring on the dictator(s). :) On Fri, Aug 2, 2013 at 7:47 PM, Aaron Dandy wrote: > That is an interesting but complicated idea. Ogre caps when an acronym is > alone, camel when acronyms are adjacent. > > GC<> > BFG<> > BfgGc<> > > I feel like this is the sort of thing we should not decide collaboratively > but instead should have beaten into us by a glorious dictator. I'm not sure > this discussion will get us far as we are not the first to discuss it. > > ------------------------------ > Date: Fri, 2 Aug 2013 19:38:44 -0700 > From: rust-dev at tomlee.co > To: rust-dev at mozilla.org > Subject: Re: [rust-dev] Java versus .NET style for acronyms in type names > > > Bikeshedding is right ;) > > I'm probably a weirdo but I like the Java style when the type name is the > acronym in its entirety, but the .NET style when you mix it up with other > stuff. > > e.g. I prefer GC<> to Gc<>, but then I prefer SimpleHttpServer to > SimpleHTTPServer :P > > Guess I'm +0.5 on both? > > > > On Fri, Aug 2, 2013 at 6:28 PM, Patrick Walton wrote: > > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I > think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style > (HTTPServer) versus .NET style (HttpServer). Currently we are usually using > .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than > "Gc", because Web APIs use Java style, and because Python does (e.g. > SimpleHTTPServer) and in general we've been following PEP 8. But I don't > feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > > > > > -- > *Tom Lee */ http://tomlee.co / @tglee > > > _______________________________________________ Rust-dev mailing list > Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Fri Aug 2 22:59:13 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Sat, 3 Aug 2013 15:59:13 +1000 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC6A2C.7020500@arrownext.com> References: <51FC5CDB.6000902@mozilla.com> <51FC6A2C.7020500@arrownext.com> Message-ID: On 03/08/2013, at 12:25 PM, Jeaye wrote: > To be fair, and I like being fair, both of these are inconsistent within Rust. If functions_are_like_this then types Should_Be_Like_This or Maybe_like_this. Having different significantly different styles for types, functions and constants aids code comprehension. They are inconsistent for ergonomic reasons. ~B From me at kevincantu.org Fri Aug 2 23:14:09 2013 From: me at kevincantu.org (Kevin Cantu) Date: Fri, 2 Aug 2013 23:14:09 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> <51FC6A2C.7020500@arrownext.com> Message-ID: Ergonomic and "nearly-ASCII text slightly more than 80 chars wide" hardly seem to match at all. Does anybody have any actual evidence about whether it is easier for names to be mostly uniform, or for names of different flavors of item to be garbled in different ways? Kevin On Fri, Aug 2, 2013 at 10:59 PM, Brendan Zabarauskas wrote: > > On 03/08/2013, at 12:25 PM, Jeaye wrote: > > > To be fair, and I like being fair, both of these are inconsistent within > Rust. If functions_are_like_this then types Should_Be_Like_This or > Maybe_like_this. > > Having different significantly different styles for types, functions and > constants aids code comprehension. They are inconsistent for ergonomic > reasons. > > ~B > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ericfode at gmail.com Fri Aug 2 23:25:58 2013 From: ericfode at gmail.com (Fode) Date: Fri, 2 Aug 2013 23:25:58 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> <51FC6A2C.7020500@arrownext.com> Message-ID: +1 for java for the following reasons: Size of java community + size of pep8 community > size of .net community. The java community and the pep8 community have historically been more open and are probably more likely to interesect with our community then the .net community then the .net community is When else do you ever capitalize the first letter of an acronym and not the rest of it? On Fri, Aug 2, 2013 at 11:14 PM, Kevin Cantu wrote: > Ergonomic and "nearly-ASCII text slightly more than 80 chars wide" hardly > seem to match at all. Does anybody have any actual evidence about whether > it is easier for names to be mostly uniform, or for names of different > flavors of item to be garbled in different ways? > > > Kevin > > > > > On Fri, Aug 2, 2013 at 10:59 PM, Brendan Zabarauskas wrote: > >> >> On 03/08/2013, at 12:25 PM, Jeaye wrote: >> >> > To be fair, and I like being fair, both of these are inconsistent >> within Rust. If functions_are_like_this then types Should_Be_Like_This or >> Maybe_like_this. >> >> Having different significantly different styles for types, functions and >> constants aids code comprehension. They are inconsistent for ergonomic >> reasons. >> >> ~B >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From uther.ii at gmail.com Sat Aug 3 01:04:38 2013 From: uther.ii at gmail.com (Uther) Date: Sat, 03 Aug 2013 10:04:38 +0200 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> <51FC6A2C.7020500@arrownext.com> Message-ID: <51FCB996.5060700@gmail.com> IMO the argument of the size of the Java community is wrong since there is no "Java style" for acronyms. Java recommendations doesn't specify the case of acronyms. It just tell to avoid them if possible. If you look at the Java API, you will see that acronym notation is inconsistent : - acl, ldap, dos, ... are lowcase - html, dom, ... are upcase - xml, http, ... are some time upcase, sometimes lowcase I'm a Java user, but I strongly prefer the ".net style". The full upcase notation make it easier to distinguish acronyms, but I just don't care if a word is an acronym or not. I think it is much more useful to easily distinct words. Le 03/08/13 08:25, Fode a ?crit : > +1 for java for the following reasons: > > Size of java community + size of pep8 community > size of .net community. > The java community and the pep8 community have historically been more > open and are probably more likely to interesect with our community > then the .net community then the .net community is > When else do you ever capitalize the first letter of an acronym and > not the rest of it? > > > On Fri, Aug 2, 2013 at 11:14 PM, Kevin Cantu > wrote: > > Ergonomic and "nearly-ASCII text slightly more than 80 chars wide" > hardly seem to match at all. Does anybody have any actual > evidence about whether it is easier for names to be mostly > uniform, or for names of different flavors of item to be garbled > in different ways? > > > Kevin > > > > > On Fri, Aug 2, 2013 at 10:59 PM, Brendan Zabarauskas > > wrote: > > > On 03/08/2013, at 12:25 PM, Jeaye > wrote: > > > To be fair, and I like being fair, both of these are > inconsistent within Rust. If functions_are_like_this then > types Should_Be_Like_This or Maybe_like_this. > > Having different significantly different styles for types, > functions and constants aids code comprehension. They are > inconsistent for ergonomic reasons. > > ~B > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From armin.ronacher at active-4.com Sat Aug 3 01:13:29 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sat, 03 Aug 2013 10:13:29 +0200 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC7293.4060809@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> <51FC7293.4060809@mozilla.com> Message-ID: <51FCBBA9.8020204@active-4.com> Hi, On 03/08/2013 05:01, Patrick Walton wrote: > Yes, I meant to mention this as a possible option but forgot to. I like > this better than the .NET style alone. Just for the record: two letter acronyms are capitalized in .NET. Eg: IOStream which would also mean GC (but Arc). JFTR: I'm for Java style. Regards, Armin From jens at nockert.se Sat Aug 3 01:53:03 2013 From: jens at nockert.se (Jens Nockert) Date: Sat, 3 Aug 2013 10:53:03 +0200 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: <610DD3DF-9838-42C1-9BFE-70CC3AA48C69@nockert.se> On 3 Aug 2013, at 03:28, Patrick Walton wrote: > Thoughts/straw poll? I prefer (and use) Java-style, I think it looks slightly better. But that's probably my ObjC background talking. From thadguidry at gmail.com Sat Aug 3 06:03:44 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sat, 3 Aug 2013 08:03:44 -0500 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <610DD3DF-9838-42C1-9BFE-70CC3AA48C69@nockert.se> References: <51FC5CDB.6000902@mozilla.com> <610DD3DF-9838-42C1-9BFE-70CC3AA48C69@nockert.se> Message-ID: Everyone is already telling you. (And Brian is on a crusade for the cause already) "Make distinguishing words in a long string...easier to interpret and read." Some of those words in a long string are abbreviations and acronymns. Deciding when its an abbreviation, an acronym, a suffix, affix, prefix, etc, etc... makes your brain work harder. We as programmers try to make lives, Easier. So, we should make it easier on ourselves as well. +1 for 1st uppercase letter on words, abbreviations, and acronyms. (.NET Style) On Sat, Aug 3, 2013 at 3:53 AM, Jens Nockert wrote: > > On 3 Aug 2013, at 03:28, Patrick Walton wrote: > > > Thoughts/straw poll? > > I prefer (and use) Java-style, I think it looks slightly better. But > that's probably my ObjC background talking. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From rsollid at gmail.com Sat Aug 3 06:07:08 2013 From: rsollid at gmail.com (Reidar M. Sollid) Date: Sat, 03 Aug 2013 06:07:08 -0700 (PDT) Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: Message-ID: <1375535227897.4b062a3f@Nodemailer> This is actually the Java style as well, some of the classes from Sun are named with uppercase but that is an error not the convention. BR Reidar ? Sent from Mailbox for iPhone On Sat, Aug 3, 2013 at 3:03 PM, Thad Guidry wrote: > Everyone is already telling you. (And Brian is on a crusade for the cause > already) > "Make distinguishing words in a long string...easier to interpret and read." > Some of those words in a long string are abbreviations and acronymns. > Deciding when its an abbreviation, an acronym, a suffix, affix, prefix, > etc, etc... makes your brain work harder. We as programmers try to make > lives, Easier. > So, we should make it easier on ourselves as well. > +1 for 1st uppercase letter on words, abbreviations, and acronyms. (.NET > Style) > On Sat, Aug 3, 2013 at 3:53 AM, Jens Nockert wrote: >> >> On 3 Aug 2013, at 03:28, Patrick Walton wrote: >> >> > Thoughts/straw poll? >> >> I prefer (and use) Java-style, I think it looks slightly better. But >> that's probably my ObjC background talking. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > -- > -Thad > Thad on Freebase.com > Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From felipekde at gmail.com Sat Aug 3 08:42:01 2013 From: felipekde at gmail.com (Felipe Oliveira Carvalho) Date: Sat, 3 Aug 2013 12:42:01 -0300 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: .Net style, but using ALL CAPS when the whole name is the acronym. Examples: GC MyGc ARC XML XmlNode HTTP XmlHttpRequest Reasoning: 1. All caps acronyms are a well known typographical convention. 2. UpperCamelCase has a constraint: word boundaries are recognized by case change. This constraint makes the concatenation of two acronyms unclear. That's why you end up with names like XMLHttpRequest() while using the impossible (IMO) Java style. My suggestion allows us to use the nice typographical typographical convention (1) and have a plan to avoid the problems caused by UpperCamelCase limitation (2). I guess this style would minimize the changes needed in the code base. -- Felipe Carvalho On Aug 2, 2013 10:29 PM, "Patrick Walton" wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I > think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style > (HTTPServer) versus .NET style (HttpServer). Currently we are usually using > .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than > "Gc", because Web APIs use Java style, and because Python does (e.g. > SimpleHTTPServer) and in general we've been following PEP 8. But I don't > feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jack at metajack.im Sat Aug 3 08:49:03 2013 From: jack at metajack.im (Jack Moffitt) Date: Sat, 3 Aug 2013 09:49:03 -0600 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: > .Net style, but using ALL CAPS when the whole name is the acronym. > > Examples: These examples are more germane to Rust, and seem a little inconsistent under your rules: GC GcMut RC RcMut ARC RwArc jack. From coder543 at gmail.com Sat Aug 3 08:54:14 2013 From: coder543 at gmail.com (Josh Leverette) Date: Sat, 3 Aug 2013 10:54:14 -0500 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: What about a new style altogether? "Toggle mode caps." thisIsANormalClass thisHasAnXMLacronymInIt someXMLcool xmlHTTPawesomeClass int float infinityFloat fastInt packetToXMLconverter httpBrowser arc gc fastGC gcSlow Lowercase to start the class name, followed by an uppercase first letter for each subsequent word. When acronyms are present, the case applies to the whole acronym, lower or upper, and the following word uses the opposite case, whether for the first letter or the whole acronym. This allows for visual distinction of each word with ease, and would provide a look that uniquely identifies Rust code from any other language. The rules are simple enough once explained, so there would be no guessing as to the capitalization. The built-in, atomic, types are already following this capitalization convention, and if you stare at it long enough each day, I'm sure it will garner its own aesthetic attraction, since beauty is in the eye of the beholder. and you'd be beholding it quite a lot. Just an idea. Sincerely, Josh On Aug 3, 2013 10:42 AM, "Felipe Oliveira Carvalho" wrote: > .Net style, but using ALL CAPS when the whole name is the acronym. > > Examples: > > GC > MyGc > ARC > XML > XmlNode > HTTP > XmlHttpRequest > > Reasoning: > > 1. All caps acronyms are a well known typographical convention. > > 2. UpperCamelCase has a constraint: word boundaries are recognized by case > change. This constraint makes the concatenation of two acronyms unclear. > That's why you end up with names like XMLHttpRequest() while using the > impossible (IMO) Java style. > > My suggestion allows us to use the nice typographical typographical > convention (1) and have a plan to avoid the problems caused by > UpperCamelCase limitation (2). > > I guess this style would minimize the changes needed in the code base. > > -- > Felipe Carvalho > On Aug 2, 2013 10:29 PM, "Patrick Walton" wrote: > >> Hi everyone, >> >> Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I >> think now is as good a time as any to have the bikeshedding debate :) >> >> I've noticed two styles for acronyms in type names: Java style >> (HTTPServer) versus .NET style (HttpServer). Currently we are usually using >> .NET style, but inconsistently (e.g. ARC). We never really decided. >> >> Here are a few examples of types in each style: >> >> * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. >> >> * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. >> >> I slightly prefer Java style myself because I think "GC" looks better >> than "Gc", because Web APIs use Java style, and because Python does (e.g. >> SimpleHTTPServer) and in general we've been following PEP 8. But I don't >> feel strongly on this issue. >> >> Thoughts/straw poll? >> >> Patrick >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From coder543 at gmail.com Sat Aug 3 08:56:22 2013 From: coder543 at gmail.com (Josh Leverette) Date: Sat, 3 Aug 2013 10:56:22 -0500 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: and I meant to emphasize, an acronym uses the opposite capitalization of the previous letter, not word, as demonstrated by packetToXMLconverter. The key is defining word boundaries. Sincerely, Josh On Aug 3, 2013 10:54 AM, "Josh Leverette" wrote: > What about a new style altogether? > > "Toggle mode caps." > > thisIsANormalClass > thisHasAnXMLacronymInIt > someXMLcool > xmlHTTPawesomeClass > int > float > infinityFloat > fastInt > packetToXMLconverter > httpBrowser > arc > gc > fastGC > gcSlow > > Lowercase to start the class name, followed by an uppercase first letter > for each subsequent word. When acronyms are present, the case applies to > the whole acronym, lower or upper, and the following word uses the opposite > case, whether for the first letter or the whole acronym. > > This allows for visual distinction of each word with ease, and would > provide a look that uniquely identifies Rust code from any other language. > The rules are simple enough once explained, so there would be no guessing > as to the capitalization. The built-in, atomic, types are already following > this capitalization convention, and if you stare at it long enough each > day, I'm sure it will garner its own aesthetic attraction, since beauty is > in the eye of the beholder. and you'd be beholding it quite a lot. > > Just an idea. > > Sincerely, > Josh > On Aug 3, 2013 10:42 AM, "Felipe Oliveira Carvalho" > wrote: > >> .Net style, but using ALL CAPS when the whole name is the acronym. >> >> Examples: >> >> GC >> MyGc >> ARC >> XML >> XmlNode >> HTTP >> XmlHttpRequest >> >> Reasoning: >> >> 1. All caps acronyms are a well known typographical convention. >> >> 2. UpperCamelCase has a constraint: word boundaries are recognized by >> case change. This constraint makes the concatenation of two acronyms >> unclear. That's why you end up with names like XMLHttpRequest() while using >> the impossible (IMO) Java style. >> >> My suggestion allows us to use the nice typographical typographical >> convention (1) and have a plan to avoid the problems caused by >> UpperCamelCase limitation (2). >> >> I guess this style would minimize the changes needed in the code base. >> >> -- >> Felipe Carvalho >> On Aug 2, 2013 10:29 PM, "Patrick Walton" wrote: >> >>> Hi everyone, >>> >>> Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. >>> I think now is as good a time as any to have the bikeshedding debate :) >>> >>> I've noticed two styles for acronyms in type names: Java style >>> (HTTPServer) versus .NET style (HttpServer). Currently we are usually using >>> .NET style, but inconsistently (e.g. ARC). We never really decided. >>> >>> Here are a few examples of types in each style: >>> >>> * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. >>> >>> * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. >>> >>> I slightly prefer Java style myself because I think "GC" looks better >>> than "Gc", because Web APIs use Java style, and because Python does (e.g. >>> SimpleHTTPServer) and in general we've been following PEP 8. But I don't >>> feel strongly on this issue. >>> >>> Thoughts/straw poll? >>> >>> Patrick >>> ______________________________**_________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/**listinfo/rust-dev >>> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at kevincantu.org Sat Aug 3 10:03:36 2013 From: me at kevincantu.org (Kevin Cantu) Date: Sat, 3 Aug 2013 10:03:36 -0700 Subject: [rust-dev] Help with a trivial TCP client example needed In-Reply-To: <51FB6967.4050401@gmail.com> References: <51FB6967.4050401@gmail.com> Message-ID: Inspired by your question, I'm now eyeballing what Servo does in the `rust-http-client` submodulel... https://github.com/mozilla-servo/rust-http-client Kevin On Fri, Aug 2, 2013 at 1:10 AM, Ivan Risti? wrote: > I am starting to play with Rust, but I got stuck early on with a trivial > TCP client example. (There's a few server examples out there, but I > couldn't find a single working client anywhere. I tried the archives, > the tests, etc.) > > My naive approach sends some data to the server and then attempts to > read, but socket.read() always times out. I have verified that the > server is receiving the request and responding to it. > > I came across a couple of tickets that suggest that I might be handling > the event loop incorrectly, but I don't know enough to fix the code. > > Your help is appreciated. Thanks. > > extern mod extra; > use extra::net::{ip, tcp}; > use extra::uv; > use std::str; > > fn main() { > let ip_addr = ip::v4::parse_addr("204.232.212.130"); > let iotask = &uv::global_loop::get(); > > let r = tcp::connect(ip_addr, 80, iotask); > match(r) { > Err(err) => { > println(fmt!("Connection failed: %?", err)) > } > > Ok(socket) => { > let r = socket.write(bytes!("GET / HTTP/1.0\r\n\r\n").to_owned()); > if (r.is_err()) { > println(fmt!("Write error: %?", r.get_err())) > } else { > let r = socket.read(2000); > if (r.is_err()) { > println(fmt!("Read error: %?", r.get_err())) > } else { > let bytes = r.get(); > println(str::from_bytes(bytes)); > } > } > } > } > } > > -- > Ivan > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pwalton at mozilla.com Sat Aug 3 11:31:39 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 03 Aug 2013 11:31:39 -0700 Subject: [rust-dev] Help with a trivial TCP client example needed In-Reply-To: <51FB6967.4050401@gmail.com> References: <51FB6967.4050401@gmail.com> Message-ID: <51FD4C8B.7070405@mozilla.com> On 8/2/13 1:10 AM, Ivan Risti? wrote: > I am starting to play with Rust, but I got stuck early on with a trivial > TCP client example. (There's a few server examples out there, but I > couldn't find a single working client anywhere. I tried the archives, > the tests, etc.) Sounds like #3599: https://github.com/mozilla/rust/issues/3599 This is going to be fixed with the new scheduler. Patrick From ivan.ristic at gmail.com Sat Aug 3 12:15:35 2013 From: ivan.ristic at gmail.com (=?UTF-8?B?SXZhbiBSaXN0acSH?=) Date: Sat, 03 Aug 2013 20:15:35 +0100 Subject: [rust-dev] Help with a trivial TCP client example needed In-Reply-To: References: <51FB6967.4050401@gmail.com> Message-ID: <51FD56D7.3060602@gmail.com> On 03/08/2013 18:03, Kevin Cantu wrote: > Inspired by your question, I'm now eyeballing what Servo does in the > `rust-http-client` submodulel... > https://github.com/mozilla-servo/rust-http-client Thanks for the pointer. It does not compile for me (using v0.7), but the source code was very useful. I rewrote my test code to use non-blocking I/O, see below. (Presumably, the use of non-blocking I/O sidesteps #3599.) extern mod extra; use extra::net::{ip, tcp}; use extra::net::tcp::TcpErrData; use extra::uv; use std::str; use std::result; fn main() { let ip_addr = ip::v4::parse_addr("204.232.212.130"); let iotask = &uv::global_loop::get(); let r = tcp::connect(ip_addr, 80, iotask); if (r.is_err()) { println(fmt!("Connection failed: %?", r.get_err())); return; } let socket = result::unwrap(r); let r = socket.write(bytes!("GET / HTTP/1.0\r\n\r\n").to_owned()); if (r.is_err()) { println(fmt!("Write error: %?", r.get_err())); return; } let r = socket.read_start(); if (r.is_err()) { println(fmt!("Read error: %?", r.get_err())); return; } let read_port = r.get(); loop { let r = read_port.recv(); if (r.is_err()) { socket.read_stop(); match r { result::Err(TcpErrData{err_name: ~"EOF", _}) => { // Not an error; the end of stream. return; } _ => { // Genuine error. println(fmt!("Read error: %?", r.get_err())); return; } } } let bytes = r.get(); println(str::from_bytes(bytes)); } } > > > Kevin > > > On Fri, Aug 2, 2013 at 1:10 AM, Ivan Risti? wrote: >> I am starting to play with Rust, but I got stuck early on with a trivial >> TCP client example. (There's a few server examples out there, but I >> couldn't find a single working client anywhere. I tried the archives, >> the tests, etc.) >> >> My naive approach sends some data to the server and then attempts to >> read, but socket.read() always times out. I have verified that the >> server is receiving the request and responding to it. >> >> I came across a couple of tickets that suggest that I might be handling >> the event loop incorrectly, but I don't know enough to fix the code. >> >> Your help is appreciated. Thanks. >> >> extern mod extra; >> use extra::net::{ip, tcp}; >> use extra::uv; >> use std::str; >> >> fn main() { >> let ip_addr = ip::v4::parse_addr("204.232.212.130"); >> let iotask = &uv::global_loop::get(); >> >> let r = tcp::connect(ip_addr, 80, iotask); >> match(r) { >> Err(err) => { >> println(fmt!("Connection failed: %?", err)) >> } >> >> Ok(socket) => { >> let r = socket.write(bytes!("GET / HTTP/1.0\r\n\r\n").to_owned()); >> if (r.is_err()) { >> println(fmt!("Write error: %?", r.get_err())) >> } else { >> let r = socket.read(2000); >> if (r.is_err()) { >> println(fmt!("Read error: %?", r.get_err())) >> } else { >> let bytes = r.get(); >> println(str::from_bytes(bytes)); >> } >> } >> } >> } >> } >> >> -- >> Ivan >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev -- Ivan From steshaw at gmail.com Sat Aug 3 14:44:42 2013 From: steshaw at gmail.com (Steven Shaw) Date: Sun, 4 Aug 2013 07:44:42 +1000 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: On 4 August 2013 01:54, Josh Leverette wrote: > What about a new style altogether? > > "Toggle mode caps." > > thisIsANormalClass > thisHasAnXMLacronymInIt > someXMLcool > xmlHTTPawesomeClass > int > float > infinityFloat > fastInt > packetToXMLconverter > httpBrowser > arc > gc > fastGC > gcSlow > Rust outsider here but this is nice. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kballard at gmail.com Sat Aug 3 18:18:15 2013 From: kballard at gmail.com (Kevin Ballard) Date: Sat, 3 Aug 2013 18:18:15 -0700 Subject: [rust-dev] Proposal for clarifying the iterator protocol Message-ID: The iterator protocol, as I'm sure you're aware, is the protocol that defines the behavior of the Iterator trait. Unfortunately, at the moment the trait does not document what happens if you call `.next()` on an iterator after a previous call has returned `None`. According to Daniel Micay, the intention was that the iterator would return `None` forever. However, this is not guaranteed by at least one iterator adaptor (Scan), nor is it documented. Furthermore, no thought has been given to what happens if an iterator pipeline has side-effects. A trivial example of the side-effect problem is this: let x = [1,2,3]; let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if *st { *st = false; Some(x) } else { None } }); (it.next(), it.next(), it.next()) This results in `(Some(1), None, None)` but it prints out &1 &2 &3 After giving it some thought, I came up with 3 possible definitions for behavior in this case: 1. Once `.next()` has returned `None`, it will return None forever. Furthermore, calls to `.next()` after `None` has been returned will not trigger side-effects in the iterator pipeline. This means that once `.next()` has returned `None`, it becomes idempotent. This is most likely going to be what people will assume the iterator protocol defines, in the absence of any explicit statement. What's more, they probably won't even consider the side-effects case. Implementing this will require care be given to every single iterator and iterator adaptor. Most iterators will probably behave like this (unless they use a user-supplied closure), but a number of different iterator adaptors will need to track this explicitly with a bool flag. It's likely that user-supplied iterator adaptors will forget to enforce this and will therefore behave subtlely wrong in the face of side-effects. 2. Once `.next()` has returned `None`, it will return `None` forever. No statement is made regarding side-effects. This is what most people will think they're assuming, if asked. The danger here is that they will almost certainly actaully assume #1, and thus may write subtlely incorrect code if they're given an iterator pipeline with side-effects. This is easier to implement than #1. Most iterators will do this already. Iterator adaptors will generally only have to take care when they use a user-supplied closure (e.g. `scan()`). 3. The behavior of `.next()` after `None` has been returned is left undefined. Individual iterators may choose to define behavior here however they see fit. This is what we actually have implemented in the standard libraries today. It's also by far the easiest to implement, as iterators and adaptors may simply choose to not define any particular behavior. This is made more attractive by the fact that some iterators may choose to actually define behavior that's different than "return `None` forever". For example, a user may write an iterator that wraps non-blocking I/O, returning `None` when there's no data available and returning `Some(x)` again once more data comes in. Or if you don't like that example, they could write an iterator that may be updated to contain more data after being exhausted. The downside is that users may assume #1 when #3 holds, which is why this needs to be documented properly. --- I believe that #3 is the right behavior to define. This gives the most flexibility to individual iterators, and we can provide an iterator adaptor that gives any iterator the behavior defined by #1 (see Fuse in PR #8276 ). I am not strongly opposed to defining #1 instead, but I am mildly worried about the likelihood that users will implement iterators that don't have this guarantee, as this is not something that can be statically checked by the compiler. What's more, if an iterator breaks this guarantee, the problem will show up in the code that calls it, rather than in the iterator itself, which may make debugging harder. I am strongly opposed to #2. If we guarantee that an iterator that returns `None` once will return `None` forever, users will assume that this means that `.next()` becomes idempotent (with regards to side-effects) after `None` is returned, but this will not be true. Furthermore, users will probably not even realize they've made a bad assumption, as most users will not be thinking about side-effects when consuming iterators. I've already gone ahead and implemented #3 in pull request #8276 . -Kevin -------------- next part -------------- An HTML attachment was scrubbed... URL: From kballard at gmail.com Sat Aug 3 19:04:59 2013 From: kballard at gmail.com (Kevin Ballard) Date: Sat, 3 Aug 2013 19:04:59 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: +1 on "Java style" On Fri, Aug 2, 2013 at 6:28 PM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I > think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style > (HTTPServer) versus .NET style (HttpServer). Currently we are usually using > .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than > "Gc", because Web APIs use Java style, and because Python does (e.g. > SimpleHTTPServer) and in general we've been following PEP 8. But I don't > feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sat Aug 3 22:49:46 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 4 Aug 2013 01:49:46 -0400 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard wrote: > The iterator protocol, as I'm sure you're aware, is the protocol that > defines the behavior of the Iterator trait. Unfortunately, at the moment the > trait does not document what happens if you call `.next()` on an iterator > after a previous call has returned `None`. According to Daniel Micay, the > intention was that the iterator would return `None` forever. However, this > is not guaranteed by at least one iterator adaptor (Scan), nor is it > documented. Furthermore, no thought has been given to what happens if an > iterator pipeline has side-effects. A trivial example of the side-effect > problem is this: > > let x = [1,2,3]; > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if > *st { *st = false; Some(x) } else { None } }); > (it.next(), it.next(), it.next()) > > This results in `(Some(1), None, None)` but it prints out > > &1 > &2 > &3 > > After giving it some thought, I came up with 3 possible definitions for > behavior in this case: > > 1. Once `.next()` has returned `None`, it will return None forever. > Furthermore, calls to `.next()` after `None` has been returned will not > trigger side-effects in the iterator pipeline. This means that once > `.next()` has returned `None`, it becomes idempotent. > > This is most likely going to be what people will assume the iterator > protocol defines, in the absence of any explicit statement. What's more, > they probably won't even consider the side-effects case. > > Implementing this will require care be given to every single iterator and > iterator adaptor. Most iterators will probably behave like this (unless they > use a user-supplied closure), but a number of different iterator adaptors > will need to track this explicitly with a bool flag. It's likely that > user-supplied iterator adaptors will forget to enforce this and will > therefore behave subtlely wrong in the face of side-effects. > > 2. Once `.next()` has returned `None`, it will return `None` forever. No > statement is made regarding side-effects. > > This is what most people will think they're assuming, if asked. The > danger here is that they will almost certainly actaully assume #1, and thus > may write subtlely incorrect code if they're given an iterator pipeline with > side-effects. > > This is easier to implement than #1. Most iterators will do this already. > Iterator adaptors will generally only have to take care when they use a > user-supplied closure (e.g. `scan()`). > > 3. The behavior of `.next()` after `None` has been returned is left > undefined. Individual iterators may choose to define behavior here however > they see fit. > > This is what we actually have implemented in the standard libraries > today. It's also by far the easiest to implement, as iterators and adaptors > may simply choose to not define any particular behavior. > > This is made more attractive by the fact that some iterators may choose > to actually define behavior that's different than "return `None` forever". > For example, a user may write an iterator that wraps non-blocking I/O, > returning `None` when there's no data available and returning `Some(x)` > again once more data comes in. Or if you don't like that example, they could > write an iterator that may be updated to contain more data after being > exhausted. > > The downside is that users may assume #1 when #3 holds, which is why this > needs to be documented properly. > > --- > > I believe that #3 is the right behavior to define. This gives the most > flexibility to individual iterators, and we can provide an iterator adaptor > that gives any iterator the behavior defined by #1 (see Fuse in PR #8276). > > I am not strongly opposed to defining #1 instead, but I am mildly worried > about the likelihood that users will implement iterators that don't have > this guarantee, as this is not something that can be statically checked by > the compiler. What's more, if an iterator breaks this guarantee, the problem > will show up in the code that calls it, rather than in the iterator itself, > which may make debugging harder. > > I am strongly opposed to #2. If we guarantee that an iterator that returns > `None` once will return `None` forever, users will assume that this means > that `.next()` becomes idempotent (with regards to side-effects) after > `None` is returned, but this will not be true. Furthermore, users will > probably not even realize they've made a bad assumption, as most users will > not be thinking about side-effects when consuming iterators. > > I've already gone ahead and implemented #3 in pull request #8276. > > -Kevin I'm leaning towards #2 or #3, mostly because adaptors *not* dispatching to the underlying next() implementation are too complex. I took a look at the behaviour of Python's iterators in these corner cases as good baseline for comparison: ~~~ >>> def peek(it): ... for x in it: ... print(x) ... yield x ... >>> xs = [1, 2, 3] >>> ys = [1, 2, 3, 4, 5] ~~~ You can tell their `zip` function short-circuits, and simply dispatches to the underlying implementations. Rust's `zip` is similar but doesn't currently short-circuit (it might as well). ~~~ >>> it = zip(peek(ys), xs) >>> next(it) 1 (1, 1) >>> next(it) 2 (2, 2) >>> next(it) 3 (3, 3) >>> next(it) 4 Traceback (most recent call last): File "", line 1, in StopIteration >>> next(it) 5 Traceback (most recent call last): File "", line 1, in StopIteration >>> next(it) Traceback (most recent call last): File "", line 1, in StopIteration >>> it = zip(xs, peek(ys)) >>> next(it) 1 (1, 1) >>> next(it) 2 (2, 2) >>> next(it) 3 (3, 3) >>> next(it) Traceback (most recent call last): File "", line 1, in StopIteration ~~~ It also makes no attempt to store whether it has stopped internally, and will start yielding again if each iterator yields an element when zip asks for them one by one (keeping in mind that it short-circuits). Most other language keep `hasNext` and `next` separate (D and Scala, among others) leading to more corner cases, and they do not seem to clearly define the semantics for side effects down the pipeline. http://dlang.org/phobos/std_range.html http://www.scala-lang.org/api/current/scala/collection/Iterator.html From corey at octayn.net Sat Aug 3 23:29:06 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 4 Aug 2013 02:29:06 -0400 Subject: [rust-dev] Getting fully qualified name from a path Message-ID: Hi all, Another roadbump with rustdoc_ng, but we're getting real close! When a reference to a type in an external crate is found, I'd like to include the fully-qualified name in the JSON. This will enable easier hyperlinking between crates. However, I'm not sure where I can get the fully-qualified name, if anywhere. I'd expect to find this functionality in resolve somewhere, since it'd need to look into the modules that are in scope and determine which it is/where it comes from etc. Is it possible? From me at chrismorgan.info Sun Aug 4 04:16:38 2013 From: me at chrismorgan.info (Chris Morgan) Date: Sun, 4 Aug 2013 21:16:38 +1000 Subject: [rust-dev] Help with a trivial TCP client example needed In-Reply-To: <51FD56D7.3060602@gmail.com> References: <51FB6967.4050401@gmail.com> <51FD56D7.3060602@gmail.com> Message-ID: Your example looked like it should be correct, but I'm not going to figure out why it's not working, because extra::net no longer exists in the Rust development head. Here is an example using the new runtime TCP library, which is currently in std::rt::io::net. Whether it compiles on Rust 0.7 or not (it doesn't quite, due to the buf.slice_to call), this example will not run there; the newrt TCP was broken at that time. This example is also just about to be slightly out of date; https://github.com/mozilla/rust/pull/8243 is changing `Ipv4(a, b, c, d, p)` to `SocketAddr { ip: Ipv4Addr(a, b, c, d), port: p }`. You will need to run this with the environment variable RUST_NEWRT=1 or you'll meet with a terrible fate, won't you. use std::rt::io::net::ip::Ipv4; use std::rt::io::net::tcp::TcpStream; use std::rt::io::{Reader, Writer}; use std::str; fn main() { let mut stream = TcpStream::connect(Ipv4(204, 232, 212, 130, 80)).expect("failed to connect :-("); stream.write(bytes!("GET / HTTP/1.0\r\n\r\n").to_owned()); let mut buf = [0u8, ..2000]; match stream.read(buf) { None => fail!("Read error :-("), Some(bytes_read) => { println(str::from_bytes(buf.slice_to(bytes_read))); } } } Whether this works for thee or no, it doth for me and prints a perfectly normal HTTP response. Note that while the old system used a Result for `connect` and `read`, the new one uses conditions and returns an Option. There are some details in the std::rt::io docs (src/libstd/rt/io/mod.rs). On Fri, Aug 2, 2013 at 1:10 AM, Ivan Risti? wrote: > I am starting to play with Rust, but I got stuck early on with a trivial > TCP client example. (There's a few server examples out there, but I > couldn't find a single working client anywhere. I tried the archives, > the tests, etc.) > > My naive approach sends some data to the server and then attempts to > read, but socket.read() always times out. I have verified that the > server is receiving the request and responding to it. > > I came across a couple of tickets that suggest that I might be handling > the event loop incorrectly, but I don't know enough to fix the code. > > Your help is appreciated. Thanks. From j.boggiano at seld.be Sun Aug 4 04:23:33 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Sun, 04 Aug 2013 13:23:33 +0200 Subject: [rust-dev] Zurich/CH Meetup Message-ID: <51FE39B5.1040600@seld.be> Heya, I know this is a long shot given I don't see many EU people on IRC, but would there be anyone around Zurich or in Switzerland at all that wants to gather up for a small Rust meetup (or we can just go have a beer)? Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From me at chrismorgan.info Sun Aug 4 05:54:19 2013 From: me at chrismorgan.info (Chris Morgan) Date: Sun, 4 Aug 2013 22:54:19 +1000 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> Message-ID: There seems to be a basic assumption of ASCII identifiers. Hey, this ain't the eighties! Let's have us an X??H???Request. Absolutely clear with no scope for misunderstanding in either direction: G?; R?; A??; SimpleH???Server. Monospace font support is a little poor, but I'm sure they'll fix that up once the desire is demonstrated. Q and X don't have small-caps variants in Unicode, so acronyms will be banned from having a Q or an X in the middle. * * * * * Between the primary contenders, I end up with no firm opinion myself, but I have come up with some arguments in both directions, a couple of which haven't arisen here yet. .NET style: - Simpler to reason about and say what should be done, especially if applied entirely purely (Io, Gc, Rc) with no exceptions (not even for IO). - More convenient for some tools (e.g. Eclipse, Emacs) to work with as they have clear word boundaries there. - Natural language can be converted to it regardless of case, entirely generally (handy in code generation, reducing duplication of names). Java style (not capitalising chained acronyms): - Argh! I have this thing, what do I name it? - Is there a reason why it's XMLHttpRequest rather than XmlHTTPRequest or XmlHttpRequest? - (The solution may be to define what should be done, but it might be difficult to convince people to do it that way.) Java style (but capitalising all acronyms): - Less ugly in general - More ugly if acronyms are chained - Easier to type (hold down the shift key for most of `GC` leading to two presses, rather than three; ditto for `SimpleHTTPServer`) You can't meaningfully convert from any of these forms of identifier to natural language; .NET fails on any acronyms, Java fails on chained acronyms. Only with an identifier style like XML_HTTP_Request can one do that. (Or small caps.) For myself, I'm content with the current convention, so my HTTP server has things like HttpVersionNotSupported and header case normalisation of "Www-Authenticate". The rules are nice and easy to apply, while it'd take a _little_ more work to produce the likes of HTTPVersionNotSupported correctly, and it simply can't be done for unknown headers?they need something like the .NET style. Sure, that isn't for identifiers, but having something recognisable like that in other parts of the language is likely a good plan. I still wonder, though: should a certain struct be named ETag or Etag? If going with .NET, I (as one who should clearly have influence approaching zero in such matters) would urge not to allow any exceptions. It's much simpler to maintain such a position. In the end, I really don't have any strong preference, so I'd probably opt for laziness and keeping the current convention. That is, assuming no one wants small caps identifiers. From jfager at gmail.com Sun Aug 4 06:18:28 2013 From: jfager at gmail.com (Jason Fager) Date: Sun, 4 Aug 2013 09:18:28 -0400 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: The new for loop already assumes #2, right? let x = [1,2,3]; let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if *st { *st = false; Some(x) } else { None } }); for i in it { printfln!("from for loop: %?", i); } Which produces: &1 from for loop: 1 &2 On Sun, Aug 4, 2013 at 1:49 AM, Daniel Micay wrote: > On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard wrote: > > The iterator protocol, as I'm sure you're aware, is the protocol that > > defines the behavior of the Iterator trait. Unfortunately, at the moment > the > > trait does not document what happens if you call `.next()` on an iterator > > after a previous call has returned `None`. According to Daniel Micay, the > > intention was that the iterator would return `None` forever. However, > this > > is not guaranteed by at least one iterator adaptor (Scan), nor is it > > documented. Furthermore, no thought has been given to what happens if an > > iterator pipeline has side-effects. A trivial example of the side-effect > > problem is this: > > > > let x = [1,2,3]; > > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { > if > > *st { *st = false; Some(x) } else { None } }); > > (it.next(), it.next(), it.next()) > > > > This results in `(Some(1), None, None)` but it prints out > > > > &1 > > &2 > > &3 > > > > After giving it some thought, I came up with 3 possible definitions for > > behavior in this case: > > > > 1. Once `.next()` has returned `None`, it will return None forever. > > Furthermore, calls to `.next()` after `None` has been returned will not > > trigger side-effects in the iterator pipeline. This means that once > > `.next()` has returned `None`, it becomes idempotent. > > > > This is most likely going to be what people will assume the iterator > > protocol defines, in the absence of any explicit statement. What's more, > > they probably won't even consider the side-effects case. > > > > Implementing this will require care be given to every single iterator > and > > iterator adaptor. Most iterators will probably behave like this (unless > they > > use a user-supplied closure), but a number of different iterator adaptors > > will need to track this explicitly with a bool flag. It's likely that > > user-supplied iterator adaptors will forget to enforce this and will > > therefore behave subtlely wrong in the face of side-effects. > > > > 2. Once `.next()` has returned `None`, it will return `None` forever. No > > statement is made regarding side-effects. > > > > This is what most people will think they're assuming, if asked. The > > danger here is that they will almost certainly actaully assume #1, and > thus > > may write subtlely incorrect code if they're given an iterator pipeline > with > > side-effects. > > > > This is easier to implement than #1. Most iterators will do this > already. > > Iterator adaptors will generally only have to take care when they use a > > user-supplied closure (e.g. `scan()`). > > > > 3. The behavior of `.next()` after `None` has been returned is left > > undefined. Individual iterators may choose to define behavior here > however > > they see fit. > > > > This is what we actually have implemented in the standard libraries > > today. It's also by far the easiest to implement, as iterators and > adaptors > > may simply choose to not define any particular behavior. > > > > This is made more attractive by the fact that some iterators may > choose > > to actually define behavior that's different than "return `None` > forever". > > For example, a user may write an iterator that wraps non-blocking I/O, > > returning `None` when there's no data available and returning `Some(x)` > > again once more data comes in. Or if you don't like that example, they > could > > write an iterator that may be updated to contain more data after being > > exhausted. > > > > The downside is that users may assume #1 when #3 holds, which is why > this > > needs to be documented properly. > > > > --- > > > > I believe that #3 is the right behavior to define. This gives the most > > flexibility to individual iterators, and we can provide an iterator > adaptor > > that gives any iterator the behavior defined by #1 (see Fuse in PR > #8276). > > > > I am not strongly opposed to defining #1 instead, but I am mildly worried > > about the likelihood that users will implement iterators that don't have > > this guarantee, as this is not something that can be statically checked > by > > the compiler. What's more, if an iterator breaks this guarantee, the > problem > > will show up in the code that calls it, rather than in the iterator > itself, > > which may make debugging harder. > > > > I am strongly opposed to #2. If we guarantee that an iterator that > returns > > `None` once will return `None` forever, users will assume that this means > > that `.next()` becomes idempotent (with regards to side-effects) after > > `None` is returned, but this will not be true. Furthermore, users will > > probably not even realize they've made a bad assumption, as most users > will > > not be thinking about side-effects when consuming iterators. > > > > I've already gone ahead and implemented #3 in pull request #8276. > > > > -Kevin > > I'm leaning towards #2 or #3, mostly because adaptors *not* > dispatching to the underlying next() implementation are too complex. > > I took a look at the behaviour of Python's iterators in these corner > cases as good baseline for comparison: > > ~~~ > >>> def peek(it): > ... for x in it: > ... print(x) > ... yield x > ... > >>> xs = [1, 2, 3] > >>> ys = [1, 2, 3, 4, 5] > ~~~ > > You can tell their `zip` function short-circuits, and simply > dispatches to the underlying implementations. Rust's `zip` is similar > but doesn't currently short-circuit (it might as well). > > ~~~ > >>> it = zip(peek(ys), xs) > >>> next(it) > 1 > (1, 1) > >>> next(it) > 2 > (2, 2) > >>> next(it) > 3 > (3, 3) > >>> next(it) > 4 > Traceback (most recent call last): > File "", line 1, in > StopIteration > >>> next(it) > 5 > Traceback (most recent call last): > File "", line 1, in > StopIteration > >>> next(it) > Traceback (most recent call last): > File "", line 1, in > StopIteration > >>> it = zip(xs, peek(ys)) > >>> next(it) > 1 > (1, 1) > >>> next(it) > 2 > (2, 2) > >>> next(it) > 3 > (3, 3) > >>> next(it) > Traceback (most recent call last): > File "", line 1, in > StopIteration > ~~~ > > It also makes no attempt to store whether it has stopped internally, > and will start yielding again if each iterator yields an element when > zip asks for them one by one (keeping in mind that it short-circuits). > > Most other language keep `hasNext` and `next` separate (D and Scala, > among others) leading to more corner cases, and they do not seem to > clearly define the semantics for side effects down the pipeline. > > http://dlang.org/phobos/std_range.html > http://www.scala-lang.org/api/current/scala/collection/Iterator.html > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Sun Aug 4 15:23:06 2013 From: kevin at sb.org (Kevin Ballard) Date: Sun, 4 Aug 2013 15:23:06 -0700 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: The new for loop works with all 3 of these. Your output shows that it queried .next() twice, and got a single Some(1) result back. Once it gets None, it never calls .next() again, whereas the 3 behaviors stated previously are exclusively concerned with what happens if you call .next() again after it has already returned None. -Kevin P.S. I changed the email address that I'm subscribed to this list with, so apologies for any potential confusion. On Aug 4, 2013, at 6:18 AM, Jason Fager wrote: > The new for loop already assumes #2, right? > > let x = [1,2,3]; > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if *st { *st = false; Some(x) } else { None } }); > > for i in it { > printfln!("from for loop: %?", i); > } > > > Which produces: > > &1 > from for loop: 1 > &2 > > > > On Sun, Aug 4, 2013 at 1:49 AM, Daniel Micay wrote: > On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard wrote: > > The iterator protocol, as I'm sure you're aware, is the protocol that > > defines the behavior of the Iterator trait. Unfortunately, at the moment the > > trait does not document what happens if you call `.next()` on an iterator > > after a previous call has returned `None`. According to Daniel Micay, the > > intention was that the iterator would return `None` forever. However, this > > is not guaranteed by at least one iterator adaptor (Scan), nor is it > > documented. Furthermore, no thought has been given to what happens if an > > iterator pipeline has side-effects. A trivial example of the side-effect > > problem is this: > > > > let x = [1,2,3]; > > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if > > *st { *st = false; Some(x) } else { None } }); > > (it.next(), it.next(), it.next()) > > > > This results in `(Some(1), None, None)` but it prints out > > > > &1 > > &2 > > &3 > > > > After giving it some thought, I came up with 3 possible definitions for > > behavior in this case: > > > > 1. Once `.next()` has returned `None`, it will return None forever. > > Furthermore, calls to `.next()` after `None` has been returned will not > > trigger side-effects in the iterator pipeline. This means that once > > `.next()` has returned `None`, it becomes idempotent. > > > > This is most likely going to be what people will assume the iterator > > protocol defines, in the absence of any explicit statement. What's more, > > they probably won't even consider the side-effects case. > > > > Implementing this will require care be given to every single iterator and > > iterator adaptor. Most iterators will probably behave like this (unless they > > use a user-supplied closure), but a number of different iterator adaptors > > will need to track this explicitly with a bool flag. It's likely that > > user-supplied iterator adaptors will forget to enforce this and will > > therefore behave subtlely wrong in the face of side-effects. > > > > 2. Once `.next()` has returned `None`, it will return `None` forever. No > > statement is made regarding side-effects. > > > > This is what most people will think they're assuming, if asked. The > > danger here is that they will almost certainly actaully assume #1, and thus > > may write subtlely incorrect code if they're given an iterator pipeline with > > side-effects. > > > > This is easier to implement than #1. Most iterators will do this already. > > Iterator adaptors will generally only have to take care when they use a > > user-supplied closure (e.g. `scan()`). > > > > 3. The behavior of `.next()` after `None` has been returned is left > > undefined. Individual iterators may choose to define behavior here however > > they see fit. > > > > This is what we actually have implemented in the standard libraries > > today. It's also by far the easiest to implement, as iterators and adaptors > > may simply choose to not define any particular behavior. > > > > This is made more attractive by the fact that some iterators may choose > > to actually define behavior that's different than "return `None` forever". > > For example, a user may write an iterator that wraps non-blocking I/O, > > returning `None` when there's no data available and returning `Some(x)` > > again once more data comes in. Or if you don't like that example, they could > > write an iterator that may be updated to contain more data after being > > exhausted. > > > > The downside is that users may assume #1 when #3 holds, which is why this > > needs to be documented properly. > > > > --- > > > > I believe that #3 is the right behavior to define. This gives the most > > flexibility to individual iterators, and we can provide an iterator adaptor > > that gives any iterator the behavior defined by #1 (see Fuse in PR #8276). > > > > I am not strongly opposed to defining #1 instead, but I am mildly worried > > about the likelihood that users will implement iterators that don't have > > this guarantee, as this is not something that can be statically checked by > > the compiler. What's more, if an iterator breaks this guarantee, the problem > > will show up in the code that calls it, rather than in the iterator itself, > > which may make debugging harder. > > > > I am strongly opposed to #2. If we guarantee that an iterator that returns > > `None` once will return `None` forever, users will assume that this means > > that `.next()` becomes idempotent (with regards to side-effects) after > > `None` is returned, but this will not be true. Furthermore, users will > > probably not even realize they've made a bad assumption, as most users will > > not be thinking about side-effects when consuming iterators. > > > > I've already gone ahead and implemented #3 in pull request #8276. > > > > -Kevin > > I'm leaning towards #2 or #3, mostly because adaptors *not* > dispatching to the underlying next() implementation are too complex. > > I took a look at the behaviour of Python's iterators in these corner > cases as good baseline for comparison: > > ~~~ > >>> def peek(it): > ... for x in it: > ... print(x) > ... yield x > ... > >>> xs = [1, 2, 3] > >>> ys = [1, 2, 3, 4, 5] > ~~~ > > You can tell their `zip` function short-circuits, and simply > dispatches to the underlying implementations. Rust's `zip` is similar > but doesn't currently short-circuit (it might as well). > > ~~~ > >>> it = zip(peek(ys), xs) > >>> next(it) > 1 > (1, 1) > >>> next(it) > 2 > (2, 2) > >>> next(it) > 3 > (3, 3) > >>> next(it) > 4 > Traceback (most recent call last): > File "", line 1, in > StopIteration > >>> next(it) > 5 > Traceback (most recent call last): > File "", line 1, in > StopIteration > >>> next(it) > Traceback (most recent call last): > File "", line 1, in > StopIteration > >>> it = zip(xs, peek(ys)) > >>> next(it) > 1 > (1, 1) > >>> next(it) > 2 > (2, 2) > >>> next(it) > 3 > (3, 3) > >>> next(it) > Traceback (most recent call last): > File "", line 1, in > StopIteration > ~~~ > > It also makes no attempt to store whether it has stopped internally, > and will start yielding again if each iterator yields an element when > zip asks for them one by one (keeping in mind that it short-circuits). > > Most other language keep `hasNext` and `next` separate (D and Scala, > among others) leading to more corner cases, and they do not seem to > clearly define the semantics for side effects down the pipeline. > > http://dlang.org/phobos/std_range.html > http://www.scala-lang.org/api/current/scala/collection/Iterator.html > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From jfager at gmail.com Sun Aug 4 16:45:06 2013 From: jfager at gmail.com (Jason Fager) Date: Sun, 4 Aug 2013 19:45:06 -0400 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: Of course. I think I'm reacting more to the possible use cases you described for option 3 than the actual meaning of it. It seems like a really bad idea to design iterators that would take advantage of the undefined behavior, not least b/c it's unexpected and not supported by the most pervasive client of the iterator protocol (the for loop, in the sense of actually iterating through all elements available through the iterator), but that doesn't mean option 3 is in itself the wrong thing to do. But addressing the use cases you mentioned, if you need that kind of functionality, shouldn't you be hoisting the iterator's return type into its own Option? i.e., an Iterator should be become an Iterator>? On Sun, Aug 4, 2013 at 6:23 PM, Kevin Ballard wrote: > The new for loop works with all 3 of these. Your output shows that it > queried .next() twice, and got a single Some(1) result back. Once it gets > None, it never calls .next() again, whereas the 3 behaviors stated > previously are exclusively concerned with what happens if you call .next() > again after it has already returned None. > > -Kevin > > P.S. I changed the email address that I'm subscribed to this list with, so > apologies for any potential confusion. > > On Aug 4, 2013, at 6:18 AM, Jason Fager wrote: > > The new for loop already assumes #2, right? > > let x = [1,2,3]; > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if > *st { *st = false; Some(x) } else { None } }); > > for i in it { > printfln!("from for loop: %?", i); > } > > > Which produces: > > &1 > from for loop: 1 > &2 > > > > On Sun, Aug 4, 2013 at 1:49 AM, Daniel Micay wrote: > >> On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard wrote: >> > The iterator protocol, as I'm sure you're aware, is the protocol that >> > defines the behavior of the Iterator trait. Unfortunately, at the >> moment the >> > trait does not document what happens if you call `.next()` on an >> iterator >> > after a previous call has returned `None`. According to Daniel Micay, >> the >> > intention was that the iterator would return `None` forever. However, >> this >> > is not guaranteed by at least one iterator adaptor (Scan), nor is it >> > documented. Furthermore, no thought has been given to what happens if an >> > iterator pipeline has side-effects. A trivial example of the side-effect >> > problem is this: >> > >> > let x = [1,2,3]; >> > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| >> { if >> > *st { *st = false; Some(x) } else { None } }); >> > (it.next(), it.next(), it.next()) >> > >> > This results in `(Some(1), None, None)` but it prints out >> > >> > &1 >> > &2 >> > &3 >> > >> > After giving it some thought, I came up with 3 possible definitions for >> > behavior in this case: >> > >> > 1. Once `.next()` has returned `None`, it will return None forever. >> > Furthermore, calls to `.next()` after `None` has been returned will not >> > trigger side-effects in the iterator pipeline. This means that once >> > `.next()` has returned `None`, it becomes idempotent. >> > >> > This is most likely going to be what people will assume the iterator >> > protocol defines, in the absence of any explicit statement. What's more, >> > they probably won't even consider the side-effects case. >> > >> > Implementing this will require care be given to every single >> iterator and >> > iterator adaptor. Most iterators will probably behave like this (unless >> they >> > use a user-supplied closure), but a number of different iterator >> adaptors >> > will need to track this explicitly with a bool flag. It's likely that >> > user-supplied iterator adaptors will forget to enforce this and will >> > therefore behave subtlely wrong in the face of side-effects. >> > >> > 2. Once `.next()` has returned `None`, it will return `None` forever. No >> > statement is made regarding side-effects. >> > >> > This is what most people will think they're assuming, if asked. The >> > danger here is that they will almost certainly actaully assume #1, and >> thus >> > may write subtlely incorrect code if they're given an iterator pipeline >> with >> > side-effects. >> > >> > This is easier to implement than #1. Most iterators will do this >> already. >> > Iterator adaptors will generally only have to take care when they use a >> > user-supplied closure (e.g. `scan()`). >> > >> > 3. The behavior of `.next()` after `None` has been returned is left >> > undefined. Individual iterators may choose to define behavior here >> however >> > they see fit. >> > >> > This is what we actually have implemented in the standard libraries >> > today. It's also by far the easiest to implement, as iterators and >> adaptors >> > may simply choose to not define any particular behavior. >> > >> > This is made more attractive by the fact that some iterators may >> choose >> > to actually define behavior that's different than "return `None` >> forever". >> > For example, a user may write an iterator that wraps non-blocking I/O, >> > returning `None` when there's no data available and returning `Some(x)` >> > again once more data comes in. Or if you don't like that example, they >> could >> > write an iterator that may be updated to contain more data after being >> > exhausted. >> > >> > The downside is that users may assume #1 when #3 holds, which is why >> this >> > needs to be documented properly. >> > >> > --- >> > >> > I believe that #3 is the right behavior to define. This gives the most >> > flexibility to individual iterators, and we can provide an iterator >> adaptor >> > that gives any iterator the behavior defined by #1 (see Fuse in PR >> #8276). >> > >> > I am not strongly opposed to defining #1 instead, but I am mildly >> worried >> > about the likelihood that users will implement iterators that don't have >> > this guarantee, as this is not something that can be statically checked >> by >> > the compiler. What's more, if an iterator breaks this guarantee, the >> problem >> > will show up in the code that calls it, rather than in the iterator >> itself, >> > which may make debugging harder. >> > >> > I am strongly opposed to #2. If we guarantee that an iterator that >> returns >> > `None` once will return `None` forever, users will assume that this >> means >> > that `.next()` becomes idempotent (with regards to side-effects) after >> > `None` is returned, but this will not be true. Furthermore, users will >> > probably not even realize they've made a bad assumption, as most users >> will >> > not be thinking about side-effects when consuming iterators. >> > >> > I've already gone ahead and implemented #3 in pull request #8276. >> > >> > -Kevin >> >> I'm leaning towards #2 or #3, mostly because adaptors *not* >> dispatching to the underlying next() implementation are too complex. >> >> I took a look at the behaviour of Python's iterators in these corner >> cases as good baseline for comparison: >> >> ~~~ >> >>> def peek(it): >> ... for x in it: >> ... print(x) >> ... yield x >> ... >> >>> xs = [1, 2, 3] >> >>> ys = [1, 2, 3, 4, 5] >> ~~~ >> >> You can tell their `zip` function short-circuits, and simply >> dispatches to the underlying implementations. Rust's `zip` is similar >> but doesn't currently short-circuit (it might as well). >> >> ~~~ >> >>> it = zip(peek(ys), xs) >> >>> next(it) >> 1 >> (1, 1) >> >>> next(it) >> 2 >> (2, 2) >> >>> next(it) >> 3 >> (3, 3) >> >>> next(it) >> 4 >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> >>> next(it) >> 5 >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> >>> next(it) >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> >>> it = zip(xs, peek(ys)) >> >>> next(it) >> 1 >> (1, 1) >> >>> next(it) >> 2 >> (2, 2) >> >>> next(it) >> 3 >> (3, 3) >> >>> next(it) >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> ~~~ >> >> It also makes no attempt to store whether it has stopped internally, >> and will start yielding again if each iterator yields an element when >> zip asks for them one by one (keeping in mind that it short-circuits). >> >> Most other language keep `hasNext` and `next` separate (D and Scala, >> among others) leading to more corner cases, and they do not seem to >> clearly define the semantics for side effects down the pipeline. >> >> http://dlang.org/phobos/std_range.html >> http://www.scala-lang.org/api/current/scala/collection/Iterator.html >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Sun Aug 4 17:12:27 2013 From: kevin at sb.org (Kevin Ballard) Date: Sun, 4 Aug 2013 17:12:27 -0700 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: I suspect you're confused about something. The for loop doesn't care in the slightest what an iterator does after it's returned None. All 3 approaches work equally well as far as the for loop is concerned. And I'm not sure what you mean by "design Iterators that would take advantage of the undefined behavior". If an iterator defines how it behaves after returning None, then it's defined behavior. If you're using iterators and you know your entire iterator pipeline, then you can use whatever behavior the iterators involved define. You only need to restrict yourself to what the iterator protocol defines if you don't know what iterator you're consuming. I also don't understand your suggestion about using Option. Iterators already return an Option. -Kevin On Aug 4, 2013, at 4:45 PM, Jason Fager wrote: > Of course. I think I'm reacting more to the possible use cases you described for option 3 than the actual meaning of it. It seems like a really bad idea to design iterators that would take advantage of the undefined behavior, not least b/c it's unexpected and not supported by the most pervasive client of the iterator protocol (the for loop, in the sense of actually iterating through all elements available through the iterator), but that doesn't mean option 3 is in itself the wrong thing to do. > > But addressing the use cases you mentioned, if you need that kind of functionality, shouldn't you be hoisting the iterator's return type into its own Option? i.e., an Iterator should be become an Iterator>? > > > On Sun, Aug 4, 2013 at 6:23 PM, Kevin Ballard wrote: > The new for loop works with all 3 of these. Your output shows that it queried .next() twice, and got a single Some(1) result back. Once it gets None, it never calls .next() again, whereas the 3 behaviors stated previously are exclusively concerned with what happens if you call .next() again after it has already returned None. > > -Kevin > > P.S. I changed the email address that I'm subscribed to this list with, so apologies for any potential confusion. > > On Aug 4, 2013, at 6:18 AM, Jason Fager wrote: > >> The new for loop already assumes #2, right? >> >> let x = [1,2,3]; >> let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if *st { *st = false; Some(x) } else { None } }); >> >> for i in it { >> printfln!("from for loop: %?", i); >> } >> >> >> Which produces: >> >> &1 >> from for loop: 1 >> &2 >> >> >> >> On Sun, Aug 4, 2013 at 1:49 AM, Daniel Micay wrote: >> On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard wrote: >> > The iterator protocol, as I'm sure you're aware, is the protocol that >> > defines the behavior of the Iterator trait. Unfortunately, at the moment the >> > trait does not document what happens if you call `.next()` on an iterator >> > after a previous call has returned `None`. According to Daniel Micay, the >> > intention was that the iterator would return `None` forever. However, this >> > is not guaranteed by at least one iterator adaptor (Scan), nor is it >> > documented. Furthermore, no thought has been given to what happens if an >> > iterator pipeline has side-effects. A trivial example of the side-effect >> > problem is this: >> > >> > let x = [1,2,3]; >> > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if >> > *st { *st = false; Some(x) } else { None } }); >> > (it.next(), it.next(), it.next()) >> > >> > This results in `(Some(1), None, None)` but it prints out >> > >> > &1 >> > &2 >> > &3 >> > >> > After giving it some thought, I came up with 3 possible definitions for >> > behavior in this case: >> > >> > 1. Once `.next()` has returned `None`, it will return None forever. >> > Furthermore, calls to `.next()` after `None` has been returned will not >> > trigger side-effects in the iterator pipeline. This means that once >> > `.next()` has returned `None`, it becomes idempotent. >> > >> > This is most likely going to be what people will assume the iterator >> > protocol defines, in the absence of any explicit statement. What's more, >> > they probably won't even consider the side-effects case. >> > >> > Implementing this will require care be given to every single iterator and >> > iterator adaptor. Most iterators will probably behave like this (unless they >> > use a user-supplied closure), but a number of different iterator adaptors >> > will need to track this explicitly with a bool flag. It's likely that >> > user-supplied iterator adaptors will forget to enforce this and will >> > therefore behave subtlely wrong in the face of side-effects. >> > >> > 2. Once `.next()` has returned `None`, it will return `None` forever. No >> > statement is made regarding side-effects. >> > >> > This is what most people will think they're assuming, if asked. The >> > danger here is that they will almost certainly actaully assume #1, and thus >> > may write subtlely incorrect code if they're given an iterator pipeline with >> > side-effects. >> > >> > This is easier to implement than #1. Most iterators will do this already. >> > Iterator adaptors will generally only have to take care when they use a >> > user-supplied closure (e.g. `scan()`). >> > >> > 3. The behavior of `.next()` after `None` has been returned is left >> > undefined. Individual iterators may choose to define behavior here however >> > they see fit. >> > >> > This is what we actually have implemented in the standard libraries >> > today. It's also by far the easiest to implement, as iterators and adaptors >> > may simply choose to not define any particular behavior. >> > >> > This is made more attractive by the fact that some iterators may choose >> > to actually define behavior that's different than "return `None` forever". >> > For example, a user may write an iterator that wraps non-blocking I/O, >> > returning `None` when there's no data available and returning `Some(x)` >> > again once more data comes in. Or if you don't like that example, they could >> > write an iterator that may be updated to contain more data after being >> > exhausted. >> > >> > The downside is that users may assume #1 when #3 holds, which is why this >> > needs to be documented properly. >> > >> > --- >> > >> > I believe that #3 is the right behavior to define. This gives the most >> > flexibility to individual iterators, and we can provide an iterator adaptor >> > that gives any iterator the behavior defined by #1 (see Fuse in PR #8276). >> > >> > I am not strongly opposed to defining #1 instead, but I am mildly worried >> > about the likelihood that users will implement iterators that don't have >> > this guarantee, as this is not something that can be statically checked by >> > the compiler. What's more, if an iterator breaks this guarantee, the problem >> > will show up in the code that calls it, rather than in the iterator itself, >> > which may make debugging harder. >> > >> > I am strongly opposed to #2. If we guarantee that an iterator that returns >> > `None` once will return `None` forever, users will assume that this means >> > that `.next()` becomes idempotent (with regards to side-effects) after >> > `None` is returned, but this will not be true. Furthermore, users will >> > probably not even realize they've made a bad assumption, as most users will >> > not be thinking about side-effects when consuming iterators. >> > >> > I've already gone ahead and implemented #3 in pull request #8276. >> > >> > -Kevin >> >> I'm leaning towards #2 or #3, mostly because adaptors *not* >> dispatching to the underlying next() implementation are too complex. >> >> I took a look at the behaviour of Python's iterators in these corner >> cases as good baseline for comparison: >> >> ~~~ >> >>> def peek(it): >> ... for x in it: >> ... print(x) >> ... yield x >> ... >> >>> xs = [1, 2, 3] >> >>> ys = [1, 2, 3, 4, 5] >> ~~~ >> >> You can tell their `zip` function short-circuits, and simply >> dispatches to the underlying implementations. Rust's `zip` is similar >> but doesn't currently short-circuit (it might as well). >> >> ~~~ >> >>> it = zip(peek(ys), xs) >> >>> next(it) >> 1 >> (1, 1) >> >>> next(it) >> 2 >> (2, 2) >> >>> next(it) >> 3 >> (3, 3) >> >>> next(it) >> 4 >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> >>> next(it) >> 5 >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> >>> next(it) >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> >>> it = zip(xs, peek(ys)) >> >>> next(it) >> 1 >> (1, 1) >> >>> next(it) >> 2 >> (2, 2) >> >>> next(it) >> 3 >> (3, 3) >> >>> next(it) >> Traceback (most recent call last): >> File "", line 1, in >> StopIteration >> ~~~ >> >> It also makes no attempt to store whether it has stopped internally, >> and will start yielding again if each iterator yields an element when >> zip asks for them one by one (keeping in mind that it short-circuits). >> >> Most other language keep `hasNext` and `next` separate (D and Scala, >> among others) leading to more corner cases, and they do not seem to >> clearly define the semantics for side effects down the pipeline. >> >> http://dlang.org/phobos/std_range.html >> http://www.scala-lang.org/api/current/scala/collection/Iterator.html >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jfager at gmail.com Sun Aug 4 17:53:19 2013 From: jfager at gmail.com (Jason Fager) Date: Sun, 4 Aug 2013 20:53:19 -0400 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: Not confused, I understand your point about for loops not caring about what happens with additional 'next' calls. But as a user of an iterator, I have the expectation that a for loop exhausts the elements available from an iterator unless I return early or break. Designing an iterator that intentionally sidesteps that expectation seems like a bad idea. Principle of least astonishment, etc. And yes, of course, iterators already return Option. But they return Option to satisfy the *iterator protocol*, not the use cases you described. I'm talking about adding another layer of Option So say I want to implement non-blocking io that plays nice w/ the iterator protocol. Using an implementation taking advantage of option#3 look something like: loop { for i in iter { foo(i); } // other stuff if(noReallyImDone) { break; } } While hoisting the Iterator's type into another layer of Option looks like: for i in iter { match i { Some(i) => foo(i); None => { //other stuff } } } The outer Option allows the iterator protocol to work as expected, i.e. iterate over all available elements in the iterator, and the inner implements the non-blocking protocol you're looking for. On Sun, Aug 4, 2013 at 8:12 PM, Kevin Ballard wrote: > I suspect you're confused about something. > > The for loop doesn't care in the slightest what an iterator does after > it's returned None. All 3 approaches work equally well as far as the for > loop is concerned. > > And I'm not sure what you mean by "design Iterators that would take > advantage of the undefined behavior". If an iterator defines how it behaves > after returning None, then it's defined behavior. If you're using iterators > and you know your entire iterator pipeline, then you can use whatever > behavior the iterators involved define. You only need to restrict yourself > to what the iterator protocol defines if you don't know what iterator > you're consuming. > > I also don't understand your suggestion about using Option. Iterators * > already* return an Option. > > -Kevin > > On Aug 4, 2013, at 4:45 PM, Jason Fager wrote: > > Of course. I think I'm reacting more to the possible use cases you > described for option 3 than the actual meaning of it. It seems like a > really bad idea to design iterators that would take advantage of the > undefined behavior, not least b/c it's unexpected and not supported by the > most pervasive client of the iterator protocol (the for loop, in the sense > of actually iterating through all elements available through the iterator), > but that doesn't mean option 3 is in itself the wrong thing to do. > > But addressing the use cases you mentioned, if you need that kind of > functionality, shouldn't you be hoisting the iterator's return type into > its own Option? i.e., an Iterator should be become an > Iterator>? > > > On Sun, Aug 4, 2013 at 6:23 PM, Kevin Ballard wrote: > >> The new for loop works with all 3 of these. Your output shows that it >> queried .next() twice, and got a single Some(1) result back. Once it gets >> None, it never calls .next() again, whereas the 3 behaviors stated >> previously are exclusively concerned with what happens if you call .next() >> again after it has already returned None. >> >> -Kevin >> >> P.S. I changed the email address that I'm subscribed to this list with, >> so apologies for any potential confusion. >> >> On Aug 4, 2013, at 6:18 AM, Jason Fager wrote: >> >> The new for loop already assumes #2, right? >> >> let x = [1,2,3]; >> let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if >> *st { *st = false; Some(x) } else { None } }); >> >> for i in it { >> printfln!("from for loop: %?", i); >> } >> >> >> Which produces: >> >> &1 >> from for loop: 1 >> &2 >> >> >> >> On Sun, Aug 4, 2013 at 1:49 AM, Daniel Micay wrote: >> >>> On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard >>> wrote: >>> > The iterator protocol, as I'm sure you're aware, is the protocol that >>> > defines the behavior of the Iterator trait. Unfortunately, at the >>> moment the >>> > trait does not document what happens if you call `.next()` on an >>> iterator >>> > after a previous call has returned `None`. According to Daniel Micay, >>> the >>> > intention was that the iterator would return `None` forever. However, >>> this >>> > is not guaranteed by at least one iterator adaptor (Scan), nor is it >>> > documented. Furthermore, no thought has been given to what happens if >>> an >>> > iterator pipeline has side-effects. A trivial example of the >>> side-effect >>> > problem is this: >>> > >>> > let x = [1,2,3]; >>> > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| >>> { if >>> > *st { *st = false; Some(x) } else { None } }); >>> > (it.next(), it.next(), it.next()) >>> > >>> > This results in `(Some(1), None, None)` but it prints out >>> > >>> > &1 >>> > &2 >>> > &3 >>> > >>> > After giving it some thought, I came up with 3 possible definitions for >>> > behavior in this case: >>> > >>> > 1. Once `.next()` has returned `None`, it will return None forever. >>> > Furthermore, calls to `.next()` after `None` has been returned will not >>> > trigger side-effects in the iterator pipeline. This means that once >>> > `.next()` has returned `None`, it becomes idempotent. >>> > >>> > This is most likely going to be what people will assume the iterator >>> > protocol defines, in the absence of any explicit statement. What's >>> more, >>> > they probably won't even consider the side-effects case. >>> > >>> > Implementing this will require care be given to every single >>> iterator and >>> > iterator adaptor. Most iterators will probably behave like this >>> (unless they >>> > use a user-supplied closure), but a number of different iterator >>> adaptors >>> > will need to track this explicitly with a bool flag. It's likely that >>> > user-supplied iterator adaptors will forget to enforce this and will >>> > therefore behave subtlely wrong in the face of side-effects. >>> > >>> > 2. Once `.next()` has returned `None`, it will return `None` forever. >>> No >>> > statement is made regarding side-effects. >>> > >>> > This is what most people will think they're assuming, if asked. The >>> > danger here is that they will almost certainly actaully assume #1, and >>> thus >>> > may write subtlely incorrect code if they're given an iterator >>> pipeline with >>> > side-effects. >>> > >>> > This is easier to implement than #1. Most iterators will do this >>> already. >>> > Iterator adaptors will generally only have to take care when they use a >>> > user-supplied closure (e.g. `scan()`). >>> > >>> > 3. The behavior of `.next()` after `None` has been returned is left >>> > undefined. Individual iterators may choose to define behavior here >>> however >>> > they see fit. >>> > >>> > This is what we actually have implemented in the standard libraries >>> > today. It's also by far the easiest to implement, as iterators and >>> adaptors >>> > may simply choose to not define any particular behavior. >>> > >>> > This is made more attractive by the fact that some iterators may >>> choose >>> > to actually define behavior that's different than "return `None` >>> forever". >>> > For example, a user may write an iterator that wraps non-blocking I/O, >>> > returning `None` when there's no data available and returning `Some(x)` >>> > again once more data comes in. Or if you don't like that example, they >>> could >>> > write an iterator that may be updated to contain more data after being >>> > exhausted. >>> > >>> > The downside is that users may assume #1 when #3 holds, which is >>> why this >>> > needs to be documented properly. >>> > >>> > --- >>> > >>> > I believe that #3 is the right behavior to define. This gives the most >>> > flexibility to individual iterators, and we can provide an iterator >>> adaptor >>> > that gives any iterator the behavior defined by #1 (see Fuse in PR >>> #8276). >>> > >>> > I am not strongly opposed to defining #1 instead, but I am mildly >>> worried >>> > about the likelihood that users will implement iterators that don't >>> have >>> > this guarantee, as this is not something that can be statically >>> checked by >>> > the compiler. What's more, if an iterator breaks this guarantee, the >>> problem >>> > will show up in the code that calls it, rather than in the iterator >>> itself, >>> > which may make debugging harder. >>> > >>> > I am strongly opposed to #2. If we guarantee that an iterator that >>> returns >>> > `None` once will return `None` forever, users will assume that this >>> means >>> > that `.next()` becomes idempotent (with regards to side-effects) after >>> > `None` is returned, but this will not be true. Furthermore, users will >>> > probably not even realize they've made a bad assumption, as most users >>> will >>> > not be thinking about side-effects when consuming iterators. >>> > >>> > I've already gone ahead and implemented #3 in pull request #8276. >>> > >>> > -Kevin >>> >>> I'm leaning towards #2 or #3, mostly because adaptors *not* >>> dispatching to the underlying next() implementation are too complex. >>> >>> I took a look at the behaviour of Python's iterators in these corner >>> cases as good baseline for comparison: >>> >>> ~~~ >>> >>> def peek(it): >>> ... for x in it: >>> ... print(x) >>> ... yield x >>> ... >>> >>> xs = [1, 2, 3] >>> >>> ys = [1, 2, 3, 4, 5] >>> ~~~ >>> >>> You can tell their `zip` function short-circuits, and simply >>> dispatches to the underlying implementations. Rust's `zip` is similar >>> but doesn't currently short-circuit (it might as well). >>> >>> ~~~ >>> >>> it = zip(peek(ys), xs) >>> >>> next(it) >>> 1 >>> (1, 1) >>> >>> next(it) >>> 2 >>> (2, 2) >>> >>> next(it) >>> 3 >>> (3, 3) >>> >>> next(it) >>> 4 >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> >>> next(it) >>> 5 >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> >>> next(it) >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> >>> it = zip(xs, peek(ys)) >>> >>> next(it) >>> 1 >>> (1, 1) >>> >>> next(it) >>> 2 >>> (2, 2) >>> >>> next(it) >>> 3 >>> (3, 3) >>> >>> next(it) >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> ~~~ >>> >>> It also makes no attempt to store whether it has stopped internally, >>> and will start yielding again if each iterator yields an element when >>> zip asks for them one by one (keeping in mind that it short-circuits). >>> >>> Most other language keep `hasNext` and `next` separate (D and Scala, >>> among others) leading to more corner cases, and they do not seem to >>> clearly define the semantics for side effects down the pipeline. >>> >>> http://dlang.org/phobos/std_range.html >>> http://www.scala-lang.org/api/current/scala/collection/Iterator.html >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Sun Aug 4 20:33:11 2013 From: kevin at sb.org (Kevin Ballard) Date: Sun, 4 Aug 2013 20:33:11 -0700 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: <1178092E-C6E3-4B18-9E65-EA05D0693726@sb.org> You could certainly design a non-blocking IO iterator that way. My example of a non-blocking IO iterator wasn't meant to illustrate something I'd actually recommend you do (since the iterator protocol isn't really a great fit for this), but rather show the flexibility of the approach. That said, in the non-blocking IO approach, it does still "exhaust the elements available", it just so happens that more elements become available over time. A better example might be an iterator that allows you to push more elements onto the end. Or one that allows you to move the iterator backwards in time, so to speak, so it re-emits the same elements it emitted previously (e.g. give it a .prev() method). Or merely one that allows you to push back a single element (that gets yielded on the next call to .next()), which is actually fairly common in character iterators in other languages (gives you the equivalent of a .peek() operation, by consuming a value and then immediately pushing it back if you don't want it). None of these examples are possible with approaches #1 or #2, only with approach #3. And all of them are still compatible with the basic for loop. -Kevin On Aug 4, 2013, at 5:53 PM, Jason Fager wrote: > Not confused, I understand your point about for loops not caring about what happens with additional 'next' calls. > > But as a user of an iterator, I have the expectation that a for loop exhausts the elements available from an iterator unless I return early or break. Designing an iterator that intentionally sidesteps that expectation seems like a bad idea. Principle of least astonishment, etc. > > And yes, of course, iterators already return Option. But they return Option to satisfy the *iterator protocol*, not the use cases you described. I'm talking about adding another layer of Option > > So say I want to implement non-blocking io that plays nice w/ the iterator protocol. Using an implementation taking advantage of option#3 look something like: > > loop { > for i in iter { > foo(i); > } > // other stuff > if(noReallyImDone) { > break; > } > } > > > While hoisting the Iterator's type into another layer of Option looks like: > > for i in iter { > match i { > Some(i) => foo(i); > None => { > //other stuff > } > } > } > > The outer Option allows the iterator protocol to work as expected, i.e. iterate over all available elements in the iterator, and the inner implements the non-blocking protocol you're looking for. > > > > > > > > On Sun, Aug 4, 2013 at 8:12 PM, Kevin Ballard wrote: > I suspect you're confused about something. > > The for loop doesn't care in the slightest what an iterator does after it's returned None. All 3 approaches work equally well as far as the for loop is concerned. > > And I'm not sure what you mean by "design Iterators that would take advantage of the undefined behavior". If an iterator defines how it behaves after returning None, then it's defined behavior. If you're using iterators and you know your entire iterator pipeline, then you can use whatever behavior the iterators involved define. You only need to restrict yourself to what the iterator protocol defines if you don't know what iterator you're consuming. > > I also don't understand your suggestion about using Option. Iterators already return an Option. > > -Kevin > > On Aug 4, 2013, at 4:45 PM, Jason Fager wrote: > >> Of course. I think I'm reacting more to the possible use cases you described for option 3 than the actual meaning of it. It seems like a really bad idea to design iterators that would take advantage of the undefined behavior, not least b/c it's unexpected and not supported by the most pervasive client of the iterator protocol (the for loop, in the sense of actually iterating through all elements available through the iterator), but that doesn't mean option 3 is in itself the wrong thing to do. >> >> But addressing the use cases you mentioned, if you need that kind of functionality, shouldn't you be hoisting the iterator's return type into its own Option? i.e., an Iterator should be become an Iterator>? >> >> >> On Sun, Aug 4, 2013 at 6:23 PM, Kevin Ballard wrote: >> The new for loop works with all 3 of these. Your output shows that it queried .next() twice, and got a single Some(1) result back. Once it gets None, it never calls .next() again, whereas the 3 behaviors stated previously are exclusively concerned with what happens if you call .next() again after it has already returned None. >> >> -Kevin >> >> P.S. I changed the email address that I'm subscribed to this list with, so apologies for any potential confusion. >> >> On Aug 4, 2013, at 6:18 AM, Jason Fager wrote: >> >>> The new for loop already assumes #2, right? >>> >>> let x = [1,2,3]; >>> let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if *st { *st = false; Some(x) } else { None } }); >>> >>> for i in it { >>> printfln!("from for loop: %?", i); >>> } >>> >>> >>> Which produces: >>> >>> &1 >>> from for loop: 1 >>> &2 >>> >>> >>> >>> On Sun, Aug 4, 2013 at 1:49 AM, Daniel Micay wrote: >>> On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard wrote: >>> > The iterator protocol, as I'm sure you're aware, is the protocol that >>> > defines the behavior of the Iterator trait. Unfortunately, at the moment the >>> > trait does not document what happens if you call `.next()` on an iterator >>> > after a previous call has returned `None`. According to Daniel Micay, the >>> > intention was that the iterator would return `None` forever. However, this >>> > is not guaranteed by at least one iterator adaptor (Scan), nor is it >>> > documented. Furthermore, no thought has been given to what happens if an >>> > iterator pipeline has side-effects. A trivial example of the side-effect >>> > problem is this: >>> > >>> > let x = [1,2,3]; >>> > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if >>> > *st { *st = false; Some(x) } else { None } }); >>> > (it.next(), it.next(), it.next()) >>> > >>> > This results in `(Some(1), None, None)` but it prints out >>> > >>> > &1 >>> > &2 >>> > &3 >>> > >>> > After giving it some thought, I came up with 3 possible definitions for >>> > behavior in this case: >>> > >>> > 1. Once `.next()` has returned `None`, it will return None forever. >>> > Furthermore, calls to `.next()` after `None` has been returned will not >>> > trigger side-effects in the iterator pipeline. This means that once >>> > `.next()` has returned `None`, it becomes idempotent. >>> > >>> > This is most likely going to be what people will assume the iterator >>> > protocol defines, in the absence of any explicit statement. What's more, >>> > they probably won't even consider the side-effects case. >>> > >>> > Implementing this will require care be given to every single iterator and >>> > iterator adaptor. Most iterators will probably behave like this (unless they >>> > use a user-supplied closure), but a number of different iterator adaptors >>> > will need to track this explicitly with a bool flag. It's likely that >>> > user-supplied iterator adaptors will forget to enforce this and will >>> > therefore behave subtlely wrong in the face of side-effects. >>> > >>> > 2. Once `.next()` has returned `None`, it will return `None` forever. No >>> > statement is made regarding side-effects. >>> > >>> > This is what most people will think they're assuming, if asked. The >>> > danger here is that they will almost certainly actaully assume #1, and thus >>> > may write subtlely incorrect code if they're given an iterator pipeline with >>> > side-effects. >>> > >>> > This is easier to implement than #1. Most iterators will do this already. >>> > Iterator adaptors will generally only have to take care when they use a >>> > user-supplied closure (e.g. `scan()`). >>> > >>> > 3. The behavior of `.next()` after `None` has been returned is left >>> > undefined. Individual iterators may choose to define behavior here however >>> > they see fit. >>> > >>> > This is what we actually have implemented in the standard libraries >>> > today. It's also by far the easiest to implement, as iterators and adaptors >>> > may simply choose to not define any particular behavior. >>> > >>> > This is made more attractive by the fact that some iterators may choose >>> > to actually define behavior that's different than "return `None` forever". >>> > For example, a user may write an iterator that wraps non-blocking I/O, >>> > returning `None` when there's no data available and returning `Some(x)` >>> > again once more data comes in. Or if you don't like that example, they could >>> > write an iterator that may be updated to contain more data after being >>> > exhausted. >>> > >>> > The downside is that users may assume #1 when #3 holds, which is why this >>> > needs to be documented properly. >>> > >>> > --- >>> > >>> > I believe that #3 is the right behavior to define. This gives the most >>> > flexibility to individual iterators, and we can provide an iterator adaptor >>> > that gives any iterator the behavior defined by #1 (see Fuse in PR #8276). >>> > >>> > I am not strongly opposed to defining #1 instead, but I am mildly worried >>> > about the likelihood that users will implement iterators that don't have >>> > this guarantee, as this is not something that can be statically checked by >>> > the compiler. What's more, if an iterator breaks this guarantee, the problem >>> > will show up in the code that calls it, rather than in the iterator itself, >>> > which may make debugging harder. >>> > >>> > I am strongly opposed to #2. If we guarantee that an iterator that returns >>> > `None` once will return `None` forever, users will assume that this means >>> > that `.next()` becomes idempotent (with regards to side-effects) after >>> > `None` is returned, but this will not be true. Furthermore, users will >>> > probably not even realize they've made a bad assumption, as most users will >>> > not be thinking about side-effects when consuming iterators. >>> > >>> > I've already gone ahead and implemented #3 in pull request #8276. >>> > >>> > -Kevin >>> >>> I'm leaning towards #2 or #3, mostly because adaptors *not* >>> dispatching to the underlying next() implementation are too complex. >>> >>> I took a look at the behaviour of Python's iterators in these corner >>> cases as good baseline for comparison: >>> >>> ~~~ >>> >>> def peek(it): >>> ... for x in it: >>> ... print(x) >>> ... yield x >>> ... >>> >>> xs = [1, 2, 3] >>> >>> ys = [1, 2, 3, 4, 5] >>> ~~~ >>> >>> You can tell their `zip` function short-circuits, and simply >>> dispatches to the underlying implementations. Rust's `zip` is similar >>> but doesn't currently short-circuit (it might as well). >>> >>> ~~~ >>> >>> it = zip(peek(ys), xs) >>> >>> next(it) >>> 1 >>> (1, 1) >>> >>> next(it) >>> 2 >>> (2, 2) >>> >>> next(it) >>> 3 >>> (3, 3) >>> >>> next(it) >>> 4 >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> >>> next(it) >>> 5 >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> >>> next(it) >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> >>> it = zip(xs, peek(ys)) >>> >>> next(it) >>> 1 >>> (1, 1) >>> >>> next(it) >>> 2 >>> (2, 2) >>> >>> next(it) >>> 3 >>> (3, 3) >>> >>> next(it) >>> Traceback (most recent call last): >>> File "", line 1, in >>> StopIteration >>> ~~~ >>> >>> It also makes no attempt to store whether it has stopped internally, >>> and will start yielding again if each iterator yields an element when >>> zip asks for them one by one (keeping in mind that it short-circuits). >>> >>> Most other language keep `hasNext` and `next` separate (D and Scala, >>> among others) leading to more corner cases, and they do not seem to >>> clearly define the semantics for side effects down the pipeline. >>> >>> http://dlang.org/phobos/std_range.html >>> http://www.scala-lang.org/api/current/scala/collection/Iterator.html >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >> >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sun Aug 4 22:53:10 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 5 Aug 2013 01:53:10 -0400 Subject: [rust-dev] rustdoc_ng status: all items extracted Message-ID: Hi all, I'm very excited to announce that rustdoc_ng now extracts and jsonifies crates completely in their entirety. Yay! Jordi has been doing some awesome work with the frontend, even adding a search. See http://seld.be/rustdoc/master/index.html, for its current state. There's still a bunch of work to do, but all of it can be implemented with plugins. The cleaned crate is sendable, and in theory it should be generically encodable, but I don't know how to sling extra::serialize, so if anyone could lend a hand with that, that'd be cool. From garethdanielsmith at gmail.com Mon Aug 5 02:04:41 2013 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Mon, 05 Aug 2013 10:04:41 +0100 Subject: [rust-dev] rustdoc_ng status: all items extracted In-Reply-To: References: Message-ID: <51FF6AA9.9090701@gmail.com> Great work, I like the search already. Thanks! On 05/08/13 06:53, Corey Richardson wrote: > Hi all, > > I'm very excited to announce that rustdoc_ng now extracts and > jsonifies crates completely in their entirety. Yay! Jordi has been > doing some awesome work with the frontend, even adding a search. See > http://seld.be/rustdoc/master/index.html, for its current state. > > There's still a bunch of work to do, but all of it can be implemented > with plugins. The cleaned crate is sendable, and in theory it should > be generically encodable, but I don't know how to sling > extra::serialize, so if anyone could lend a hand with that, that'd be > cool. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From thadguidry at gmail.com Mon Aug 5 07:55:45 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Mon, 5 Aug 2013 09:55:45 -0500 Subject: [rust-dev] rustdoc_ng status: all items extracted In-Reply-To: <51FF6AA9.9090701@gmail.com> References: <51FF6AA9.9090701@gmail.com> Message-ID: But why is "cool" coming up with so many search hits ? lololol On Mon, Aug 5, 2013 at 4:04 AM, Gareth Smith wrote: > Great work, I like the search already. Thanks! > > > On 05/08/13 06:53, Corey Richardson wrote: > >> Hi all, >> >> I'm very excited to announce that rustdoc_ng now extracts and >> jsonifies crates completely in their entirety. Yay! Jordi has been >> doing some awesome work with the frontend, even adding a search. See >> http://seld.be/rustdoc/master/**index.html, >> for its current state. >> >> There's still a bunch of work to do, but all of it can be implemented >> with plugins. The cleaned crate is sendable, and in theory it should >> be generically encodable, but I don't know how to sling >> extra::serialize, so if anyone could lend a hand with that, that'd be >> cool. >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From loebel.marvin at gmail.com Sun Aug 4 17:18:59 2013 From: loebel.marvin at gmail.com (=?ISO-8859-1?Q?Marvin_L=F6bel?=) Date: Mon, 05 Aug 2013 02:18:59 +0200 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: <51FEEF73.9010405@googlemail.com> I'm for the .NET style. - Easy to reason about. - No confusion about what to do with acronyms. - No inconsistency about what to do with acronyms. (If there are special rules, people WILL use them inconsistent.) - Gc/GcMut looks in my opinion better than either GC/GCMut and GC/GcMut. Am 03.08.2013 03:28, schrieb Patrick Walton: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over > `Gc<>`. I think now is as good a time as any to have the bikeshedding > debate :) > > I've noticed two styles for acronyms in type names: Java style > (HTTPServer) versus .NET style (HttpServer). Currently we are usually > using .NET style, but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better > than "Gc", because Web APIs use Java style, and because Python does > (e.g. SimpleHTTPServer) and in general we've been following PEP 8. But > I don't feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From coder543 at gmail.com Mon Aug 5 11:40:25 2013 From: coder543 at gmail.com (Josh Leverette) Date: Mon, 5 Aug 2013 13:40:25 -0500 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FEEF73.9010405@googlemail.com> References: <51FC5CDB.6000902@mozilla.com> <51FEEF73.9010405@googlemail.com> Message-ID: Better even than the "toggle mode caps" style of gc/gcMut? (assuming "mut" is an abbreviation here, if it's an acronym, then it would be gc/gcMUT) But of course, looks are purely subjective. The key is objective comparison. Pure .NET style loses information about whether something is an acronym or an abbreviation, and that information can be useful. On Sun, Aug 4, 2013 at 7:18 PM, Marvin L?bel wrote: > I'm for the .NET style. > > - Easy to reason about. > - No confusion about what to do with acronyms. > - No inconsistency about what to do with acronyms. (If there are special > rules, people WILL use them inconsistent.) > - Gc/GcMut looks in my opinion better than either GC/GCMut and GC/GcMut. > > Am 03.08.2013 03:28, schrieb Patrick Walton: > > Hi everyone, >> >> Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I >> think now is as good a time as any to have the bikeshedding debate :) >> >> I've noticed two styles for acronyms in type names: Java style >> (HTTPServer) versus .NET style (HttpServer). Currently we are usually using >> .NET style, but inconsistently (e.g. ARC). We never really decided. >> >> Here are a few examples of types in each style: >> >> * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. >> >> * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. >> >> I slightly prefer Java style myself because I think "GC" looks better >> than "Gc", because Web APIs use Java style, and because Python does (e.g. >> SimpleHTTPServer) and in general we've been following PEP 8. But I don't >> feel strongly on this issue. >> >> Thoughts/straw poll? >> >> Patrick >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From reshef.dov at gmail.com Mon Aug 5 11:56:32 2013 From: reshef.dov at gmail.com (Dov Reshef) Date: Mon, 5 Aug 2013 21:56:32 +0300 Subject: [rust-dev] Order of appearance in files of extern mod, mod and use Message-ID: Hi everyone Currently extern mod, mod and use statements must appear in source files only in the following order: extern mod foo_c; use foo::bar; mod foo; I'd like if it can be changed to extern mod foo_c; mod foo; use foo::bar; If I understand correctly "mod foo" import the foo module into the current module, and "use foo::bar" bring bar from foo module into the current scope, so it seems more logical that use should follow mod, not the other way around. When I asked about this in the channel I was told the current rule was to prevent import collisions. I think import collisions should be an error anyway. There is also a simple solution with "use new_name = ...". Anyway sorry for the bikesheddy (a bit) mail. It just something that bit me and made me confuse their meaning up till today. Thanks for reading, Dov -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Mon Aug 5 12:15:01 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Mon, 5 Aug 2013 14:15:01 -0500 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> <51FEEF73.9010405@googlemail.com> Message-ID: On Mon, Aug 5, 2013 at 1:40 PM, Josh Leverette wrote: > Better even than the "toggle mode caps" style of gc/gcMut? (assuming "mut" > is an abbreviation here, if it's an acronym, then it would be gc/gcMUT) > > But of course, looks are purely subjective. The key is objective > comparison. Pure .NET style loses information about whether something is an > acronym or an abbreviation, and that information can be useful. > > Josh, I would argue that the information is NOT lost... GcMut still means "something somewhere", and the information of which is merely "moved over" to another, better place, in the form of "documentation" like http://seld.be/rustdoc/master/index.html...which can be easily searched and parsed itself...and linked to other data and the greater Semantic Web, tag and vocabulary systems, etc. -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeaye at arrownext.com Mon Aug 5 12:24:54 2013 From: jeaye at arrownext.com (Jeaye) Date: Mon, 05 Aug 2013 13:24:54 -0600 Subject: [rust-dev] Order of appearance in files of extern mod, mod and use In-Reply-To: References: Message-ID: <55c22d43004d37f3415d1c0d831e93eb@arrownext.com> > Currently extern mod, mod and use statements must appear in source > files only in the following order: > > extern mod foo_c; > use foo::bar; > mod foo; > > I'd like if it can be changed to > > extern mod foo_c; > mod foo; > > use foo::bar; I'm actually 100% for this change. It seems very weird to add a 'mod foo' and then have to go *above* the import to 'use foo::bar;'. If this can be done without much of a hassle, my vote is in its favor. Jeaye From corey at octayn.net Mon Aug 5 12:52:08 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 5 Aug 2013 15:52:08 -0400 Subject: [rust-dev] Order of appearance in files of extern mod, mod and use In-Reply-To: <55c22d43004d37f3415d1c0d831e93eb@arrownext.com> References: <55c22d43004d37f3415d1c0d831e93eb@arrownext.com> Message-ID: I agree that this is really weird and confusing. I think the simple fix would just be allowing mod to also come before `use`? On Mon, Aug 5, 2013 at 3:24 PM, Jeaye wrote: >> Currently extern mod, mod and use statements must appear in source >> files only in the following order: >> >> extern mod foo_c; >> use foo::bar; >> mod foo; >> >> I'd like if it can be changed to >> >> extern mod foo_c; >> mod foo; >> >> use foo::bar; > > > I'm actually 100% for this change. It seems very weird to add a 'mod foo' > and then have to go *above* the import to 'use foo::bar;'. If this can be > done without much of a hassle, my vote is in its favor. > > Jeaye > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From garethdanielsmith at gmail.com Mon Aug 5 12:53:06 2013 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Mon, 05 Aug 2013 20:53:06 +0100 Subject: [rust-dev] Order of appearance in files of extern mod, mod and use In-Reply-To: References: Message-ID: <520002A2.1000203@gmail.com> On 05/08/13 19:56, Dov Reshef wrote: > > If I understand correctly "mod foo" import the foo module into the > current module, and "use foo::bar" bring bar from foo module into the > current scope, so it seems more logical that use should follow mod, > not the other way around. My understanding is that "mod foo;" is kind of like "mod foo { ... }" except that with "mod foo;" the body of the module comes from a different file, so it is more like a definition than an import. Gareth From ben.striegel at gmail.com Mon Aug 5 15:47:03 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Mon, 5 Aug 2013 18:47:03 -0400 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> <51FEEF73.9010405@googlemail.com> Message-ID: I'm mostly indifferent. The only reason I slightly prefer the .NET convention is to avoid confusion with statics (`GC` could easily be a static, `Gc` could not). +1 to having Graydon flip a coin. That way we can shift all blame to the fundamental randomness of the universe. -------------- next part -------------- An HTML attachment was scrubbed... URL: From coder543 at gmail.com Mon Aug 5 15:56:30 2013 From: coder543 at gmail.com (Josh Leverette) Date: Mon, 5 Aug 2013 17:56:30 -0500 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> <51FEEF73.9010405@googlemail.com> Message-ID: You may be able to look up the information elsewhere -- we have the whole internet at our disposal -- but that doesn't mean information isn't lost. A style convention for capitalization within a language is naturally a form of lossy compression intended to aid the human mind in getting to the correct answer accurately. Not all forms of lossy compression are as lossy as others, and different forms choose to preserve different types of data. .NET's style is lossier than I prefer, as a rule of thumb, but no style convention is perfect. On Mon, Aug 5, 2013 at 2:15 PM, Thad Guidry wrote: > > On Mon, Aug 5, 2013 at 1:40 PM, Josh Leverette wrote: > >> Better even than the "toggle mode caps" style of gc/gcMut? (assuming >> "mut" is an abbreviation here, if it's an acronym, then it would be >> gc/gcMUT) >> >> But of course, looks are purely subjective. The key is objective >> comparison. Pure .NET style loses information about whether something is an >> acronym or an abbreviation, and that information can be useful. >> >> > Josh, > > I would argue that the information is NOT lost... GcMut still means > "something somewhere", and the information of which is merely "moved over" > to another, better place, in the form of "documentation" like > http://seld.be/rustdoc/master/index.html...which can be easily searched > and parsed itself...and linked to other data and the greater Semantic Web, > tag and vocabulary systems, etc. > > -- > -Thad > Thad on Freebase.com > Thad on LinkedIn > -- Sincerely, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Mon Aug 5 16:08:40 2013 From: kevin at sb.org (Kevin Ballard) Date: Mon, 5 Aug 2013 16:08:40 -0700 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: <1178092E-C6E3-4B18-9E65-EA05D0693726@sb.org> References: <1178092E-C6E3-4B18-9E65-EA05D0693726@sb.org> Message-ID: <992D357C-D627-42A1-91BC-AC77A32C1690@sb.org> As an example of something that #3 makes possible, here's a proof-of-concept implementation of the previously-mentioned push back behavior (renamed here as .push_front(), because .push_back() in this context sounds like it pushes onto the end): pub struct PushFront { priv val: Option, priv iter: T } impl> PushFront { #[inline] fn new(iter: T) -> PushFront { PushFront{ val: None, iter: iter } } /// Pushes the value onto the front of the iterator, replacing any previous /// pushed value if it hasn't already been yielded. /// /// Only one value may be buffered at any time. #[inline] fn push_front(&mut self, val: A) { self.val = Some(val); } } impl> Iterator for PushFront { #[inline] fn next(&mut self) -> Option { if self.val.is_some() { self.val.take() } else { self.iter.next() } } #[inline] fn size_hint(&self) -> (uint, Option) { let (low, hi) = self.iter.size_hint(); if self.val.is_some() { (low+1, hi.map_consume(|x| if x < uint::max_value { x+1 } else { x })) } else { (low, hi) } } } impl> DoubleEndedIterator for PushFront { #[inline] fn next_back(&mut self) -> Option { match self.iter.next() { Some(x) => Some(x), None if self.val.is_some() => self.val.take(), _ => None } } } impl> RandomAccessIterator for PushFront { #[inline] fn indexable(&self) -> uint { let x = self.iter.indexable(); if self.val.is_some() { if x < uint::max_value { x+1 } else { x } } else { x } } #[inline] fn idx(&self, index: uint) -> Option { if index == 0 && self.val.is_some() { self.val.clone() } else { self.iter.idx(index-1) } } } -Kevin On Aug 4, 2013, at 8:33 PM, Kevin Ballard wrote: > You could certainly design a non-blocking IO iterator that way. My example of a non-blocking IO iterator wasn't meant to illustrate something I'd actually recommend you do (since the iterator protocol isn't really a great fit for this), but rather show the flexibility of the approach. > > That said, in the non-blocking IO approach, it does still "exhaust the elements available", it just so happens that more elements become available over time. > > A better example might be an iterator that allows you to push more elements onto the end. Or one that allows you to move the iterator backwards in time, so to speak, so it re-emits the same elements it emitted previously (e.g. give it a .prev() method). Or merely one that allows you to push back a single element (that gets yielded on the next call to .next()), which is actually fairly common in character iterators in other languages (gives you the equivalent of a .peek() operation, by consuming a value and then immediately pushing it back if you don't want it). None of these examples are possible with approaches #1 or #2, only with approach #3. And all of them are still compatible with the basic for loop. > > -Kevin > > On Aug 4, 2013, at 5:53 PM, Jason Fager wrote: > >> Not confused, I understand your point about for loops not caring about what happens with additional 'next' calls. >> >> But as a user of an iterator, I have the expectation that a for loop exhausts the elements available from an iterator unless I return early or break. Designing an iterator that intentionally sidesteps that expectation seems like a bad idea. Principle of least astonishment, etc. >> >> And yes, of course, iterators already return Option. But they return Option to satisfy the *iterator protocol*, not the use cases you described. I'm talking about adding another layer of Option >> >> So say I want to implement non-blocking io that plays nice w/ the iterator protocol. Using an implementation taking advantage of option#3 look something like: >> >> loop { >> for i in iter { >> foo(i); >> } >> // other stuff >> if(noReallyImDone) { >> break; >> } >> } >> >> >> While hoisting the Iterator's type into another layer of Option looks like: >> >> for i in iter { >> match i { >> Some(i) => foo(i); >> None => { >> //other stuff >> } >> } >> } >> >> The outer Option allows the iterator protocol to work as expected, i.e. iterate over all available elements in the iterator, and the inner implements the non-blocking protocol you're looking for. >> >> >> >> >> >> >> >> On Sun, Aug 4, 2013 at 8:12 PM, Kevin Ballard wrote: >> I suspect you're confused about something. >> >> The for loop doesn't care in the slightest what an iterator does after it's returned None. All 3 approaches work equally well as far as the for loop is concerned. >> >> And I'm not sure what you mean by "design Iterators that would take advantage of the undefined behavior". If an iterator defines how it behaves after returning None, then it's defined behavior. If you're using iterators and you know your entire iterator pipeline, then you can use whatever behavior the iterators involved define. You only need to restrict yourself to what the iterator protocol defines if you don't know what iterator you're consuming. >> >> I also don't understand your suggestion about using Option. Iterators already return an Option. >> >> -Kevin >> >> On Aug 4, 2013, at 4:45 PM, Jason Fager wrote: >> >>> Of course. I think I'm reacting more to the possible use cases you described for option 3 than the actual meaning of it. It seems like a really bad idea to design iterators that would take advantage of the undefined behavior, not least b/c it's unexpected and not supported by the most pervasive client of the iterator protocol (the for loop, in the sense of actually iterating through all elements available through the iterator), but that doesn't mean option 3 is in itself the wrong thing to do. >>> >>> But addressing the use cases you mentioned, if you need that kind of functionality, shouldn't you be hoisting the iterator's return type into its own Option? i.e., an Iterator should be become an Iterator>? >>> >>> >>> On Sun, Aug 4, 2013 at 6:23 PM, Kevin Ballard wrote: >>> The new for loop works with all 3 of these. Your output shows that it queried .next() twice, and got a single Some(1) result back. Once it gets None, it never calls .next() again, whereas the 3 behaviors stated previously are exclusively concerned with what happens if you call .next() again after it has already returned None. >>> >>> -Kevin >>> >>> P.S. I changed the email address that I'm subscribed to this list with, so apologies for any potential confusion. >>> >>> On Aug 4, 2013, at 6:18 AM, Jason Fager wrote: >>> >>>> The new for loop already assumes #2, right? >>>> >>>> let x = [1,2,3]; >>>> let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if *st { *st = false; Some(x) } else { None } }); >>>> >>>> for i in it { >>>> printfln!("from for loop: %?", i); >>>> } >>>> >>>> >>>> Which produces: >>>> >>>> &1 >>>> from for loop: 1 >>>> &2 >>>> >>>> >>>> >>>> On Sun, Aug 4, 2013 at 1:49 AM, Daniel Micay wrote: >>>> On Sat, Aug 3, 2013 at 9:18 PM, Kevin Ballard wrote: >>>> > The iterator protocol, as I'm sure you're aware, is the protocol that >>>> > defines the behavior of the Iterator trait. Unfortunately, at the moment the >>>> > trait does not document what happens if you call `.next()` on an iterator >>>> > after a previous call has returned `None`. According to Daniel Micay, the >>>> > intention was that the iterator would return `None` forever. However, this >>>> > is not guaranteed by at least one iterator adaptor (Scan), nor is it >>>> > documented. Furthermore, no thought has been given to what happens if an >>>> > iterator pipeline has side-effects. A trivial example of the side-effect >>>> > problem is this: >>>> > >>>> > let x = [1,2,3]; >>>> > let mut it = x.iter().peek_(|x| printfln!(*x)).scan(true, |st, &x| { if >>>> > *st { *st = false; Some(x) } else { None } }); >>>> > (it.next(), it.next(), it.next()) >>>> > >>>> > This results in `(Some(1), None, None)` but it prints out >>>> > >>>> > &1 >>>> > &2 >>>> > &3 >>>> > >>>> > After giving it some thought, I came up with 3 possible definitions for >>>> > behavior in this case: >>>> > >>>> > 1. Once `.next()` has returned `None`, it will return None forever. >>>> > Furthermore, calls to `.next()` after `None` has been returned will not >>>> > trigger side-effects in the iterator pipeline. This means that once >>>> > `.next()` has returned `None`, it becomes idempotent. >>>> > >>>> > This is most likely going to be what people will assume the iterator >>>> > protocol defines, in the absence of any explicit statement. What's more, >>>> > they probably won't even consider the side-effects case. >>>> > >>>> > Implementing this will require care be given to every single iterator and >>>> > iterator adaptor. Most iterators will probably behave like this (unless they >>>> > use a user-supplied closure), but a number of different iterator adaptors >>>> > will need to track this explicitly with a bool flag. It's likely that >>>> > user-supplied iterator adaptors will forget to enforce this and will >>>> > therefore behave subtlely wrong in the face of side-effects. >>>> > >>>> > 2. Once `.next()` has returned `None`, it will return `None` forever. No >>>> > statement is made regarding side-effects. >>>> > >>>> > This is what most people will think they're assuming, if asked. The >>>> > danger here is that they will almost certainly actaully assume #1, and thus >>>> > may write subtlely incorrect code if they're given an iterator pipeline with >>>> > side-effects. >>>> > >>>> > This is easier to implement than #1. Most iterators will do this already. >>>> > Iterator adaptors will generally only have to take care when they use a >>>> > user-supplied closure (e.g. `scan()`). >>>> > >>>> > 3. The behavior of `.next()` after `None` has been returned is left >>>> > undefined. Individual iterators may choose to define behavior here however >>>> > they see fit. >>>> > >>>> > This is what we actually have implemented in the standard libraries >>>> > today. It's also by far the easiest to implement, as iterators and adaptors >>>> > may simply choose to not define any particular behavior. >>>> > >>>> > This is made more attractive by the fact that some iterators may choose >>>> > to actually define behavior that's different than "return `None` forever". >>>> > For example, a user may write an iterator that wraps non-blocking I/O, >>>> > returning `None` when there's no data available and returning `Some(x)` >>>> > again once more data comes in. Or if you don't like that example, they could >>>> > write an iterator that may be updated to contain more data after being >>>> > exhausted. >>>> > >>>> > The downside is that users may assume #1 when #3 holds, which is why this >>>> > needs to be documented properly. >>>> > >>>> > --- >>>> > >>>> > I believe that #3 is the right behavior to define. This gives the most >>>> > flexibility to individual iterators, and we can provide an iterator adaptor >>>> > that gives any iterator the behavior defined by #1 (see Fuse in PR #8276). >>>> > >>>> > I am not strongly opposed to defining #1 instead, but I am mildly worried >>>> > about the likelihood that users will implement iterators that don't have >>>> > this guarantee, as this is not something that can be statically checked by >>>> > the compiler. What's more, if an iterator breaks this guarantee, the problem >>>> > will show up in the code that calls it, rather than in the iterator itself, >>>> > which may make debugging harder. >>>> > >>>> > I am strongly opposed to #2. If we guarantee that an iterator that returns >>>> > `None` once will return `None` forever, users will assume that this means >>>> > that `.next()` becomes idempotent (with regards to side-effects) after >>>> > `None` is returned, but this will not be true. Furthermore, users will >>>> > probably not even realize they've made a bad assumption, as most users will >>>> > not be thinking about side-effects when consuming iterators. >>>> > >>>> > I've already gone ahead and implemented #3 in pull request #8276. >>>> > >>>> > -Kevin >>>> >>>> I'm leaning towards #2 or #3, mostly because adaptors *not* >>>> dispatching to the underlying next() implementation are too complex. >>>> >>>> I took a look at the behaviour of Python's iterators in these corner >>>> cases as good baseline for comparison: >>>> >>>> ~~~ >>>> >>> def peek(it): >>>> ... for x in it: >>>> ... print(x) >>>> ... yield x >>>> ... >>>> >>> xs = [1, 2, 3] >>>> >>> ys = [1, 2, 3, 4, 5] >>>> ~~~ >>>> >>>> You can tell their `zip` function short-circuits, and simply >>>> dispatches to the underlying implementations. Rust's `zip` is similar >>>> but doesn't currently short-circuit (it might as well). >>>> >>>> ~~~ >>>> >>> it = zip(peek(ys), xs) >>>> >>> next(it) >>>> 1 >>>> (1, 1) >>>> >>> next(it) >>>> 2 >>>> (2, 2) >>>> >>> next(it) >>>> 3 >>>> (3, 3) >>>> >>> next(it) >>>> 4 >>>> Traceback (most recent call last): >>>> File "", line 1, in >>>> StopIteration >>>> >>> next(it) >>>> 5 >>>> Traceback (most recent call last): >>>> File "", line 1, in >>>> StopIteration >>>> >>> next(it) >>>> Traceback (most recent call last): >>>> File "", line 1, in >>>> StopIteration >>>> >>> it = zip(xs, peek(ys)) >>>> >>> next(it) >>>> 1 >>>> (1, 1) >>>> >>> next(it) >>>> 2 >>>> (2, 2) >>>> >>> next(it) >>>> 3 >>>> (3, 3) >>>> >>> next(it) >>>> Traceback (most recent call last): >>>> File "", line 1, in >>>> StopIteration >>>> ~~~ >>>> >>>> It also makes no attempt to store whether it has stopped internally, >>>> and will start yielding again if each iterator yields an element when >>>> zip asks for them one by one (keeping in mind that it short-circuits). >>>> >>>> Most other language keep `hasNext` and `next` separate (D and Scala, >>>> among others) leading to more corner cases, and they do not seem to >>>> clearly define the semantics for side effects down the pipeline. >>>> >>>> http://dlang.org/phobos/std_range.html >>>> http://www.scala-lang.org/api/current/scala/collection/Iterator.html >>>> _______________________________________________ >>>> Rust-dev mailing list >>>> Rust-dev at mozilla.org >>>> https://mail.mozilla.org/listinfo/rust-dev >>>> >>>> _______________________________________________ >>>> Rust-dev mailing list >>>> Rust-dev at mozilla.org >>>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> > From illissius at gmail.com Mon Aug 5 17:15:58 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Tue, 6 Aug 2013 02:15:58 +0200 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: <51FC5CDB.6000902@mozilla.com> References: <51FC5CDB.6000902@mozilla.com> Message-ID: I think I prefer .NET style. I liked the mixed approach, until I saw it applied to GC/GcMut and co. I'm ambivalent about grandfathering in IO: consistency is good, but Io /really does/ look unusually stupid, with other acronyms it's not as ingrained for whatever reason. (I wonder whether it has anything to do at a subconscious level with the fact that, in Input/Output, the two words are on the same level and independent, whereas in e.g. "garbage collected", the latter depends on the former... or whether it's just frequency of exposure.) The one case where I don't like .NET is when an acronym also forms a familiar word, i.e. Arc. The solution there might just be to rename it to AtomicRc. (That would /also/ be helpful to avoid confusion with Apple's ARC.) On Sat, Aug 3, 2013 at 3:28 AM, Patrick Walton wrote: > Hi everyone, > > Brendan Eich emailed me expressing a preference for `GC<>` over `Gc<>`. I > think now is as good a time as any to have the bikeshedding debate :) > > I've noticed two styles for acronyms in type names: Java style (HTTPServer) > versus .NET style (HttpServer). Currently we are usually using .NET style, > but inconsistently (e.g. ARC). We never really decided. > > Here are a few examples of types in each style: > > * Java style: GC, ARC, SimpleHTTPServer, XMLHTTPRequest. > > * .NET style: Gc, Arc, SimpleHttpServer, XmlHttpRequest. > > I slightly prefer Java style myself because I think "GC" looks better than > "Gc", because Web APIs use Java style, and because Python does (e.g. > SimpleHTTPServer) and in general we've been following PEP 8. But I don't > feel strongly on this issue. > > Thoughts/straw poll? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- Your ship was destroyed in a monadic eruption. From illissius at gmail.com Mon Aug 5 18:16:36 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Tue, 6 Aug 2013 03:16:36 +0200 Subject: [rust-dev] RFC: Overloadable dereference operator In-Reply-To: <51F74F10.5060808@mozilla.com> References: <51F74F10.5060808@mozilla.com> Message-ID: I agree that overloadable * would be very desirable for smart pointers. I also really like the interaction with newtypes. Is it still the plan (from the GC thread) to push all mutability into Cell? Would that interact with this proposal in any way (e.g. to allow mutating through * in some cases)? The method lookup part of it feels too magical. What if both the pointer and the pointee have a method with the same name? In general, how can you tell whether you're calling a method on the "pointer" or the "pointee"? The reason using the dot both for calling methods directly and for calling them through pointers worked so far is that pointers didn't have methods. Disambiguating this situation is what C++ has the -> operator for: would it be so bad to adopt it? With a simple desugaring to (*foo).bar it would remove the magic, and the common fields use case would also continue to work with a different syntax. I'm guessing this is another of those decisions that was discussed and settled a long time ago. Is there any other language with universal dot notation where custom smart pointers are common? On Tue, Jul 30, 2013 at 7:28 AM, Patrick Walton wrote: > Currently, newtype structs automatically dereference to the value they > contain; for example: > > struct MyInt(int); > fn main() { > let x = MyInt(3); > printfln("1 + 2 = " + x.to_str()); // prints "1 + 2 = 3" > } > > This behavior is sometimes undesirable, as Brian often points out. Haskell > allows behavior similar to this to be controlled on an opt-in basis with > `GeneralizedNewtypeDeriving`. I think these are subtly different. Rust is automatically unwrapping the newtype when calling a method on it, while Haskell is automatically generating requested trait impls based on the ones for the inner type. But not vice versa: for functions other than those on derived traits/classes Haskell still requires manual unwrapping, and Rust doesn't consider the newtype to impl traits just because the inner type does. Allowing overloads of */-> on newtypes and GeneralizedNewtypeDeriving would be independently useful features (just be careful when mixing the latter with associated types). -- Your ship was destroyed in a monadic eruption. From kevin at sb.org Mon Aug 5 18:23:21 2013 From: kevin at sb.org (Kevin Ballard) Date: Mon, 5 Aug 2013 18:23:21 -0700 Subject: [rust-dev] RFC: Overloadable dereference operator In-Reply-To: References: <51F74F10.5060808@mozilla.com> Message-ID: Go calls methods through pointers using ., and allows for method declarations on pointers as well as structs. It also allows for embedding one struct in another, and method resolution will search the embedded struct if the embedding struct doesn't have a match. This seems to be working well there. I don't see why it can't work for Rust. -Kevin On Aug 5, 2013, at 6:16 PM, G?bor Lehel wrote: > I agree that overloadable * would be very desirable for smart > pointers. I also really like the interaction with newtypes. Is it > still the plan (from the GC thread) to push all mutability into Cell? > Would that interact with this proposal in any way (e.g. to allow > mutating through * in some cases)? > > The method lookup part of it feels too magical. What if both the > pointer and the pointee have a method with the same name? In general, > how can you tell whether you're calling a method on the "pointer" or > the "pointee"? The reason using the dot both for calling methods > directly and for calling them through pointers worked so far is that > pointers didn't have methods. Disambiguating this situation is what > C++ has the -> operator for: would it be so bad to adopt it? With a > simple desugaring to (*foo).bar it would remove the magic, and the > common fields use case would also continue to work with a different > syntax. I'm guessing this is another of those decisions that was > discussed and settled a long time ago. Is there any other language > with universal dot notation where custom smart pointers are common? > > On Tue, Jul 30, 2013 at 7:28 AM, Patrick Walton wrote: >> Currently, newtype structs automatically dereference to the value they >> contain; for example: >> >> struct MyInt(int); >> fn main() { >> let x = MyInt(3); >> printfln("1 + 2 = " + x.to_str()); // prints "1 + 2 = 3" >> } >> >> This behavior is sometimes undesirable, as Brian often points out. Haskell >> allows behavior similar to this to be controlled on an opt-in basis with >> `GeneralizedNewtypeDeriving`. > > I think these are subtly different. Rust is automatically unwrapping > the newtype when calling a method on it, while Haskell is > automatically generating requested trait impls based on the ones for > the inner type. But not vice versa: for functions other than those on > derived traits/classes Haskell still requires manual unwrapping, and > Rust doesn't consider the newtype to impl traits just because the > inner type does. Allowing overloads of */-> on newtypes and > GeneralizedNewtypeDeriving would be independently useful features > (just be careful when mixing the latter with associated types). > > -- > Your ship was destroyed in a monadic eruption. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From bjzaba at yahoo.com.au Mon Aug 5 20:06:06 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 6 Aug 2013 13:06:06 +1000 Subject: [rust-dev] Order of appearance in files of extern mod, mod and use In-Reply-To: <520002A2.1000203@gmail.com> References: <520002A2.1000203@gmail.com> Message-ID: <3E28D6EA-67A1-4250-B741-53DDCED11BE3@yahoo.com.au> That was my understanding. Without knowing much about the compiler, `mod` seems to declare an item. It would be weird to allow imports between item declarations. ~Brendan On 06/08/2013, at 5:53 AM, Gareth Smith wrote: > On 05/08/13 19:56, Dov Reshef wrote: >> >> If I understand correctly "mod foo" import the foo module into the current module, and "use foo::bar" bring bar from foo module into the current scope, so it seems more logical that use should follow mod, not the other way around. > > My understanding is that "mod foo;" is kind of like "mod foo { ... }" except that with "mod foo;" the body of the module comes from a different file, so it is more like a definition than an import. > > Gareth > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From graydon at mozilla.com Mon Aug 5 20:16:12 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 05 Aug 2013 20:16:12 -0700 Subject: [rust-dev] Java versus .NET style for acronyms in type names In-Reply-To: References: <51FC5CDB.6000902@mozilla.com> <51FEEF73.9010405@googlemail.com> Message-ID: <52006A7C.5010205@mozilla.com> On 13-08-05 03:47 PM, Benjamin Striegel wrote: > I'm mostly indifferent. The only reason I slightly prefer the .NET > convention is to avoid confusion with statics (`GC` could easily be a > static, `Gc` could not). > > +1 to having Graydon flip a coin. That way we can shift all blame to the > fundamental randomness of the universe. I'll declare it ".NET style" if it'll stop this thread! Goodness. We had _two people_ unsubscribe during it! Teach me to step away from the computer for a weekend of R&R. -Graydon (Fwiw I actually prefer "everything_in_lowercase" but I lost that one a few years ago, around when I started writing my name, and new sentences, with a leading capital. Pfft.) From ivan.ristic at gmail.com Tue Aug 6 08:31:35 2013 From: ivan.ristic at gmail.com (=?UTF-8?B?SXZhbiBSaXN0acSH?=) Date: Tue, 06 Aug 2013 16:31:35 +0100 Subject: [rust-dev] Help with a trivial TCP client example needed In-Reply-To: References: <51FB6967.4050401@gmail.com> <51FD56D7.3060602@gmail.com> Message-ID: <520116D7.1040003@gmail.com> On 04/08/2013 12:16, Chris Morgan wrote: > Your example looked like it should be correct, but I'm not going to > figure out why it's not working, because extra::net no longer exists > in the Rust development head. > > Here is an example using the new runtime TCP library, which is > currently in std::rt::io::net. Thank you. In the meantime I also came across your HTTP server written in Rust, and I will keep an eye on it. Is it known when the new net stuff is expected to stabilize? > Whether it compiles on Rust 0.7 or not (it doesn't quite, due to the > buf.slice_to call), this example will not run there; the newrt TCP was > broken at that time. > > This example is also just about to be slightly out of date; > https://github.com/mozilla/rust/pull/8243 is changing `Ipv4(a, b, c, > d, p)` to `SocketAddr { ip: Ipv4Addr(a, b, c, d), port: p }`. > > You will need to run this with the environment variable RUST_NEWRT=1 > or you'll meet with a terrible fate, won't you. > > use std::rt::io::net::ip::Ipv4; > use std::rt::io::net::tcp::TcpStream; > use std::rt::io::{Reader, Writer}; > use std::str; > > fn main() { > let mut stream = TcpStream::connect(Ipv4(204, 232, 212, 130, > 80)).expect("failed to connect :-("); > > stream.write(bytes!("GET / HTTP/1.0\r\n\r\n").to_owned()); > let mut buf = [0u8, ..2000]; > match stream.read(buf) { > None => fail!("Read error :-("), > Some(bytes_read) => { > println(str::from_bytes(buf.slice_to(bytes_read))); > } > } > } > > Whether this works for thee or no, it doth for me and prints a > perfectly normal HTTP response. > > Note that while the old system used a Result for `connect` and `read`, > the new one uses conditions and returns an Option. There are some > details in the std::rt::io docs (src/libstd/rt/io/mod.rs). > > On Fri, Aug 2, 2013 at 1:10 AM, Ivan Risti? wrote: >> I am starting to play with Rust, but I got stuck early on with a trivial >> TCP client example. (There's a few server examples out there, but I >> couldn't find a single working client anywhere. I tried the archives, >> the tests, etc.) >> >> My naive approach sends some data to the server and then attempts to >> read, but socket.read() always times out. I have verified that the >> server is receiving the request and responding to it. >> >> I came across a couple of tickets that suggest that I might be handling >> the event loop incorrectly, but I don't know enough to fix the code. >> >> Your help is appreciated. Thanks. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Ivan From graydon at mozilla.com Tue Aug 6 09:24:57 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 06 Aug 2013 09:24:57 -0700 Subject: [rust-dev] Order of appearance in files of extern mod, mod and use In-Reply-To: <3E28D6EA-67A1-4250-B741-53DDCED11BE3@yahoo.com.au> References: <520002A2.1000203@gmail.com> <3E28D6EA-67A1-4250-B741-53DDCED11BE3@yahoo.com.au> Message-ID: <52012359.7010308@mozilla.com> On 13-08-05 08:06 PM, Brendan Zabarauskas wrote: > That was my understanding. Without knowing much about the compiler, `mod` seems to declare an item. It would be weird to allow imports between item declarations. Yes. 'mod foo' is a definition just like 'mod foo { ... }' and will shadow any 'use' directive. As a result of this shadowing relationship, we decided to mandate that the definitions come after the things-they-shadow. It used to be possible to mix them freely and it was confusing to see a definition _before_ a 'use' still shadowing it. (People have spatial / order intuitions about shadowing, when it exists) -Graydon From corey at octayn.net Tue Aug 6 10:09:40 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 6 Aug 2013 13:09:40 -0400 Subject: [rust-dev] rustdoc_ng metabug Message-ID: Hi all, If you're doing triage and happen to come upon a rustdoc bug, do cc @cmr and know that https://github.com/mozilla/rust/issues/8125 exists. Thanks From corey at octayn.net Tue Aug 6 10:16:55 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 6 Aug 2013 13:16:55 -0400 Subject: [rust-dev] This Week in Rust Message-ID: Sorry that I forgot to send this earlier. Content from http://cmr.github.io/blog/2013/08/04/this-week-in-rust/. -- Hello and welcome to the ninth issue of *This Week in Rust*. This week brings the new `for` loop, which is very exciting, as well as a bunch of runtime changes and cleanup. # What's cooking on `master`? Issue churn was +4 this week. A total of 63 PRs were merged (again). ## Breaking Changes - **The `for` loop now uses external iterators.** This means any code written to use the old internal iterator protocol will no longer work. See the [iterator tutorial](http://static.rust-lang.org/doc/tutorial-container.html) for more information on how to use it. Related pull requests: [#8141](https://github.com/mozilla/rust/pull/8141), [#8184](https://github.com/mozilla/rust/pull/8184), [#8190](https://github.com/mozilla/rust/pull/8190), [#8244](https://github.com/mozilla/rust/pull/8244). A few uses now require `do` rather than `for` because they cannot/have not been implemented in terms of external iterators. - `unsafe` is [no longer allowed](https://github.com/mozilla/rust/pull/8235) for functions in `extern` blocks: they are all unsafe. - The [`extra::dbg` module](https://github.com/mozilla/rust/pull/8175) has been removed. - `uint::range` and all its friends have been replaced with an [external iterator](https://github.com/mozilla/rust/pull/8216), that is in the prelude. Code like the following now works: ``` for x in range(0, 10) { println(x.to_str()); } ``` - The pipes compiler (the thing driving `proto!`) [has been removed](https://github.com/mozilla/rust/pull/8170), as it saw limited use, was very old, and was a significant maintenance burden. - `PortSet` [has been removed](https://github.com/mozilla/rust/pull/8164) from std, as the new scheduler does not support it. - A bunch of old task APIs [have been removed](https://github.com/mozilla/rust/pull/8139), aslo in preparation for the new schduler. - `is_utf8` now [rejects overlong encodings](https://github.com/mozilla/rust/pull/8133). - The iterator adaptors [no longer have the Iterator suffix](https://github.com/mozilla/rust/pull/8090), same with [str and vec iterators](https://github.com/mozilla/rust/pull/8095) as well. ## newrt changes A bunch of newrt things landed this week, so it gets its own section. - Some [bugs preventing the arc and sync tests from passing](https://github.com/mozilla/rust/pull/8234) have been fixed. - The new scheduler now supports [the `SingleThreaded` spawn mode](https://github.com/mozilla/rust/pull/8221). - A bunch of work with task killing [has landed](https://github.com/mozilla/rust/pull/8195). - Some [major TLS changes](https://github.com/mozilla/rust/pull/8116) also landed. - Tasks can [now be named](https://github.com/mozilla/rust/pull/8158). - [`select` on newrt pipes](https://github.com/mozilla/rust/pull/8008) has been implemented. ## Notable library additions, bugfixes, and cleanup - `Map::contains_key` is [now a default method](https://github.com/mozilla/rust/pull/8246) implemented in terms of `Map::find` - A `dynamic_lib` segfault [has been fixed](https://github.com/mozilla/rust/pull/8219). - A keyed `HashMap` constructor is [now exposed](https://github.com/mozilla/rust/pull/8186) for runtimeless programs that want to use it. - The `Str` trait now has an [`into_owned` method](https://github.com/mozilla/rust/pull/8204) to avoid copies when you already have a `~str`. - A bunch of [SHA1 and SHA2 cleanup/optimizations](https://github.com/mozilla/rust/pull/8174) landed. I hear that the speed is almost optimal, only a few cycles/byte short of Intel's optimized implementation. - Errno coverage has been [significantly expanded for Linux](https://github.com/mozilla/rust/pull/8193). I added all of the ones that were missing, at least the ones that were present on my system. - `assert!()` without a message [now does less allocation](https://github.com/mozilla/rust/pull/8150). - '\' is [no longer treated as a path separater](https://github.com/mozilla/rust/pull/8138) on POSIX system. - `getopt`'s `opts_str` [has been corrected to use more than just the first element of the vector](https://github.com/mozilla/rust/pull/8135). - Some more methods [were added](https://github.com/mozilla/rust/pull/8115) in `std::num`. - An iterator over the offsets of each character in a string [was added](https://github.com/mozilla/rust/pull/8082). - A bunch of `RandomAccessIterator` implementations [have been added](https://github.com/mozilla/rust/pull/8120). - `Clone` and `DeepClone` are [now implemented](https://github.com/mozilla/rust/pull/8109) for `extern "Rust" fn`. ## Notable compiler additions, bugfixes, and cleanup - A `cfg!` syntax extension [has been added](https://github.com/mozilla/rust/pull/8188) for conditionally running code based on crate configuration, similar to what `#[cfg]` does for conditional compilation. It expands into a true/false constant, so LLVM should optimize out the dead branches. - Some more codegen tests [have been added](https://github.com/mozilla/rust/pull/8165). - `copy` [has been removed as a keyword](https://github.com/mozilla/rust/pull/8162). - Static struct initializers [can now contain `..base`](https://github.com/mozilla/rust/pull/8091) for functional update. - Take glue [has been unified](https://github.com/mozilla/rust/pull/8146) for unique pointer type. - Pointer arithmetic is [now implemented with GEP](https://github.com/mozilla/rust/pull/8121) rather than casting to int and back to the pointer. - Some more AST types [were renamed](https://github.com/mozilla/rust/pull/8107). - Cross-crate conditions [now work](https://github.com/mozilla/rust/pull/8185). ## Documentation, tools, and other stuff - LLVM assertions [can now be disabled](https://github.com/mozilla/rust/pull/8147) with a configure option. - Benchmarking can [now be disabled](https://github.com/mozilla/rust/pull/8111) by passing `NO_BENCH=1` to make. - `NO_REBUILD` [no longer requires a re-boostrap](https://github.com/mozilla/rust/pull/8110), which should make debug cycles on libstd much shorter. - `vec` [now has module documentation](https://github.com/mozilla/rust/pull/7223). - rustpkg [now handles tags](https://github.com/mozilla/rust/pull/8032), and not just version numbers, in the package ID. # Meetings The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-07-30) this week was quite meaty. I'm not going to try to summarize it, as it seems no real decisions were made. # Discussion + Blog posts - [Visibility scopes in Rust Debug Info](http://michaelwoerister.github.io/2013/08/03/visibility-scopes.html). - [Architecting Servo: Pipelines and Parallelism](https://air.mozilla.org/2013-intern-kuehn/), a talk by Tim Kuehn. - [Runtimeless sprocketnes](http://www.reddit.com/r/rust/comments/1jo431/runtimeless_sprocketnes/). - [Porting machine learning algorithms to Rust](http://www.reddit.com/r/rust/comments/1joy7f/porting_machine_learning_algorithms_to_rust/). - [RFC: Overloadable dereference operator](https://mail.mozilla.org/pipermail/rust-dev/2013-July/005039.html). # External projects - [RustGnuplot](https://github.com/SiegeLord/RustGnuplot) was updated to latest Rust. - A [protobuf implementation](https://github.com/stepancheg/rust-protobuf) has been started. - [rustsqlite](https://github.com/linuxfood/rustsqlite) has been updated to latest Rust. - A [library for HTML escaping](https://github.com/veddan/rust-htmlescape) has been created. - A [library for procedurally generating noise](https://github.com/bjz/noise-rs) has been created. - A [pure-Rust implementation of Keccak](https://github.com/MarkJr94/rust-keccak) has been created. - [rust-zmq](https://github.com/erickt/rust-zmq) has been updated to latest Rust, as well as cleaner error/constant interface. - [q3](https://github.com/Jeaye/q3) now does multithreaded rendering. From armin.ronacher at active-4.com Wed Aug 7 07:18:33 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Wed, 07 Aug 2013 15:18:33 +0100 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: References: Message-ID: <52025739.7000903@active-4.com> Hi, On 04/08/2013 02:18, Kevin Ballard wrote: > I believe that #3 is the right behavior to define. This gives the most > flexibility to individual iterators, and we can provide an iterator > adaptor that gives any iterator the behavior defined by #1 (see Fuse in > PR #8276 ). I think #3 is a terrible idea. It requires that every user of an iterator needs to keep track of if the iterator was exhausted and need to replace it with a dummy iterator that yields None forever or signal to other code that the iterator is exhausted. There is a lot of code that fetches a number of items from an iterator and then passes the iterator on to something else that does more with it. If I now need to check if the iterator was exhaused and then create a new and empty iterator to pass onwards to the other function it makes it a lot more complicated. Imagine this Python code: def dropwhile(predicate, iterable): iterable = iter(iterable) for x in iterable: if not predicate(x): yield x break for x in iterable: yield x If it's not guaranteed that an iterator returns None (StopIteration) after it was exhausted it needs to be rewritten to this: def dropwhile(predicate, iterable): iterable = iter(iterable) exhausted = True for x in iterable: if not predicate(x): yield x exhausted = False break if not exhausted: for x in iterable: yield x People will forget that they have to do this and cause bugs with composable iterator patterns. Just look through the Python itertools package for how many cases of partial iterator processing exist: http://docs.python.org/2/library/itertools.html Regards, Armin From kevin at sb.org Wed Aug 7 12:28:04 2013 From: kevin at sb.org (Kevin Ballard) Date: Wed, 7 Aug 2013 12:28:04 -0700 Subject: [rust-dev] Proposal for clarifying the iterator protocol In-Reply-To: <52025739.7000903@active-4.com> References: <52025739.7000903@active-4.com> Message-ID: <1F62D518-0A39-46D9-ADDE-127415AF58FE@sb.org> Most clients of iterators won't care if they exhausted the iterator. The vast majority of use cases looks like for pat in iter { // do stuff } // never touch iter again For the few times where you might actually care, that's what the Fuse adaptor is for, so you can say let mut iter = iter.fuse(); // now the iterator conforms to behavior #1 -Kevin On Aug 7, 2013, at 7:18 AM, Armin Ronacher wrote: > Hi, > > On 04/08/2013 02:18, Kevin Ballard wrote: >> I believe that #3 is the right behavior to define. This gives the most >> flexibility to individual iterators, and we can provide an iterator >> adaptor that gives any iterator the behavior defined by #1 (see Fuse in >> PR #8276 ). > I think #3 is a terrible idea. It requires that every user of an iterator needs to keep track of if the iterator was exhausted and need to replace it with a dummy iterator that yields None forever or signal to other code that the iterator is exhausted. There is a lot of code that fetches a number of items from an iterator and then passes the iterator on to something else that does more with it. > > If I now need to check if the iterator was exhaused and then create a new and empty iterator to pass onwards to the other function it makes it a lot more complicated. Imagine this Python code: > > def dropwhile(predicate, iterable): > iterable = iter(iterable) > for x in iterable: > if not predicate(x): > yield x > break > for x in iterable: > yield x > > If it's not guaranteed that an iterator returns None (StopIteration) after it was exhausted it needs to be rewritten to this: > > def dropwhile(predicate, iterable): > iterable = iter(iterable) > exhausted = True > for x in iterable: > if not predicate(x): > yield x > exhausted = False > break > if not exhausted: > for x in iterable: > yield x > > People will forget that they have to do this and cause bugs with composable iterator patterns. Just look through the Python itertools package for how many cases of partial iterator processing exist: http://docs.python.org/2/library/itertools.html > > > Regards, > Armin > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From graydon at mozilla.com Wed Aug 7 13:37:15 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 07 Aug 2013 13:37:15 -0700 Subject: [rust-dev] android builder active Message-ID: <5202AFFB.4090508@mozilla.com> Hi, Just a heads-up: there's a newly configured builder in the buildbot auto group that does a linux->android cross compile. It does not presently run any tests, though at some point it probably will. But for bors to land new code, it must now at least _build_ on android-cross. See: http://buildbot.rust-lang.org/builders/auto-linux-64-x-android https://github.com/mozilla/rust/wiki/Doc-building-for-android -Graydon From duddlf.choi at samsung.com Wed Aug 7 16:58:58 2013 From: duddlf.choi at samsung.com (=?euc-kr?B?w9a/tcDP?=) Date: Wed, 07 Aug 2013 23:58:58 +0000 (GMT) Subject: [rust-dev] android builder active Message-ID: <15675801.311811375919937035.JavaMail.weblogic@epv6ml02> Thanks! I am describing additional information for further configuration to run test - need to configure default AVD (Android Virtual Devices) to run test http://developer.android.com/tools/help/avd-manager.html http://developer.android.com/tools/devices/managing-avds.html can copy existing avd files of other devices located in ~[user]/.android/avd/[AVD name].avd ~[user]/.android/avd/[AVD name].ini - need to activate Android emulator contains in android-sdk Typically [Android_SDK_Path]/tools/emulator64-arm or [Android_SDK_Path]/tools/emulator-arm with argument no-window e.g.) /opt/andoird-sdk/tools/emulator64-arm -avd [AVD name] -no-window if emulator runs successfuly, It might checked with "adb devices" [jet@~] adb devices List of devices attached emulator-5554 device - then make check with Rust configured arm-linux-androideabi ------- Original Message ------- Sender : Graydon Hoare Date : 2013-08-08 05:37 (GMT+09:00) Title : [rust-dev] android builder active Hi, Just a heads-up: there's a newly configured builder in the buildbot auto group that does a linux->android cross compile. It does not presently run any tests, though at some point it probably will. But for bors to land new code, it must now at least _build_ on android-cross. See: http://buildbot.rust-lang.org/builders/auto-linux-64-x-android https://github.com/mozilla/rust/wiki/Doc-building-for-android -Graydon _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev

 

 

From banderson at mozilla.com Wed Aug 7 19:32:13 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 07 Aug 2013 19:32:13 -0700 Subject: [rust-dev] android builder active In-Reply-To: <5202AFFB.4090508@mozilla.com> References: <5202AFFB.4090508@mozilla.com> Message-ID: <5203032D.1030205@mozilla.com> On 08/07/2013 01:37 PM, Graydon Hoare wrote: > Hi, > > Just a heads-up: there's a newly configured builder in the buildbot auto > group that does a linux->android cross compile. It does not presently > run any tests, though at some point it probably will. But for bors to > land new code, it must now at least _build_ on android-cross. > This build slave was slightly misconfigured such that it wasn't actually cross-compiling to Android. My mistake! I've attempted a tweak. From jens at nockert.se Thu Aug 8 01:53:33 2013 From: jens at nockert.se (Jens Nockert) Date: Thu, 8 Aug 2013 10:53:33 +0200 Subject: [rust-dev] android builder active In-Reply-To: <5202AFFB.4090508@mozilla.com> References: <5202AFFB.4090508@mozilla.com> Message-ID: <2506D826-0919-44DC-B365-A3E1DA2D9A00@nockert.se> Hello, On 7 Aug 2013, at 22:37, Graydon Hoare wrote: > Just a heads-up: there's a newly configured builder in the buildbot auto > group that does a linux->android cross compile. It does not presently > run any tests, though at some point it probably will. But for bors to > land new code, it must now at least _build_ on android-cross. Is there a possibility for it to build for all three major Android architectures in the future (x86, mipsel and arm?) so there's even less possibility of breakage? Ps. If someone want remote access to a Android mipsel tablet, I could probably manage to set that up, otherwise they are dead cheap to pick up. From duddlf.choi at samsung.com Thu Aug 8 01:57:43 2013 From: duddlf.choi at samsung.com (=?euc-kr?B?w9a/tcDP?=) Date: Thu, 08 Aug 2013 08:57:43 +0000 (GMT) Subject: [rust-dev] android builder active Message-ID: <1389201.334081375952262749.JavaMail.weblogic@epv6ml02> The reason to setup ARM Android build bot is to test "ARM" architecture not general "Android" itself. I think emulator is enough to test Rust not needed actual device right now. ------- Original Message ------- Sender : Jens Nockert Date : 2013-08-08 17:53 (GMT+09:00) Title : Re: [rust-dev] android builder active Hello, On 7 Aug 2013, at 22:37, Graydon Hoare wrote: > Just a heads-up: there's a newly configured builder in the buildbot auto > group that does a linux->android cross compile. It does not presently > run any tests, though at some point it probably will. But for bors to > land new code, it must now at least _build_ on android-cross. Is there a possibility for it to build for all three major Android architectures in the future (x86, mipsel and arm?) so there's even less possibility of breakage? Ps. If someone want remote access to a Android mipsel tablet, I could probably manage to set that up, otherwise they are dead cheap to pick up. _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev

 

 

From kmcallister at mozilla.com Thu Aug 8 10:36:04 2013 From: kmcallister at mozilla.com (Keegan McAllister) Date: Thu, 8 Aug 2013 10:36:04 -0700 (PDT) Subject: [rust-dev] android builder active In-Reply-To: <1389201.334081375952262749.JavaMail.weblogic@epv6ml02> References: <1389201.334081375952262749.JavaMail.weblogic@epv6ml02> Message-ID: <603769938.4188764.1375983364257.JavaMail.zimbra@mozilla.com> In that case it might be easier to build the tests as normal ARM GNU/Linux binaries and run them in magic QEMUlated chroots: https://wiki.ubuntu.com/UbuntuDevelopment/Ports#schroot.2BAC8-sbuild_and_QEMU_syscall_emulation keegan ----- Original Message ----- From: "???" To: "Jens Nockert" , "Graydon Hoare" Cc: rust-dev at mozilla.org Sent: Thursday, August 8, 2013 1:57:43 AM Subject: Re: [rust-dev] android builder active The reason to setup ARM Android build bot is to test "ARM" architecture not general "Android" itself. I think emulator is enough to test Rust not needed actual device right now. ------- Original Message ------- Sender : Jens Nockert Date : 2013-08-08 17:53 (GMT+09:00) Title : Re: [rust-dev] android builder active Hello, On 7 Aug 2013, at 22:37, Graydon Hoare wrote: > Just a heads-up: there's a newly configured builder in the buildbot auto > group that does a linux->android cross compile. It does not presently > run any tests, though at some point it probably will. But for bors to > land new code, it must now at least _build_ on android-cross. Is there a possibility for it to build for all three major Android architectures in the future (x86, mipsel and arm?) so there's even less possibility of breakage? Ps. If someone want remote access to a Android mipsel tablet, I could probably manage to set that up, otherwise they are dead cheap to pick up. _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev

 

 

_______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From asb at asbradbury.org Thu Aug 8 11:18:39 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Thu, 8 Aug 2013 19:18:39 +0100 Subject: [rust-dev] android builder active In-Reply-To: <603769938.4188764.1375983364257.JavaMail.zimbra@mozilla.com> References: <1389201.334081375952262749.JavaMail.weblogic@epv6ml02> <603769938.4188764.1375983364257.JavaMail.zimbra@mozilla.com> Message-ID: On 8 August 2013 18:36, Keegan McAllister wrote: > In that case it might be easier to build the tests as normal ARM GNU/Linux binaries and run them in magic QEMUlated chroots: > > https://wiki.ubuntu.com/UbuntuDevelopment/Ports#schroot.2BAC8-sbuild_and_QEMU_syscall_emulation qemu-user has improved, but it's still rather brittle (and probably always will be). You're much better off just running qemu-system-arm IMO. Alex From banderson at mozilla.com Thu Aug 8 11:38:22 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 08 Aug 2013 11:38:22 -0700 Subject: [rust-dev] android builder active In-Reply-To: <2506D826-0919-44DC-B365-A3E1DA2D9A00@nockert.se> References: <5202AFFB.4090508@mozilla.com> <2506D826-0919-44DC-B365-A3E1DA2D9A00@nockert.se> Message-ID: <5203E59E.3080407@mozilla.com> On 08/08/2013 01:53 AM, Jens Nockert wrote: > Hello, > > On 7 Aug 2013, at 22:37, Graydon Hoare wrote: > >> Just a heads-up: there's a newly configured builder in the buildbot auto >> group that does a linux->android cross compile. It does not presently >> run any tests, though at some point it probably will. But for bors to >> land new code, it must now at least _build_ on android-cross. > Is there a possibility for it to build for all three major Android architectures in the future (x86, mipsel and arm?) so there's even less possibility of breakage? I don't anticipate that Mozilla itself will provide support for these in the near term. Every build slave and supported configuration (i.e. those that block landing of patches) imposes more maintenance burden, and we (mostly Graydon) already expend a very large amount of effort maintaining the continuous integration infrastructure. I do believe though that we are open to letting others set up their own build slaves that report into the build master. From banderson at mozilla.com Thu Aug 8 11:54:26 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 08 Aug 2013 11:54:26 -0700 Subject: [rust-dev] New Rust runtime turned on. What next? Message-ID: <5203E962.9010809@mozilla.com> Hey there. Today we've turned on the new runtime, written in Rust, for all Rust programs. This completely replaces the old task scheduler written in C++. This is an important milestone in the ongoing [I/O rewrite], and there are a lot of feature and perf changes in the air, so now's a good time to update everybody on the state of things and what's going to be happening for the remainder of the year. As a reminder, the reason we are doing this is to integrate an I/O event loop (libuv) directly into the task scheduler. We expect this strategy to give is us reasonably fast and scalable I/O with a traditional synchronous interface - a task that blocks on I/O will be descheduled, not blocking the progress of other tasks. [I/O rewrite]: https://github.com/mozilla/rust/issues/4419 Instead of continuing to develop the task scheduler in C++ we decided to rewrite it in Rust. This should make it much easier to maintain, primarily because there's no FFI boundary to design around, so the interface between the standard library and the runtime is richer, more efficient and more idiomatic. It's also a good test of Rust's suitability for systemsy things. The next weeks and months are undoubtedly going to be a turbulent period in Rust's evolution, so I ask for your patience and understanding as we work through the kinks. The rest of this email explains the current state of the scheduler and I/O, important regressions, API changes and future work. ## The current status It's not even close to done yet, sadly, but I'm confident we've laid a solid groundwork for the future, and things will improve quickly from here. There aren't a lot of immediate benefits, though tasks are now migrated across threads by the scheduler, whereas in the old scheduler a single task was always run in the same thread. At the moment performance is not what you might expect: the current scheduling algorithm is very naive, using a single work queue shared between scheduler threads; there are two shared data structures that are implemented with locks that will be heavily contested; there are a lot of wasted allocations and work. Basically, the focus for the last two months has been on transitioning to the new scheduler and not on performance. I advise against drawing any conclusion from benchmarks at this time. Aaron Todd is going to be pushing on performance for the next few weeks. He's already got a patch to convert to work stealing and his preliminary measurements are promising. The I/O subsystem, in `rt::io` is still immature and will change a lot yet, but it does implement TCP and UDP on both IPv4 and IPv6. Chris Morgan has been working on an [HTTP server] built on `rt::io` so it does work somewhat. A word of caution though: I/O is not yet threadsafe so will fail if you don't set `RUST_THREADS=1`. [HTTP server]: http://hg.chrismorgan.info/rusthttpserver The new runtime does come with one very major regression: segmented stacks are not implemented. For now all tasks run on 2MB stacks, which can be overridden by setting `stack_size` in the `TaskOpts` structure on `TaskBuilder`. Overflowing the stack will cause havok. Reimplementing segmented stacks is a major effort, and I don't have an estimate for when it will be done (there are some higher priority work items yet). Also, linked failure has a race condition that causes segfaults. That will be fixed soon. Despite all these caveats I have a very strong sense that writing the runtime in Rust will go a long way to validate Rust in the domains it's aiming for: concurrent and systems programming. Even in the task scheduler, where there's quite a bit of unsafe code, the shared-nothing nature of unique types forces you to consciously break the type system to share memory, and that seems to go a long way to making parallel programming easier to reason about. The structure of this scheduler is very different from the old, reflecting the preferences of the Rust type system, and anecdotally at least it's been much easier to get working reliably. I hope to write more on this topic in the future. ## Feature changes For the most part the new runtime is a drop-in replacement. The new task scheduler though is structured much differently than the former, so a number of the previously-available scheduler options in `std::task` have been removed. For the most part this should go unnoticed, since a lot of those options were unused or unimplemented. The `CurrentScheduler`, `DefaultScheduler`, `ExistingScheduler`, `ThreadPerTask` and `ManualThreads` scheduler modes are gone. The only remaining mode is `SingleThreaded`, which is often used for putting blocking tasks into their own threads. The big disruptive change is that the `PlatformThread` spawn mode is gone. This was a way to tell a new task to run on the *actual main thread* of the process, which is required for many windowing systems (generally all tasks run on other threads, leaving the main thread empty). It always felt like a bit of a hack, and required setting up an extra task scheduler just in case the process wanted to use it. The new runtime does not provide this capability by default, but there is a way to opt into putting a scheduler on the main thread. Because the new runtime is written in Rust, it is available for arbitrary Rust code to call, so applications that want to use the main thread are now required to set up the runtime themselves by overriding the application entry point using `#[start]` (a lower-level entry point than the default `main`) and then starting the runtime with `std::rt::start_on_main_thread`. See the following test case for an example: https://github.com/mozilla/rust/blob/master/src/test/run-pass/rt-start-main-thread.rs As far as interfaces go, these `start` functions are a little ugly, passing around a bunch of unsafe pointers that shouldn't be touched, so this will probably be refined over time. For now though, this should get you by. On the I/O side, most people by now have noticed that the `extra::net`, `extra::timer`, and related modules have disappeared. These mostly have replacements in `std::rt::io`, though as I mentioned before this code is not yet threadsafe. It will be soon though. One other minor regression is that the debugging code for tracking dynamic borrows is currently broken. I suspect that this won't be missed since it appears to require a recompile of std anyway to turn on. ## What's next? I told you last time I wanted to get this merge done before July, so I'm about a month behind the schedule I set at the beginning of summer. In the immediate future I'll be working on a few things: * Removing the C++ runtime * Implementing a new HTTP client on top of `rt::io`, possibly using Chris Morgan's HTTP code, for use in Servo * Porting Servo to the latest Rust * Fixing any major problems that turn up as a result of this transition Once these things are out of the way my next major task will be to replace uses of legacy `std::io` with `std::rt::io`, then once that's done to move `std::rt::io` to `std::io`. In the process I'll be implementing whatever features are missing to make that happen. Additionally Eric Reed is going to be spending a number of weeks here going full speed to implement I/O features and making sure it's fast, and Jeff Olson and others are also starting to ramp up on the new I/O system. The focus for the rest of the year will be on making sure that I/O is cleanly-designed, stable and fast. I'm not sure when we'll be able to restore segmented stacks. I imagine it will take about a month of effort, so it's difficult to know where to prioritize that. This progress owes a lot to three of our interns: Aaron Todd, Eric Reed and Ben Blum, who have been doing most of the feature work on the runtime this summer. Regards, Brian From graydon at mozilla.com Thu Aug 8 12:53:45 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 08 Aug 2013 12:53:45 -0700 Subject: [rust-dev] New Rust runtime turned on. What next? In-Reply-To: <5203E962.9010809@mozilla.com> References: <5203E962.9010809@mozilla.com> Message-ID: <5203F749.2010406@mozilla.com> On 13-08-08 11:54 AM, Brian Anderson wrote: > Hey there. > > Today we've turned on the new runtime, written in Rust, for all Rust > programs. This completely replaces the old task scheduler written in > C++. This is an important milestone in the ongoing [I/O rewrite], and > there are a lot of feature and perf changes in the air, so now's a good > time to update everybody on the state of things and what's going to be > happening for the remainder of the year. Congratulations! This has been really impressive to watch coming together. > ## The current status > > It's not even close to done yet, sadly, but I'm confident we've laid a > solid groundwork for the future, and things will improve quickly from > here. There aren't a lot of immediate benefits, though tasks are now > migrated across threads by the scheduler, whereas in the old scheduler a > single task was always run in the same thread. That's actually a pretty big benefit! It's something we've failed to achieve in every iteration of the runtime till now, and something everyone expects of a language in this space. > Basically, the focus for the last two > months has been on transitioning to the new scheduler and not on > performance. Agreed. Please everyone don't assume this will be faster yet. It may well be a little slower for a while still. The new structure is the important part. > Despite all these caveats I have a very strong sense that writing the > runtime in Rust will go a long way to validate Rust in the domains it's > aiming for: concurrent and systems programming. Even in the task > scheduler, where there's quite a bit of unsafe code, the shared-nothing > nature of unique types forces you to consciously break the type system > to share memory, and that seems to go a long way to making parallel > programming easier to reason about. Yes, even just reading it seems much clearer since the mutability, lifetime and ownership of each value and reference is spelled out, not just "some Foo* that you have to remember special validity rules about". It's noticeably easier to reason about. Really interesting! > This progress owes a lot to three of our interns: Aaron Todd, Eric Reed > and Ben Blum, who have been doing most of the feature work on the > runtime this summer. Congratulations to you all as well. This has been an exceptional team effort, I think we're all excited and looking forward to giving this code a workout. (Incidentally, the code is also _really nice_. Kudos all around for extensive docs, modularization, unit tests, clear naming, reasonably isolated bits of unsafe code, etc. etc.) -Graydon From ben.striegel at gmail.com Thu Aug 8 14:00:33 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 8 Aug 2013 17:00:33 -0400 Subject: [rust-dev] New Rust runtime turned on. What next? In-Reply-To: <5203E962.9010809@mozilla.com> References: <5203E962.9010809@mozilla.com> Message-ID: Well done to all involved! > * Implementing a new HTTP client on top of `rt::io`, possibly using Chris Morgan's HTTP code, for use in Servo Will this HTTP lib be included in libextra, or will it be external? -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Aug 8 14:03:35 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 08 Aug 2013 14:03:35 -0700 Subject: [rust-dev] New Rust runtime turned on. What next? In-Reply-To: References: <5203E962.9010809@mozilla.com> Message-ID: <520407A7.2080801@mozilla.com> On 08/08/2013 02:00 PM, Benjamin Striegel wrote: > Well done to all involved! > > > * Implementing a new HTTP client on top of `rt::io`, possibly using > Chris Morgan's HTTP code, for use in Servo > > Will this HTTP lib be included in libextra, or will it be external? > I expect that whatever HTTP solution Servo uses will be an officially-maintaned package in the hypothetical package incubator, so effectively part of the 'standard Rust distribution'. It won't be merged into the monolithic libextra (which may or may not survive - all these details are still nebulous). From catamorphism at gmail.com Thu Aug 8 15:52:16 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Thu, 8 Aug 2013 15:52:16 -0700 Subject: [rust-dev] rustpkg feedback In-Reply-To: <5200C3E0.50804@seld.be> References: <5200C3E0.50804@seld.be> Message-ID: [replying on-list, with Jordi's permission] On Tue, Aug 6, 2013 at 2:37 AM, Jordi Boggiano wrote: > Heya, > > Someone mentioned you are the one doing most things on rustpkg these > days, so here comes my feedback after reading > https://github.com/mozilla/rust/blob/master/doc/rustpkg.md - I hope it's > a bit valuable :) > > - I'm not sure if standardizing on main.rs/lib.rs files is the best > idea? It seems like the language itself now loads foo/mod.rs for `mod > foo;`, and #[link] can tell you if the file is to be built as a binary > or lib as far as I understand. So maybe it'd be best to just have mod.rs > for packages too? On the other hand having two files might allow you to > have a package that can both contain a library and a binary. That'd be > kinda neat for some things. We're trying to move away from requiring attributes inside files, like #[link], and trying to make rustpkg infer as much as possible about the build process from directory structure. You'll still be able to use #[link] to override rustpkg's inference, but the goal is that you should never have to write it. (Although, if we did use mod.rs instead of main/lib/test/bench, it would still be possible to have both a library and binary in one package -- you would just have to put them in different subdirectories.) > > - "When building a package that is not under version control, or that > has no tags, rustpkg assumes the intended version is 0.1." - this sounds > pretty bad to me. I think it should in that case read the vers field in > #[link] or something. Yeah, that was kind of a placeholder. It's not documented yet, because it's not implemented yet, but you should be able to specify a version inside the file if you want to -- see https://github.com/mozilla/rust/issues/8239 (the bug is about the name attribute, but the same goes for "vers"). > > - "When building a package that is in a git repository, rustpkg assumes > that the most recent tag specifies the current version." - I can see > that one backfiring on large projects where you maintain two branches at > the same time. Say you make a 2.0.2 release but then you create a > security update for the old branch and tag 1.5.4. If rustpkg suddenly > thinks 1.5.4 is the most current version we'll have issues. It really > should work based on semver IMO. It's a great way to do sane versioning > and starting a new ecosystem without semver would be extremely sad. > That's a reasonable point. rustpkg has just the beginning of semver support right now, but the plan has always been to support semver. Again, it's not documented because it's still to-do :-) > In any case, I may not be able to help much with development because I'm > already quite busy with other things, but I've been leading the > development of Composer [1] - a PHP dependency manager - for the last > two years. It is - much like rustpkg - fully VCS-based when it comes to > finding package releases, so I hope I can at least help on a higher > level. If you want to discuss anything feel free to ask, I'm also on IRC > as Seldaek. I'll take a look at Composer. Thanks for the feedback! Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Being queer is not about a right to privacy; it is about the freedom to be public, to just be who we are." -- anonymous, June 1990 From corey at octayn.net Thu Aug 8 19:30:14 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 8 Aug 2013 22:30:14 -0400 Subject: [rust-dev] PSA: benchmarks Message-ID: If ever you commit a perf improvement, add a benchmark! If there isn't a benchmark to measure, it never got faster. I mean, you already wrote a benchmark, otherwise you wouldn't be able to measure the perf improvement, right? It should either be a #[bench] (as described in https://github.com/mozilla/rust/wiki/Doc-unit-testing#benchmarking), or its own file in src/test/bench. From alex at crichton.co Thu Aug 8 21:19:18 2013 From: alex at crichton.co (Alex Crichton) Date: Thu, 8 Aug 2013 21:19:18 -0700 Subject: [rust-dev] Formatting syntax bikeshed Message-ID: Hello rust-dev! The initial framework for the new fmt! syntax extension landed recently, and I think it's time to start bikeshedding formatting syntax. To recap what the state of the world is now: * The goal of this new system is to support internationalization functions as well as everyday use cases. * The placeholder for an argument is now `{}` instead of `%` * There are now the possibility of named arguments. These names are all just rust identifiers to identify an argumnt. The support which has landed consists of a runtime, the compile-time support to back it, and the syntax extension to generate all the code. You can actually use it today with the `ifmt!` macro, although nothing about formatting will work (except for selecting which formatter you'd like). To get a flavor of what the new syntax looks like (and the current interim formatting syntax), take a look at: https://github.com/mozilla/rust/blob/ffb670ffcd69ed8e7cd13a7f06375ede752349e2/src/test/run-pass/ifmt.rs My current idea for the syntax is something along the lines of: { [argument and format args] [, method information] } Where everything in [] is optional. From this, the `{}`-style placeholders are pretty much here to stay at this point (they support nesting), and I don't think that there's much to discuss in the "method information" section of things (although I could be wrong!). What I'd mainly like to bikeshed is the [argument and format args] section. The purpose of this section is to identify which argument should fill this placeholder and how it should be formatted. Implementation-wise, this will invoke the corresponding formatting trait's method on one of the arguments with a "Formatter" struct argument which contains information about the requested format. It would then be up to each implementation to respect the formatting arguments. So without further ado, here's some options that should be considered: 1. The current fmt! style syntax: As described in extfmt.rs, the syntax for these modifiers are: Format := '%' Parameter? Flag* Width? Precision? Type Parameter := [0-9]+ '$' Flag := [ 0#+-] Width := Parameter | [0-9]+ Precision := '.' [0-9]+ Type := [bcdfiostuxX?] This gets you things like: %x %08x %.*s %10s %-10s %.10s So to extrapolate this to ifmt, I would basically replace this to be: Format := Parameter? (':' Flag* Width? Precision? Type?)? Parameter := [0-9]+ | Identifier Which would yield formattings of the style: {:x} // hex number {0:08x} // format the 0th argument as hex {foo:.*s} // format the argument named 'foo' as a string {:-10s} // format the next argument as a left-aligned string 2. Python-like modifiers -- http://docs.python.org/3/library/string.html#formatstrings This would have a syntax like: format_spec := [argument][':'[[fill]align][sign]['#'][width][.precision][type]] fill := character align := '<' | '>' sign := '+' | '-' width := count precision := count | '*' type := identifier | '' count := parameter | integer parameter := integer '$' This is similar to the above syntax except that it's a bit clearer what the alignment is. Some things can look slightly odd though {: <+#10.10d} // means something, but who knows what? Also note that in this syntax everything is optional, if you just provide something like `{}` it's the same as `%?` today Those are my ideas for now, and I was wondering what others thought about the syntax. Some important things which I think need to be expressable: 1. The width of the thing being formatted 2. Precision for floats along with digit widths for integers 3. Specific fill characters would be nice 4. "%.*s" is actually a pretty useful modifier in C, I'd love to keep it in some way shape or form 5. It should be fairly terse to format something the default way. What do others think? I certainly don't want to leave out important use cases that I forgot! From ben.striegel at gmail.com Fri Aug 9 11:41:50 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Fri, 9 Aug 2013 14:41:50 -0400 Subject: [rust-dev] Formatting syntax bikeshed In-Reply-To: References: Message-ID: This looks really great. In general I like the look of the braces. For the details of the syntax, I think we should borrow as much as possible from other languages; no need to be very novel in this space. I also don't think we should worry too much about cases like "{: <+#10.10d}" as long as the majority of uses are pleasant and readable. There is one important thing I want to point out. The shortest specifier of "{}" is likely to get quite a lot of use, and having it use reflection (analogous to "%?" today) can't be allowed in safe code, as per https://github.com/mozilla/rust/issues/7606 . I'd prefer it if "{}" attempted to call .to_str() on its argument. -------------- next part -------------- An HTML attachment was scrubbed... URL: From arteme at gmail.com Fri Aug 9 13:59:30 2013 From: arteme at gmail.com (Artem Egorkine) Date: Fri, 9 Aug 2013 23:59:30 +0300 Subject: [rust-dev] Formatting syntax bikeshed In-Reply-To: References: Message-ID: Hello, rust-dev! I have only recently discovered rust and haven't written anything substantial in the language yet. I come from a background of python, so it may seem natural that I lean towards a python syntax. Still, I have rarely found myself using anything more complex than '{}', '{1}', or '{variable}' in real life. That said, my point is this: the would could one less formating syntax instead of one more. -Artem On Fri, Aug 9, 2013 at 9:41 PM, Benjamin Striegel wrote: > This looks really great. In general I like the look of the braces. For the > details of the syntax, I think we should borrow as much as possible from > other languages; no need to be very novel in this space. I also don't think > we should worry too much about cases like "{: <+#10.10d}" as long as the > majority of uses are pleasant and readable. > > There is one important thing I want to point out. The shortest specifier > of "{}" is likely to get quite a lot of use, and having it use reflection > (analogous to "%?" today) can't be allowed in safe code, as per > https://github.com/mozilla/rust/issues/7606 . I'd prefer it if "{}" > attempted to call .to_str() on its argument. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Fri Aug 9 17:33:21 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 9 Aug 2013 20:33:21 -0400 Subject: [rust-dev] Getting fully qualified name from a path In-Reply-To: References: Message-ID: <20130810003321.GB14198@Mr-Bennet> The answer depends on what you want. You can use `ty::item_path()` which will give you something like what you want, but maybe not quite. Basically if `ty::item_path()` refers to an item `Y::Z` in crate `X`, it will give a path like `X::Y::Z`. But this path may not be valid relative to the current crate, since the crate `X` could have been declared somewhere else. For example, in this scenario `ty::item_path()` would give a path that cannot actually be used by the user: mod foo { extern mod X; } Here `ty::item_path()` would return `X::Y::Z` but maybe you wanted the `foo::X::Y::Z`. Niko On Sun, Aug 04, 2013 at 02:29:06AM -0400, Corey Richardson wrote: > Hi all, > > Another roadbump with rustdoc_ng, but we're getting real close! When a > reference to a type in an external crate is found, I'd like to include > the fully-qualified name in the JSON. This will enable easier > hyperlinking between crates. However, I'm not sure where I can get the > fully-qualified name, if anywhere. I'd expect to find this > functionality in resolve somewhere, since it'd need to look into the > modules that are in scope and determine which it is/where it comes > from etc. > > Is it possible? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From micah at micahchalmer.net Fri Aug 9 23:30:06 2013 From: micah at micahchalmer.net (Micah Chalmer) Date: Sat, 10 Aug 2013 02:30:06 -0400 Subject: [rust-dev] Question about threads (that arose while trying to write a FUSE interface) Message-ID: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> Hi Rust devs, What can I assume about the safety of having a C library spawn its own threads, from which it calls function pointers to "extern" functions written in rust? My guess (and only a guess--I have no actual reasoning behind it) would be something like this: * I cannot expect anything involving tasks or the task scheduler to work properly in this situation. That means no spawning tasks, no use of ports and chans, and no use of @ boxes. * I can expect plain "c-like" rust code to work, subject to the same rules about thread safety as the equivalent C code. That could include borrowed references and ~ boxes. Rust's rules ensure basic memory integrity within each thread (except for unsafe blocks/fns), but I would still have to be aware of potential race conditions, just as if I were writing C in the same situation. If my guesses are true, how much of the standard library can I use? What functions make assumptions about threads and the runtime behind the scenes in non-obvious ways? Is there a way to know? Will there be? If my guesses are false, I would appreciate a correct view of the situation. I've already been able to get very simple "c-like rust code" to work in a situation like this, but I haven't done enough testing to have any confidence in it. There could be hidden race conditions/crashes that would eventually appear, even for the simple case--my tests may have just "accidentally worked." Why this came up for me: As a "curiosity project," I decided I'd see if I could write an interface to the Fuse library to the point where I'd be able to create a working userspace filesystem in rust. At this point all it does is implement the minimum interface required to get a rust version of the FUSE tutorial "hellofs" working. When writing a filesystem using the high-level FUSE API, the filesystem is expected to call the "fuse_main" function and pass it a structure full of pointers to its own functions. FUSE then runs its main loop and calls the passed-in functions when a filesystem operation is requested. By default, FUSE will spawn its own OS threads and may call the filesystem functions from any of them. It's possible to force the library to run single-threaded, but at the cost of performance--it can no longer perform more than one file system operation at a time. You can see the barely-started WIP at https://github.com/MicahChalmer/rust-fuse if you're curious. I plan to post again to the list when it's in some sort of shape that would be worth looking at for its own sake, but I'm writing now because of the question above. Thanks -Micah From michaelwoerister at gmail.com Sat Aug 10 06:23:38 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Sat, 10 Aug 2013 15:23:38 +0200 Subject: [rust-dev] Iterator blocks (yield) Message-ID: <52063EDA.1070503@gmail.com> Hi everyone, I'm writing a series of blog posts about a possible *yield statement* for Rust. I just published the article that warrants some discussion and I'd really like to hear what you all think about the things therein: http://michaelwoerister.github.io/2013/08/10/iterator-blocks-features.html The first post in the series, giving a bit of an overview of what I plan to do, can be found at: http://michaelwoerister.github.io/2013/07/26/Iterator-Blocks.html Thanks for reading! -Michael From raphael.catolino at gmail.com Sat Aug 10 06:27:49 2013 From: raphael.catolino at gmail.com (raphael catolino) Date: Sat, 10 Aug 2013 15:27:49 +0200 Subject: [rust-dev] Question about threads (that arose while trying to write a FUSE interface) In-Reply-To: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> References: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> Message-ID: Hi Micah, I don't have much experience with rust but I stumbled onto a similar problem a few weeks ago. What I found out was that calling rust functions from code that have no rust-thread context will fail most often than not. Except if those functions are simple wrappers around extern c functions. If you run something like that http://pastebin.mozilla.org/2824359, the c function runs fine but the `println` aborts with "fatal runtime error: thread-local pointer is null. bogus!" (and some Lovecraft excerpt??). If you're not in a rust thread you can't access the tls so I'd say you can expect most std::* functions that allocate/access tlsmemory to fail the same way. Have you thought about patching libfuse to use rust threads instead? This would probably be a whole lot of work, but then I think you could use rust in your fuse callbacks transparently. Another, probably simpler/saner, way would be to use the single-threaded option and then spawn a new rust thread in each callback. You have to ensure that the callbacks are called from a rust context though. I think that libufse forks into the background when you call fuse_main() which might make you lose it (if libfuse uses some 'clone()' call instead of fork()/daemon()). In this case you should pass the '-f' option to fuse_main() to prevent it and you should retain the rust context. Good luck! On Sat, Aug 10, 2013 at 8:30 AM, Micah Chalmer wrote: > Hi Rust devs, > > What can I assume about the safety of having a C library spawn its own threads, from which it calls function pointers to "extern" functions written in rust? My guess (and only a guess--I have no actual reasoning behind it) would be something like this: > > * I cannot expect anything involving tasks or the task scheduler to work properly in this situation. That means no spawning tasks, no use of ports and chans, and no use of @ boxes. > * I can expect plain "c-like" rust code to work, subject to the same rules about thread safety as the equivalent C code. That could include borrowed references and ~ boxes. Rust's rules ensure basic memory integrity within each thread (except for unsafe blocks/fns), but I would still have to be aware of potential race conditions, just as if I were writing C in the same situation. > > If my guesses are true, how much of the standard library can I use? What functions make assumptions about threads and the runtime behind the scenes in non-obvious ways? Is there a way to know? Will there be? > > If my guesses are false, I would appreciate a correct view of the situation. > > I've already been able to get very simple "c-like rust code" to work in a situation like this, but I haven't done enough testing to have any confidence in it. There could be hidden race conditions/crashes that would eventually appear, even for the simple case--my tests may have just "accidentally worked." > > Why this came up for me: > > As a "curiosity project," I decided I'd see if I could write an interface to the Fuse library to the point where I'd be able to create a working userspace filesystem in rust. At this point all it does is implement the minimum interface required to get a rust version of the FUSE tutorial "hellofs" working. > > When writing a filesystem using the high-level FUSE API, the filesystem is expected to call the "fuse_main" function and pass it a structure full of pointers to its own functions. FUSE then runs its main loop and calls the passed-in functions when a filesystem operation is requested. By default, FUSE will spawn its own OS threads and may call the filesystem functions from any of them. It's possible to force the library to run single-threaded, but at the cost of performance--it can no longer perform more than one file system operation at a time. > > You can see the barely-started WIP at https://github.com/MicahChalmer/rust-fuse if you're curious. I plan to post again to the list when it's in some sort of shape that would be worth looking at for its own sake, but I'm writing now because of the question above. > > Thanks > > -Micah > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From simon.sapin at exyr.org Sat Aug 10 07:10:35 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Sat, 10 Aug 2013 15:10:35 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python Message-ID: <520649DB.1040104@exyr.org> Hi, Now that the for loop is based on external iterators, can we reconsider "for-else"? Proposal: for i in iter { // ... } else { // ... } The optional else block is executed when the for loop stops without exhausting the iterator, ie. when "break" is used. -- Simon Sapin From j.boggiano at seld.be Sat Aug 10 07:56:01 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Sat, 10 Aug 2013 16:56:01 +0200 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <520649DB.1040104@exyr.org> References: <520649DB.1040104@exyr.org> Message-ID: <52065481.4080000@seld.be> On 10.08.2013 16:10, Simon Sapin wrote: > Proposal: > > for i in iter { > // ... > } else { > // ... > } > > The optional else block is executed when the for loop stops without > exhausting the iterator, ie. when "break" is used. Maybe that's common to python devs, but I would expect else to be executed if the iterator yielded nothing/was empty. IMO if you break you'll already be in a conditional of some sort in the for body, so you can add more code there. But the else-on-empty would save you the trouble of wrapping the whole for block e.g.: if not empty { for { ... } } else { ... } Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From simon.sapin at exyr.org Sat Aug 10 08:36:00 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Sat, 10 Aug 2013 16:36:00 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <52065481.4080000@seld.be> References: <520649DB.1040104@exyr.org> <52065481.4080000@seld.be> Message-ID: <52065DE0.4040406@exyr.org> Le 10/08/2013 15:56, Jordi Boggiano a ?crit : > On 10.08.2013 16:10, Simon Sapin wrote: >> >Proposal: >> > >> > for i in iter { >> > // ... >> > } else { >> > // ... >> > } >> > >> >The optional else block is executed when the for loop stops without >> >exhausting the iterator, ie. when "break" is used. > Maybe that's common to python devs, but I would expect else to be > executed if the iterator yielded nothing/was empty. I agree that would also be useful, but I don?t know how to have both. It is what Jinja2 is doing. (A templating language for Python.) For what it?s worth, I find else-on-empty especially useful in "templates" (ie. generating stuff based on some data) and else-on-exhaustion especially useful in "data-manipulation" code. > IMO if you break you'll already be in a conditional of some sort in the > for body, so you can add more code there. Yes, it?s trivial to do stuff when you break. The trick is doing stuff when you *don?t*. Without this proposal, the options are: * Using a boolean flag, flipped when you break * Avoiding the for loop entirely, using iter.next(), and doing stuff when receiving None. ? none of which is great. -- Simon Sapin From arteme at gmail.com Sat Aug 10 09:31:36 2013 From: arteme at gmail.com (Artem Egorkine) Date: Sat, 10 Aug 2013 19:31:36 +0300 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <52065DE0.4040406@exyr.org> References: <520649DB.1040104@exyr.org> <52065481.4080000@seld.be> <52065DE0.4040406@exyr.org> Message-ID: In all my programming career as a python programmer I have never used a for-else construct. In fact, I won't be able to tell you exactly when the else-block is executed off the top of my head either. Even though that probably speaks more about me as a programmer than about the python language, it also underlines the fact that "else" is likely the most misplaced term here. For what it's worth, django template language adopts an "empty" keyword for thes block that will execute if the for block didn't (if the iterator was empty). For-empty. Is there, however, no way to check if the iterator was exhausted or not? Wouldn't this be nice to have: for x in iter { ... } if (iter.exhausted()) { ... } On Aug 10, 2013 6:36 PM, "Simon Sapin" wrote: > Le 10/08/2013 15:56, Jordi Boggiano a ?crit : > >> On 10.08.2013 16:10, Simon Sapin wrote: >> >>> >Proposal: >>> > >>> > for i in iter { >>> > // ... >>> > } else { >>> > // ... >>> > } >>> > >>> >The optional else block is executed when the for loop stops without >>> >exhausting the iterator, ie. when "break" is used. >>> >> Maybe that's common to python devs, but I would expect else to be >> executed if the iterator yielded nothing/was empty. >> > > I agree that would also be useful, but I don?t know how to have both. > > It is what Jinja2 is doing. (A templating language for Python.) For what > it?s worth, I find else-on-empty especially useful in "templates" (ie. > generating stuff based on some data) and else-on-exhaustion especially > useful in "data-manipulation" code. > > > IMO if you break you'll already be in a conditional of some sort in the >> for body, so you can add more code there. >> > > Yes, it?s trivial to do stuff when you break. The trick is doing stuff > when you *don?t*. Without this proposal, the options are: > > * Using a boolean flag, flipped when you break > * Avoiding the for loop entirely, using iter.next(), and doing stuff when > receiving None. > > ? none of which is great. > > -- > Simon Sapin > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.sapin at exyr.org Sat Aug 10 10:13:47 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Sat, 10 Aug 2013 18:13:47 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <520649DB.1040104@exyr.org> References: <520649DB.1040104@exyr.org> Message-ID: <520674CB.5020905@exyr.org> Le 10/08/2013 15:10, Simon Sapin a ?crit : > Proposal: > > for i in iter { > // ... > } else { > // ... > } > > The optional else block is executed when the for loop stops without > exhausting the iterator, ie. when "break" is used. Typical usage is finding an element in a container and have a default/fallback: for element is container.iter() { if is_relevant(element) { do_something_with(element); break } } else { not_found() } -- Simon Sapin From pnathan at vandals.uidaho.edu Sat Aug 10 10:24:32 2013 From: pnathan at vandals.uidaho.edu (Paul Nathan) Date: Sat, 10 Aug 2013 10:24:32 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <520649DB.1040104@exyr.org> References: <520649DB.1040104@exyr.org> Message-ID: <52067750.7060205@vandals.uidaho.edu> On 8/10/13 7:10 AM, Simon Sapin wrote: > Hi, > > Now that the for loop is based on external iterators, can we reconsider > "for-else"? > > Proposal: > > for i in iter { > // ... > } else { > // ... > } > > The optional else block is executed when the for loop stops without > exhausting the iterator, ie. when "break" is used. > I spent quite some time in Python, delving into as much of the language as I could, and for-else was not something I used. It actually caused me a bug due to a mis-indented if block in the for loop. I would suggest that perhaps for-else belongs as a macro construct for a while to test adoption; if it proves useful and strongly adhered to, it could be moved into the core language? -- Regards, Paul -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 946 bytes Desc: OpenPGP digital signature URL: From michaelwoerister at gmail.com Sat Aug 10 11:22:35 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Sat, 10 Aug 2013 20:22:35 +0200 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <52067750.7060205@vandals.uidaho.edu> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> Message-ID: <520684EB.7060701@gmail.com> On 08/10/2013 07:24 PM, Paul Nathan wrote: > On 8/10/13 7:10 AM, Simon Sapin wrote: >> Hi, >> >> Now that the for loop is based on external iterators, can we reconsider >> "for-else"? >> >> Proposal: >> >> for i in iter { >> // ... >> } else { >> // ... >> } >> >> The optional else block is executed when the for loop stops without >> exhausting the iterator, ie. when "break" is used. >> > I spent quite some time in Python, delving into as much of the language > as I could, and for-else was not something I used. It actually caused me > a bug due to a mis-indented if block in the for loop. > > I would suggest that perhaps for-else belongs as a macro construct for a > while to test adoption; if it proves useful and strongly adhered to, it > could be moved into the core language? +1 for a macro approach. From banderson at mozilla.com Sat Aug 10 15:44:49 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 10 Aug 2013 15:44:49 -0700 Subject: [rust-dev] Question about threads (that arose while trying to write a FUSE interface) In-Reply-To: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> References: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> Message-ID: <5206C261.6050807@mozilla.com> On 08/09/2013 11:30 PM, Micah Chalmer wrote: > Hi Rust devs, > > What can I assume about the safety of having a C library spawn its own threads, from which it calls function pointers to "extern" functions written in rust? My guess (and only a guess--I have no actual reasoning behind it) would be something like this: > > * I cannot expect anything involving tasks or the task scheduler to work properly in this situation. That means no spawning tasks, no use of ports and chans, and no use of @ boxes. > * I can expect plain "c-like" rust code to work, subject to the same rules about thread safety as the equivalent C code. That could include borrowed references and ~ boxes. Rust's rules ensure basic memory integrity within each thread (except for unsafe blocks/fns), but I would still have to be aware of potential race conditions, just as if I were writing C in the same situation. This is about right. The major limitation of using Rust in this type of scenario is that there isn't a simple, supported mechanism for communicating from outside of Rust tasks into Rust tasks, and vice-versa. This functionality falls under the general area of runtime embedding. > > If my guesses are true, how much of the standard library can I use? What functions make assumptions about threads and the runtime behind the scenes in non-obvious ways? Is there a way to know? Will there be? Most of the standard library will work. The major things that won't are GC, task-local storage, and failure. This may or may not include logging, depending on whether it currently depends on GC and whether you use "%?". There's no particular way to know what specific functions are off limits. > > If my guesses are false, I would appreciate a correct view of the situation. > > I've already been able to get very simple "c-like rust code" to work in a situation like this, but I haven't done enough testing to have any confidence in it. There could be hidden race conditions/crashes that would eventually appear, even for the simple case--my tests may have just "accidentally worked." No. Besides calling functions that might `fail!` unexpectedly there shouldn't be any lurking dangers. If you do something off-limits the process will abort. From banderson at mozilla.com Sat Aug 10 15:49:40 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 10 Aug 2013 15:49:40 -0700 Subject: [rust-dev] Question about threads (that arose while trying to write a FUSE interface) In-Reply-To: References: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> Message-ID: <5206C384.8060303@mozilla.com> On 08/10/2013 06:27 AM, raphael catolino wrote: > Hi Micah, I don't have much experience with rust but I stumbled onto a > similar problem a few weeks ago. What I found out was that calling > rust functions from code that have no rust-thread context will fail > most often than not. Except if those functions are simple wrappers > around extern c functions. > > If you run something like that http://pastebin.mozilla.org/2824359, > the c function runs fine but the `println` aborts with "fatal runtime > error: thread-local pointer is null. bogus!" (and some Lovecraft > excerpt??). If you're not in a rust thread you can't access the tls so > I'd say you can expect most std::* functions that allocate/access > tlsmemory to fail the same way. This is probably because println is using `std::io` which erroneously uses GC in a few places. Very unfortunate. Of course this is going to take a lot of effort to solve in the new runtime too since the default I/O implementation will depend on the scheduler event loop. We're likely to have two implementations of each of the I/O types: one that uses the event loop and one that doesn't. In a situation like this where `println` doesn't have access to the scheduler I would expect it to dynamically choose the native, blocking I/O implementation. It's a lot of effort to get there though. So in general, using std I/O from outside of tasks is going to continue to be sketchy for quite a while. From ruediger at c-plusplus.de Sat Aug 10 07:55:00 2013 From: ruediger at c-plusplus.de (=?ISO-8859-1?Q?R=FCdiger?= Sonderfeld) Date: Sat, 10 Aug 2013 16:55 +0200 Subject: [rust-dev] Emacs mode for rusti (repl) Message-ID: <3047504.pegsgs4OTk@descartes> Hello, I wrote an Emacs mode to integrate rusti (the rust repl) into Emacs. https://github.com/ruediger/rusti.el/blob/master/rusti.el Load the file and run M-x rusti RET to open a buffer containing a rusti session. It also comes with rusti-minor-mode to add keybindings to rust-mode making it easy to send code to the rusti session. Please give me some feedback, bug reports, patches! Regards, R?diger From corey at octayn.net Sat Aug 10 15:55:15 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 10 Aug 2013 18:55:15 -0400 Subject: [rust-dev] Question about threads (that arose while trying to write a FUSE interface) In-Reply-To: <5206C261.6050807@mozilla.com> References: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> <5206C261.6050807@mozilla.com> Message-ID: On Sat, Aug 10, 2013 at 6:44 PM, Brian Anderson wrote: > Most of the standard library will work. The major things that won't are GC, > task-local storage, and failure. This may or may not include logging, > depending on whether it currently depends on GC and whether you use "%?". > There's no particular way to know what specific functions are off limits. > For the record, I'm working on a patch that will let you compile libstd with `--cfg no_rt`, to get a runtimeless stdlib. It's mostly simple, although I need to start a separate ML thread to address some of the stickier issues. From corey at octayn.net Sat Aug 10 20:51:12 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 10 Aug 2013 23:51:12 -0400 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <52063EDA.1070503@gmail.com> References: <52063EDA.1070503@gmail.com> Message-ID: On Sat, Aug 10, 2013 at 9:23 AM, Michael Woerister wrote: > Hi everyone, > I'm writing a series of blog posts about a possible *yield statement* for > Rust. I just published the article that warrants some discussion and I'd > really like to hear what you all think about the things therein: > http://michaelwoerister.github.io/2013/08/10/iterator-blocks-features.html > I don't know a lot about the topic, but generators would be really awesome. I would put "No dependence on threads, scheduler and garbage collection" from nice-to-have to essential, however. Language features with a keyword shouldn't depend on any specific runtime environment, IMO. Most of my interaction with the subject has been in Python, or using Lua's coroutines. Having similar but zero-overhead functionality would make Rust ever-more appealing. From corey at octayn.net Sat Aug 10 21:05:20 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 11 Aug 2013 00:05:20 -0400 Subject: [rust-dev] This Week in Rust Message-ID: content copied from http://cmr.github.io/blog/2013/08/10/this-week-in-rust/ -- Hello and welcome to the tenth issue of *This Week in Rust*. This week marks the enabling of the new runtime written entirely in Rust. A lot happens every week, so I'm going to start omitting PRs that I deem of lesser importance. This process is entirely arbitrary, don't feel hurt if I exclude your PR :). # What's cooking on `master`? Issue churn was -12 this week. A total of 70 PRs were merged. [The new runtime has been enabled by default](https://github.com/mozilla/rust/pull/8358). This is the culmination of a lot of work by brson and the rt interns (toddaaro, bblum, and ecr being the ones I know of). You can get the old runtime by setting the `RUST_OLDRT` environment variable to `1`. It's written entirely in Rust, and lives in `std::rt`. Additionally, the [old C++ runtime has been removed](https://github.com/mozilla/rust/pull/8387). ## Breaking Changes - [**Trailing nulls have been removed from all string types.**](https://github.com/mozilla/rust/pull/8296). This will break your FFI code in subtle and mysterious ways, if you didn't explicitly use the `as_c_str` methods. FFI code using the new `str::c_str` code will be more robust, as it forbids interior nulls, and ensures that a trailing null always exists. The replacement for `str.as_c_str` is `str.to_c_str().as_slice()`, from what I can tell. - [The `priv` keyword is no longer allowed where it has no meaning](https://github.com/cmr/rust/commit/e99eff172a11816f335153147dd0800fc4877bee). - [`iter` and `iter_err` in Result have been replaced with external iterators](https://github.com/mozilla/rust/pull/8265). - [The `get` method of `Option`, `Either`, and `Result` has been removed in favor of `unwrap`](https://github.com/mozilla/rust/pull/8288). They both did the same thing, which was useless duplication. - [`std::gc` and `std::stackwalk`](https://github.com/mozilla/rust/pull/8218) have been removed, as they are obsolete with the new runtime. - [The transitionary `foreach` has been removed](https://github.com/mozilla/rust/pull/8264). ## Notable library additions, bugfixes, and cleanup - [Some redundant `Ord` methods were removed from impls](https://github.com/mozilla/rust/pull/8357) where the default methods sufficed. - [FromStr for IpAddr and SocketAddr](https://github.com/mozilla/rust/pull/8336) is implemented. - [Work steealing is implemented for the newrt scheduler](https://github.com/mozilla/rust/pull/8356). - [A frequency counting function has been added to `extra::stat`](https://github.com/mozilla/rust/pull/8320). - [Saturating math](https://github.com/mozilla/rust/pull/8323) is now implemented. I knew this as "clamping": it is arithmetic that clamps results into a specific interval. - [A hexadecimal encoding module](https://github.com/mozilla/rust/pull/8287) has been added to `extra`. - [`EnumSet` has been moved into `extra`, it previously existed as a utility in `rustc`](https://github.com/mozilla/rust/pull/8054) - [`str::is_utf8` has seen some more optimization](https://github.com/mozilla/rust/pull/8237). ## Notable compiler additions, bugfixes, and cleanup - [Initial support for the new formatting code](https://github.com/mozilla/rust/pull/8245) has been added. - [A `no_main` attribute has been added](https://github.com/mozilla/rust/pull/8279), to omit the Rust entry point entirely. - [Vanilla Linux on ARM](https://github.com/mozilla/rust/pull/8220) is now supported. - [Extra copies of rvalues ](https://github.com/mozilla/rust/pull/8262) are no longer omitted. - [Some cross-arch bugs with node hash metadata](https://github.com/mozilla/rust/pull/8361) have been fixed. - [A soundness bug in struct matching has been fixed](https://github.com/mozilla/rust/pull/8350). - [An `option_env!` syntax extension has been added](https://github.com/mozilla/rust/pull/8362) for compile-time inclusion of environment variables that may or may not be present. - [`extern mod a = "b/c/d"` has been implemented](https://github.com/mozilla/rust/pull/8176), paving the way for more rustpkg awesomeness. # Meetings The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-08-06) seems to have been a bit under-attended. SIMD, ARM, trailing nulls, order of `mod` and `use`, and the condition system were all briefly discussed.. # Discussion + Blog posts - ["A Work-stealing Runtime for Rust"](https://air.mozilla.org/2013-intern-todd/), toddaaro's intern presentation. - ["Iterator Blocks for Rust - Feature Survey"](http://michaelwoerister.github.io/2013/08/10/iterator-blocks-features.html) # External projects - [Galvanized: a simple JIT VM written in Rust, using LibJIT](http://www.reddit.com/r/rust/comments/1k43px/a_simple_jit_vm_written_using_rust_and_libjit/) - [Q3 has a new logger](https://github.com/Jeaye/q3/commit/f4c82ce9c276327cababdb6650038e2c1d62f2d5). I think it's nicer than the built-in one! - [rust-protobuf: a protobuf implementation generating rust code, written in rust](https://github.com/stepancheg/rust-protobuf). - [Servo: almost passing acid1 !](https://twitter.com/metajack/status/364571230331875331/photo/1) From rust-dev at tomlee.co Sat Aug 10 22:53:31 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Sat, 10 Aug 2013 22:53:31 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <520684EB.7060701@gmail.com> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> Message-ID: I'm a big Python user, but I'm -1 on for..else -- mostly because of the choice of the "else" keyword. The issue is that it's downright misleading. You don't look at the 'else' clause and think "oh, I don't know what that means" & go look up the docs like you might with other unfamiliar parts of a new language. You make assumptions because of 'else's familiar semantics elsewhere in the language (i.e. "else" implies that the block is executed when the test fails). In the case of for..else those assumptions don't hold, and invariably lead to bugs. For this reason I never bothered to memorize the *real* behavior of for..else in Python, and never missed it. It's just asking for trouble. Call me a curmudgeon, but I think your code will be more explicit if you declare a mut bool & check its state post-`break`. :) Cheers, Tom On Sat, Aug 10, 2013 at 11:22 AM, Michael Woerister < michaelwoerister at gmail.com> wrote: > On 08/10/2013 07:24 PM, Paul Nathan wrote: > >> On 8/10/13 7:10 AM, Simon Sapin wrote: >> >>> Hi, >>> >>> Now that the for loop is based on external iterators, can we reconsider >>> "for-else"? >>> >>> Proposal: >>> >>> for i in iter { >>> // ... >>> } else { >>> // ... >>> } >>> >>> The optional else block is executed when the for loop stops without >>> exhausting the iterator, ie. when "break" is used. >>> >>> I spent quite some time in Python, delving into as much of the language >> as I could, and for-else was not something I used. It actually caused me >> a bug due to a mis-indented if block in the for loop. >> >> I would suggest that perhaps for-else belongs as a macro construct for a >> while to test adoption; if it proves useful and strongly adhered to, it >> could be moved into the core language? >> > +1 for a macro approach. > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeaye at arrownext.com Sat Aug 10 23:08:16 2013 From: jeaye at arrownext.com (Jeaye) Date: Sat, 10 Aug 2013 23:08:16 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> Message-ID: <52072A50.4020705@arrownext.com> I'm not very familiar with Python at all, coming from C++ land. At first glance, I must say that this seems totally backward and not desirable; I'd wager any case where this for...else would come in handy has an alternate design that is just as sexy (or more) and does not require the pattern. That said, as a non-Python programmer, I may be missing out on something lovely. Jeaye > On Sat, Aug 10, 2013 at 11:22 AM, Michael Woerister > > wrote: > > On 08/10/2013 07:24 PM, Paul Nathan wrote: > > On 8/10/13 7:10 AM, Simon Sapin wrote: > > Hi, > > Now that the for loop is based on external iterators, can > we reconsider > "for-else"? > > Proposal: > > for i in iter { > // ... > } else { > // ... > } > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jens at nockert.se Sun Aug 11 01:18:43 2013 From: jens at nockert.se (Jens Nockert) Date: Sun, 11 Aug 2013 10:18:43 +0200 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <52072A50.4020705@arrownext.com> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> Message-ID: I wouldn't call myself a Python programmer, but I have written a lot of Python and I know quite a few that do use and love the "for-else" construct. The most common (if not only?) usage that I have seen is something like for i in xrange(?): some-algorithm? if coverged: break else: fail!("Did not converge!") While cool and all, I cannot think that it has many use-cases outside of this. A macro is probably sufficient. From armin.ronacher at active-4.com Sun Aug 11 03:01:01 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sun, 11 Aug 2013 11:01:01 +0100 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <52063EDA.1070503@gmail.com> References: <52063EDA.1070503@gmail.com> Message-ID: <520760DD.70708@active-4.com> Hi, On 10/08/2013 14:23, Michael Woerister wrote: > Hi everyone, > I'm writing a series of blog posts about a possible *yield statement* > for Rust. I just published the article that warrants some discussion and > I'd really like to hear what you all think about the things therein: > http://michaelwoerister.github.io/2013/08/10/iterator-blocks-features.html I have been toying around with the idea of yield for a bit, but I think there are quite a few big problems that need figuring out. The way "yield return" works in C# is that it rewrites the code into a state machine behind the scenes. It essentially generates a helper class that encapsulates all the state. In Rust that's much harder to do due to the type system. Imagine you are doing a yield from a generic hash map. The code that does the rewriting would have to place the hash map itself on the helper struct that holds the state. Which means that the person writing the generator would have to put that into the return value. I currently have a really hard time thinking about how the c# trick would work :-( Aside from this some random notes from Python: - generators go in both directions in Python which caused problems until Python 3.3 where "yield from" (your "yield ..") was introduced that expands into a monstrosity that forwards generators into both directions. - instead of using "fn" like "def" in Python I would prefer if it was an explicit "yield fn" that indicates that the function generates an iterator. The fact that Python reuses "def" is a source of lots of bugs and confusion. Regards, Armin From matthieu.monrocq at gmail.com Sun Aug 11 03:31:01 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sun, 11 Aug 2013 12:31:01 +0200 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <520760DD.70708@active-4.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> Message-ID: Hello, I cannot comment on the difficulty of implementation, however I can only join Armin in wishing that if it ever takes off it would be better to make the declaration explicit rather than having to parse the definition of the function to suddenly realize that this is not a simple function but a full-blown generator. Furthermore, in keeping with the iterator ongoing, I would obviously push toward unifying the systems by having the generator implementing the Iterator trait (or whatever its name). -- Matthieu On Sun, Aug 11, 2013 at 12:01 PM, Armin Ronacher < armin.ronacher at active-4.com> wrote: > Hi, > > > On 10/08/2013 14:23, Michael Woerister wrote: > >> Hi everyone, >> I'm writing a series of blog posts about a possible *yield statement* >> for Rust. I just published the article that warrants some discussion and >> I'd really like to hear what you all think about the things therein: >> http://michaelwoerister.**github.io/2013/08/10/iterator-** >> blocks-features.html >> > I have been toying around with the idea of yield for a bit, but I think > there are quite a few big problems that need figuring out. > > The way "yield return" works in C# is that it rewrites the code into a > state machine behind the scenes. It essentially generates a helper class > that encapsulates all the state. > > In Rust that's much harder to do due to the type system. Imagine you are > doing a yield from a generic hash map. The code that does the rewriting > would have to place the hash map itself on the helper struct that holds the > state. Which means that the person writing the generator would have to put > that into the return value. > > I currently have a really hard time thinking about how the c# trick would > work :-( > > > Aside from this some random notes from Python: > > - generators go in both directions in Python which caused problems > until Python 3.3 where "yield from" (your "yield ..") was introduced > that expands into a monstrosity that forwards generators into both > directions. > - instead of using "fn" like "def" in Python I would prefer if it was > an explicit "yield fn" that indicates that the function generates an > iterator. The fact that Python reuses "def" is a source of lots of > bugs and confusion. > > > Regards, > Armin > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Sun Aug 11 06:25:56 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Sun, 11 Aug 2013 09:25:56 -0400 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> Message-ID: Note that we have an issue open in the bug tracker for this: https://github.com/mozilla/rust/issues/7746 -------------- next part -------------- An HTML attachment was scrubbed... URL: From michaelwoerister at gmail.com Sun Aug 11 07:43:31 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Sun, 11 Aug 2013 16:43:31 +0200 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <520760DD.70708@active-4.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> Message-ID: <5207A313.60700@gmail.com> On 11.08.2013 12:01, Armin Ronacher wrote: > The way "yield return" works in C# is that it rewrites the code into a > state machine behind the scenes. It essentially generates a helper > class that encapsulates all the state. > > In Rust that's much harder to do due to the type system. Imagine you > are doing a yield from a generic hash map. The code that does the > rewriting would have to place the hash map itself on the helper struct > that holds the state. Which means that the person writing the > generator would have to put that into the return value. I think transforming the yielding function into a state machine, like done in C#, will be the way to go for Rust too. Rust's type system makes this a bit more complicated than in C#. However, the necessary code transformation has many similarities with supporting closures: * For a closure, the compiler generates a hidden environment struct, containing the captured variables, which is then implicitly passed to the closure function. * For yield, the compiler also generates a hidden struct, implementing the state machine logic, but also 'capturing' the arguments and local parameters of the yielding function. It is really rather similar as far as the type system is concerned. If we can define sound semantics for closures, we should also be able to define sound semantics for yielding functions. As for having to put the hashmap into the return value, I don't think this is necessary because implementation details of the function are hidden behind the std::Iterator trait. I imagine, the compiler would do a desugaring like the following: // Original function fn yield_some(xs: &'a HashMap, a: int, b: int) -> Iterator { yield return xs.get(a); yield return xs.get(b); } // Desugared version fn yield_some(xs: &'a HashMap, a: int, b: int) -> yield_some_iterator<'a> { return yield_some_iterator{ state: 0, xs: xs, a: a, b: b, }; } struct yield_some_iterator<'self> { priv state: uint, priv xs: &'self HashMap, priv a: int, priv b: int } impl std::iterator::Iterator for yield_some_iterator { fn next(&self) -> Option { match self.state { 0 => { state = 1; Some(self.xs.get(self.a)) } 1 => { state = 2; Some(self.xs.get(self.b)) } 2 => None } } } As you can see, the compiler substitutes a concrete iterator type. But this iterator type can only ever be accessed through the std::iterator::Iterator interface, which only exposes the return value of the next() method. The internal state of the iterator (such as the hash map) does not have to be considered by the user. (The lifetimes of the yielding function's arguments can, however, influence the lifetime of the resulting iterator, as is the case with closures and captured variables). > I currently have a really hard time thinking about how the c# trick > would work :-( Maybe you do now :) > > Aside from this some random notes from Python: > > - generators go in both directions in Python which caused problems > until Python 3.3 where "yield from" (your "yield ..") was introduced > that expands into a monstrosity that forwards generators into both > directions. Can you elaborate on what you mean by "both directions"? > - instead of using "fn" like "def" in Python I would prefer if it was > an explicit "yield fn" that indicates that the function generates an > iterator. The fact that Python reuses "def" is a source of lots of > bugs and confusion. I think Rust has an advantage over Python here, in that for every function the return type is explicitly declared. So, if a function returns an Iterator (or better), one does not have to care about whether the function is implemented via 'yield' or if it returns a handwritten iterator. So I think "yield fn" would be redundant here. The type checker won't let through anything confused. From michaelwoerister at gmail.com Sun Aug 11 08:00:28 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Sun, 11 Aug 2013 17:00:28 +0200 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> Message-ID: <5207A70C.2030901@gmail.com> On 11.08.2013 12:31, Matthieu Monrocq wrote: > I cannot comment on the difficulty of implementation, however I can > only join Armin in wishing that if it ever takes off it would be > better to make the declaration explicit rather than having to parse > the definition of the function to suddenly realize that this is not a > simple function but a full-blown generator. As already mentioned in the response to Armin, Rust's requirement for explicitly declared return types will let you see already in the functions signature whether you are dealing with an iterator. However, there is a small (technical) problem with writing a function signature like this: fn generate() -> Iterator {...} since Iterator is just a trait and can't be returned by value (because its concrete type is not known). We could still allow the above; but it could lead to some confusion as to why it sometimes is allowed to return a trait by value and most of the time it's not. A possible solution for this would be to use some special syntax for yielding functions, such as: fn generate() -> yield int {...} where the 'yield int' part could then be replaced with the concrete (generated) iterator type by the compiler. This would make it more explicit that something special is happening here, and it would make the python people happy at the same time :) -Michael From armin.ronacher at active-4.com Sun Aug 11 08:18:17 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sun, 11 Aug 2013 16:18:17 +0100 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <5207A313.60700@gmail.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> <5207A313.60700@gmail.com> Message-ID: <5207AB39.1060906@active-4.com> Hi, On 11/08/2013 15:43, Michael Woerister wrote: > Maybe you do now :) I see where this is going, that's actually not too bad. So essentially it would generate some anonymous struct and impl. > Can you elaborate on what you mean by "both directions"? Python has this inheritance tree (virtual): Iterable Iterator Generator An iterable is defined as a class with a __iter__() that returns an iterator. An iterator is defined as an iterable that returns itself and also has a __next__ method which either returns a value or raises a StopIterator. A generator is a separate beast that is produced by the compiled if it spots a function with a 'yield' expression. A generator also exposes the iterator protocol but actually does more. If you call __next__() on a generator is equivalent to calling .send(None). Essentially in Python a generator can produce values, but also get data sent: def g(): num = 0 while 1: next_num = (yield num) if next_num is not None: num = next_num else: num += 1 If you just iterate over it, it's an eternal iterator that produces ever increasing numbers. If you however call .send(NUM) on it, it sets the internal counter to NUM and yields the same number back next iteration. The ugly side effect of this is that you now need to forward these generators in both directions. PEP 0380 explains how that looks like. eg: for item in x(): yield item is not good enough, as it now throws away the return value from yield. The reason I'm bringing this up is because in case Rust ever wants to gain support for bidirectional generators it should from the very start have something like a "yield from" to not break the reverse forwarding. > I think Rust has an advantage over Python here, in that for every > function the return type is explicitly declared. So, if a function > returns an Iterator (or better), one does not have to care about > whether the function is implemented via 'yield' or if it returns a > handwritten iterator. You would think, neither do you in Python. The problem is actually not so much the consuming of the function but the writing of it. In a regular function you have execution as the function is called. In a generator function the execution immediately suspends until you call next(). It's very confusing for beginners and has caused in many, many broken WSGI applications in Python (WSGI is the Python web abstraction protocol that uses iterators). Even more than that, how do you make an empty generator? There is a lot of code that does any of those: def iter_nothing(): return iter([]) def iter_nothing(): if False: yield None Lastly, in Python 3 we now are getting async IO support through generators and the frameworks do weird things to make generator and regular functions decorated with the same decorator, behave similarly in case someone deletes the last 'yield' from the function. An explicit 'yield fn' outside of the function solves this case, where a function degrades to not having any yield expressions any more. Yes, in theory you could make a function that returns nil but is declared as returning an iterator, just return the empty iterator for that type, but that seems wrong. Regards, Armin From armin.ronacher at active-4.com Sun Aug 11 08:19:53 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sun, 11 Aug 2013 16:19:53 +0100 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <5207AB39.1060906@active-4.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> <5207A313.60700@gmail.com> <5207AB39.1060906@active-4.com> Message-ID: <5207AB99.6060508@active-4.com> Hi, On 11/08/2013 16:18, Armin Ronacher wrote: > Yes, in theory you could make a function that returns nil but is > declared as returning an iterator, just return the empty iterator for > that type, but that seems wrong. In addition to that does "yield fn" do a step towards solving the confusion that the return type from the function gets magically substituted for something else. Regards, Armin From corey at octayn.net Sun Aug 11 10:42:32 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 11 Aug 2013 13:42:32 -0400 Subject: [rust-dev] RFC: Runtimeless libstd Message-ID: I've opened a pull request for basic runtimeless support on libstd: https://github.com/mozilla/rust/pull/8454 I think it needs a wider discussion. I think it's very desirable to have a libstd that can be used without a runtime, especially once we have static linking and link-time DCE. As it stands, this patch is more of a hack. It removes swaths of libstd that currently can't work without a "runtime", but adds some simple stub implementations of the free/malloc lang items that call into the libc, so really it requires a C runtime. What I think we should end up with is various "levels" of runtime. Some environments can provide unwinding, while others can't, for example. You can mix-and-match various cfgs for specific pieces of the runtime to get a libstd that can run on your platform. Other things require explicit language items (think zero.rs). Thankfully the compiler now errors when you use something that requires a language item you don't implement, so it's easy to see what you need and where. I envision a sort of "platform file" that implements language items for a specific platform, and you'd include this in the libstd build for the platform. But libstd, as it stands, is insanely dependant on a full, robust runtime, especially task failure and TLS. A runtimeless libstd can't depend on either of those. You can see the hack in str.rs to not use conditions when no_rt is given. While I don't think my PR should be merged as-is, I think the discussion for the best way to achieve what it accomplishes correctly is important. From michaelwoerister at gmail.com Sun Aug 11 11:53:14 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Sun, 11 Aug 2013 20:53:14 +0200 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <5207AB39.1060906@active-4.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> <5207A313.60700@gmail.com> <5207AB39.1060906@active-4.com> Message-ID: <5207DD9A.5030404@gmail.com> Hi, > [...] The reason I'm bringing this up is because in case Rust ever > wants to gain support for bidirectional generators it should from the > very start have something like a "yield from" to not break the reverse > forwarding. Thanks for the extensive explanation. These iterators with bi-directional communication seem to be similar to what Ruby does (as described in the last section of my blog article). I'll have to think more about implications of and use cases for this kind of functionality. It would not be compatible with the current std::Iterator trait though. And it may encourage writing hard-to-read code/control flow. Though this is just a guess. Maybe its actually easier to read and follow than the struct-with-methods equivalent. >> I think Rust has an advantage over Python here, in that for every >> function the return type is explicitly declared. So, if a function >> returns an Iterator (or better), one does not have to care about >> whether the function is implemented via 'yield' or if it returns a >> handwritten iterator. > You would think, neither do you in Python. The problem is actually > not so much the consuming of the function but the writing of it. In a > regular function you have execution as the function is called. In a > generator function the execution immediately suspends until you call > next(). It's very confusing for beginners and has caused in many, > many broken WSGI applications in Python (WSGI is the Python web > abstraction protocol that uses iterators). Yes, it would certainly be more clear to not declare iterator fns as regular functions (because they aren't :) Though (IMO), it works rather well in C#. I don't have a strong opinion on the subject. > Even more than that, how do you make an empty generator? [...] I'd say, this should be a library function, something like `Iterator::empty()`. With the `yield break` command from C# you could also have one canonical version: fn empty() -> Iterator { yield break; } > Lastly, in Python 3 we now are getting async IO support through > generators and the frameworks do weird things to make generator and > regular functions decorated with the same decorator, behave similarly > in case someone deletes the last 'yield' from the function. An > explicit 'yield fn' outside of the function solves this case, where a > function degrades to not having any yield expressions any more. > > Yes, in theory you could make a function that returns nil but is > declared as returning an iterator, just return the empty iterator for > that type, but that seems wrong. I think I know too little about this topic say something useful here. But it seems like a specific library design issue. -Michael From matthieu.monrocq at gmail.com Sun Aug 11 12:15:18 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sun, 11 Aug 2013 21:15:18 +0200 Subject: [rust-dev] RFC: Runtimeless libstd In-Reply-To: References: Message-ID: Hi Corey, It's great to see that people are thinking more and more about integrating Rust in existing languages! I wonder however whether the other alternative has been envisioned: if Rust requires a runtime to work properly (specifically: TLS, task failure), would it be possible to provide an external caller the ability to setup the runtime before calling Rust methods ? I have absolutely no idea whether this is sensible or possible, but maybe rather than either extreme (a full runtime setup vs a no runtime mode) there is a way to meet in the middle; with a core runtime that can be set from a C interface (TLS ? ...) and then a set of cfgs for various additional pieces (such as garbage collection ? ...). -- Matthieu On Sun, Aug 11, 2013 at 7:42 PM, Corey Richardson wrote: > I've opened a pull request for basic runtimeless support on libstd: > https://github.com/mozilla/rust/pull/8454 > > I think it needs a wider discussion. I think it's very desirable to > have a libstd that can be used without a runtime, especially once we > have static linking and link-time DCE. As it stands, this patch is > more of a hack. It removes swaths of libstd that currently can't work > without a "runtime", but adds some simple stub implementations of the > free/malloc lang items that call into the libc, so really it requires > a C runtime. > > What I think we should end up with is various "levels" of runtime. > Some environments can provide unwinding, while others can't, for > example. You can mix-and-match various cfgs for specific pieces of the > runtime to get a libstd that can run on your platform. Other things > require explicit language items (think zero.rs). Thankfully the > compiler now errors when you use something that requires a language > item you don't implement, so it's easy to see what you need and where. > I envision a sort of "platform file" that implements language items > for a specific platform, and you'd include this in the libstd build > for the platform. > > But libstd, as it stands, is insanely dependant on a full, robust > runtime, especially task failure and TLS. A runtimeless libstd can't > depend on either of those. You can see the hack in str.rs to not use > conditions when no_rt is given. > > While I don't think my PR should be merged as-is, I think the > discussion for the best way to achieve what it accomplishes correctly > is important. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sun Aug 11 12:53:58 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 11 Aug 2013 15:53:58 -0400 Subject: [rust-dev] RFC: Runtimeless libstd In-Reply-To: References: Message-ID: On Sun, Aug 11, 2013 at 3:15 PM, Matthieu Monrocq wrote: > Hi Corey, > > It's great to see that people are thinking more and more about integrating > Rust in existing languages! > I didn't even consider that aspect of it tbh; I was only thinking of bare-metal Rust. > I wonder however whether the other alternative has been envisioned: if Rust > requires a runtime to work properly (specifically: TLS, task failure), would > it be possible to provide an external caller the ability to setup the > runtime before calling Rust methods ? > > I have absolutely no idea whether this is sensible or possible, but maybe > rather than either extreme (a full runtime setup vs a no runtime mode) there > is a way to meet in the middle; with a core runtime that can be set from a > C interface (TLS ? ...) and then a set of cfgs for various additional pieces > (such as garbage collection ? ...). > It seems quite possible, but it'd require extensive setup, and a lot of detail to be exposed. brson or someone else might be able to better address this. From corey at octayn.net Sun Aug 11 13:00:14 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 11 Aug 2013 16:00:14 -0400 Subject: [rust-dev] RFC: Runtimeless libstd In-Reply-To: References: Message-ID: For reference, here are some open issues relating to this: https://github.com/mozilla/rust/issues/7282 https://github.com/mozilla/rust/issues/8344 https://github.com/mozilla/rust/issues/3608 https://github.com/mozilla/rust/issues/7283 https://github.com/mozilla/rust/issues/1793 https://github.com/mozilla/rust/issues/4404 On Sun, Aug 11, 2013 at 1:42 PM, Corey Richardson wrote: > I've opened a pull request for basic runtimeless support on libstd: > https://github.com/mozilla/rust/pull/8454 > > I think it needs a wider discussion. I think it's very desirable to > have a libstd that can be used without a runtime, especially once we > have static linking and link-time DCE. As it stands, this patch is > more of a hack. It removes swaths of libstd that currently can't work > without a "runtime", but adds some simple stub implementations of the > free/malloc lang items that call into the libc, so really it requires > a C runtime. > > What I think we should end up with is various "levels" of runtime. > Some environments can provide unwinding, while others can't, for > example. You can mix-and-match various cfgs for specific pieces of the > runtime to get a libstd that can run on your platform. Other things > require explicit language items (think zero.rs). Thankfully the > compiler now errors when you use something that requires a language > item you don't implement, so it's easy to see what you need and where. > I envision a sort of "platform file" that implements language items > for a specific platform, and you'd include this in the libstd build > for the platform. > > But libstd, as it stands, is insanely dependant on a full, robust > runtime, especially task failure and TLS. A runtimeless libstd can't > depend on either of those. You can see the hack in str.rs to not use > conditions when no_rt is given. > > While I don't think my PR should be merged as-is, I think the > discussion for the best way to achieve what it accomplishes correctly > is important. From simon.sapin at exyr.org Sun Aug 11 13:06:29 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Sun, 11 Aug 2013 21:06:29 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> Message-ID: <5207EEC5.2090407@exyr.org> Le 11/08/2013 06:53, Tom Lee a ?crit : > I think your code will be more explicit if you declare a mut bool & > check its state post-`break`. :) Resorting to boolean flags to cope with insufficient control flow feels like Basic, which makes me sad :( -- Simon Sapin From rust-dev at tomlee.co Sun Aug 11 13:20:37 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Sun, 11 Aug 2013 13:20:37 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> Message-ID: To be clear: should that `if` test be "if not converged" ? On Sun, Aug 11, 2013 at 1:18 AM, Jens Nockert wrote: > I wouldn't call myself a Python programmer, but I have written a lot of > Python and I know quite a few that do use and love the "for-else" construct. > > The most common (if not only?) usage that I have seen is something like > > for i in xrange(?): > some-algorithm? > if coverged: > break > else: > fail!("Did not converge!") > > While cool and all, I cannot think that it has many use-cases outside of > this. A macro is probably sufficient. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From rust-dev at tomlee.co Sun Aug 11 13:25:19 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Sun, 11 Aug 2013 13:25:19 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <5207EEC5.2090407@exyr.org> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <5207EEC5.2090407@exyr.org> Message-ID: On Sun, Aug 11, 2013 at 1:06 PM, Simon Sapin wrote: > Le 11/08/2013 06:53, Tom Lee a ?crit : > > I think your code will be more explicit if you declare a mut bool & >> check its state post-`break`. :) >> > > Resorting to boolean flags to cope with insufficient control flow feels > like Basic, which makes me sad :( > > :) I can appreciate that, but I'm still not really convinced that this "problem" deserves more syntax. That said, I might hate for..else less if it used something other than the 'else' keyword. *shrug* -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sun Aug 11 13:27:42 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 12 Aug 2013 08:27:42 +1200 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <5207EEC5.2090407@exyr.org> Message-ID: <5207F3BE.2060008@mozilla.com> On 8/12/13 8:25 AM, Tom Lee wrote: > :) I can appreciate that, but I'm still not really convinced that this > "problem" deserves more syntax. > > That said, I might hate for..else less if it used something other than > the 'else' keyword. *shrug* It seems to me that a big benefit of macros in Rust is to make less-commonly-used syntax still usable and reasonably convenient without having to build it into the compiler. "for/else" may be a perfect use case here. Patrick From rust-dev at tomlee.co Sun Aug 11 13:30:15 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Sun, 11 Aug 2013 13:30:15 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <5207F3BE.2060008@mozilla.com> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <5207EEC5.2090407@exyr.org> <5207F3BE.2060008@mozilla.com> Message-ID: On Sun, Aug 11, 2013 at 1:27 PM, Patrick Walton wrote: > On 8/12/13 8:25 AM, Tom Lee wrote: > >> :) I can appreciate that, but I'm still not really convinced that this >> "problem" deserves more syntax. >> >> That said, I might hate for..else less if it used something other than >> the 'else' keyword. *shrug* >> > > It seems to me that a big benefit of macros in Rust is to make > less-commonly-used syntax still usable and reasonably convenient without > having to build it into the compiler. "for/else" may be a perfect use case > here. > > You're right. I keep forgetting the macro proposal when I come back to read this thread. -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sun Aug 11 13:44:06 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 11 Aug 2013 16:44:06 -0400 Subject: [rust-dev] Privacy of items Message-ID: So I came across a weird fact that is entirely inconsistent with my mental model of Rust. extra::arc::RWArc is private, but you can use it *everywhere*. You can call RWArc::new, you can use it as a type, etc. What is happening? From jens at nockert.se Sun Aug 11 14:28:08 2013 From: jens at nockert.se (Jens Nockert) Date: Sun, 11 Aug 2013 23:28:08 +0200 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> Message-ID: <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> On H.25/08/11, at 22:20, Tom Lee wrote: > To be clear: should that `if` test be "if not converged" ? No, the else in Python executes if the for loop consumes the whole iterator, and you want to fail if it does not converge. From vadimcn at gmail.com Sun Aug 11 14:56:17 2013 From: vadimcn at gmail.com (Vadim) Date: Sun, 11 Aug 2013 14:56:17 -0700 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <5207DD9A.5030404@gmail.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> <5207A313.60700@gmail.com> <5207AB39.1060906@active-4.com> <5207DD9A.5030404@gmail.com> Message-ID: I wonder if Rust could do something along the lines of F# computation expressions (or Haskell's do-notation, if one is so inclined). This approach would put more strain on the optimizer, which would have to deal with all those lambda functions, but on the plus side, this is a more general approach, and we could get both generators and asyncs out of it in one swoop. Hmm, come to think about it, couldn't this be done with a syntax extension? Vadim On Sun, Aug 11, 2013 at 11:53 AM, Michael Woerister < michaelwoerister at gmail.com> wrote: > Hi, > >> [...] The reason I'm bringing this up is because in case Rust ever wants >> to gain support for bidirectional generators it should from the very start >> have something like a "yield from" to not break the reverse forwarding. >> > Thanks for the extensive explanation. These iterators with bi-directional > communication seem to be similar to what Ruby does (as described in the > last section of my blog article). > I'll have to think more about implications of and use cases for this kind > of functionality. It would not be compatible with the current std::Iterator > trait though. And it may encourage writing hard-to-read code/control flow. > Though this is just a guess. Maybe its actually easier to read and follow > than the struct-with-methods equivalent. > > I think Rust has an advantage over Python here, in that for every >>> function the return type is explicitly declared. So, if a function >>> returns an Iterator (or better), one does not have to care about >>> whether the function is implemented via 'yield' or if it returns a >>> handwritten iterator. >>> >> You would think, neither do you in Python. The problem is actually not >> so much the consuming of the function but the writing of it. In a regular >> function you have execution as the function is called. In a generator >> function the execution immediately suspends until you call next(). It's >> very confusing for beginners and has caused in many, many broken WSGI >> applications in Python (WSGI is the Python web abstraction protocol that >> uses iterators). >> > Yes, it would certainly be more clear to not declare iterator fns as > regular functions (because they aren't :) > Though (IMO), it works rather well in C#. I don't have a strong opinion on > the subject. > > Even more than that, how do you make an empty generator? [...] >> > I'd say, this should be a library function, something like > `Iterator::empty()`. > With the `yield break` command from C# you could also have one canonical > version: > > fn empty() -> Iterator { > yield break; > } > > Lastly, in Python 3 we now are getting async IO support through >> generators and the frameworks do weird things to make generator and regular >> functions decorated with the same decorator, behave similarly in case >> someone deletes the last 'yield' from the function. An explicit 'yield fn' >> outside of the function solves this case, where a function degrades to not >> having any yield expressions any more. >> >> Yes, in theory you could make a function that returns nil but is declared >> as returning an iterator, just return the empty iterator for that type, but >> that seems wrong. >> > I think I know too little about this topic say something useful here. But > it seems like a specific library design issue. > > -Michael > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Sun Aug 11 15:12:28 2013 From: kevin at sb.org (Kevin Ballard) Date: Sun, 11 Aug 2013 18:12:28 -0400 Subject: [rust-dev] Privacy of items In-Reply-To: References: Message-ID: Is it `pub use`d elsewhere? That would be my first thought (can't check now as I'm away from a computer). -Kevin Ballard > On Aug 11, 2013, at 4:44 PM, Corey Richardson wrote: > > So I came across a weird fact that is entirely inconsistent with my > mental model of Rust. extra::arc::RWArc is private, but you can use it > *everywhere*. You can call RWArc::new, you can use it as a type, etc. > What is happening? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From jens at nockert.se Sun Aug 11 15:18:16 2013 From: jens at nockert.se (Jens Nockert) Date: Mon, 12 Aug 2013 00:18:16 +0200 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> Message-ID: <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> On 12 Aug 2013, at 00:09, Tom Lee wrote: > Anyway, this sort of confusion is exactly why I don't like for..else. But then maybe I'm the only one that's confused here. :) Obviously you were not the only one, since there was a long thread without clarification. While I think it is reasonably clear (since I am used to it), I don't think it is more clear than something like (in faux pyrust) let iterations = xrange(100); for i in iterations { ? if converged { break; } } if iterations.finished() { fail!("Oh noes, it did not converge"); } And I most certainly don't think for-else is more clear than a good macro implementation of a similar pattern. What I am worried about is that we add more edge-cases to syntax. The more syntax we add, the more likely it is that people will just use a subset and then be really confused when someone uses something special (break out of ifs in JS anyone?) -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sun Aug 11 15:31:22 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 11 Aug 2013 18:31:22 -0400 Subject: [rust-dev] Privacy of items In-Reply-To: References: Message-ID: Nope :( On Sun, Aug 11, 2013 at 6:12 PM, Kevin Ballard wrote: > Is it `pub use`d elsewhere? That would be my first thought (can't check now as I'm away from a computer). > > -Kevin Ballard > >> On Aug 11, 2013, at 4:44 PM, Corey Richardson wrote: >> >> So I came across a weird fact that is entirely inconsistent with my >> mental model of Rust. extra::arc::RWArc is private, but you can use it >> *everywhere*. You can call RWArc::new, you can use it as a type, etc. >> What is happening? >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev From rust-dev at tomlee.co Sun Aug 11 15:32:41 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Sun, 11 Aug 2013 15:32:41 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> Message-ID: On Sun, Aug 11, 2013 at 3:18 PM, Jens Nockert wrote: > > On 12 Aug 2013, at 00:09, Tom Lee wrote: > > Anyway, this sort of confusion is exactly why I don't like for..else. But > then maybe I'm the only one that's confused here. :) > > > Obviously you were not the only one, since there was a long thread without > clarification. > > While I think it is reasonably clear (since I am used to it), I don't > think it is more clear than something like (in faux pyrust) > > let iterations = xrange(100); > > for i in iterations { > ? > if converged { > break; > } > } > > if iterations.finished() { > fail!("Oh noes, it did not converge"); > } > > I really like this. There's no room for confusion here. > And I most certainly don't think for-else is more clear than a good macro > implementation of a similar pattern. > > What I am worried about is that we add more edge-cases to syntax. The more > syntax we add, the more likely it is that people will just use a subset and > then be really confused when someone uses something special (break out of > ifs in JS anyone?) > > > I think we agree on all of this. Cheers, Tom -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sun Aug 11 15:47:43 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 11 Aug 2013 18:47:43 -0400 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> Message-ID: On Sun, Aug 11, 2013 at 6:32 PM, Tom Lee wrote: > > On Sun, Aug 11, 2013 at 3:18 PM, Jens Nockert wrote: >> >> >> On 12 Aug 2013, at 00:09, Tom Lee wrote: >> >> Anyway, this sort of confusion is exactly why I don't like for..else. But >> then maybe I'm the only one that's confused here. :) >> >> >> Obviously you were not the only one, since there was a long thread without >> clarification. >> >> While I think it is reasonably clear (since I am used to it), I don't >> think it is more clear than something like (in faux pyrust) >> >> let iterations = xrange(100); >> >> for i in iterations { >> ? >> if converged { >> break; >> } >> } >> >> if iterations.finished() { >> fail!("Oh noes, it did not converge"); >> } >> > > I really like this. There's no room for confusion here. The iterator adaptors don't keep track of whether they've finished, they only bubble up the underlying `next()` calls. The `None` will be returned during the loop, and after that there's no way to query whether it has finished. For example, this is zip: fn next(&mut self) -> Option<(A, B)> { match (self.a.next(), self.b.next()) { (Some(x), Some(y)) => Some((x, y)), _ => None } } There's a separate thread about this, but I don't think returning `None` forever without side effects is a guarantee we should make. Python does not make the guarantee, and the functions like `zip` there will continue calling the underlying iterators. From pwalton at mozilla.com Sun Aug 11 15:51:24 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 12 Aug 2013 10:51:24 +1200 Subject: [rust-dev] Privacy of items In-Reply-To: References: Message-ID: <5208156C.6050104@mozilla.com> On 8/12/13 10:12 AM, Kevin Ballard wrote: >> So I came across a weird fact that is entirely inconsistent with my >> mental model of Rust. extra::arc::RWArc is private, but you can use it >> *everywhere*. You can call RWArc::new, you can use it as a type, etc. >> What is happening? This is a known bug, and is on my list to fix soon. Patrick From armin.ronacher at active-4.com Sun Aug 11 15:58:48 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sun, 11 Aug 2013 23:58:48 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> Message-ID: <52081728.1020503@active-4.com> Hi, On 11/08/2013 23:47, Daniel Micay wrote: > Python does not make the guarantee, and the functions like `zip` there > will continue calling the underlying iterators. That's incorrect. Python's definition of the iterator protocol is that an iterator not continue raising StopIteration is in violation of the protocol. Regards, Armin From danielmicay at gmail.com Sun Aug 11 16:10:34 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 11 Aug 2013 19:10:34 -0400 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <52081728.1020503@active-4.com> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> <52081728.1020503@active-4.com> Message-ID: On Sun, Aug 11, 2013 at 6:58 PM, Armin Ronacher wrote: > Hi, > > > On 11/08/2013 23:47, Daniel Micay wrote: >> >> Python does not make the guarantee, and the functions like `zip` there >> will continue calling the underlying iterators. > > That's incorrect. Python's definition of the iterator protocol is that an > iterator not continue raising StopIteration is in violation of the protocol. > > > Regards, > Armin If the underlying iterators continue to raise StopIteration, zip will continue to do so. It will *not* stop calling __next__ on them, and will happily start yielding elements again if they all do. The other itertools adaptors are the same way. Perhaps it's a violation of the protocol to stop raising StopIteration, but zip will continue to cause side effects like I/O. From armin.ronacher at active-4.com Sun Aug 11 16:21:10 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 12 Aug 2013 00:21:10 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> <52081728.1020503@active-4.com> Message-ID: <52081C66.9040009@active-4.com> Hi, On 12/08/2013 00:10, Daniel Micay wrote: > Perhaps it's a violation of the protocol to stop raising > StopIteration, but zip will continue to cause side effects like I/O. It's undefined what happens if you continue producing items after you stopped. There are no safeguards in place. However any consumer of iterators can ignore the case where it might receive an already exhausted iterator which is a very good thing because it makes all the code much easier. No need to handle a special case. Regards, Armin From kevin at sb.org Sun Aug 11 18:54:01 2013 From: kevin at sb.org (Kevin Ballard) Date: Sun, 11 Aug 2013 21:54:01 -0400 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> Message-ID: <5145877A-0278-4A3E-BAC2-14DA86094245@sb.org> For reference, in my iterative proposal, I've been considering adding a `.finished()` method to the Fuse adaptor, which would let you easily add that capability to any iterator. -Kevin Ballard > On Aug 11, 2013, at 6:47 PM, Daniel Micay wrote: > >> On Sun, Aug 11, 2013 at 6:32 PM, Tom Lee wrote: >> >>> On Sun, Aug 11, 2013 at 3:18 PM, Jens Nockert wrote: >>> >>> >>> On 12 Aug 2013, at 00:09, Tom Lee wrote: >>> >>> Anyway, this sort of confusion is exactly why I don't like for..else. But >>> then maybe I'm the only one that's confused here. :) >>> >>> >>> Obviously you were not the only one, since there was a long thread without >>> clarification. >>> >>> While I think it is reasonably clear (since I am used to it), I don't >>> think it is more clear than something like (in faux pyrust) >>> >>> let iterations = xrange(100); >>> >>> for i in iterations { >>> ? >>> if converged { >>> break; >>> } >>> } >>> >>> if iterations.finished() { >>> fail!("Oh noes, it did not converge"); >>> } >> >> I really like this. There's no room for confusion here. > > The iterator adaptors don't keep track of whether they've finished, > they only bubble up the underlying `next()` calls. The `None` will be > returned during the loop, and after that there's no way to query > whether it has finished. > > For example, this is zip: > > fn next(&mut self) -> Option<(A, B)> { > match (self.a.next(), self.b.next()) { > (Some(x), Some(y)) => Some((x, y)), > _ => None > } > } > > There's a separate thread about this, but I don't think returning > `None` forever without side effects is a guarantee we should make. > Python does not make the guarantee, and the functions like `zip` there > will continue calling the underlying iterators. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From micah at micahchalmer.net Sun Aug 11 22:23:56 2013 From: micah at micahchalmer.net (Micah Chalmer) Date: Mon, 12 Aug 2013 01:23:56 -0400 Subject: [rust-dev] Question about threads (that arose while trying to write a FUSE interface) In-Reply-To: <5206C384.8060303@mozilla.com> References: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> <5206C384.8060303@mozilla.com> Message-ID: > So in general, using std I/O from outside of tasks is going to continue to be sketchy for quite a while. Thanks for the info, unfortunate though it may be. Given this, it doesn't look like I should bother even trying to get anything to work with the high level FUSE API providing its own threads. Sure, I can get it to run some trivial rust code, but that rust code can't even use any I/O--and I/O is the purpose of just about any reasonable filesystem! Raphael raised another potential issue: > libufse forks into the background when you call fuse_main() which might make you lose it (if lib fuse uses some 'clone()' call instead of fork()/daemon()). Does rust's scheduler work through a fork? If not, is it still OK if the fork happens before any other tasks are spawned? I.e. before any rust tasks are spawned, the process forks, and the child process continues and the parent exits without spawning. I tried a simple test (https://gist.github.com/MicahChalmer/1f056005e29ab3f1b912) and it didn't seem to have any problems, but are there any hidden traps around forking to be aware of? As for what I'm trying to do with libfuse, I do have a workaround: FUSE has a low level API that can be used instead, in which it calls the filesystem back in an asynchronous manner--instead of returning the info the operation seeks, you call a reply function to pass it back, and you're allowed to do so at some point after you've already returned from the callback. The low-level API is harder to work with, but appears to be the way to go if I want to continue working on this. Instead of fiddling with the subset of rust that's usable without the scheduler, I could actually use the scheduler to run each filesystem operation in its own task. It will be interesting to see how many of the documented rules of usage that exist only as comments in the C API can be made enforceable in rust's type system... -Micah -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.sapin at exyr.org Sun Aug 11 23:59:39 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Mon, 12 Aug 2013 07:59:39 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> Message-ID: <520887DB.2020306@exyr.org> Le 11/08/2013 23:18, Jens Nockert a ?crit : > for i in iterations { > ? > if converged { > break; > } > } > > if iterations.finished() { > fail!("Oh noes, it did not converge"); > } The only way to implement .finished() non destructively (so that, when returning false, it does not eat an element) is with a Peekable iterator as in this pull request: https://github.com/mozilla/rust/pull/8428 Then .finished() is .peek().is_none(). But this is unnecessary overhead if you don?t otherwise use .peek(). The for-loop already knows how it exited. -- Simon Sapin From corey at octayn.net Mon Aug 12 08:33:13 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 12 Aug 2013 11:33:13 -0400 Subject: [rust-dev] rustdoc_ng: 95% done Message-ID: Hello all, I present to you: rustdoc_ng http://seld.be/rustdoc/master/index.html It's basically done, only a few minor bugs remain, as well as the listing of `pub use`'s. I've been using it as my only doc browser the past day and it's quite wonderful. The search is still a bit primitive, but that's not a blocker. So, give it a spin. Report any bugs either in reply here, or in IRC in either #rust or #rustdoc-wg. Super thanks to Jed Estep and Huon Wilson, who helped a lot with the backend. And, of course, this would have taken 3x longer and the result would have been half as good if it were not for Jordi Boggiano and his amazing work with the web frontend. From michaelwoerister at gmail.com Mon Aug 12 09:14:35 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Mon, 12 Aug 2013 18:14:35 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: <520909EB.1090105@gmail.com> On 08/12/2013 05:33 PM, Corey Richardson wrote: > Hello all, > > I present to you: rustdoc_ng http://seld.be/rustdoc/master/index.html > > It's basically done, only a few minor bugs remain, as well as the > listing of `pub use`'s. I've been using it as my only doc browser the > past day and it's quite wonderful. > > The search is still a bit primitive, but that's not a blocker. So, > give it a spin. Report any bugs either in reply here, or in IRC in > either #rust or #rustdoc-wg. > > Super thanks to Jed Estep and Huon Wilson, who helped a lot with the > backend. And, of course, this would have taken 3x longer and the > result would have been half as good if it were not for Jordi Boggiano > and his amazing work with the web frontend. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev This is great! Thanks to everyone involved :) -Michael From martine at danga.com Mon Aug 12 09:15:53 2013 From: martine at danga.com (Evan Martin) Date: Mon, 12 Aug 2013 09:15:53 -0700 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: This looks really great. Some random feedback from a skim. I love that there are cross-references within the code snippets. It's great to be able to quickly look up what a trait means. I noticed that "prelude" in the discussion on http://seld.be/rustdoc/master/std/index.html isn't a link, is that easy to make work or is it too Javadoc-y to need to mark up cross references in free text like that? Speaking of the prelude, I noticed that these docs, like the old rust docs, don't say anything in the prelude. Is that possible to fix? That was one of the first places I wanted to skim when I was trying to get a handle on the language. The relative weights of fonts on the page don't correspond to their importance. That is, the "TUTORIAL | MANUAL" bit is the largest, boldest, most whitespaced piece of the page but they're only links you're really looking for when you first open the docs, not something you need at the forefront when you're digging into the details of some random function. ' This is vague, I feel like there's too many clicks to get into the details of something. E.g. if I'm trying to see what the std module offers, the overview page just lists modules without any description. if I click into ascii, I see a list of functions but I need to click on each one to see what it does. In the golang world they have a convention of providing short summary docs separate from the detailed docs to avoid this; see http://golang.org/pkg/ . I often use ctl-F on that page to find what I'm looking for. Similarly if you click in to a package there -- they show the function types inline which is often a hint to their behavior. You could make the links to source more stable by linking to exactly the version of the source that the docs were built from. E.g. rather than having http://seld.be/rustdoc/master/std/either/fn.lefts.html link to https://github.com/mozilla/rust/blob/master/src/libstd/either.rs#L121-130 you could replace 'master' there with the commit, like https://github.com/mozilla/rust/blob/fad7857c7b2c42da6081e593ab92d03d88643c81/src/libstd/either.rs#L121-130 Consider using the 'title' attribute on links to make the tooltip give some hint about their other side. For example you could embed the short description there. On Mon, Aug 12, 2013 at 8:33 AM, Corey Richardson wrote: > Hello all, > > I present to you: rustdoc_ng http://seld.be/rustdoc/master/index.html > > It's basically done, only a few minor bugs remain, as well as the > listing of `pub use`'s. I've been using it as my only doc browser the > past day and it's quite wonderful. > > The search is still a bit primitive, but that's not a blocker. So, > give it a spin. Report any bugs either in reply here, or in IRC in > either #rust or #rustdoc-wg. > > Super thanks to Jed Estep and Huon Wilson, who helped a lot with the > backend. And, of course, this would have taken 3x longer and the > result would have been half as good if it were not for Jordi Boggiano > and his amazing work with the web frontend. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Mon Aug 12 09:20:47 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 12 Aug 2013 12:20:47 -0400 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: On Mon, Aug 12, 2013 at 12:15 PM, Evan Martin wrote: > I love that there are cross-references within the code snippets. It's great > to be able to quickly look up what a trait means. I noticed that "prelude" > in the discussion on http://seld.be/rustdoc/master/std/index.html isn't a > link, is that easy to make work or is it too Javadoc-y to need to mark up > cross references in free text like that? > Sure, a plugin could implement this. It would not be very easy, though, it'd need to hook into `resolve`, which I don't know how to do. > > Speaking of the prelude, I noticed that these docs, like the old rust docs, > don't say anything in the prelude. Is that possible to fix? That was one > of the first places I wanted to skim when I was trying to get a handle on > the language. > As I said, documentation of `pub use` (which is all the prelude consists of) is the last missing piece of functionality. From robertknight at gmail.com Mon Aug 12 09:41:05 2013 From: robertknight at gmail.com (Robert Knight) Date: Mon, 12 Aug 2013 17:41:05 +0100 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: Hello Corey, Thanks for your work on this. The live search is especially welcome. > The relative weights of fonts on the page don't correspond to their importance. That is, the "TUTORIAL | MANUAL" bit is the largest, boldest, > most whitespaced piece of the page but they're only links you're really looking for when you first open the docs, not something you need at the forefront > when you're digging into the details of some random function. That was my first impression as well, possibly because of the contrast with the manual and Github interfaces. I'd suggest lightening the font weights and sizes in general. Regards, Rob. On 12 August 2013 17:20, Corey Richardson wrote: > On Mon, Aug 12, 2013 at 12:15 PM, Evan Martin wrote: >> I love that there are cross-references within the code snippets. It's great >> to be able to quickly look up what a trait means. I noticed that "prelude" >> in the discussion on http://seld.be/rustdoc/master/std/index.html isn't a >> link, is that easy to make work or is it too Javadoc-y to need to mark up >> cross references in free text like that? >> > > Sure, a plugin could implement this. It would not be very easy, > though, it'd need to hook into `resolve`, which I don't know how to > do. > >> >> Speaking of the prelude, I noticed that these docs, like the old rust docs, >> don't say anything in the prelude. Is that possible to fix? That was one >> of the first places I wanted to skim when I was trying to get a handle on >> the language. >> > > As I said, documentation of `pub use` (which is all the prelude > consists of) is the last missing piece of functionality. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From slabode at aim.com Mon Aug 12 09:59:20 2013 From: slabode at aim.com (SiegeLord) Date: Mon, 12 Aug 2013 12:59:20 -0400 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: <52091468.4040603@aim.com> On 08/12/2013 12:15 PM, Evan Martin wrote: > You could make the links to source more stable by linking to exactly the > version of the source that the docs were built from. > E.g. rather than having > http://seld.be/rustdoc/master/std/either/fn.lefts.html > link to > https://github.com/mozilla/rust/blob/master/src/libstd/either.rs#L121-130 > you could replace 'master' there with the commit, like > https://github.com/mozilla/rust/blob/fad7857c7b2c42da6081e593ab92d03d88643c81/src/libstd/either.rs#L121-130 Along the same lines, what I'm planning on doing is providing snapshots of the source (created via pygments or something similar), so it'd be nice to be able to specify the format of the line anchors/file extensions in some way. As far as I can tell, for pygments it will look like this: module.html#foo-123, for example. -SL From micah at micahchalmer.net Mon Aug 12 10:23:40 2013 From: micah at micahchalmer.net (Micah Chalmer) Date: Mon, 12 Aug 2013 13:23:40 -0400 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <520887DB.2020306@exyr.org> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> <520887DB.2020306@exyr.org> Message-ID: <7704BD61-40B4-4607-8815-EBCC8A0FE621@micahchalmer.net> > The only way to implement .finished() non destructively (so that, when returning false, it does not eat an element) is with a Peekable iterator as in this pull request: > > https://github.com/mozilla/rust/pull/8428 > > Then .finished() is .peek().is_none(). If you loop all the way through the iterator without calling peek(), then when you call peek() after that, it's going to call next() on the underlying iterator after it has already returned None. Without guarantees discussed earlier in this thread about what happens if you call next() on an iterator that has already returned None once, this won't necessarily work--and as referenced earlier, those guarantees cannot be assumed. > But this is unnecessary overhead if you don?t otherwise use .peek(). The for-loop already knows how it exited. It only "knows" if something explicitly makes it know. This boils down to one of two things: either the boolean flag approach as discussed earlier, or the compiler turning every "break" in the block into an explicit call to the else block. > > -- > Simon Sapin > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From alex at crichton.co Mon Aug 12 10:27:06 2013 From: alex at crichton.co (Alex Crichton) Date: Mon, 12 Aug 2013 10:27:06 -0700 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: This is awesome! If you're taking suggestions, it seems like one case can be improved. If you just heard about this TreeMap thing, you'd go to the dox, search for treemap (awesome live update btw), hit the first link, and then get bombarded with a *lot* of type signatures. If all you wanted to find was the signature for "pop", you've got to scroll down aways and find the small "pop" word. It'd be kinda nice to all instance methods in a nice easily-scannable location which eventually had links with something along the lines of "provided by the XXX trait" or something like that. I'm also a fan of large-ish documentation pages. Currently there's only ever one method per page, but I personally prefer having all the methods all on one page. That way I can just scan up and down the page (and use anchors for links) to find what the method was that I needed. This isn't really major though. Also, it appears that type parameterization for return types isn't showing up just yet, the return value of "pop" is just Option, not Option. Finally, perhaps all of the types/traits don't have to be listed with their full paths? It clutters up things like the Encodable implementation for TreeMap, and everything is a hyperlink anyway so it should be pretty easy to find the full path. On Mon, Aug 12, 2013 at 8:33 AM, Corey Richardson wrote: > Hello all, > > I present to you: rustdoc_ng http://seld.be/rustdoc/master/index.html > > It's basically done, only a few minor bugs remain, as well as the > listing of `pub use`'s. I've been using it as my only doc browser the > past day and it's quite wonderful. > > The search is still a bit primitive, but that's not a blocker. So, > give it a spin. Report any bugs either in reply here, or in IRC in > either #rust or #rustdoc-wg. > > Super thanks to Jed Estep and Huon Wilson, who helped a lot with the > backend. And, of course, this would have taken 3x longer and the > result would have been half as good if it were not for Jordi Boggiano > and his amazing work with the web frontend. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From danielmicay at gmail.com Mon Aug 12 10:39:28 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 12 Aug 2013 13:39:28 -0400 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: On Mon, Aug 12, 2013 at 11:33 AM, Corey Richardson wrote: > Hello all, > > I present to you: rustdoc_ng http://seld.be/rustdoc/master/index.html > > It's basically done, only a few minor bugs remain, as well as the > listing of `pub use`'s. I've been using it as my only doc browser the > past day and it's quite wonderful. > > The search is still a bit primitive, but that's not a blocker. So, > give it a spin. Report any bugs either in reply here, or in IRC in > either #rust or #rustdoc-wg. > > Super thanks to Jed Estep and Huon Wilson, who helped a lot with the > backend. And, of course, this would have taken 3x longer and the > result would have been half as good if it were not for Jordi Boggiano > and his amazing work with the web frontend. It looks awesome, thanks for all the hard work on this! A nitpick is that the markdown isn't being rendered correctly, at least not how it would be with an up-to-date pandoc. From simon.sapin at exyr.org Mon Aug 12 10:56:44 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Mon, 12 Aug 2013 18:56:44 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <7704BD61-40B4-4607-8815-EBCC8A0FE621@micahchalmer.net> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> <520887DB.2020306@exyr.org> <7704BD61-40B4-4607-8815-EBCC8A0FE621@micahchalmer.net> Message-ID: <520921DC.9020309@exyr.org> Le 12/08/2013 18:23, Micah Chalmer a ?crit : >> The for-loop already knows how it exited. > It only "knows" if something explicitly makes it know. This boils > down to one of two things: either the boolean flag approach as > discussed earlier, or the compiler turning every "break" in the block > into an explicit call to the else block. No, it?s the opposite. The for-else loop jumps to the else block when the iterator?s next() returns None. -- Simon Sapin From armin.ronacher at active-4.com Mon Aug 12 11:10:52 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 12 Aug 2013 19:10:52 +0100 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: <5209252C.1090404@active-4.com> Hi, On 12/08/2013 16:33, Corey Richardson wrote: > Super thanks to Jed Estep and Huon Wilson, who helped a lot with the > backend. And, of course, this would have taken 3x longer and the > result would have been half as good if it were not for Jordi Boggiano > and his amazing work with the web frontend. Amazing work. Just one question: is there a mode where you can see all the functions, structs and members in a module on one page? Regards, Armin From pwalton at mozilla.com Mon Aug 12 11:19:13 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 13 Aug 2013 06:19:13 +1200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: <52092721.6030607@mozilla.com> On 8/13/13 4:15 AM, Evan Martin wrote: > This is vague, I feel like there's too many clicks to get into the > details of something. E.g. if I'm trying to see what the std module > offers, the overview page just lists modules without any description. > if I click into ascii, I see a list of functions but I need to click > on each one to see what it does. In the golang world they have a > convention of providing short summary docs separate from the detailed > docs to avoid this; see http://golang.org/pkg/ . I often use ctl-F on > that page to find what I'm looking for. Similarly if you click in to a > package there -- they show the function types inline which is often a > hint to their behavior. Yes, this was the first thing I noticed. I'd prefer if there were a short summary of each item next to it in the module view. Patrick From banderson at mozilla.com Mon Aug 12 11:30:50 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 12 Aug 2013 11:30:50 -0700 Subject: [rust-dev] Question about threads (that arose while trying to write a FUSE interface) In-Reply-To: References: <9AE75971-C0D0-4EB3-89FA-3EDB3692E555@micahchalmer.net> <5206C384.8060303@mozilla.com> Message-ID: <520929DA.4030707@mozilla.com> On 08/11/2013 10:23 PM, Micah Chalmer wrote: >> So in general, using std I/O from outside of tasks is going to >> continue to be sketchy for quite a while. > > Thanks for the info, unfortunate though it may be. Given this, it > doesn't look like I should bother even trying to get anything to work > with the high level FUSE API providing its own threads. Sure, I can > get it to run some trivial rust code, but that rust code can't even > use any I/O--and I/O is the purpose of just about any reasonable > filesystem! > > Raphael raised another potential issue: > >> libufse forks into the background when you call fuse_main() which >> might make you lose it (if lib fuse uses some 'clone()' call instead >> of fork()/daemon()). > > Does rust's scheduler work through a fork? If not, is it still OK if > the fork happens before any other tasks are spawned? I.e. before any > rust tasks are spawned, the process forks, and the child process > continues and the parent exits without spawning. I tried a simple > test (https://gist.github.com/MicahChalmer/1f056005e29ab3f1b912) and > it didn't seem to have any problems, but are there any hidden traps > around forking to be aware of? If you do it before starting the runtime then it's fine. Forking without execing while the scheduler is running will likely be disastrous. > > As for what I'm trying to do with libfuse, I do have a workaround: > FUSE has a low level API that can be used instead, in which it calls > the filesystem back in an asynchronous manner--instead of returning > the info the operation seeks, you call a reply function to pass it > back, and you're allowed to do so at some point after you've already > returned from the callback. The low-level API is harder to work with, > but appears to be the way to go if I want to continue working on this. > Instead of fiddling with the subset of rust that's usable without the > scheduler, I could actually use the scheduler to run each filesystem > operation in its own task. > > It will be interesting to see how many of the documented rules of > usage that exist only as comments in the C API can be made enforceable > in rust's type system... > > -Micah -------------- next part -------------- An HTML attachment was scrubbed... URL: From simon.sapin at exyr.org Mon Aug 12 11:54:56 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Mon, 12 Aug 2013 19:54:56 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <5207EEC5.2090407@exyr.org> <5207F3BE.2060008@mozilla.com> Message-ID: <52092F80.9000806@exyr.org> Le 11/08/2013 21:30, Tom Lee a ?crit : > On Sun, Aug 11, 2013 at 1:27 PM, Patrick Walton > wrote: > > On 8/12/13 8:25 AM, Tom Lee wrote: > > :) I can appreciate that, but I'm still not really convinced > that this > "problem" deserves more syntax. > > That said, I might hate for..else less if it used something > other than > the 'else' keyword. *shrug* > > > It seems to me that a big benefit of macros in Rust is to make > less-commonly-used syntax still usable and reasonably convenient > without having to build it into the compiler. "for/else" may be a > perfect use case here. > > > You're right. I keep forgetting the macro proposal when I come back to > read this thread. Here it is, with an usage example. You have to assign the iterator to a mutable variable explicitly: macro_rules! for_( ($pattern: pat in $iter: ident $body: expr) => { for_!($pattern in $iter $body else {}); }; ($pattern: pat in $iter: ident $body: expr else $else_: expr) => { loop { match $iter.next() { None => { $else_; break }, Some($pattern) => { $body; }, } } }; ) fn main() { let v = ~[1u, 7, 42, 0]; let mut it = v.move_iter().enumerate(); for_!((i, v) in it { if v == 42 { printfln!("Found it at %u", i); break } } else { println("Not found"); }) } -- Simon Sapin From armin.ronacher at active-4.com Mon Aug 12 12:10:01 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 12 Aug 2013 20:10:01 +0100 Subject: [rust-dev] Initialization Syntax [was: Iterator blocks (yield)] In-Reply-To: <52063EDA.1070503@gmail.com> References: <52063EDA.1070503@gmail.com> Message-ID: <52093309.6030301@active-4.com> Hi, I was just thinking about that again, and I wonder if that could be used to create a pattern for initialization "literals" for collections. Once we have "yield fn" there could be syntax that converts initialization code into a generator that is passed to a function call: let mut l = List::literal() {{ ~"foo", ~"bar" }}; /* -> */ let mut l = List::literal((yield || -> Iterator<(~str)> { yield return ~"foo", yield return ~"bar" }})()); And as an extension to make hashmap syntax nicer: let mut hm = HashMap::literal() {{ ~"foo" => 1, ~"bar" => 2 }}; /* -> */ let mut hm = HashMap::literal((yield || -> Iterator<(~str, int)> { yield return (~"foo", 1), yield return (~"bar", 2) }})()); Unfortunately it could not be HashMap::new() because we can't have functions with different argument counts :( Regards, Armin From graydon at mozilla.com Mon Aug 12 12:11:43 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 12 Aug 2013 12:11:43 -0700 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <520921DC.9020309@exyr.org> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> <520887DB.2020306@exyr.org> <7704BD61-40B4-4607-8815-EBCC8A0FE621@micahchalmer.net> <520921DC.9020309@exyr.org> Message-ID: <5209336F.1040507@mozilla.com> Given that many people have noted that they've never used it in python, and nobody seems to agree on what the intuitive behavior for it would be, and all such behaviors can be implemented via macros, I think we'll pass. -Graydon From corey at octayn.net Mon Aug 12 12:16:14 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 12 Aug 2013 15:16:14 -0400 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <52092F80.9000806@exyr.org> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <5207EEC5.2090407@exyr.org> <5207F3BE.2060008@mozilla.com> <52092F80.9000806@exyr.org> Message-ID: On Mon, Aug 12, 2013 at 2:54 PM, Simon Sapin wrote: > fn main() { > let v = ~[1u, 7, 42, 0]; > let mut it = v.move_iter().enumerate(); > for_!((i, v) in it { > if v == 42 { > printfln!("Found it at %u", i); > break > } > } else { > println("Not found"); > }) > } > v.move_iter().position(|a| a == 42) One of Rust's strengths compared to Python is that we can implement traits on adaptors and have generic methods. From graydon at mozilla.com Mon Aug 12 12:19:39 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 12 Aug 2013 12:19:39 -0700 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <5207AB99.6060508@active-4.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> <5207A313.60700@gmail.com> <5207AB39.1060906@active-4.com> <5207AB99.6060508@active-4.com> Message-ID: <5209354B.1060102@mozilla.com> I'm happy to reserve 'yield' as a keyword for future experiments, but I don't think we have either scope or a coherent enough design to commit to doing anything particular with it at the moment. We're generally trying to get all the things we have semi-working or agreed-to-be-done *done* rather than extend the language in new directions just now. -Graydon From j.boggiano at seld.be Mon Aug 12 12:35:19 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 12 Aug 2013 21:35:19 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: <5209252C.1090404@active-4.com> References: <5209252C.1090404@active-4.com> Message-ID: <520938F7.6070705@seld.be> On 12.08.2013 20:10, Armin Ronacher wrote: > Hi, > > On 12/08/2013 16:33, Corey Richardson wrote: >> Super thanks to Jed Estep and Huon Wilson, who helped a lot with the >> backend. And, of course, this would have taken 3x longer and the >> result would have been half as good if it were not for Jordi Boggiano >> and his amazing work with the web frontend. > Amazing work. Just one question: is there a mode where you can see all > the functions, structs and members in a module on one page? Not in full with definitions and docs etc. like the current docs do. I find this particularly messy when there is more than one liner docs (which I hope we have one day;). It wouldn't be impossible to add obviously, but I'd rather focus on one use case for now, get things to work well, and then perhaps add more later as needed. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From j.boggiano at seld.be Mon Aug 12 12:36:43 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 12 Aug 2013 21:36:43 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: <5209394B.8060406@seld.be> On 12.08.2013 19:39, Daniel Micay wrote: > A nitpick is that the markdown isn't being rendered correctly, at > least not how it would be with an up-to-date pandoc. Can you give specifics? It's using the npm marked package right now with GFM (github flavoured markdown) enabled. As far as I could see from a quick scan it works fine but perhaps there are a few differences I didn't spot. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From j.boggiano at seld.be Mon Aug 12 12:44:36 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 12 Aug 2013 21:44:36 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: Message-ID: <52093B24.80702@seld.be> On 12.08.2013 19:27, Alex Crichton wrote: > This is awesome! If you're taking suggestions, it seems like one case > can be improved. If you just heard about this TreeMap thing, you'd go > to the dox, search for treemap (awesome live update btw), hit the > first link, and then get bombarded with a *lot* of type signatures. > > If all you wanted to find was the signature for "pop", you've got to > scroll down aways and find the small "pop" word. It'd be kinda nice to > all instance methods in a nice easily-scannable location which > eventually had links with something along the lines of "provided by > the XXX trait" or something like that. I'm also a fan of large-ish > documentation pages. Currently there's only ever one method per page, > but I personally prefer having all the methods all on one page. That > way I can just scan up and down the page (and use anchors for links) > to find what the method was that I needed. This isn't really major > though. Agreed, this is still a bit confusing. There is a lot of info on structs and it's hard to display it all without making a mess, but I'll definitely try to improve this over time :) > Also, it appears that type parameterization for return types isn't > showing up just yet, the return value of "pop" is just Option, not > Option. Thanks - I'll get that fixed, simple omission because we didn't have type params early on. > Finally, perhaps all of the types/traits don't have to be listed with > their full paths? It clutters up things like the Encodable > implementation for TreeMap, and everything is a hyperlink anyway so it > should be pretty easy to find the full path. module-local types are shown in short form, and the others are shown with fully qualified name for now. One improvement I have planned is to show short form for whatever is in the prelude as well, that should help in some cases. But yeah it is in some case a bit messy and quite long so perhaps we can do short-form everywhere with the fully qualified name in the link's title attribute. I'll play with it and see. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From armin.ronacher at active-4.com Mon Aug 12 12:46:07 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 12 Aug 2013 20:46:07 +0100 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: <520938F7.6070705@seld.be> References: <5209252C.1090404@active-4.com> <520938F7.6070705@seld.be> Message-ID: <52093B7F.4000807@active-4.com> Hi, On 12/08/2013 20:35, Jordi Boggiano wrote: > Not in full with definitions and docs etc. like the current docs do. I > find this particularly messy when there is more than one liner docs > (which I hope we have one day;). It wouldn't be impossible to add > obviously, but I'd rather focus on one use case for now, get things to > work well, and then perhaps add more later as needed. I have a really hard time getting information efficiently out of the new docs unfortunately. I find in page search much better to find the relevant information than having to trust a search index to bring me to the page I want. I find this especially bad if a module only exposes a single type and some related types that are returned from functions. For instance this one: http://seld.be/rustdoc/std/hashmap/index.html I much rather have all the information related to the hash map on a single page. I can see that being personal preference, which is why I'm wondering if we can't have both :-) Regards, Armin From j.boggiano at seld.be Mon Aug 12 12:46:29 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 12 Aug 2013 21:46:29 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: <52092721.6030607@mozilla.com> References: <52092721.6030607@mozilla.com> Message-ID: <52093B95.5020701@seld.be> On 12.08.2013 20:19, Patrick Walton wrote: > On 8/13/13 4:15 AM, Evan Martin wrote: >> This is vague, I feel like there's too many clicks to get into the >> details of something. E.g. if I'm trying to see what the std module >> offers, the overview page just lists modules without any description. >> if I click into ascii, I see a list of functions but I need to click >> on each one to see what it does. In the golang world they have a >> convention of providing short summary docs separate from the detailed >> docs to avoid this; see http://golang.org/pkg/ . I often use ctl-F on >> that page to find what I'm looking for. Similarly if you click in to a >> package there -- they show the function types inline which is often a >> hint to their behavior. > > Yes, this was the first thing I noticed. I'd prefer if there were a > short summary of each item next to it in the module view. It's coming :) Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From danielmicay at gmail.com Mon Aug 12 13:27:18 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 12 Aug 2013 16:27:18 -0400 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: <5209394B.8060406@seld.be> References: <5209394B.8060406@seld.be> Message-ID: On Mon, Aug 12, 2013 at 3:36 PM, Jordi Boggiano wrote: > On 12.08.2013 19:39, Daniel Micay wrote: >> A nitpick is that the markdown isn't being rendered correctly, at >> least not how it would be with an up-to-date pandoc. > > Can you give specifics? It's using the npm marked package right now with > GFM (github flavoured markdown) enabled. As far as I could see from a > quick scan it works fine but perhaps there are a few differences I > didn't spot. > > Cheers > > -- > Jordi Boggiano > @seldaek - http://nelm.io/jordi I noticed it because the code samples weren't syntax highlighted but there are some other quirks with lists/headers. Rust's documentation doesn't stick to the very small part of the language that's common across most implementations. It would mean no nested lists, tables, code snippets, definition lists, formulas, etc. http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html From j.boggiano at seld.be Mon Aug 12 13:41:15 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 12 Aug 2013 22:41:15 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: <5209394B.8060406@seld.be> Message-ID: <5209486B.4030405@seld.be> > I noticed it because the code samples weren't syntax highlighted but > there are some other quirks with lists/headers. Rust's documentation > doesn't stick to the very small part of the language that's common > across most implementations. It would mean no nested lists, tables, > code snippets, definition lists, formulas, etc. > > http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html OK, well the syntax highlighting is another problem, the lib I'm using seems to have an out of date rust syntax or something and it fails hard when trying to highlight blocks so I temporarily disabled it. nested lists and tables are supported, code blocks too. definition lists can be inlined in html in the docs if really needed, formulas I have no idea. The bottom line is most things are possible too with GFM and it is my opinion that it's more common/well-known than pandoc given that pretty much everyone these days uses github at some point or another. So I would say if that's ok we switch whatever few things don't work from the pandoc syntax over to GFM syntax. Is this acceptable? I don't mind helping with it, but it would help if people report any incompatibilities then. Cheers From jeaye at arrownext.com Mon Aug 12 13:47:04 2013 From: jeaye at arrownext.com (Jeaye) Date: Mon, 12 Aug 2013 14:47:04 -0600 Subject: [rust-dev] =?utf-8?q?rustdoc=5Fng=3A_95=25_done?= In-Reply-To: <5209486B.4030405@seld.be> References: <5209394B.8060406@seld.be> <5209486B.4030405@seld.be> Message-ID: Searching for std::hashmap::HashMap, I typed "Hash". When the ideal results didn't show up, I added an 'M' to make my query "HashM" at this point, I'm told nothing is found and that I should try DDG. However, if I continue to type 'ap' to make my query "HashMap", I get proper results. This seems broken to me; do you know about it? Cheers, Jeaye From j.boggiano at seld.be Mon Aug 12 13:50:15 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 12 Aug 2013 22:50:15 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: <5209394B.8060406@seld.be> <5209486B.4030405@seld.be> Message-ID: <52094A87.3010705@seld.be> On 12.08.2013 22:47, Jeaye wrote: > Searching for std::hashmap::HashMap, I typed "Hash". When the ideal > results didn't show up, I added an 'M' to make my query "HashM" at this > point, I'm told nothing is found and that I should try DDG. However, if > I continue to type 'ap' to make my query "HashMap", I get proper > results. This seems broken to me; do you know about it? Yes search is now a bit dumb and kinda only does exact matches. It's a decent search engine for natural language stuff, but does not scale very well to the needs we have. Ultimately I hope someone will find the time to rewrite it, but for now it's not the top priority. If you'd like to help obviously feel free to get in touch :) From danielmicay at gmail.com Mon Aug 12 14:06:32 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 12 Aug 2013 17:06:32 -0400 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: <5209486B.4030405@seld.be> References: <5209394B.8060406@seld.be> <5209486B.4030405@seld.be> Message-ID: On Mon, Aug 12, 2013 at 4:41 PM, Jordi Boggiano wrote: >> I noticed it because the code samples weren't syntax highlighted but >> there are some other quirks with lists/headers. Rust's documentation >> doesn't stick to the very small part of the language that's common >> across most implementations. It would mean no nested lists, tables, >> code snippets, definition lists, formulas, etc. >> >> http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html > > OK, well the syntax highlighting is another problem, the lib I'm using > seems to have an out of date rust syntax or something and it fails hard > when trying to highlight blocks so I temporarily disabled it. > > nested lists and tables are supported, code blocks too. definition lists > can be inlined in html in the docs if really needed, formulas I have no > idea. > > The bottom line is most things are possible too with GFM and it is my > opinion that it's more common/well-known than pandoc given that pretty > much everyone these days uses github at some point or another. So I > would say if that's ok we switch whatever few things don't work from the > pandoc syntax over to GFM syntax. Is this acceptable? I don't mind > helping with it, but it would help if people report any > incompatibilities then. > > Cheers I don't think it makes sense to switch from pandoc. It's more featureful than the other generators, and has many supported output formats. The perceived popularity is much less important than quantifiable differences between the alternatives. If we embedded HTML for definition lists, footnotes, math formulas and even superscript/subscript, we would lose the ability to compile the documentation to other formats and it would no longer be easily readable/editable as plain text. Pandoc also comes with a high quality syntax highlighter and can be used to generate man pages from markdown instead of using an alternate format. From banderson at mozilla.com Mon Aug 12 14:13:02 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 12 Aug 2013 14:13:02 -0700 Subject: [rust-dev] RFC: Runtimeless libstd In-Reply-To: References: Message-ID: <52094FDE.9050002@mozilla.com> On 08/11/2013 10:42 AM, Corey Richardson wrote: > I've opened a pull request for basic runtimeless support on libstd: > https://github.com/mozilla/rust/pull/8454 > > I think it needs a wider discussion. I think it's very desirable to > have a libstd that can be used without a runtime, especially once we > have static linking and link-time DCE. As it stands, this patch is > more of a hack. It removes swaths of libstd that currently can't work > without a "runtime", but adds some simple stub implementations of the > free/malloc lang items that call into the libc, so really it requires > a C runtime. > > What I think we should end up with is various "levels" of runtime. > Some environments can provide unwinding, while others can't, for > example. You can mix-and-match various cfgs for specific pieces of the > runtime to get a libstd that can run on your platform. Other things > require explicit language items (think zero.rs). Thankfully the > compiler now errors when you use something that requires a language > item you don't implement, so it's easy to see what you need and where. > I envision a sort of "platform file" that implements language items > for a specific platform, and you'd include this in the libstd build > for the platform. > > But libstd, as it stands, is insanely dependant on a full, robust > runtime, especially task failure and TLS. A runtimeless libstd can't > depend on either of those. You can see the hack in str.rs to not use > conditions when no_rt is given. > > While I don't think my PR should be merged as-is, I think the > discussion for the best way to achieve what it accomplishes correctly > is important. There are a lot of different interrelated use cases here. * Some users don't want to use green threads for whatever reason * Some platforms can't support green threads (JS) * Some use cases don't want to link to libc (kernels, maybe microcontrollers) * Some don't want to or can't link to libc++ or libuv * Some platforms can't support threads (JS, microcontrollers?) Simply talking about a std without a runtime is troublesome, since what exactly the runtime is isn't clear, and really it is specific features that are untenable in different scenarios. It would probably be most productive to identify specific use cases and make Rust work there instead of just having a goal of removing the runtime. From my perspective, making std work in emscripten is probably the coolest project, but there are also a lot of people interested in microcontrollers so that would be a good avenue to explore too. Some of the big problem areas in Rust's runtime semantics are unwinding and task-local storage - but also anything that depends on task-local state. To make this work without green threads I expect to add another subtype of `Task` that is not a coroutine (#8474). It should be compatible with most environments. Of course, if you consider tasks to be runtime, and you want a runtimeless rust, then this may be unsatisfying still. This is why I no longer think of this goal as 'runtimeless' but as 'profiles' - to have full Rust functionality you really need to have some implementation of the task abstraction. Though maybe in a single-threaded environment where `fail!()` can mean `abort()` you could imagine not having a task at all while preserving most functionality - still though it seems like we're going down the path of using conditions more and those require local storage, so I don't think we're going to get away from thread-local/task-local state as a firm requirement for std. I guess I don't have any specific advice here besides to work toward a specific, testable use-case, and do it in small steps that have minimal impact on the common case. I will say that the current patch that sprinkles `#[cfg(not(no_rt))]` in *very many* places is pretty tough to swallow. Good luck. -Brian From banderson at mozilla.com Mon Aug 12 14:19:37 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 12 Aug 2013 14:19:37 -0700 Subject: [rust-dev] RFC: Runtimeless libstd In-Reply-To: References: Message-ID: <52095169.4070107@mozilla.com> On 08/11/2013 12:15 PM, Matthieu Monrocq wrote: > Hi Corey, > > It's great to see that people are thinking more and more about > integrating Rust in existing languages! > > I wonder however whether the other alternative has been envisioned: if > Rust requires a runtime to work properly (specifically: TLS, task > failure), would it be possible to provide an external caller the > ability to setup the runtime before calling Rust methods ? Yes, this is absolutely a requirement for embedding Rust. Servo needs it so it will happen. Specifically, in order to do any useful embedding you need to be able to communicate from outside a task to inside and vice versa. What I am expecting here is to provide a `Task` subclass like `ThreadTask` or `StackTask` (a task that isn't a green thread and runs on the local thread's stack) that provides most of the task-local functionality without the user-space context switching. In an FFI callback from another language you might do something vaguely like extern fn callback(cbdata: *Void) { let data = from_cbdata(cbdata); do in_stack_task { // Send a message to a normal Rust task data.chan.send(GoDoSomethingInARustTask); } } I haven't put any work into this because there are so many other things I need to do, but this is the gist of what I have in mind. From daede003 at umn.edu Mon Aug 12 14:33:01 2013 From: daede003 at umn.edu (Thomas Daede) Date: Mon, 12 Aug 2013 16:33:01 -0500 Subject: [rust-dev] Cell as trait Message-ID: Is there any reason that Cell is implemented as a struct containing only an Option? Wouldn't it be equivalent to have Cell's methods implemented in Option, and then apply Cell as a trait? How do you determine when to make the split between more traits, and a new struct? From danielmicay at gmail.com Mon Aug 12 14:34:58 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 12 Aug 2013 17:34:58 -0400 Subject: [rust-dev] Cell as trait In-Reply-To: References: Message-ID: On Mon, Aug 12, 2013 at 5:33 PM, Thomas Daede wrote: > Is there any reason that Cell is implemented as a struct containing > only an Option? Wouldn't it be equivalent to have Cell's methods > implemented in Option, and then apply Cell as a trait? How do you > determine when to make the split between more traits, and a new > struct? Cell uses unsafe code to break the mutability rules, and has a `#[no_freeze]` attribute marking it as non-Freeze to keep it from opening up holes in memory safety when combined with types using Freeze to enforce safety. From daede003 at umn.edu Mon Aug 12 14:40:53 2013 From: daede003 at umn.edu (Thomas Daede) Date: Mon, 12 Aug 2013 16:40:53 -0500 Subject: [rust-dev] RFC: Runtimeless libstd In-Reply-To: <52095169.4070107@mozilla.com> References: <52095169.4070107@mozilla.com> Message-ID: > extern fn callback(cbdata: *Void) { > let data = from_cbdata(cbdata); > do in_stack_task { > // Send a message to a normal Rust task > data.chan.send(GoDoSomethingInARustTask); > } > } Something like this is also very important for microcontroller interrupts - though it might not be from another language. How most modern interrupt controllers work (for example, ARM NVIC) is by pushing a partial C stack frame, and then calling a particular address - which can be a void C function as the ABI is the same. In the case of Rust, we could write a pure Rust interrupt, however it would execute outside of the context of the normal scheduler and need to push a message into it. Because Rust's scheduler is not preemptive, it would not perform a task switch immediately, though the scheduler might need some sort of special indication that someone changed its data without it looking, so the next switch takes the new message into account. From michaelwoerister at gmail.com Mon Aug 12 14:42:46 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Mon, 12 Aug 2013 23:42:46 +0200 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <5209354B.1060102@mozilla.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> <5207A313.60700@gmail.com> <5207AB39.1060906@active-4.com> <5207AB99.6060508@active-4.com> <5209354B.1060102@mozilla.com> Message-ID: <520956D6.7030700@gmail.com> On 12.08.2013 21:19, Graydon Hoare wrote: > I'm happy to reserve 'yield' as a keyword for future experiments, but I > don't think we have either scope or a coherent enough design to commit > to doing anything particular with it at the moment. We're generally > trying to get all the things we have semi-working or agreed-to-be-done > *done* rather than extend the language in new directions just now. > > -Graydon I know that the feature request (at: https://github.com/mozilla/rust/issues/7746) is assigned to the "far future" milestone. This thread and my blog series was intended to collect information about the topic and get some light discussion about possibilities going, so that when there are resources available (some time after Rust 1.0) some of the ground work has already been done and we know a bit about what people expect from 'yield'. So please don't read this as "I want this feature now and I don't care if that's feasible or not" :) -Michael From michaelwoerister at gmail.com Mon Aug 12 14:45:42 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Mon, 12 Aug 2013 23:45:42 +0200 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> Message-ID: <52095786.3040104@gmail.com> On 11.08.2013 15:25, Benjamin Striegel wrote: > Note that we have an issue open in the bug tracker for this: > > https://github.com/mozilla/rust/issues/7746 > Sorry for not replying to this earlier. Thanks for the hint! I have read the discussion in the issue and tried to take it into account in my writing. Cheers, Michael From simon.sapin at exyr.org Mon Aug 12 14:54:46 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Mon, 12 Aug 2013 22:54:46 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <5207EEC5.2090407@exyr.org> <5207F3BE.2060008@mozilla.com> <52092F80.9000806@exyr.org> Message-ID: <520959A6.3070800@exyr.org> Le 12/08/2013 20:16, Corey Richardson a ?crit : > On Mon, Aug 12, 2013 at 2:54 PM, Simon Sapin wrote: >> fn main() { >> let v = ~[1u, 7, 42, 0]; >> let mut it = v.move_iter().enumerate(); >> for_!((i, v) in it { >> if v == 42 { >> printfln!("Found it at %u", i); >> break >> } >> } else {e >> println("Not found"); >> }) >> } >> > > v.move_iter().position(|a| a == 42) > > One of Rust's strengths compared to Python is that we can implement > traits on adaptors and have generic methods. That?s good, but this was only a trivial example to demonstrate the macro. I?m not that interested about position() itself. What triggered me starting this thread is this: https://github.com/SimonSapin/servo-style/blob/c1b7e157b/media_queries.rs#L101 This is parsing a comma-separated list of Media Queries from an iterator of tokens. Invalid comma-separated parts evaluate to false. So on a syntax error, we consume the iterator until finding a comma, or the end of the input. We want to do two different things in each case. The `loop { match iter.next() { ? }}` pattern works out okay in this case, but a for-else loop would have been much nicer IMO. -- Simon Sapin From graydon at mozilla.com Mon Aug 12 14:58:57 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 12 Aug 2013 14:58:57 -0700 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: References: <5209394B.8060406@seld.be> <5209486B.4030405@seld.be> Message-ID: <52095AA1.2070508@mozilla.com> On 13-08-12 02:06 PM, Daniel Micay wrote: > I don't think it makes sense to switch from pandoc. It's more > featureful than the other generators, and has many supported output > formats. The perceived popularity is much less important than > quantifiable differences between the alternatives. Yeah, I'd prefer we don't change the doc format on a whim. Most pandoc-supported extensions are either common across markdown implementations or not-used in rust docs. If you find particularly troubling ones we can evaluate them / remove them on a case by case basis. Which ones are you running into? -Graydon From j.boggiano at seld.be Mon Aug 12 15:09:56 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Tue, 13 Aug 2013 00:09:56 +0200 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: <52095AA1.2070508@mozilla.com> References: <5209394B.8060406@seld.be> <5209486B.4030405@seld.be> <52095AA1.2070508@mozilla.com> Message-ID: <52095D34.1060106@seld.be> On 12.08.2013 23:58, Graydon Hoare wrote: > On 13-08-12 02:06 PM, Daniel Micay wrote: > >> I don't think it makes sense to switch from pandoc. It's more >> featureful than the other generators, and has many supported output >> formats. The perceived popularity is much less important than >> quantifiable differences between the alternatives. > > Yeah, I'd prefer we don't change the doc format on a whim. > > Most pandoc-supported extensions are either common across markdown > implementations or not-used in rust docs. If you find particularly > troubling ones we can evaluate them / remove them on a case by case > basis. Which ones are you running into? Valid points. I'd just rather not have to defer to an external process for every small piece of markdown we render during the build. But let's see if there is anything critical that is not supported by the lib I'm using now, and if so I'll add a pandoc renderer. I still don't know *what* is problematic at the moment though. Anyway this can be adjusted later. It's not really a show-stopper right now if a couple docblocks appear funny I think? Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From danielmicay at gmail.com Mon Aug 12 15:32:28 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 12 Aug 2013 18:32:28 -0400 Subject: [rust-dev] rustdoc_ng: 95% done In-Reply-To: <52095D34.1060106@seld.be> References: <5209394B.8060406@seld.be> <5209486B.4030405@seld.be> <52095AA1.2070508@mozilla.com> <52095D34.1060106@seld.be> Message-ID: On Mon, Aug 12, 2013 at 6:09 PM, Jordi Boggiano wrote: > On 12.08.2013 23:58, Graydon Hoare wrote: >> On 13-08-12 02:06 PM, Daniel Micay wrote: >> >>> I don't think it makes sense to switch from pandoc. It's more >>> featureful than the other generators, and has many supported output >>> formats. The perceived popularity is much less important than >>> quantifiable differences between the alternatives. >> >> Yeah, I'd prefer we don't change the doc format on a whim. >> >> Most pandoc-supported extensions are either common across markdown >> implementations or not-used in rust docs. If you find particularly >> troubling ones we can evaluate them / remove them on a case by case >> basis. Which ones are you running into? > > Valid points. I'd just rather not have to defer to an external process > for every small piece of markdown we render during the build. But let's > see if there is anything critical that is not supported by the lib I'm > using now, and if so I'll add a pandoc renderer. > > I still don't know *what* is problematic at the moment though. Anyway > this can be adjusted later. It's not really a show-stopper right now if > a couple docblocks appear funny I think? > > Cheers > > -- > Jordi Boggiano > @seldaek - http://nelm.io/jordi It's not at all a big deal, but the documentation generator will determine the documentation syntax we use due to being the defacto standard. From graydon at mozilla.com Mon Aug 12 16:09:55 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 12 Aug 2013 16:09:55 -0700 Subject: [rust-dev] Iterator blocks (yield) In-Reply-To: <520956D6.7030700@gmail.com> References: <52063EDA.1070503@gmail.com> <520760DD.70708@active-4.com> <5207A313.60700@gmail.com> <5207AB39.1060906@active-4.com> <5207AB99.6060508@active-4.com> <5209354B.1060102@mozilla.com> <520956D6.7030700@gmail.com> Message-ID: <52096B43.80600@mozilla.com> On 13-08-12 02:42 PM, Michael Woerister wrote: > I know that the feature request (at: > https://github.com/mozilla/rust/issues/7746) is assigned to the "far > future" milestone. This thread and my blog series was intended to > collect information about the topic and get some light discussion about > possibilities going, so that when there are resources available (some > time after Rust 1.0) some of the ground work has already been done and > we know a bit about what people expect from 'yield'. So please don't > read this as "I want this feature now and I don't care if that's > feasible or not" :) Ok. Sorry for sounding a bit touchy there. Two new-syntax threads in the same day gets me anxious. I'll stick with speeding up buildbots for the evening :) -Graydon From ipc at informatic.io Mon Aug 12 17:19:56 2013 From: ipc at informatic.io (Ian P. Cooke) Date: Mon, 12 Aug 2013 19:19:56 -0500 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <5145877A-0278-4A3E-BAC2-14DA86094245@sb.org> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> <5145877A-0278-4A3E-BAC2-14DA86094245@sb.org> Message-ID: <8B3CC5F2-6B41-435E-89FD-F01E071D8465@informatic.io> I'm reminded of the work done at Microsoft the showed that Observable and Enumerable were duals (e.g. http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf ) The relevant idea is that a richer interface that includes wether the the subject completed normally or via exception is very useful especially when it comes to composition of such things. as for something concrete: -1 for for-else. I don't like the reuse of 'else' and it's not a construct most people use often. On Aug 11, 2013, at 20:54 , Kevin Ballard wrote: > For reference, in my iterative proposal, I've been considering adding a `.finished()` method to the Fuse adaptor, which would let you easily add that capability to any iterator. > > -Kevin Ballard > >> On Aug 11, 2013, at 6:47 PM, Daniel Micay wrote: >> >>> On Sun, Aug 11, 2013 at 6:32 PM, Tom Lee wrote: >>> >>>> On Sun, Aug 11, 2013 at 3:18 PM, Jens Nockert wrote: >>>> >>>> >>>> On 12 Aug 2013, at 00:09, Tom Lee wrote: >>>> >>>> Anyway, this sort of confusion is exactly why I don't like for..else. But >>>> then maybe I'm the only one that's confused here. :) >>>> >>>> >>>> Obviously you were not the only one, since there was a long thread without >>>> clarification. >>>> >>>> While I think it is reasonably clear (since I am used to it), I don't >>>> think it is more clear than something like (in faux pyrust) >>>> >>>> let iterations = xrange(100); >>>> >>>> for i in iterations { >>>> ? >>>> if converged { >>>> break; >>>> } >>>> } >>>> >>>> if iterations.finished() { >>>> fail!("Oh noes, it did not converge"); >>>> } >>> >>> I really like this. There's no room for confusion here. >> >> The iterator adaptors don't keep track of whether they've finished, >> they only bubble up the underlying `next()` calls. The `None` will be >> returned during the loop, and after that there's no way to query >> whether it has finished. >> >> For example, this is zip: >> >> fn next(&mut self) -> Option<(A, B)> { >> match (self.a.next(), self.b.next()) { >> (Some(x), Some(y)) => Some((x, y)), >> _ => None >> } >> } >> >> There's a separate thread about this, but I don't think returning >> `None` forever without side effects is a guarantee we should make. >> Python does not make the guarantee, and the functions like `zip` there >> will continue calling the underlying iterators. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Mon Aug 12 19:15:07 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Mon, 12 Aug 2013 22:15:07 -0400 Subject: [rust-dev] Initialization Syntax [was: Iterator blocks (yield)] In-Reply-To: <52093309.6030301@active-4.com> References: <52063EDA.1070503@gmail.com> <52093309.6030301@active-4.com> Message-ID: Could a macro work just as well here? On Mon, Aug 12, 2013 at 3:10 PM, Armin Ronacher wrote: > Hi, > > I was just thinking about that again, and I wonder if that could be used > to create a pattern for initialization "literals" for collections. > > Once we have "yield fn" there could be syntax that converts initialization > code into a generator that is passed to a function call: > > > let mut l = List::literal() {{ > ~"foo", > ~"bar" > }}; > > /* -> */ > > let mut l = List::literal((yield || -> Iterator<(~str)> { > yield return ~"foo", > yield return ~"bar" > }})()); > > > And as an extension to make hashmap syntax nicer: > > > let mut hm = HashMap::literal() {{ > ~"foo" => 1, > ~"bar" => 2 > }}; > > /* -> */ > > let mut hm = HashMap::literal((yield || -> Iterator<(~str, int)> { > yield return (~"foo", 1), > yield return (~"bar", 2) > }})()); > > > Unfortunately it could not be HashMap::new() because we can't have > functions with different argument counts :( > > > Regards, > Armin > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Mon Aug 12 19:20:11 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 12 Aug 2013 22:20:11 -0400 Subject: [rust-dev] RFC: Runtimeless libstd In-Reply-To: <52094FDE.9050002@mozilla.com> References: <52094FDE.9050002@mozilla.com> Message-ID: On Mon, Aug 12, 2013 at 5:13 PM, Brian Anderson wrote: > On 08/11/2013 10:42 AM, Corey Richardson wrote: >> >> I've opened a pull request for basic runtimeless support on libstd: >> https://github.com/mozilla/rust/pull/8454 >> >> I think it needs a wider discussion. I think it's very desirable to >> have a libstd that can be used without a runtime, especially once we >> have static linking and link-time DCE. As it stands, this patch is >> more of a hack. It removes swaths of libstd that currently can't work >> without a "runtime", but adds some simple stub implementations of the >> free/malloc lang items that call into the libc, so really it requires >> a C runtime. >> >> What I think we should end up with is various "levels" of runtime. >> Some environments can provide unwinding, while others can't, for >> example. You can mix-and-match various cfgs for specific pieces of the >> runtime to get a libstd that can run on your platform. Other things >> require explicit language items (think zero.rs). Thankfully the >> compiler now errors when you use something that requires a language >> item you don't implement, so it's easy to see what you need and where. >> I envision a sort of "platform file" that implements language items >> for a specific platform, and you'd include this in the libstd build >> for the platform. >> >> But libstd, as it stands, is insanely dependant on a full, robust >> runtime, especially task failure and TLS. A runtimeless libstd can't >> depend on either of those. You can see the hack in str.rs to not use >> conditions when no_rt is given. >> >> While I don't think my PR should be merged as-is, I think the >> discussion for the best way to achieve what it accomplishes correctly >> is important. > > > There are a lot of different interrelated use cases here. > > * Some users don't want to use green threads for whatever reason > * Some platforms can't support green threads (JS) > * Some use cases don't want to link to libc (kernels, maybe > microcontrollers) > * Some don't want to or can't link to libc++ or libuv > * Some platforms can't support threads (JS, microcontrollers?) > > Simply talking about a std without a runtime is troublesome, since what > exactly the runtime is isn't clear, and really it is specific features that > are untenable in different scenarios. It would probably be most productive > to identify specific use cases and make Rust work there instead of just > having a goal of removing the runtime. From my perspective, making std work > in emscripten is probably the coolest project, but there are also a lot of > people interested in microcontrollers so that would be a good avenue to > explore too. > > Some of the big problem areas in Rust's runtime semantics are unwinding and > task-local storage - but also anything that depends on task-local state. To > make this work without green threads I expect to add another subtype of > `Task` that is not a coroutine (#8474). It should be compatible with most > environments. Of course, if you consider tasks to be runtime, and you want a > runtimeless rust, then this may be unsatisfying still. This is why I no > longer think of this goal as 'runtimeless' but as 'profiles' - to have full > Rust functionality you really need to have some implementation of the task > abstraction. Though maybe in a single-threaded environment where `fail!()` > can mean `abort()` you could imagine not having a task at all while > preserving most functionality - still though it seems like we're going down > the path of using conditions more and those require local storage, so I > don't think we're going to get away from thread-local/task-local state as a > firm requirement for std. > > I guess I don't have any specific advice here besides to work toward a > specific, testable use-case, and do it in small steps that have minimal > impact on the common case. I will say that the current patch that sprinkles > `#[cfg(not(no_rt))]` in *very many* places is pretty tough to swallow. Good > luck. > This is very valuable feedback, thank you! I'll mull on it a bit and see if I can't come up with something better, targeting the case of simple libc-only environment (as I think that will be easiest), or a more detailed RFC. From simon.sapin at exyr.org Tue Aug 13 01:35:35 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Tue, 13 Aug 2013 09:35:35 +0100 Subject: [rust-dev] Adding "else" on "for" loops, like Python In-Reply-To: <8B3CC5F2-6B41-435E-89FD-F01E071D8465@informatic.io> References: <520649DB.1040104@exyr.org> <52067750.7060205@vandals.uidaho.edu> <520684EB.7060701@gmail.com> <52072A50.4020705@arrownext.com> <168197CD-45B8-41D7-A9E3-ABB765BF3491@nockert.se> <942E17DE-6752-42F5-8225-CDB49E9A747B@nockert.se> <5145877A-0278-4A3E-BAC2-14DA86094245@sb.org> <8B3CC5F2-6B41-435E-89FD-F01E071D8465@informatic.io> Message-ID: <5209EFD7.4000304@exyr.org> Le 13/08/2013 01:19, Ian P. Cooke a ?crit : > I'm reminded of the work done at Microsoft the showed that Observable > and Enumerable were duals (e.g. > http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf > ) > > The relevant idea is that a richer interface that includes wether the > the subject completed normally or via exception is very useful > especially when it comes to composition of such things. > > as for something concrete: -1 for for-else. I don't like the reuse of > 'else' and it's not a construct most people use often. I?m not too attached to the name. Do you have suggestions on how it could work? -- Simon Sapin From allpowerful32 at gmail.com Tue Aug 13 20:50:30 2013 From: allpowerful32 at gmail.com (Joshua Warner) Date: Tue, 13 Aug 2013 21:50:30 -0600 Subject: [rust-dev] Linking to nested modules Message-ID: Hi, I'm seeing some strange behavior when modifying the "hello world" crates example in the 0.7 tutorial ( http://static.rust-lang.org/doc/0.7/tutorial.html#modules-and-crates). It works fine as is, but when I modify it such that the "explore" function is inside a nested module, it compiles fine but I get undefined reference errors during the linking process. Is this intended behavior? Is this a bug, or am I doing something wrong? Thanks, Joshua ---------------------- I'm using rust 0.7, on ubuntu 12.04 (64-bit). What follows is a set of commands to reproduce the problem: ---------------------- Bash: ---------------------- cat > hello.rs < world.rs < &str { "world" } } EOF rustc world.rs rustc -o hello -L . hello.rs ---------------------- Output compiling hello.rs: ---------------------- error: linking with `cc` failed with code 1 note: cc arguments: -L/usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib -m64 -o hello hello.o -L/usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib -lstd-6c65cf4b443341b1-0.7 -L. -lworld-15fb3a718ea23983-0.1 -lrustrt -lrt -lpthread -L. -lrt -ldl -lm -lmorestack -lrustrt -Wl,-rpath,$ORIGIN/../../../../../usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib -Wl,-rpath,$ORIGIN/. -Wl,-rpath,/usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib -Wl,-rpath,/tmp/test/. note: hello.o: In function `main::_f3d4197390d6bb2a::_0$x2e0': hello.rc:(.text+0x54): undefined reference to `columbus::explore::_3de4895354bdc485::_0$x2e1' collect2: ld returned 1 exit status error: aborting due to previous error -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Tue Aug 13 21:08:44 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 14 Aug 2013 16:08:44 +1200 Subject: [rust-dev] Linking to nested modules In-Reply-To: References: Message-ID: <520B02CC.6020805@mozilla.com> On 8/14/13 3:50 PM, Joshua Warner wrote: > Hi, > > I'm seeing some strange behavior when modifying the "hello world" crates > example in the 0.7 tutorial > (http://static.rust-lang.org/doc/0.7/tutorial.html#modules-and-crates). > It works fine as is, but when I modify it such that the "explore" > function is inside a nested module, it compiles fine but I get undefined > reference errors during the linking process. > > Is this intended behavior? Is this a bug, or am I doing something wrong? This is a bug. Please file it :) Patrick From me at chrismorgan.info Tue Aug 13 21:16:38 2013 From: me at chrismorgan.info (Chris Morgan) Date: Wed, 14 Aug 2013 14:16:38 +1000 Subject: [rust-dev] Linking to nested modules In-Reply-To: References: Message-ID: The error is certainly nasty and shouldn't happen like that, but yes, there was something wrong with what you did: the module columbus isn't public. Change `mod columbus` to `pub mod columbus` and it'll work. On Wed, Aug 14, 2013 at 1:50 PM, Joshua Warner wrote: > Hi, > > I'm seeing some strange behavior when modifying the "hello world" crates > example in the 0.7 tutorial ( > http://static.rust-lang.org/doc/0.7/tutorial.html#modules-and-crates). > It works fine as is, but when I modify it such that the "explore" function > is inside a nested module, it compiles fine but I get undefined reference > errors during the linking process. > > Is this intended behavior? Is this a bug, or am I doing something wrong? > > Thanks, > Joshua > > ---------------------- > > I'm using rust 0.7, on ubuntu 12.04 (64-bit). What follows is a set of > commands to reproduce the problem: > > ---------------------- Bash: ---------------------- > cat > hello.rs < extern mod world; > > fn main() { > println("hello " + world::columbus::explore()); > } > EOF > > cat > world.rs < #[ link(name = "world", > vers = "0.1")]; > > #[ crate_type = "lib" ]; > > mod columbus { > pub fn explore() -> &str { "world" } > } > EOF > > rustc world.rs > rustc -o hello -L . hello.rs > > ---------------------- Output compiling hello.rs: ---------------------- > error: linking with `cc` failed with code 1 > note: cc arguments: -L/usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib > -m64 -o hello hello.o -L/usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib > -lstd-6c65cf4b443341b1-0.7 -L. -lworld-15fb3a718ea23983-0.1 -lrustrt -lrt > -lpthread -L. -lrt -ldl -lm -lmorestack -lrustrt > -Wl,-rpath,$ORIGIN/../../../../../usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib > -Wl,-rpath,$ORIGIN/. > -Wl,-rpath,/usr/local/lib/rustc/x86_64-unknown-linux-gnu/lib > -Wl,-rpath,/tmp/test/. > note: hello.o: In function `main::_f3d4197390d6bb2a::_0$x2e0': > hello.rc:(.text+0x54): undefined reference to > `columbus::explore::_3de4895354bdc485::_0$x2e1' > collect2: ld returned 1 exit status > > error: aborting due to previous error > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allpowerful32 at gmail.com Tue Aug 13 21:38:37 2013 From: allpowerful32 at gmail.com (Joshua Warner) Date: Tue, 13 Aug 2013 22:38:37 -0600 Subject: [rust-dev] Linking to nested modules In-Reply-To: References: Message-ID: > > The error is certainly nasty and shouldn't happen like that, but yes, > there was something wrong with what you did: the module columbus isn't > public. Change `mod columbus` to `pub mod columbus` and it'll work. > Thanks. That worked perfectly. It sounds like the bug is that this ended up being a link-time error rather than a compile-time one. I'll file it as such. -Joshua -------------- next part -------------- An HTML attachment was scrubbed... URL: From allpowerful32 at gmail.com Tue Aug 13 21:52:02 2013 From: allpowerful32 at gmail.com (Joshua Warner) Date: Tue, 13 Aug 2013 22:52:02 -0600 Subject: [rust-dev] Linking to nested modules In-Reply-To: References: Message-ID: Filed under https://github.com/mozilla/rust/issues/8505. I'd be interested in taking a crack at fixing this myself (provided it's not going to be a huge fix). Any pointers in where to look? Thanks, Joshua On 13 August 2013 22:38, Joshua Warner wrote: > The error is certainly nasty and shouldn't happen like that, but yes, >> there was something wrong with what you did: the module columbus isn't >> public. Change `mod columbus` to `pub mod columbus` and it'll work. >> > > Thanks. That worked perfectly. It sounds like the bug is that this ended > up being a link-time error rather than a compile-time one. I'll file it as > such. > > -Joshua > -------------- next part -------------- An HTML attachment was scrubbed... URL: From raul.san at sent.com Wed Aug 14 00:59:26 2013 From: raul.san at sent.com (Archos) Date: Wed, 14 Aug 2013 08:59:26 +0100 Subject: [rust-dev] HTML5 parser Message-ID: <520B38DE.8070806@sent.com> I think that Servo is using a binding to a C library to parsing HTML5 (from Nginx). But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. So it could be used until that somebody builds a parser in pure Rust. https://github.com/google/gumbo-parser From simon.sapin at exyr.org Wed Aug 14 01:04:16 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Wed, 14 Aug 2013 09:04:16 +0100 Subject: [rust-dev] HTML5 parser In-Reply-To: <520B38DE.8070806@sent.com> References: <520B38DE.8070806@sent.com> Message-ID: <520B3A00.3040004@exyr.org> Le 14/08/2013 08:59, Archos a ?crit : > I think that Servo is using a binding to a C library to parsing HTML5 > (from Nginx). Right now, Servo is using Hubbub, from the NetSurf project. How is Nginx related to this? http://www.netsurf-browser.org/projects/hubbub/ > But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. > So it could be used until that somebody builds a parser in pure Rust. > > https://github.com/google/gumbo-parser That?s cool, but what would it buy us to switch from one C library to another? Is Gumbo better than Hubbub? -- Simon Sapin From pwalton at mozilla.com Wed Aug 14 01:07:13 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 14 Aug 2013 20:07:13 +1200 Subject: [rust-dev] HTML5 parser In-Reply-To: <520B38DE.8070806@sent.com> References: <520B38DE.8070806@sent.com> Message-ID: <520B3AB1.8050506@mozilla.com> On 8/14/13 7:59 PM, Archos wrote: > I think that Servo is using a binding to a C library to parsing HTML5 > (from Nginx). > > But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. > So it could be used until that somebody builds a parser in pure Rust. > > https://github.com/google/gumbo-parser I don't see much of a point in switching. It doesn't buy us any security, because it's still written in unsafe code. It also probably doesn't buy us speed, because the project explicitly says it's not designed to be the fastest HTML parser around. It would be better to switch to a Rust parser, possibly generated from validator.nu. Patrick From raul.san at sent.com Wed Aug 14 01:15:38 2013 From: raul.san at sent.com (Archos) Date: Wed, 14 Aug 2013 09:15:38 +0100 Subject: [rust-dev] HTML5 parser In-Reply-To: <520B3A00.3040004@exyr.org> References: <520B38DE.8070806@sent.com> <520B3A00.3040004@exyr.org> Message-ID: <520B3CAA.5020602@sent.com> El 14/08/13 09:04, Simon Sapin escribi?: > Le 14/08/2013 08:59, Archos a ?crit : >> I think that Servo is using a binding to a C library to parsing HTML5 >> (from Nginx). > > Right now, Servo is using Hubbub, from the NetSurf project. How is Nginx > related to this? > > http://www.netsurf-browser.org/projects/hubbub/ I though that Servo was using C files related to Nginx after of read the header of this one file: https://github.com/mozilla-servo/rust-http-client/blob/master/http_parser.c "Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev" got from message: https://mail.mozilla.org/pipermail/rust-dev/2013-August/005109.html >> But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. >> So it could be used until that somebody builds a parser in pure Rust. >> >> https://github.com/google/gumbo-parser > > That?s cool, but what would it buy us to switch from one C library to > another? Is Gumbo better than Hubbub? Well, it has tested on over 2.5 billion pages from Google's index. From masklinn at masklinn.net Wed Aug 14 01:28:13 2013 From: masklinn at masklinn.net (Masklinn) Date: Wed, 14 Aug 2013 10:28:13 +0200 Subject: [rust-dev] HTML5 parser In-Reply-To: <520B3CAA.5020602@sent.com> References: <520B38DE.8070806@sent.com> <520B3A00.3040004@exyr.org> <520B3CAA.5020602@sent.com> Message-ID: <01623B94-5E96-4A1C-9865-266690B7BBD9@masklinn.net> On 2013-08-14, at 10:15 , Archos wrote: > > >> But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. > >> So it could be used until that somebody builds a parser in pure Rust. > >> > >> https://github.com/google/gumbo-parser > > > > That?s cool, but what would it buy us to switch from one C library to > > another? Is Gumbo better than Hubbub? > > Well, it has tested on over 2.5 billion pages from Google's index. Only to ensure that it doesn't crash as far as I can see. From sh4.seo at samsung.com Wed Aug 14 01:46:45 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Wed, 14 Aug 2013 08:46:45 +0000 (GMT) Subject: [rust-dev] HTML5 parser Message-ID: <18592567.469601376470004837.JavaMail.weblogic@epml08> > I though that Servo was using C files related to Nginx after of read the > header of this one file: > > https://github.com/mozilla-servo/rust-http-client/blob/master/http_parser.c > > "Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev" You are confusing HTTP with HTML. From banderson at mozilla.com Wed Aug 14 15:17:17 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 14 Aug 2013 15:17:17 -0700 Subject: [rust-dev] HTML5 parser In-Reply-To: <520B3AB1.8050506@mozilla.com> References: <520B38DE.8070806@sent.com> <520B3AB1.8050506@mozilla.com> Message-ID: <520C01ED.90500@mozilla.com> On 08/14/2013 01:07 AM, Patrick Walton wrote: > On 8/14/13 7:59 PM, Archos wrote: >> I think that Servo is using a binding to a C library to parsing HTML5 >> (from Nginx). >> >> But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. >> So it could be used until that somebody builds a parser in pure Rust. >> >> https://github.com/google/gumbo-parser > > I don't see much of a point in switching. It doesn't buy us any > security, because it's still written in unsafe code. It also probably > doesn't buy us speed, because the project explicitly says it's not > designed to be the fastest HTML parser around. > > It would be better to switch to a Rust parser, possibly generated from > validator.nu. Agree. I was excited too, but this doesn't look useful for Servo. The next step up from hubbub will be something in Rust. From jonas at mailup.net Wed Aug 14 01:13:59 2013 From: jonas at mailup.net (Jonas) Date: Wed, 14 Aug 2013 09:13:59 +0100 Subject: [rust-dev] HTML5 parser In-Reply-To: <520B3A00.3040004@exyr.org> References: <520B38DE.8070806@sent.com> <520B3A00.3040004@exyr.org> Message-ID: <520B3C47.4070200@mailup.net> El 14/08/13 09:04, Simon Sapin escribi?: > Le 14/08/2013 08:59, Archos a ?crit : >> I think that Servo is using a binding to a C library to parsing HTML5 >> (from Nginx). > > Right now, Servo is using Hubbub, from the NetSurf project. How is Nginx > related to this? > > http://www.netsurf-browser.org/projects/hubbub/ I though that Servo was using C files related to Nginx after of read the header of this one file: https://github.com/mozilla-servo/rust-http-client/blob/master/http_parser.c "Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev" got from message: https://mail.mozilla.org/pipermail/rust-dev/2013-August/005109.html >> But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. >> So it could be used until that somebody builds a parser in pure Rust. >> >> https://github.com/google/gumbo-parser > > That?s cool, but what would it buy us to switch from one C library to > another? Is Gumbo better than Hubbub? Well, it has tested on over 2.5 billion pages from Google's index. From amitava.shee at gmail.com Thu Aug 15 18:33:50 2013 From: amitava.shee at gmail.com (Amitava Shee) Date: Thu, 15 Aug 2013 21:33:50 -0400 Subject: [rust-dev] map on range generates internal compiler error Message-ID: I am getting the following error - is this a bug? amitava:learn amitava$ cat app.rs // vi:ts=4:sw=4:nu fn main() { range(1u,3).map(|_| 5); } amitava:learn amitava$ make rustc -Z debug-info -o app app.rs app.rs:4:21: 4:22 error: internal compiler error: debuginfo: FunctionDebugContext should be initialized but is not! app.rs:4 range(1u,3).map(|_| 5); ^ make: *** [app] Error 101 amitava:learn amitava$ rustc --version rustc 0.8-pre (5c0d192 2013-08-15 13:50:10 -0700) host: x86_64-apple-darwin --- Amitava -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Thu Aug 15 21:32:21 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Fri, 16 Aug 2013 14:32:21 +1000 Subject: [rust-dev] map on range generates internal compiler error In-Reply-To: References: Message-ID: <520DAB55.7000304@gmail.com> On 16/08/13 11:33, Amitava Shee wrote: > I am getting the following error - is this a bug? > > amitava:learn amitava$ cat app.rs > // vi:ts=4:sw=4:nu > > fn main() { > range(1u,3).map(|_| 5); > } > amitava:learn amitava$ make > rustc -Z debug-info -o app app.rs > app.rs:4:21: 4:22 error: internal compiler error: debuginfo: > FunctionDebugContext should be initialized but is not! > app.rs:4 range(1u,3).map(|_| 5); > ^ > make: *** [app] Error 101 > > amitava:learn amitava$ rustc --version > rustc 0.8-pre (5c0d192 2013-08-15 13:50:10 -0700) > host: x86_64-apple-darwin > > --- > Amitava > This is indeed a bug with debugging and closures; in fact, it was independently filed a few days ago (https://github.com/mozilla/rust/issues/8513); it looks like it'll be fixed very soon. Huon -------------- next part -------------- An HTML attachment was scrubbed... URL: From michaelwoerister at gmail.com Fri Aug 16 00:06:42 2013 From: michaelwoerister at gmail.com (Michael Woerister) Date: Fri, 16 Aug 2013 09:06:42 +0200 Subject: [rust-dev] map on range generates internal compiler error In-Reply-To: <520DAB55.7000304@gmail.com> References: <520DAB55.7000304@gmail.com> Message-ID: <520DCF82.7080700@gmail.com> On 08/16/2013 06:32 AM, Huon Wilson wrote: > On 16/08/13 11:33, Amitava Shee wrote: >> I am getting the following error - is this a bug? >> >> amitava:learn amitava$ cat app.rs >> // vi:ts=4:sw=4:nu >> >> fn main() { >> range(1u,3).map(|_| 5); >> } >> amitava:learn amitava$ make >> rustc -Z debug-info -o app app.rs >> app.rs:4:21: 4:22 error: internal compiler error: debuginfo: >> FunctionDebugContext should be initialized but is not! >> app.rs:4 range(1u,3).map(|_| 5); >> ^ >> make: *** [app] Error 101 >> >> amitava:learn amitava$ rustc --version >> rustc 0.8-pre (5c0d192 2013-08-15 13:50:10 -0700) >> host: x86_64-apple-darwin >> >> --- >> Amitava >> > > This is indeed a bug with debugging and closures; in fact, it was > independently filed a few days ago > (https://github.com/mozilla/rust/issues/8513); it looks like it'll be > fixed very soon. > > > Huon > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev Yes, this is the same bug and will be fixed with the PR I plan to do later today. I added your case to the test-suite to make sure that it indeed doesn't crash anymore. Compiling with -Zdebug-info should still be considered experimental at the moment. That being said, we are always glad about getting reports like this! -Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Fri Aug 16 00:24:34 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 16 Aug 2013 00:24:34 -0700 Subject: [rust-dev] HTML5 parser In-Reply-To: <520B3C47.4070200@mailup.net> References: <520B38DE.8070806@sent.com> <520B3A00.3040004@exyr.org> <520B3C47.4070200@mailup.net> Message-ID: <520DD3B2.4090909@mozilla.com> On 8/14/13 1:13 AM, Jonas wrote: >> That?s cool, but what would it buy us to switch from one C library to >> another? Is Gumbo better than Hubbub? > > Well, it has tested on over 2.5 billion pages from Google's index. That is not enough of a reason for us to spend a lot of engineering effort moving from one C parser to another. The point of Servo's HTML parser is to be *fast* and *safe*. Gumbo is neither. "Written by Google" is not a criterion that should guide our engineering decisions. Patrick From graydon at mozilla.com Fri Aug 16 16:27:04 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 16 Aug 2013 16:27:04 -0700 Subject: [rust-dev] bors queue overflow Message-ID: <520EB548.6020705@mozilla.com> Hi, The bors queue length recently caused us to overflow the github API rate limit. I will reduce the poll frequency (and possibly look into getting us a proper API token), but it would also help if people could regularly clean out stale or bad requests and/or merge larger groups of their PRs together until we have cycle time under better control. Thanks, -Graydon From dpx.infinity at gmail.com Sat Aug 17 02:54:09 2013 From: dpx.infinity at gmail.com (Vladimir Matveev) Date: Sat, 17 Aug 2013 13:54:09 +0400 Subject: [rust-dev] Borrowed pointers with lifetime in structures cause weird errors Message-ID: Hello, I'm writing a simple tokenizer which is defined by this trait: trait Tokenizer { fn next_token(&mut self) -> ~str; fn eof(&self) -> bool; } Obvious application for a tokenizer is splitting a stream going from Reader, so I have the following structure which should implement Tokenizer: pub struct ReaderTokenizer<'self> { priv inner: &'self Reader, priv buffer: ~CyclicBuffer, priv seps: ~[~str] } I have used 'self lifetime parameter since I want for the tokenizer work for any Reader. CyclicBuffer is another structure which essentially is an array of u8 with special read/write operations. Implementation of a Tokenizer for ReaderTokenizer involves reading from the Reader one byte at a time. I decided to use buffering to improve performance. But I still want to keep the useful abstraction of single byte reading, so I decided to implement Iterator for my Reader+CyclicBuffer pair. BTW, internal iterators in 0.7 were much better for this, because internal iterator code was very simple and didn't use explicit lifetimes at all, but 0.7 compiler suffers from several errors related to pointers to traits which prevented my program from compiling (I couldn't pass a reference to Reader to CyclicBuffer method; there were other errors I've encountered too). I So, I decided to use trunk version of the compiler in which these errors are resolved according to github, but trunk version does not allow internal iterators, which is very sad since now I'm forced to create intermediate structures to achieve the same thing. So, I came up with the following iterator structure: struct RTBytesIterator<'self> { tokenizer: &'self mut ReaderTokenizer<'self> } impl<'self> Iterator for RTBytesIterator<'self> { fn next(&mut self) -> Option { if self.tokenizer.eof() { return None; } if self.tokenizer.buffer.readable_bytes() > 0 || self.tokenizer.buffer.fill_from_reader(self.tokenizer.inner) > 0 { return Some(self.tokenizer.buffer.read_unsafe()); } else { return None; } } } Note that tokenizer field is &'self mut since CyclicBuffer is mutable. buffer.fill_from_reader() function reads as much as possible from the reader (returning a number of bytes read), and buffer.read_unsafe() returns next byte from the cyclic buffer. Then I've added the following method to ReaderTokenizer: impl<'self> ReaderTokenizer<'self> { ... fn bytes_iter(&mut self) -> RTBytesIterator<'self> { RTBytesIterator { tokenizer: self } } ... } This does not compile with the following error: io/convert_io.rs:98:37: 98:43 error: cannot infer an appropriate lifetime due to conflicting requirements io/convert_io.rs:98 RTBytesIterator { tokenizer: self } ^~~~~~ io/convert_io.rs:97:55: 99:5 note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 97:55... io/convert_io.rs:97 fn bytes_iter(&mut self) -> RTBytesIterator<'self> { io/convert_io.rs:98 RTBytesIterator { tokenizer: self } io/convert_io.rs:99 } io/convert_io.rs:98:37: 98:43 note: ...due to the following expression io/convert_io.rs:98 RTBytesIterator { tokenizer: self } ^~~~~~ io/convert_io.rs:97:55: 99:5 note: but, the lifetime must be valid for the lifetime &'self as defined on the block at 97:55... io/convert_io.rs:97 fn bytes_iter(&mut self) -> RTBytesIterator<'self> { io/convert_io.rs:98 RTBytesIterator { tokenizer: self } io/convert_io.rs:99 } io/convert_io.rs:98:8: 98:23 note: ...due to the following expression io/convert_io.rs:98 RTBytesIterator { tokenizer: self } ^~~~~~~~~~~~~~~ error: aborting due to previous error OK, fair enough, I guess I have to annotate self parameter with 'self lifetime: fn bytes_iter(&'self mut self) -> RTBytesIterator<'self> { RTBytesIterator { tokenizer: self } } This compiles, but now I'm getting another error at bytes_iter() usage site, for example, the following code: fn try_read_sep(&mut self, first: u8) -> (~[u8], bool) { let mut part = ~[first]; for b in self.bytes_iter() { part.push(b); if !self.is_sep_prefix(part) { return (part, false); } if self.is_sep(part) { break; } } return (part, true); } fails to compile with this error: io/convert_io.rs:117:17: 117:36 error: cannot infer an appropriate lifetime due to conflicting requirements io/convert_io.rs:117 for b in self.bytes_iter() { ^~~~~~~~~~~~~~~~~~~ io/convert_io.rs:117:17: 117:22 note: first, the lifetime cannot outlive the expression at 117:17... io/convert_io.rs:117 for b in self.bytes_iter() { ^~~~~ io/convert_io.rs:117:17: 117:22 note: ...due to the following expression io/convert_io.rs:117 for b in self.bytes_iter() { ^~~~~ io/convert_io.rs:117:17: 117:36 note: but, the lifetime must be valid for the method call at 117:17... io/convert_io.rs:117 for b in self.bytes_iter() { ^~~~~~~~~~~~~~~~~~~ io/convert_io.rs:117:17: 117:22 note: ...due to the following expression io/convert_io.rs:117 for b in self.bytes_iter() { ^~~~~ And now I'm completely stuck. I can't avoid these errors at all. This looks like a bug to me, but I'm not completely sure - maybe it's me who is wrong here. I've studied libstd/libextra code for clues and found out that some iterable structures have code very similar to mine, for example, RingBuf. Here is its mut_iter() method: pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> { RingBufMutIterator{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts} } I have tried to implement bytes_iter() method like this, but it naturally didn't work because of 'a and 'self lifetimes conflict. In my understanding, this works here because RingBuf does not have lifetime parameter, so no conflict between 'self and 'a lifetime is possible at all. But this will not work in my case, because I have to have 'self parameter because of &'self Reader field. What can I do to implement my ReaderTokenizer? Maybe there are other ways of which I'm unaware? Thank you very much in advance. Best regards, Vladimir. From amitava.shee at gmail.com Sun Aug 18 14:06:34 2013 From: amitava.shee at gmail.com (Amitava Shee) Date: Sun, 18 Aug 2013 17:06:34 -0400 Subject: [rust-dev] Kick the tires on the new rust runtime Message-ID: I would like to kick the tires with the new rust runtime. I am currently on master at commit 88bd2155d780d2d7d976ff271b6bb25a9b03e119. I do not see libcore. What is the best way to bring in the bit? Thanks & Regards, Amitava -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Sun Aug 18 16:03:35 2013 From: kevin at sb.org (Kevin Ballard) Date: Sun, 18 Aug 2013 16:03:35 -0700 Subject: [rust-dev] Kick the tires on the new rust runtime In-Reply-To: References: Message-ID: <42091C9A-4129-4DA4-AC86-59ED262AE9B8@sb.org> core was renamed to std quite some time ago (and std renamed to extra). -Kevin On Aug 18, 2013, at 2:06 PM, Amitava Shee wrote: > I would like to kick the tires with the new rust runtime. I am currently on master at commit 88bd2155d780d2d7d976ff271b6bb25a9b03e119. I do not see libcore. > > What is the best way to bring in the bit? > > Thanks & Regards, > Amitava > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From corey at octayn.net Sun Aug 18 23:10:00 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 19 Aug 2013 02:10:00 -0400 Subject: [rust-dev] This Week in Rust Message-ID: Content copied from http://cmr.github.io/blog/2013/08/19/this-week-in-rust/ -- Hello and welcome to the 11th edition of `This Week in Rust`! I'm starting uni this week, so if you notice I'm not quite as omnipresent and omniprescient as usual, that'd be why. **Please** [send me an email](mailto:corey at octayn.net) if you would like your pull request, project, or blog post mentioned. I would hate to overlook something cool or important. The Mozilla Intern talks happened this past week or so. The ones I know about relating to Rust are: - [Default Methods in Rust (sully)](https://air.mozilla.org/intern-presentation-sullivan/) - [Types of Types in Rust (bblum)](https://air.mozilla.org/ben-blum-from-the-research-team-presents-types-of-types-in-rust/) - [A Work-stealing Runtime for Rust (toddaaro)](https://air.mozilla.org/2013-intern-todd/) - [A Forest of Quadtrees: The Graphics of Servo](https://air.mozilla.org/eston-schweickart-from-the-research-team-presents-a-forest-of-quadtrees-the-graphics-of-servo/) - [Layout in Servo: Parallel and Rustic Tree Traversals (eatkinson)](https://air.mozilla.org/2013-intern-presentations-august-13/) - [Architecting Servo: Pipelines and Parallelism (tikue)](https://air.mozilla.org/2013-intern-kuehn/) Congratulations to them all. The interns did a ton of great work over the summer. # What's cooking on master? There were only 46 PRs merged this week. I don't quite know why that number is so low this week. It certainly wasn't for lack of PRs: the queue has been constantly backlogged. Issue churn was -26, yay! ## Breaking Changes - [Some functions in Result and Either were replaced to work with external iterators](https://github.com/mozilla/rust/pull/8526) - [The `priv` and `pub` visibility modifiers are now forbidden on contexts where they have no meaning](https://github.com/mozilla/rust/pull/8423). For example, marking a struct field `pub`, or a module `priv`. The compiler errors for this are quite informative, and the conversion is purely mechanical. - [`to_c_str` now raises a condition if the string contains interior `NUL`s, as it is impossible to create a valid C string with interior `NUL`s](https://github.com/mozilla/rust/pull/8532). ## Library improvments, bugfixes, and cleanup - [`ifmt!`, the new formatter, has been finished](https://github.com/mozilla/rust/pull/8446). Yay! - [`extra::stats::write_boxplot` now works with negative or zero sample values](https://github.com/mozilla/rust/pull/8453). - [Some missing pieces in libstd have been filled in](https://github.com/mozilla/rust/pull/8452). - [A `sample` method has been added to `RngUtil`, for resevior sampling](https://github.com/mozilla/rust/pull/8491). ## Compiler improvements, bugfixes, and cleanup - [A ton of work was done on a new visitor](https://github.com/mozilla/rust/pull/8527). This is the first of a series of five. - [Vector repeat exprs (`[0, ..16]`) are now allowed in statics](https://github.com/mozilla/rust/pull/8483). - [A hint has been added for incorrect use of static methods](https://github.com/mozilla/rust/pull/8477). - [Trait object coercion to `&Trait` has been fixed to handle freezing and reborrowing more correctly](https://github.com/mozilla/rust/pull/8497). - [Debuginfo of lexical scopes and variable shadowing has been massively improved](https://github.com/mozilla/rust/pull/8329). - [A `--target-cpu` flag has been added to select the target CPU, rather than always using "generic"](https://github.com/mozilla/rust/pull/8410). - [Support for owned and borrowed trait objects has been made better added](https://github.com/mozilla/rust/pull/8455). - [An `address_insignificant` attribute has been added](https://github.com/mozilla/rust/pull/8421). LLVM will do merging of statics marked with that attribute. - [Intrinsics for checked overflow on add, sub, and mul have been added](https://github.com/mozilla/rust/pull/8408). ## Tools, documentation, etc - [The tutorial was translated into Japanese](https://github.com/mozilla/rust/pull/8469). I think this is the first translation of anything, so it's a pretty big milestone I think. # Meeting The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-08-13) discussed turning jemalloc back on, default arguments, and method invocation ordering. It also discussed the new IO code and stage0 stdtest. # Notable discourse - [Phantom Types in Rust](http://bluishcoder.co.nz/2013/08/15/phantom_types_in_rust.html) - [RFC: Runtimeless libstd](http://www.reddit.com/r/rust/comments/1k6hua/rustdev_rfc_runtimeless_libstd/) # External projects - [Bindings to elasticsearch](https://github.com/erickt/rust-elasticsearch) - [zeromq bindings have been updated](https://github.com/erickt/rust-zmq) - [A spellchecker for Rust code, written in Rust](https://github.com/huonw/spellck) - [rust-encoding: character encoding support for Rust](http://www.reddit.com/r/rust/comments/1kd8ah/rustencoding_character_encoding_support_for_rust/) - [A simple vocabulary trainer](http://www.reddit.com/r/rust/comments/1kctjn/my_first_rust_program_vocabulary_trainer/) - [`rustdoc_ng`: 95% done](http://www.reddit.com/r/rust/comments/1k7mfn/rustdev_rustdoc_ng_95_done/) - [Some pages as rendered by Servo](http://www.reddit.com/r/rust/comments/1k5kqx/some_pages_in_servo_as_of_20130810/) - [d3cap: a libpcap-based network activity visualizer](https://github.com/jfager/d3cap) - [postgres bindings](https://github.com/sfackler/rust-postgres) - [RemoteJoy: a program for remotely viewing the screen of your PlayStation Portable](https://gist.github.com/luqmana/6264106). ([screnshot](http://i.imgur.com/9Kda25J.jpg)) - [The new OpenGL loader is working, pending the function pointer fix](https://github.com/bjz/gl-rs) From amitava.shee at gmail.com Mon Aug 19 06:57:44 2013 From: amitava.shee at gmail.com (Amitava Shee) Date: Mon, 19 Aug 2013 09:57:44 -0400 Subject: [rust-dev] Kick the tires on the new rust runtime In-Reply-To: <42091C9A-4129-4DA4-AC86-59ED262AE9B8@sb.org> References: <42091C9A-4129-4DA4-AC86-59ED262AE9B8@sb.org> Message-ID: I am probably not on the right branch but I see only C++ code in rt. amitava:rt amitava$ pwd /Users/amitava/opt/rust/src/rust/src/rt amitava:rt amitava$ find . -name "*.rs" amitava:rt amitava$ git log -1 commit 88bd2155d780d2d7d976ff271b6bb25a9b03e119 Merge: 0a23828 e7b8524 Author: bors Date: Sun Aug 18 10:01:55 2013 -0700 auto merge of #8558 : kballard/rust/xorshift-seed, r=cmr Fixes #8359. amitava:rt amitava$ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/auto remotes/origin/dist-snap remotes/origin/incoming remotes/origin/master remotes/origin/ndm remotes/origin/servo remotes/origin/snap-stage1 remotes/origin/snap-stage3 remotes/origin/try remotes/origin/try2 remotes/origin/try3 amitava:rt amitava$ --- Amitava On Sun, Aug 18, 2013 at 7:03 PM, Kevin Ballard wrote: > core was renamed to std quite some time ago (and std renamed to extra). > > -Kevin > > On Aug 18, 2013, at 2:06 PM, Amitava Shee wrote: > > > I would like to kick the tires with the new rust runtime. I am currently > on master at commit 88bd2155d780d2d7d976ff271b6bb25a9b03e119. I do not see > libcore. > > > > What is the best way to bring in the bit? > > > > Thanks & Regards, > > Amitava > > > > > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Mon Aug 19 09:37:52 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 19 Aug 2013 12:37:52 -0400 Subject: [rust-dev] Kick the tires on the new rust runtime In-Reply-To: References: <42091C9A-4129-4DA4-AC86-59ED262AE9B8@sb.org> Message-ID: The new runtime is in src/libstd/rt On Mon, Aug 19, 2013 at 9:57 AM, Amitava Shee wrote: > I am probably not on the right branch but I see only C++ code in rt. > > amitava:rt amitava$ pwd > /Users/amitava/opt/rust/src/rust/src/rt > > amitava:rt amitava$ find . -name "*.rs" > > amitava:rt amitava$ git log -1 > commit 88bd2155d780d2d7d976ff271b6bb25a9b03e119 > Merge: 0a23828 e7b8524 > Author: bors > Date: Sun Aug 18 10:01:55 2013 -0700 > > auto merge of #8558 : kballard/rust/xorshift-seed, r=cmr > > Fixes #8359. > > amitava:rt amitava$ git branch -a > * master > remotes/origin/HEAD -> origin/master > remotes/origin/auto > remotes/origin/dist-snap > remotes/origin/incoming > remotes/origin/master > remotes/origin/ndm > remotes/origin/servo > remotes/origin/snap-stage1 > remotes/origin/snap-stage3 > remotes/origin/try > remotes/origin/try2 > remotes/origin/try3 > amitava:rt amitava$ > > > --- > Amitava > > > > On Sun, Aug 18, 2013 at 7:03 PM, Kevin Ballard wrote: >> >> core was renamed to std quite some time ago (and std renamed to extra). >> >> -Kevin >> >> On Aug 18, 2013, at 2:06 PM, Amitava Shee wrote: >> >> > I would like to kick the tires with the new rust runtime. I am currently >> > on master at commit 88bd2155d780d2d7d976ff271b6bb25a9b03e119. I do not see >> > libcore. >> > >> > What is the best way to bring in the bit? >> > >> > Thanks & Regards, >> > Amitava >> > >> > >> > >> > _______________________________________________ >> > Rust-dev mailing list >> > Rust-dev at mozilla.org >> > https://mail.mozilla.org/listinfo/rust-dev >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From jeaye at arrownext.com Mon Aug 19 21:54:17 2013 From: jeaye at arrownext.com (Jeaye) Date: Mon, 19 Aug 2013 21:54:17 -0700 Subject: [rust-dev] Avoiding borrow check assertions with @mut Message-ID: <5212F679.1040805@arrownext.com> Howdy, I've become a big fan of @mut throughout my codebase for its compatibility with closures, but I think it's really biting me in the ass right now. >.< Assume there's a state stack (in a state Director) that I'm looping through to let the states know about an event. In this particular instance, the event is a key action of ENTER, since 'load_map q3ctf1' was just typed into the in-game console and ENTER was pressed. The console state is interested in this event, no doubt. When the console state gets this load_map command, it'll spring off a function that creates a game and game_renderer, which are both states that need to be pushed onto the state stack. But wait! We're currently looping through the state stack, so trying to add something to it is an assertion failure on the borrow (BAM, hard failure). In C++, this could would be perfectly valid, so long as I'm iterating through the state stack with indices and I'm pushing to the end of it, thus not affecting the current index. In Rust, this is a big no-no. My question is: how can I avoid this? Is it just because I'm using @mut that I'm having this problem? What are some potential solutions that people can think of, and has anyone hit the same snag in their own code? Something I have tried: Adding a queue to the state Director of callback functions (deferred modifications to the states) that states will push closures onto instead of modifying the Director while it's looping. With this, the Director could loop through each state, updating it, and then loop through the queue of deferred callbacks and run them, which would update the states stack. This didn't work for me since the Director itself has the borrow lock on it, not just the states stack -- I reckon I could put the deferred queue into TLS so that I wouldn't need a mutable reference to the Director to add to it... but there has to be a better way. Any tips would be appreciated. Jeaye From oren at ben-kiki.org Mon Aug 19 22:19:22 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Tue, 20 Aug 2013 08:19:22 +0300 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: <5212F679.1040805@arrownext.com> References: <5212F679.1040805@arrownext.com> Message-ID: I had a similar problem when writing an iterator for a tree-like data structure. The iterator held a stack (vector) of per-node iterators and needed to push into it while accessing the last node. In my case the whole thing works with owned and burrowed pointers. I managed to implement the immutable iterator by providing the correct lifetime incantation and, like you said, only using indices (actually I implemented a `mut_last()` function for mutable vectors - somehow this isn't in the standard library - but this is just a shorthand for accessing by `[len() - 1]`). I couldn't get any safe code to work for the mutable iterator though :-( I ended up using an unsafe code with a `*mut` pointer. It seems like you could do the same, if you are willing to give up the type-enforced safety... I love the compiler-enforced safety wrt. pointer lifetime and ownership, but like all type systems it has its limitations. It seems that the current approach is to implement safe containers with very careful sprinkling of `unsafe` (hey, even std::vec does it!), and then to have the bulk of the code use these safe containers. Maybe you could do something similar. It would be awesome if one could come up with a non-zero-cost extension to the type system where one could say "I know this seems unsafe but I assert it is just because the static type system is too weak; please insert minimal efficient dynamic assertions that things are OK". This would need to be explicit since it would incur some (hopefully low) run-time penalty. Probably such a mechanism wouldn't be 100% generic, but if we had a list of cases where people were forced to resort to unsafe code, perhaps we could cover the interesting "80%" of the cases and somehow provide them as a library or macro or something. ARC and RW ARC are sort of like that (libraries compensating for too-weak builtin-types system), maybe we need more? On Tue, Aug 20, 2013 at 7:54 AM, Jeaye wrote: > Howdy, > > I've become a big fan of @mut throughout my codebase for its compatibility > with closures, but I think it's really biting me in the ass right now. >.< > > Assume there's a state stack (in a state Director) that I'm looping > through to let the states know about an event. In this particular instance, > the event is a key action of ENTER, since 'load_map q3ctf1' was just typed > into the in-game console and ENTER was pressed. The console state is > interested in this event, no doubt. > > When the console state gets this load_map command, it'll spring off a > function that creates a game and game_renderer, which are both states that > need to be pushed onto the state stack. But wait! We're currently looping > through the state stack, so trying to add something to it is an assertion > failure on the borrow (BAM, hard failure). > > In C++, this could would be perfectly valid, so long as I'm iterating > through the state stack with indices and I'm pushing to the end of it, thus > not affecting the current index. In Rust, this is a big no-no. My question > is: how can I avoid this? Is it just because I'm using @mut that I'm having > this problem? What are some potential solutions that people can think of, > and has anyone hit the same snag in their own code? > > Something I have tried: Adding a queue to the state Director of callback > functions (deferred modifications to the states) that states will push > closures onto instead of modifying the Director while it's looping. With > this, the Director could loop through each state, updating it, and then > loop through the queue of deferred callbacks and run them, which would > update the states stack. This didn't work for me since the Director itself > has the borrow lock on it, not just the states stack -- I reckon I could > put the deferred queue into TLS so that I wouldn't need a mutable reference > to the Director to add to it... but there has to be a better way. > > Any tips would be appreciated. > > Jeaye > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Mon Aug 19 22:55:51 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Tue, 20 Aug 2013 15:55:51 +1000 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: References: <5212F679.1040805@arrownext.com> Message-ID: <521304E7.3020801@gmail.com> On 20/08/13 15:19, Oren Ben-Kiki wrote: > > I love the compiler-enforced safety wrt. pointer lifetime and > ownership, but like all type systems it has its limitations. It seems > that the current approach is to implement safe containers with very > careful sprinkling of `unsafe` (hey, even std::vec does it!), and then > to have the bulk of the code use these safe containers. Maybe you > could do something similar. > Note that the iterator-related unsafe in vec is entirely for efficiency, it can easily be implemented manipulating &[] slices directly. (I'm fairly sure the &mut [] iterator is possible without unsafe, but my experimentation revealed a (possible) bug: https://github.com/mozilla/rust/issues/8636.) Huon From danielmicay at gmail.com Mon Aug 19 23:05:46 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 20 Aug 2013 02:05:46 -0400 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: References: <5212F679.1040805@arrownext.com> Message-ID: On Tue, Aug 20, 2013 at 1:19 AM, Oren Ben-Kiki wrote: > I had a similar problem when writing an iterator for a tree-like data > structure. The iterator held a stack (vector) of per-node iterators and > needed to push into it while accessing the last node. > > In my case the whole thing works with owned and burrowed pointers. I managed > to implement the immutable iterator by providing the correct lifetime > incantation and, like you said, only using indices (actually I implemented a > `mut_last()` function for mutable vectors - somehow this isn't in the > standard library - but this is just a shorthand for accessing by `[len() - > 1]`). > > I couldn't get any safe code to work for the mutable iterator though :-( I > ended up using an unsafe code with a `*mut` pointer. It seems like you could > do the same, if you are willing to give up the type-enforced safety... It's possible to implement a mutable iterator through a tree-like object without unsafe code. If you're using unsafe code to return a reference overlapping with the children, it's not a memory safe interface. You can use pattern matching to split a mutable reference into disjoint mutable references (one as the yielded value, the other pointing to the children): // can be done with a struct too let mut t = (1, 2); let (ref mut x, ref mut y) = t; > I love the compiler-enforced safety wrt. pointer lifetime and ownership, but > like all type systems it has its limitations. It seems that the current > approach is to implement safe containers with very careful sprinkling of > `unsafe` (hey, even std::vec does it!), and then to have the bulk of the > code use these safe containers. Maybe you could do something similar. Vectors are the lowest-level dynamically sized memory allocation primitive in Rust. There's no existing safe code for them to leverage, so it either has to be implemented in the compiler or the library, and library code is simpler. There are many containers implemented entirely without unsafe code, copies or managed pointers including `std::hashmap`, `std::trie`, `extra::treemap` and `extra::ringbuf`. The `extra::priority_queue` implementation was originally safe, but contains a simple micro-optimization with a bit of unsafe code. It's likely that the `ringbuf` implementation will be micro-optimized with unsafe code in the future, but for the others it's a matter of improving the compiler's codegen. > It would be awesome if one could come up with a non-zero-cost extension to > the type system where one could say "I know this seems unsafe but I assert > it is just because the static type system is too weak; please insert minimal > efficient dynamic assertions that things are OK". This would need to be > explicit since it would incur some (hopefully low) run-time penalty. The minimal dynamic assertions are the dynamic borrow checking errors provided by mutable managed/reference-counted pointers. I don't think there's going to be anything cheaper than reference counting + freezing/unfreezing on borrow scopes. > Probably such a mechanism wouldn't be 100% generic, but if we had a list of > cases where people were forced to resort to unsafe code, perhaps we could > cover the interesting "80%" of the cases and somehow provide them as a > library or macro or something. ARC and RW ARC are sort of like that > (libraries compensating for too-weak builtin-types system), maybe we need > more? I wouldn't really say `extra::arc` is working around the type system. It exists only to provide atomic reference counting for references from multiple tasks, and a mutex to guard mutability. Rust implements concurrency in the standard library, so the building blocks in the standard library have to use unsafe code. The type system allows them to be *used* within entirely safe code. From niko at alum.mit.edu Tue Aug 20 03:38:08 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 20 Aug 2013 06:38:08 -0400 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: <5212F679.1040805@arrownext.com> References: <5212F679.1040805@arrownext.com> Message-ID: <20130820103808.GE15491@Mr-Bennet> One simple way to iterate over a vector and preserve the right to push onto it is to use something like a while loop instead: let mut i = 0; while i < vec.len() { process(vec[i]); // may alter vec } It would be trivial to package this pattern up into a special iterator that only works on `@mut` vectors and which iterated by value (not by reference). Rust won't let you push while iterating by reference, because pushing onto the vector may resize it and hence free the memory. Would this solve your problem? Niko On Mon, Aug 19, 2013 at 09:54:17PM -0700, Jeaye wrote: > Howdy, > > I've become a big fan of @mut throughout my codebase for its > compatibility with closures, but I think it's really biting me in the > ass right now. >.< > > Assume there's a state stack (in a state Director) that I'm looping > through to let the states know about an event. In this particular > instance, the event is a key action of ENTER, since 'load_map q3ctf1' > was just typed into the in-game console and ENTER was pressed. The > console state is interested in this event, no doubt. > > When the console state gets this load_map command, it'll spring off a > function that creates a game and game_renderer, which are both states > that need to be pushed onto the state stack. But wait! We're > currently looping through the state stack, so trying to add something > to it is an assertion failure on the borrow (BAM, hard failure). > > In C++, this could would be perfectly valid, so long as I'm iterating > through the state stack with indices and I'm pushing to the end of > it, thus not affecting the current index. In Rust, this is a big > no-no. My question is: how can I avoid this? Is it just because I'm > using @mut that I'm having this problem? What are some potential > solutions that people can think of, and has anyone hit the same snag > in their own code? > > Something I have tried: Adding a queue to the state Director of > callback functions (deferred modifications to the states) that states > will push closures onto instead of modifying the Director while it's > looping. With this, the Director could loop through each state, > updating it, and then loop through the queue of deferred callbacks > and run them, which would update the states stack. This didn't work > for me since the Director itself has the borrow lock on it, not just > the states stack -- I reckon I could put the deferred queue into TLS > so that I wouldn't need a mutable reference to the Director to add to > it... but there has to be a better way. > > Any tips would be appreciated. > > Jeaye > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Tue Aug 20 03:39:29 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 20 Aug 2013 06:39:29 -0400 Subject: [rust-dev] Borrowed pointers with lifetime in structures cause weird errors In-Reply-To: References: Message-ID: <20130820103929.GF15491@Mr-Bennet> Hi, Sorry for not responding more quickly. I've been wanting to sit down and work out your example; I am confident that it can be made to work, although from reading it quickly it sounds like a case that might be better served with two lifetime parameters, which are not yet supported (on my list...). However, I did want to briefly point out that you can continue to use "internal" iterators, you just don't get the `for` syntax anymore. Just write a higher-order function as you always did, possibly returning bool to indicate whether to break or continue. Niko On Sat, Aug 17, 2013 at 01:54:09PM +0400, Vladimir Matveev wrote: > Hello, > > I'm writing a simple tokenizer which is defined by this trait: > > trait Tokenizer { > fn next_token(&mut self) -> ~str; > fn eof(&self) -> bool; > } > > Obvious application for a tokenizer is splitting a stream going from > Reader, so I have the following structure which should implement > Tokenizer: > > pub struct ReaderTokenizer<'self> { > priv inner: &'self Reader, > priv buffer: ~CyclicBuffer, > priv seps: ~[~str] > } > > I have used 'self lifetime parameter since I want for the tokenizer > work for any Reader. CyclicBuffer is another structure which > essentially is an array of u8 with special read/write operations. > > Implementation of a Tokenizer for ReaderTokenizer involves reading > from the Reader one byte at a time. I decided to use buffering to > improve performance. But I still want to keep the useful abstraction > of single byte reading, so I decided to implement Iterator for my > Reader+CyclicBuffer pair. BTW, internal iterators in 0.7 were much > better for this, because internal iterator code was very simple and > didn't use explicit lifetimes at all, but 0.7 compiler suffers from > several errors related to pointers to traits which prevented my > program from compiling (I couldn't pass a reference to Reader to > CyclicBuffer method; there were other errors I've encountered too). I > So, I decided to use trunk version of the compiler in which these > errors are resolved according to github, but trunk version does not > allow internal iterators, which is very sad since now I'm forced to > create intermediate structures to achieve the same thing. > > So, I came up with the following iterator structure: > > struct RTBytesIterator<'self> { > tokenizer: &'self mut ReaderTokenizer<'self> > } > > impl<'self> Iterator for RTBytesIterator<'self> { > fn next(&mut self) -> Option { > if self.tokenizer.eof() { > return None; > } > if self.tokenizer.buffer.readable_bytes() > 0 || > self.tokenizer.buffer.fill_from_reader(self.tokenizer.inner) > 0 { > return Some(self.tokenizer.buffer.read_unsafe()); > } else { > return None; > } > } > } > > Note that tokenizer field is &'self mut since CyclicBuffer is mutable. > buffer.fill_from_reader() function reads as much as possible from the > reader (returning a number of bytes read), and buffer.read_unsafe() > returns next byte from the cyclic buffer. > > Then I've added the following method to ReaderTokenizer: > > impl<'self> ReaderTokenizer<'self> { > ... > fn bytes_iter(&mut self) -> RTBytesIterator<'self> { > RTBytesIterator { tokenizer: self } > } > ... > } > > This does not compile with the following error: > > io/convert_io.rs:98:37: 98:43 error: cannot infer an appropriate > lifetime due to conflicting requirements > io/convert_io.rs:98 RTBytesIterator { tokenizer: self } > ^~~~~~ > io/convert_io.rs:97:55: 99:5 note: first, the lifetime cannot outlive > the anonymous lifetime #1 defined on the block at 97:55... > io/convert_io.rs:97 fn bytes_iter(&mut self) -> RTBytesIterator<'self> { > io/convert_io.rs:98 RTBytesIterator { tokenizer: self } > io/convert_io.rs:99 } > io/convert_io.rs:98:37: 98:43 note: ...due to the following expression > io/convert_io.rs:98 RTBytesIterator { tokenizer: self } > ^~~~~~ > io/convert_io.rs:97:55: 99:5 note: but, the lifetime must be valid for > the lifetime &'self as defined on the block at 97:55... > io/convert_io.rs:97 fn bytes_iter(&mut self) -> RTBytesIterator<'self> { > io/convert_io.rs:98 RTBytesIterator { tokenizer: self } > io/convert_io.rs:99 } > io/convert_io.rs:98:8: 98:23 note: ...due to the following expression > io/convert_io.rs:98 RTBytesIterator { tokenizer: self } > ^~~~~~~~~~~~~~~ > error: aborting due to previous error > > OK, fair enough, I guess I have to annotate self parameter with 'self lifetime: > > fn bytes_iter(&'self mut self) -> RTBytesIterator<'self> { > RTBytesIterator { tokenizer: self } > } > > This compiles, but now I'm getting another error at bytes_iter() usage > site, for example, the following code: > > fn try_read_sep(&mut self, first: u8) -> (~[u8], bool) { > let mut part = ~[first]; > for b in self.bytes_iter() { > part.push(b); > if !self.is_sep_prefix(part) { > return (part, false); > } > if self.is_sep(part) { > break; > } > } > return (part, true); > } > > fails to compile with this error: > > io/convert_io.rs:117:17: 117:36 error: cannot infer an appropriate > lifetime due to conflicting requirements > io/convert_io.rs:117 for b in self.bytes_iter() { > ^~~~~~~~~~~~~~~~~~~ > io/convert_io.rs:117:17: 117:22 note: first, the lifetime cannot > outlive the expression at 117:17... > io/convert_io.rs:117 for b in self.bytes_iter() { > ^~~~~ > io/convert_io.rs:117:17: 117:22 note: ...due to the following expression > io/convert_io.rs:117 for b in self.bytes_iter() { > ^~~~~ > io/convert_io.rs:117:17: 117:36 note: but, the lifetime must be valid > for the method call at 117:17... > io/convert_io.rs:117 for b in self.bytes_iter() { > ^~~~~~~~~~~~~~~~~~~ > io/convert_io.rs:117:17: 117:22 note: ...due to the following expression > io/convert_io.rs:117 for b in self.bytes_iter() { > ^~~~~ > > And now I'm completely stuck. I can't avoid these errors at all. This > looks like a bug to me, but I'm not completely sure - maybe it's me > who is wrong here. > > I've studied libstd/libextra code for clues and found out that some > iterable structures have code very similar to mine, for example, > RingBuf. Here is its mut_iter() method: > > pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> { > RingBufMutIterator{index: 0, rindex: self.nelts, lo: self.lo, > elts: self.elts} > } > > I have tried to implement bytes_iter() method like this, but it > naturally didn't work because of 'a and 'self lifetimes conflict. In > my understanding, this works here because RingBuf does not have > lifetime parameter, so no conflict between 'self and 'a lifetime is > possible at all. But this will not work in my case, because I have to > have 'self parameter because of &'self Reader field. > > What can I do to implement my ReaderTokenizer? Maybe there are other > ways of which I'm unaware? > > Thank you very much in advance. > > Best regards, > Vladimir. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From oren at ben-kiki.org Tue Aug 20 07:50:31 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Tue, 20 Aug 2013 17:50:31 +0300 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: <20130820103808.GE15491@Mr-Bennet> References: <5212F679.1040805@arrownext.com> <20130820103808.GE15491@Mr-Bennet> Message-ID: Here is the heart of the code, maybe it will be clearer why I had to use unsafe (or, maybe, how I could avoid it): /// A path is just an array of atoms. #[deriving(Eq, TotalEq, Ord, TotalOrd, Clone, IterBytes)] pub struct Path { /// The array of atoms the path consists of. pub atoms: ~[Atom], } /// An entry contained in the tree map. #[deriving(Eq, TotalEq, Ord, TotalOrd)] pub struct TreeMapEntry { /// The full path of the entry. path: Path, /// The value of the entry. value: T, } /// A tree map holds values of some arbitrary type, indexed by a path. pub struct TreeMap { /// The entry of this node, if any. priv entry: Option>, /// The sub-trees under this node, if any. priv sub_trees: HashMap> } /// Iterate and mutate on a single level of the tree map. struct LevelMutIterator<'self, T> { /// The root node to return the value of (as the 1st result). root: Option<&'self mut TreeMapEntry>, /// The iterator at the current level of the tree. iterator: HashMapMutIterator<'self, Atom, ~TreeMap>, } /// Iterate and mutate on a tree map in an arbitrary order. pub struct TreeMapMutIterator<'self, T> { /// The iterators of all levels we have reached so far. priv levels: ~[LevelMutIterator<'self, T>] } /// Iterate and mutate on a tree map in an arbitrary order. impl<'self, T> Iterator<(&'self Path, &'self mut T)> for TreeMapMutIterator<'self, T> { /// Move to the next value contained in the tree map. fn next(&mut self) -> Option<(&'self Path, &'self mut T)> { if self.levels.len() == 0 { None } else { unsafe { let last: *mut LevelMutIterator<'self, T> = &mut self.levels[self.levels.len() - 1]; match (*last).root { Some(ref mut entry) => { let path = &entry.path; let value = &mut entry.value; // TRICKY: This makes the entry inaccessible, which is // why we took the returned path and value above. (*last).root = None; Some((path, value)) } None => { match self.levels[self.levels.len() - 1].iterator.next() { Some((_atom, treemap)) => { self.levels.push(treemap.level_mut_iter()); } None => { self.levels.pop(); } } self.next() } } } } } } I tried for around a day to make this work without the unsafe, to no avail. The trick is I want to take the value out of the option (leaving None behind), and return the value. I'm probably missing some solution which may be obvious to a non-newbie to Rust...? -------------- next part -------------- An HTML attachment was scrubbed... URL: From sebastian.sylvan at gmail.com Tue Aug 20 13:51:31 2013 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Tue, 20 Aug 2013 13:51:31 -0700 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: <5212F679.1040805@arrownext.com> References: <5212F679.1040805@arrownext.com> Message-ID: On Mon, Aug 19, 2013 at 9:54 PM, Jeaye wrote: > Howdy, > > I've become a big fan of @mut throughout my codebase for its compatibility > with closures, but I think it's really biting me in the ass right now. >.< > > Assume there's a state stack (in a state Director) that I'm looping > through to let the states know about an event. In this particular instance, > the event is a key action of ENTER, since 'load_map q3ctf1' was just typed > into the in-game console and ENTER was pressed. The console state is > interested in this event, no doubt. > > When the console state gets this load_map command, it'll spring off a > function that creates a game and game_renderer, which are both states that > need to be pushed onto the state stack. But wait! We're currently looping > through the state stack, so trying to add something to it is an assertion > failure on the borrow (BAM, hard failure). > > In C++, this could would be perfectly valid, so long as I'm iterating > through the state stack with indices and I'm pushing to the end of it, thus > not affecting the current index. In Rust, this is a big no-no. My question > is: how can I avoid this? Is it just because I'm using @mut that I'm having > this problem? What are some potential solutions that people can think of, > and has anyone hit the same snag in their own code? > > Something I have tried: Adding a queue to the state Director of callback > functions (deferred modifications to the states) that states will push > closures onto instead of modifying the Director while it's looping. With > this, the Director could loop through each state, updating it, and then > loop through the queue of deferred callbacks and run them, which would > update the states stack. This didn't work for me since the Director itself > has the borrow lock on it, not just the states stack -- I reckon I could > put the deferred queue into TLS so that I wouldn't need a mutable reference > to the Director to add to it... but there has to be a better way. > > Any tips would be appreciated. I'm not entirely sure I understand why that last thing you mentioned wouldn't work. Maybe you could refactor your event handlers to return changes to the state stack instead of mutating? Or perhaps just make changes to the stack itself work differently - while you're looping through them any calls to modify the stack gets put on a side-queue, and then after you've finished looping you apply them all. You're not running arbitrary code at this point, just adding stuff to the stack. -- Sebastian Sylvan -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue Aug 20 14:27:17 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 20 Aug 2013 14:27:17 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <5213DE50.6040705@gmail.com> References: <5213DE50.6040705@gmail.com> Message-ID: <5213DF35.7050100@mozilla.com> Hi, We had a meeting today that was mostly about cycle time. Integrating a change on the rust repo currently takes about 2 hours, which is still far too much. We've tried approaching this from a variety of perspectives in the past and I feel like possibly I've not conveyed the cost and work breakdown, or discussed systematic approaches to the problem yet. I'd like to do so now, as I believe the issues are all quite solvable and I'd very much like people to shift their energy to focus more on these matters: - Top level measurements of cycle time are here: http://huonw.github.io/isrustfastyet/buildbot/all - Our worst offenders are the -all and -vg builders. The former does a full cross-compile bootstrap, thus winds up building 9 copies of the compiler and libraries. The latter runs the testsuite under valgrind. I've (temporarily) turned these off, in order to drain the queue some, but I'd like to turn them back on asap. For ideas relating to organizing the bots to have a lower total cycle time (not related to compiler perf), see https://github.com/mozilla/rust/issues/8456 - The remaining time on other builders (non-all and non-vg) is closer to 1h and breaks down about 50/50, 30 min compile, 30 min test. One hour is still way too long. - Of the testsuite time, there are two major foreground issues: subprocess efficiency and metadata reading. - On valgrind and non-valgrind alike, we're running subprocesses inefficiently. This results in both too many threads (which hurts valgrind especially badly) and too many blocking calls (which hurts all platforms). I believe rewriting std::run to use libuv will help significantly here. Alex is on this but I imagine he can use help. See https://github.com/mozilla/rust/pull/8645 - Metadata reading takes the majority of non-wait / non-system CPU time of the testsuite. A 'perf top' of a run looks like this: 14.23% 0xffffffff810940d0 7.43% tinfl_decompress 3.32% ebml::reader::vuint_at 2.27% bfd_link_hash_traverse 2.22% io::u64_from_be_bytes 1.99% __memcpy_ssse3_back 1.94% metadata::decoder::lookup_hash 1.49% ebml::reader::tagged_docs 1.46% hash::__extensions__::meth_23277::write 1.26% __memmove_ssse3_back 1.26% ebml::reader::maybe_get_doc 1.26% malloc 1.17% 0x000000000006b4a0 1.15% bfd_hash_lookup 1.02% free The amount of metadata itself is partly at issue, but more seriously is just that we read (and parse) all the metadata in any crate used, rather than just the part pertaining to the use being made. So, two subproblems: we parse all of it (due to algorithms that read every item's metadata recursively, mostly in resolve) and that because we parse all of it, we decompress all of it. The parse-all-of-it subproblem, pcwalton is on right now. I'll try to help out as I can in terms of filing down any technical debt in metadata that I can. The main bug for the "bad algorithm" issue is https://github.com/mozilla/rust/issues/4572 but I've also opened a metabug on general metadata technical debt so that we can possibly remove some of the horrors that scare people away form anything metadata-related: https://github.com/mozilla/rust/issues/8652 - Concerning metadata compression: We could decompress using a different algorithm (or none at all) and this might save us some time. But it's been tried (see https://github.com/mozilla/rust/issues/6902) and wasn't a huge win, and I think the larger win would be to change algorithms to avoid reading the entire metadata segment. Of course we can also try to compress each chunk of metadata separately (say, each item or index worth) and only decompress those of interest. We should not even be _reading_ the entire metadata section from disk, period, if we're only pulling in std::println or such. - In terms of straight-line compile speed on libstd/extra/rustc, there are a number of lingering codegen problems. No single one accounts for all the overhead, I'm collecting together those I'm aware of in https://github.com/mozilla/rust/issues/6819 but I'd like to draw attention to: - By far the most obvious to me is "generating too many copies of functions". Take a look at: http://people.mozilla.org/~graydon/symbols-by-name.txt This is from today. 79 copies of hashtable functions. 200 copies of iterator::next. 71 copies of Option::is_none. 70 copies of ptr::mut_offset. 123 copies of util::swap. 188 copies of vec::capacity. This might relate to bugs like: https://github.com/mozilla/rust/issues/2529 https://github.com/mozilla/rust/issues/2537 https://github.com/mozilla/rust/issues/7349 It's honestly not clear to me exactly what's causing it, it might just be a question of factoring out code to have fewer dependencies on type. Often C++ libraries go out of their way to factor algorithms into type dependent and type-independent parts. I've opened https://github.com/mozilla/rust/issues/8651 to rewrite type use altogether. Nobody's on this presently. - There looks like there might be a particularly egregious interaction with default methods? More than feels healthy. For example of the 20,000 functions compiled for rustc, 1,900 of them are copies of functions from visit::, which ... seems like a lot, to me. I've opened https://github.com/mozilla/rust/issues/8650 for investigating this. Nobody's on this presently. - If you look in that set of symbols you'll also see far too much glue being generated, especially visitor glue but also a lot of seemingly redundant (same-size) drop and take glue. Patrick has an old change that never landed to help with visit glue https://github.com/mozilla/rust/pull/6744 and I suspect there's a lot more analysis of type dependency that we could do to cut down on the other glues. Nobody's on this presently. - Removing as much of the redundant drop machinery as we can subject to tightened move-semantics. There's a bug for this https://github.com/mozilla/rust/issues/5016 and Niko is looking at it. Possibly he could use some help. - Finally, for up-close testing of codegen, I strongly suggest adding more cases to the codegen tests in test/codegen. They've very easy to add and make for helpful "are we generating anything remotely as good as clang/C++ here?" checks. Some of those tests we're doing as well as clang, some we're doing 2x worse. If you have spare time or are otherwise intimidated by optimization tasks, this is a great area to pitch in. You just have to be able to express some idiom in both rust and C++. I've also been trying to improve overall visibility of performance issues over recent months. To this end, we've been recording and archiving all #[bench] benchmarks and similar metrics, and as I mentioned in previous emails there's a simple mechanism for ratcheting metrics now in the test runner. I've also asked Corey to take a look at landing a consolidated framework for metrics-recording in https://github.com/mozilla/rust/issues/6810 (he has an initial sketch in https://github.com/mozilla/rust/pull/8646). I'm hoping this plays two roles: - Making it sufficiently easy to record "new metrics" that we discover previously-unknown dark matter performance problems. - Finding metrics that we are comfortable ratcheting on, so that we can continue to develop the compiler without regressing on aspects relevant to performance. If you have other ideas and areas of concern, or disagree or are unclear on things I've mentioned in this email, please follow up. Thanks, -Graydon From niko at alum.mit.edu Tue Aug 20 19:35:49 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 20 Aug 2013 22:35:49 -0400 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: References: <5212F679.1040805@arrownext.com> <20130820103808.GE15491@Mr-Bennet> Message-ID: <20130821023549.GB3475@Mr-Bennet> There may be another way, but one safe option is to use util::replace to always set the `root` field to None but preserve the old value, as shown below (this code compiles). In general, the rule you are running into (which prevents mutation to the path that contains a borrowed &mut) is one that I have gone back and forth on. I have to go consult my notes as to the reason it is setup the way it is; it may be that we could potentially loosen the rule in this case, but I seem to recall that doing so had dangerous consequences that I cannot remember at the moment. > /// Iterate and mutate on a tree map in an arbitrary order. > impl<'self, T> Iterator<(&'self Path, &'self mut T)> for > TreeMapMutIterator<'self, T> { > /// Move to the next value contained in the tree map. > fn next(&mut self) -> Option<(&'self Path, &'self mut T)> { > if self.levels.len() == 0 { > None > } else { > let last = self.levels.len() - 1; > let root = util::replace(&mut self.levels[last].root, None); > match root { > Some(&ref mut entry) => { > let path = &entry.path; > let value = &mut entry.value; > Some((path, value)) > } > None => { > match self.levels[last].iterator.next() { > Some((_atom, treemap)) => { > self.levels.push(fail!()); > } > None => { > self.levels.pop(); > } > } > self.next() > } > } > } > } > } Niko On Tue, Aug 20, 2013 at 05:50:31PM +0300, Oren Ben-Kiki wrote: > Here is the heart of the code, maybe it will be clearer why I had to use > unsafe (or, maybe, how I could avoid it): > > /// A path is just an array of atoms. > #[deriving(Eq, TotalEq, Ord, TotalOrd, Clone, IterBytes)] > pub struct Path { > /// The array of atoms the path consists of. > pub atoms: ~[Atom], > } > > /// An entry contained in the tree map. > #[deriving(Eq, TotalEq, Ord, TotalOrd)] > pub struct TreeMapEntry { > /// The full path of the entry. > path: Path, > > /// The value of the entry. > value: T, > } > > /// A tree map holds values of some arbitrary type, indexed by a path. > pub struct TreeMap { > /// The entry of this node, if any. > priv entry: Option>, > > /// The sub-trees under this node, if any. > priv sub_trees: HashMap> > } > > /// Iterate and mutate on a single level of the tree map. > struct LevelMutIterator<'self, T> { > /// The root node to return the value of (as the 1st result). > root: Option<&'self mut TreeMapEntry>, > > /// The iterator at the current level of the tree. > iterator: HashMapMutIterator<'self, Atom, ~TreeMap>, > } > > /// Iterate and mutate on a tree map in an arbitrary order. > pub struct TreeMapMutIterator<'self, T> { > /// The iterators of all levels we have reached so far. > priv levels: ~[LevelMutIterator<'self, T>] > } > > /// Iterate and mutate on a tree map in an arbitrary order. > impl<'self, T> Iterator<(&'self Path, &'self mut T)> for > TreeMapMutIterator<'self, T> { > /// Move to the next value contained in the tree map. > fn next(&mut self) -> Option<(&'self Path, &'self mut T)> { > if self.levels.len() == 0 { > None > } else { > unsafe { > let last: *mut LevelMutIterator<'self, T> = &mut > self.levels[self.levels.len() - 1]; > match (*last).root { > Some(ref mut entry) => { > let path = &entry.path; > let value = &mut entry.value; > // TRICKY: This makes the entry inaccessible, which > is > // why we took the returned path and value above. > (*last).root = None; > Some((path, value)) > } > None => { > match self.levels[self.levels.len() - > 1].iterator.next() { > Some((_atom, treemap)) => { > self.levels.push(treemap.level_mut_iter()); > } > None => { > self.levels.pop(); > } > } > self.next() > } > } > } > } > } > } > > I tried for around a day to make this work without the unsafe, to no avail. > The trick is I want to take the value out of the option (leaving None > behind), and return the value. I'm probably missing some solution which may > be obvious to a non-newbie to Rust...? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From banderson at mozilla.com Tue Aug 20 19:48:59 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 20 Aug 2013 19:48:59 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <5213DF35.7050100@mozilla.com> References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> Message-ID: <52142A9B.3020506@mozilla.com> On 08/20/2013 02:27 PM, Graydon Hoare wrote: > Hi, > > We had a meeting today that was mostly about cycle time. Integrating a > change on the rust repo currently takes about 2 hours, which is still > far too much. We've tried approaching this from a variety of > perspectives in the past and I feel like possibly I've not conveyed the > cost and work breakdown, or discussed systematic approaches to the > problem yet. I'd like to do so now, as I believe the issues are all > quite solvable and I'd very much like people to shift their energy to > focus more on these matters: Thanks, Graydon! > > - On valgrind and non-valgrind alike, we're running subprocesses > inefficiently. This results in both too many threads (which > hurts valgrind especially badly) and too many blocking calls > (which hurts all platforms). I believe rewriting std::run to > use libuv will help significantly here. Alex is on this > but I imagine he can use help. See > https://github.com/mozilla/rust/pull/8645 A complete fix here is going to require uv-based process bindings, file bindings, then an API for accessing stdin/out/err, so it will take a while. Alex and Jefferey are both on various portions of this and we'll try to get it done soon. I'm not sure though that this is causing the valgrind regression on the bots - I tried all day to reproduce it and I can't. > > - Concerning metadata compression: > > We could decompress using a different algorithm (or none at > all) and this might save us some time. But it's been tried > (see https://github.com/mozilla/rust/issues/6902) and wasn't > a huge win, and I think the larger win would be to change > algorithms to avoid reading the entire metadata segment. I'd like to add some kind of --no-compress-metadata flag to rustc to turn off compression, see what that buys. This is very low-hanging fruit. Algorithmic changes to metadata reading are obviously more important long-term, but ISTM that not compressing is just going to be faster than compressing - no matter what else we do - so to get cycle times down we will want that optimization. Is this ok? > > If you have other ideas and areas of concern, or disagree or are unclear > on things I've mentioned in this email, please follow up. Besides what I mentioned above I'll take another look at how the test suite works and see if I can find any obvious improvements. After that I'll circle back around and see if any of the other things you mentioned are within my grasp. From banderson at mozilla.com Tue Aug 20 19:51:49 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 20 Aug 2013 19:51:49 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <52142A9B.3020506@mozilla.com> References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> <52142A9B.3020506@mozilla.com> Message-ID: <52142B45.1020000@mozilla.com> On 08/20/2013 07:48 PM, Brian Anderson wrote: > On 08/20/2013 02:27 PM, Graydon Hoare wrote: >> Hi, >> >> We had a meeting today that was mostly about cycle time. Integrating a >> change on the rust repo currently takes about 2 hours, which is still >> far too much. We've tried approaching this from a variety of >> perspectives in the past and I feel like possibly I've not conveyed the >> cost and work breakdown, or discussed systematic approaches to the >> problem yet. I'd like to do so now, as I believe the issues are all >> quite solvable and I'd very much like people to shift their energy to >> focus more on these matters: > > Thanks, Graydon! > >> >> - On valgrind and non-valgrind alike, we're running subprocesses >> inefficiently. This results in both too many threads (which >> hurts valgrind especially badly) and too many blocking calls >> (which hurts all platforms). I believe rewriting std::run to >> use libuv will help significantly here. Alex is on this >> but I imagine he can use help. See >> https://github.com/mozilla/rust/pull/8645 > > A complete fix here is going to require uv-based process bindings, > file bindings, then an API for accessing stdin/out/err, so it will > take a while. Alex and Jefferey are both on various portions of this > and we'll try to get it done soon. I'm not sure though that this is > causing the valgrind regression on the bots - I tried all day to > reproduce it and I can't. I misspoke here. It needs pipe bindings, not file bindings. From banderson at mozilla.com Tue Aug 20 21:15:50 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 20 Aug 2013 21:15:50 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <52142A9B.3020506@mozilla.com> References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> <52142A9B.3020506@mozilla.com> Message-ID: <52143EF6.8010605@mozilla.com> On 08/20/2013 07:48 PM, Brian Anderson wrote: > On 08/20/2013 02:27 PM, Graydon Hoare wrote: >> Hi, >> >> We had a meeting today that was mostly about cycle time. Integrating a >> change on the rust repo currently takes about 2 hours, which is still >> far too much. We've tried approaching this from a variety of >> perspectives in the past and I feel like possibly I've not conveyed the >> cost and work breakdown, or discussed systematic approaches to the >> problem yet. I'd like to do so now, as I believe the issues are all >> quite solvable and I'd very much like people to shift their energy to >> focus more on these matters: > > Thanks, Graydon! > >> >> - On valgrind and non-valgrind alike, we're running subprocesses >> inefficiently. This results in both too many threads (which >> hurts valgrind especially badly) and too many blocking calls >> (which hurts all platforms). I believe rewriting std::run to >> use libuv will help significantly here. Alex is on this >> but I imagine he can use help. See >> https://github.com/mozilla/rust/pull/8645 > > A complete fix here is going to require uv-based process bindings, > file bindings, then an API for accessing stdin/out/err, so it will > take a while. Alex and Jefferey are both on various portions of this > and we'll try to get it done soon. I'm not sure though that this is > causing the valgrind regression on the bots - I tried all day to > reproduce it and I can't. I tried reproducing the regression with a subset of the run-pass tests earlier and failed, so tonight I tried harder by running all of make check like `make check CFG_ENABLE_VALGRIND=1 RUST_THREADS=1` (after previously building the compiler with `make`), and I did come up with a slight regression: 75m before and 81m after. This still isn't close to what the bots are showing though. The regression range I tested was 680eb71-15fca2d (covering the span on IRFY where the regression happened). From graydon at mozilla.com Wed Aug 21 08:27:27 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 21 Aug 2013 08:27:27 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <52143EF6.8010605@mozilla.com> References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> <52142A9B.3020506@mozilla.com> <52143EF6.8010605@mozilla.com> Message-ID: <5214DC5F.9060008@mozilla.com> On 13-08-20 09:15 PM, Brian Anderson wrote: > I tried reproducing the regression with a subset of the run-pass tests > earlier and failed, so tonight I tried harder by running all of make > check like `make check CFG_ENABLE_VALGRIND=1 RUST_THREADS=1` (after > previously building the compiler with `make`), and I did come up with a > slight regression: 75m before and 81m after. This still isn't close to > what the bots are showing though. The regression range I tested was > 680eb71-15fca2d (covering the span on IRFY where the regression happened). The bots are also configured to pass RUST_RT_TEST_THREADS=1 fwiw. -Graydon From piyush.ag at samsung.com Wed Aug 21 04:38:49 2013 From: piyush.ag at samsung.com (Piyush Agarwal) Date: Wed, 21 Aug 2013 11:38:49 +0000 (GMT) Subject: [rust-dev] Issue in borrowing Message-ID: <47.86.07473.AC6A4125@epcpsbgx2.samsung.com> An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 201308211708632_BGFC2LL5.gif Type: image/gif Size: 14036 bytes Desc: not available URL: From eric+rust-dev at teratorn.org Wed Aug 21 13:32:38 2013 From: eric+rust-dev at teratorn.org (Eric P. Mangold) Date: Wed, 21 Aug 2013 16:32:38 -0400 Subject: [rust-dev] Issue in borrowing In-Reply-To: <47.86.07473.AC6A4125@epcpsbgx2.samsung.com> References: <47.86.07473.AC6A4125@epcpsbgx2.samsung.com> Message-ID: <20130821203238.GL10637@ragnarok.teratorn.org> Hi Piyush, could you try that again without HTML email and tracking gifs? Plain text mail is standard for mailing lists. Thanks, -E On Wed, Aug 21, 2013 at 11:38:49AM +0000, Piyush Agarwal wrote: > Samsung Enterprise Portal mySingle > > > > > > >

Hi All,

>

Rust Compiler is giving error in following code :-

>

 

>

fn main() {

>

 let mut vec = ~[1 ,2 , 3, 4];
 
 f1(&mut vec);

>

}

>

fn f1 (b: &mut ~[int]) {

>

 let mut a = &mut b[0];
 //process(a);
 
 a = &mut b[3];
}

>

 

>

error: cannot borrow '(**b)[]' as mutable more than once at a time

>

 

>

Thanks and Regards,

>

Piyush Agarwal

>

 

> > > >
>

> _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Wed Aug 21 13:40:03 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 21 Aug 2013 16:40:03 -0400 Subject: [rust-dev] Issue in borrowing In-Reply-To: <47.86.07473.AC6A4125@epcpsbgx2.samsung.com> References: <47.86.07473.AC6A4125@epcpsbgx2.samsung.com> Message-ID: <20130821204003.GB32210@Mr-Bennet> Depending on what you are trying to do, there are multiple answers to your (implied) question. In general you are not permitted to have two borrows of the same element at the same time; in this case, your program is being rejected because the compiler is conservative and it assumes that any two array elements might be the same. However, it appears from your example that the two borrows will not overlap in time. In that case, you just need to help the compiler out by creating a scope that indicates how long the first borrow should last: > fn f1 (b: &mut ~[int]) { > let mut a; > { > a = &mut b[0]; > //process(a); > } > > { > a = &mut b[3]; > } > } The explicit blocks indicate to the compiler how long the borrowed value can be used, and based on that it can see that the first borrow and the second will not overlap. If you DO want multiple borrows that overlap in time, you can use the `split_mut()` method. Niko On Wed, Aug 21, 2013 at 11:38:49AM +0000, Piyush Agarwal wrote: > Hi All, > > Rust Compiler is giving error in following code :- > > > > fn main() { > > let mut vec = ~[1 ,2 , 3, 4]; > > f1(&mut vec); > > } > > fn f1 (b: &mut ~[int]) { > > let mut a = &mut b[0]; > //process(a); > > a = &mut b[3]; > } > > > > error: cannot borrow '(**b)[]' as mutable more than once at a time > > > > Thanks and Regards, > > Piyush Agarwal > > > > [cid] > > * > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From kevin at sb.org Wed Aug 21 14:16:11 2013 From: kevin at sb.org (Kevin Ballard) Date: Wed, 21 Aug 2013 14:16:11 -0700 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: <20130821023549.GB3475@Mr-Bennet> References: <5212F679.1040805@arrownext.com> <20130820103808.GE15491@Mr-Bennet> <20130821023549.GB3475@Mr-Bennet> Message-ID: You should be able to just use .take() instead of invoking util::replace(), although the end-result should be the same. let root = self.levels[last].root.take(); -Kevin On Aug 20, 2013, at 7:35 PM, Niko Matsakis wrote: > There may be another way, but one safe option is to use util::replace > to always set the `root` field to None but preserve the old value, as > shown below (this code compiles). > > In general, the rule you are running into (which prevents mutation to > the path that contains a borrowed &mut) is one that I have gone back > and forth on. I have to go consult my notes as to the reason it is > setup the way it is; it may be that we could potentially loosen the > rule in this case, but I seem to recall that doing so had dangerous > consequences that I cannot remember at the moment. > >> /// Iterate and mutate on a tree map in an arbitrary order. >> impl<'self, T> Iterator<(&'self Path, &'self mut T)> for >> TreeMapMutIterator<'self, T> { >> /// Move to the next value contained in the tree map. >> fn next(&mut self) -> Option<(&'self Path, &'self mut T)> { >> if self.levels.len() == 0 { >> None >> } else { >> let last = self.levels.len() - 1; >> let root = util::replace(&mut self.levels[last].root, None); >> match root { >> Some(&ref mut entry) => { >> let path = &entry.path; >> let value = &mut entry.value; >> Some((path, value)) >> } >> None => { >> match self.levels[last].iterator.next() { >> Some((_atom, treemap)) => { >> self.levels.push(fail!()); >> } >> None => { >> self.levels.pop(); >> } >> } >> self.next() >> } >> } >> } >> } >> } > > > Niko > > > On Tue, Aug 20, 2013 at 05:50:31PM +0300, Oren Ben-Kiki wrote: >> Here is the heart of the code, maybe it will be clearer why I had to use >> unsafe (or, maybe, how I could avoid it): >> >> /// A path is just an array of atoms. >> #[deriving(Eq, TotalEq, Ord, TotalOrd, Clone, IterBytes)] >> pub struct Path { >> /// The array of atoms the path consists of. >> pub atoms: ~[Atom], >> } >> >> /// An entry contained in the tree map. >> #[deriving(Eq, TotalEq, Ord, TotalOrd)] >> pub struct TreeMapEntry { >> /// The full path of the entry. >> path: Path, >> >> /// The value of the entry. >> value: T, >> } >> >> /// A tree map holds values of some arbitrary type, indexed by a path. >> pub struct TreeMap { >> /// The entry of this node, if any. >> priv entry: Option>, >> >> /// The sub-trees under this node, if any. >> priv sub_trees: HashMap> >> } >> >> /// Iterate and mutate on a single level of the tree map. >> struct LevelMutIterator<'self, T> { >> /// The root node to return the value of (as the 1st result). >> root: Option<&'self mut TreeMapEntry>, >> >> /// The iterator at the current level of the tree. >> iterator: HashMapMutIterator<'self, Atom, ~TreeMap>, >> } >> >> /// Iterate and mutate on a tree map in an arbitrary order. >> pub struct TreeMapMutIterator<'self, T> { >> /// The iterators of all levels we have reached so far. >> priv levels: ~[LevelMutIterator<'self, T>] >> } >> >> /// Iterate and mutate on a tree map in an arbitrary order. >> impl<'self, T> Iterator<(&'self Path, &'self mut T)> for >> TreeMapMutIterator<'self, T> { >> /// Move to the next value contained in the tree map. >> fn next(&mut self) -> Option<(&'self Path, &'self mut T)> { >> if self.levels.len() == 0 { >> None >> } else { >> unsafe { >> let last: *mut LevelMutIterator<'self, T> = &mut >> self.levels[self.levels.len() - 1]; >> match (*last).root { >> Some(ref mut entry) => { >> let path = &entry.path; >> let value = &mut entry.value; >> // TRICKY: This makes the entry inaccessible, which >> is >> // why we took the returned path and value above. >> (*last).root = None; >> Some((path, value)) >> } >> None => { >> match self.levels[self.levels.len() - >> 1].iterator.next() { >> Some((_atom, treemap)) => { >> self.levels.push(treemap.level_mut_iter()); >> } >> None => { >> self.levels.pop(); >> } >> } >> self.next() >> } >> } >> } >> } >> } >> } >> >> I tried for around a day to make this work without the unsafe, to no avail. >> The trick is I want to take the value out of the option (leaving None >> behind), and return the value. I'm probably missing some solution which may >> be obvious to a non-newbie to Rust...? > >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From dpx.infinity at gmail.com Wed Aug 21 12:15:41 2013 From: dpx.infinity at gmail.com (Vladimir Matveev) Date: Wed, 21 Aug 2013 23:15:41 +0400 Subject: [rust-dev] Borrowed pointers with lifetime in structures cause weird errors In-Reply-To: <20130820103929.GF15491@Mr-Bennet> References: <20130820103929.GF15491@Mr-Bennet> Message-ID: Hi Niko, Thank you for your response. I forgot to put it in the original message, but here is a link to bitbucket repository with all the code I got so far: https://bitbucket.org/googolplex/algo/src, see module io. Maybe it will be helpful. I'm still inclined to think that this is a bug, and I really do not see how can I do what I want to with two lifetime parameters. There really should be one lifetime (the one of the Reader), or maybe I'm missing something? As for internal iterators, yes, I tried to do that first, but since it is impossible to break out or return from inside of the iterator loop directly via `break` or `return` it quickly becomes pretty unfeasible since I have to use a lot of boilerplate boolean parameters and check them in many places. This may be not so apparent for finite structures, but for potentially infinite ones (like a wrapper for `Reader`) it is. Nonetheless, as far as I understand, external iterators are the future of iteration in Rust (generators won't appear in the nearest future, will they?), so I want to use the most idiomatic style. 2013/8/20 Niko Matsakis : > Hi, > > Sorry for not responding more quickly. I've been wanting to sit down > and work out your example; I am confident that it can be made to work, > although from reading it quickly it sounds like a case that might be > better served with two lifetime parameters, which are not yet > supported (on my list...). > > However, I did want to briefly point out that you can continue to use > "internal" iterators, you just don't get the `for` syntax > anymore. Just write a higher-order function as you always did, > possibly returning bool to indicate whether to break or continue. > > > Niko > > > On Sat, Aug 17, 2013 at 01:54:09PM +0400, Vladimir Matveev wrote: >> Hello, >> >> I'm writing a simple tokenizer which is defined by this trait: >> >> trait Tokenizer { >> fn next_token(&mut self) -> ~str; >> fn eof(&self) -> bool; >> } >> >> Obvious application for a tokenizer is splitting a stream going from >> Reader, so I have the following structure which should implement >> Tokenizer: >> >> pub struct ReaderTokenizer<'self> { >> priv inner: &'self Reader, >> priv buffer: ~CyclicBuffer, >> priv seps: ~[~str] >> } >> >> I have used 'self lifetime parameter since I want for the tokenizer >> work for any Reader. CyclicBuffer is another structure which >> essentially is an array of u8 with special read/write operations. >> >> Implementation of a Tokenizer for ReaderTokenizer involves reading >> from the Reader one byte at a time. I decided to use buffering to >> improve performance. But I still want to keep the useful abstraction >> of single byte reading, so I decided to implement Iterator for my >> Reader+CyclicBuffer pair. BTW, internal iterators in 0.7 were much >> better for this, because internal iterator code was very simple and >> didn't use explicit lifetimes at all, but 0.7 compiler suffers from >> several errors related to pointers to traits which prevented my >> program from compiling (I couldn't pass a reference to Reader to >> CyclicBuffer method; there were other errors I've encountered too). I >> So, I decided to use trunk version of the compiler in which these >> errors are resolved according to github, but trunk version does not >> allow internal iterators, which is very sad since now I'm forced to >> create intermediate structures to achieve the same thing. >> >> So, I came up with the following iterator structure: >> >> struct RTBytesIterator<'self> { >> tokenizer: &'self mut ReaderTokenizer<'self> >> } >> >> impl<'self> Iterator for RTBytesIterator<'self> { >> fn next(&mut self) -> Option { >> if self.tokenizer.eof() { >> return None; >> } >> if self.tokenizer.buffer.readable_bytes() > 0 || >> self.tokenizer.buffer.fill_from_reader(self.tokenizer.inner) > 0 { >> return Some(self.tokenizer.buffer.read_unsafe()); >> } else { >> return None; >> } >> } >> } >> >> Note that tokenizer field is &'self mut since CyclicBuffer is mutable. >> buffer.fill_from_reader() function reads as much as possible from the >> reader (returning a number of bytes read), and buffer.read_unsafe() >> returns next byte from the cyclic buffer. >> >> Then I've added the following method to ReaderTokenizer: >> >> impl<'self> ReaderTokenizer<'self> { >> ... >> fn bytes_iter(&mut self) -> RTBytesIterator<'self> { >> RTBytesIterator { tokenizer: self } >> } >> ... >> } >> >> This does not compile with the following error: >> >> io/convert_io.rs:98:37: 98:43 error: cannot infer an appropriate >> lifetime due to conflicting requirements >> io/convert_io.rs:98 RTBytesIterator { tokenizer: self } >> ^~~~~~ >> io/convert_io.rs:97:55: 99:5 note: first, the lifetime cannot outlive >> the anonymous lifetime #1 defined on the block at 97:55... >> io/convert_io.rs:97 fn bytes_iter(&mut self) -> RTBytesIterator<'self> { >> io/convert_io.rs:98 RTBytesIterator { tokenizer: self } >> io/convert_io.rs:99 } >> io/convert_io.rs:98:37: 98:43 note: ...due to the following expression >> io/convert_io.rs:98 RTBytesIterator { tokenizer: self } >> ^~~~~~ >> io/convert_io.rs:97:55: 99:5 note: but, the lifetime must be valid for >> the lifetime &'self as defined on the block at 97:55... >> io/convert_io.rs:97 fn bytes_iter(&mut self) -> RTBytesIterator<'self> { >> io/convert_io.rs:98 RTBytesIterator { tokenizer: self } >> io/convert_io.rs:99 } >> io/convert_io.rs:98:8: 98:23 note: ...due to the following expression >> io/convert_io.rs:98 RTBytesIterator { tokenizer: self } >> ^~~~~~~~~~~~~~~ >> error: aborting due to previous error >> >> OK, fair enough, I guess I have to annotate self parameter with 'self lifetime: >> >> fn bytes_iter(&'self mut self) -> RTBytesIterator<'self> { >> RTBytesIterator { tokenizer: self } >> } >> >> This compiles, but now I'm getting another error at bytes_iter() usage >> site, for example, the following code: >> >> fn try_read_sep(&mut self, first: u8) -> (~[u8], bool) { >> let mut part = ~[first]; >> for b in self.bytes_iter() { >> part.push(b); >> if !self.is_sep_prefix(part) { >> return (part, false); >> } >> if self.is_sep(part) { >> break; >> } >> } >> return (part, true); >> } >> >> fails to compile with this error: >> >> io/convert_io.rs:117:17: 117:36 error: cannot infer an appropriate >> lifetime due to conflicting requirements >> io/convert_io.rs:117 for b in self.bytes_iter() { >> ^~~~~~~~~~~~~~~~~~~ >> io/convert_io.rs:117:17: 117:22 note: first, the lifetime cannot >> outlive the expression at 117:17... >> io/convert_io.rs:117 for b in self.bytes_iter() { >> ^~~~~ >> io/convert_io.rs:117:17: 117:22 note: ...due to the following expression >> io/convert_io.rs:117 for b in self.bytes_iter() { >> ^~~~~ >> io/convert_io.rs:117:17: 117:36 note: but, the lifetime must be valid >> for the method call at 117:17... >> io/convert_io.rs:117 for b in self.bytes_iter() { >> ^~~~~~~~~~~~~~~~~~~ >> io/convert_io.rs:117:17: 117:22 note: ...due to the following expression >> io/convert_io.rs:117 for b in self.bytes_iter() { >> ^~~~~ >> >> And now I'm completely stuck. I can't avoid these errors at all. This >> looks like a bug to me, but I'm not completely sure - maybe it's me >> who is wrong here. >> >> I've studied libstd/libextra code for clues and found out that some >> iterable structures have code very similar to mine, for example, >> RingBuf. Here is its mut_iter() method: >> >> pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> { >> RingBufMutIterator{index: 0, rindex: self.nelts, lo: self.lo, >> elts: self.elts} >> } >> >> I have tried to implement bytes_iter() method like this, but it >> naturally didn't work because of 'a and 'self lifetimes conflict. In >> my understanding, this works here because RingBuf does not have >> lifetime parameter, so no conflict between 'self and 'a lifetime is >> possible at all. But this will not work in my case, because I have to >> have 'self parameter because of &'self Reader field. >> >> What can I do to implement my ReaderTokenizer? Maybe there are other >> ways of which I'm unaware? >> >> Thank you very much in advance. >> >> Best regards, >> Vladimir. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev From oren at ben-kiki.org Wed Aug 21 17:19:08 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Thu, 22 Aug 2013 03:19:08 +0300 Subject: [rust-dev] Avoiding borrow check assertions with @mut In-Reply-To: References: <5212F679.1040805@arrownext.com> <20130820103808.GE15491@Mr-Bennet> <20130821023549.GB3475@Mr-Bennet> Message-ID: Thanks for all the responses! I knew there was something simple I could do in my specific case - in this case, `.take()` or more generically `utils::replace`. Thanks for the pointers. That said, the general problem remains. I think it goes as follows: - There is a container accessible from some root pointer. - One burrows a mutable pointer to some entry nested in the container. - At this point, we can split all the memory reachable from the root pointer into three kinds: A. The mutable entry data we burrowed a pointer to. B. The data along the path leading from (including) the root pointer to the mutable entry. C. Other data reachable by the container. For example, if I have a `&mut T` to the `i`th entry of a `~[T]` array, then: A. Is the `&mut T` and anything reached from it. B. Is the pointer to the base of the array (the `&mut T` is that base plus `i` * the size of `T`). C. Is all the data contained in all the entries other than the `i`th, and anything reached from them. Now, there are three kinds of mutations one can do to the container - these that mutate A, B or C data. Burrowing a 2nd mutable pointer to A data is forbidden, to avoid two mutable pointers to the same data. So far, so good. Burrowing a mutable pointer to B data is forbidden, because if it mutates than the entry we have a pointer to might be disconnected from the container or compromised in another way. Burrowing a mutable pointer to C data should be allowed, as it doesn't overlap with our mutable pointer in any way. For example, one could reasonably expect to be able to burrow a mutable pointer to both `vec[0]` and `vec[1]` at the same time. However, the type system can't tell (in general) whether a specific mutable operation on the container touches only B date or also C data. It doesn't know that `vec.push()` might change the base pointer (B data) but `vec[1]` doesn't. All it can see is that there is mutable access in both case, so it plays it safe. It is hard to do better. Even in the simple vector case. Suppose I get two parameters, `i` and `j`, and I tryu to get `&mut T` for both `vec[i]` and `vec[j]`. This is OK as long as i is different from j. If they are equal, this is forbidden. But there's no way to make these kinds of decisions in the type system - this requires a run-time check. It might be able to do somewhat better by using nested lifetimes. I'm not certain this can be done in a general way using the current type system, though. But even with nested lifetimes, this wouldn't solve the general problem. When the static type system fails, one must rely on either unsafe code ("trust me") or a dynamic type system ("verify me"). The latter may be expensive - in fact, supporting "verify me" might require extra cost for code that has no need for this feature (to make relevant meta-data available and up-to-date). Right now, Rust goes along the way of "trust me". That said, there are idioms (like `take`) which can hide the nastiness in their inside. Perhaps we need a cheat cheat of common use cases and the patterns for achieving them using the current mechanisms (that is, libraries that provide support for the common use cases). ARC for example, but also `take` and `replace` and I guess a few more besides. Then we could say "if you feel none of them is enough, define a new useful generic safe mechanism (with unsafe internals) to cover the case"; but in general all containers code should not include any `unsafe` blocks, it should just use one of the debugger/approved standard library "trust me" functions (which would presumably be well-debugged). This would be quite a project, though... even when based on existing code. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bill_myers at outlook.com Wed Aug 21 17:53:22 2013 From: bill_myers at outlook.com (Bill Myers) Date: Thu, 22 Aug 2013 00:53:22 +0000 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <5213DF35.7050100@mozilla.com> References: <5213DE50.6040705@gmail.com>,<5213DF35.7050100@mozilla.com> Message-ID: Have you considered the following "non-specific" quick fixes? 1. Build on a ramfs/ramdisk 2. Distribute compilations and tests across a cluster of machines (like distcc) 3. If non-parallelizable code is still the bottleneck, use the fastest CPU possible (i.e. an overclocked Core i7 4770K, overclocked Core i7 4960X/3960X/4930K/3930K, dual Xeon E5 2687W or quad Xeon E5 4650 depending on whether you need 4, 6, 16 or 32 cores) 4. Read metadata only once, in one of these ways: 4a. Pass all files to a single compiler invocation (per machine or core) 4b. Have a long-lived rustc "daemon" (per machine or core) that keeps crate metadata in memory and gets passed files to compile by fd 4c. Use CRIU suspend/restore (or the unexec from Emacs or whatever) to suspend a rustc process after metadata is read and restore that image for each file instead of spawning a new one 4d. Allocate metadata using a special allocator that allocates it from a block at a fixed memory address, then just dump the block into a file, and read metadata with a single mmap system call at that same fixed address (this is a security hole in general, so it needs to be optional and off by default) -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Wed Aug 21 19:44:21 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 21 Aug 2013 19:44:21 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com>, <5213DF35.7050100@mozilla.com> Message-ID: <52157B05.3000805@mozilla.com> On 13-08-21 05:53 PM, Bill Myers wrote: > Have you considered the following "non-specific" quick fixes? > > 1. Build on a ramfs/ramdisk Not I/O bound. > 2. Distribute compilations and tests across a cluster of machines (like > distcc) Already doing what we can here. The remainder doesn't parallelize without a huge amount of compiler rearchitecture. > 3. If non-parallelizable code is still the bottleneck, use the fastest > CPU possible (i.e. an overclocked Core i7 4770K, overclocked Core i7 > 4960X/3960X/4930K/3930K, dual Xeon E5 2687W or quad Xeon E5 4650 > depending on whether you need 4, 6, 16 or 32 cores) They're all quad xeons and i7s. We could push a little ways up this slope but it gets expensive and the returns are not great. > 4. Read metadata only once, in one of these ways: > 4a. Pass all files to a single compiler invocation (per machine or core) That's check-fast. Some tests don't like that, so we only do it on windows. We could do it on more machines but we don't want to lose coverage for the tests that don't work for check-fast. Someone's suggested doing check-fast everywhere + manually running the xfail-fast ones on the side. That might work, but it won't get us below 45min on a single bootstrap (because it's 30min to build straight-line) and 1h on an -all bootstrap. > 4b. Have a long-lived rustc "daemon" (per machine or core) that keeps > crate metadata in memory and gets passed files to compile by fd That would be a huge amount of rearchitecture. > 4c. Use CRIU suspend/restore (or the unexec from Emacs or whatever) to > suspend a rustc process after metadata is read and restore that image > for each file instead of spawning a new one The metadata is read in response to the source file being processed. By the time we could do this, we're committed to compiling a particular source file. Again, major work to redesign for this not to be true. > 4d. Allocate metadata using a special allocator that allocates it from a > block at a fixed memory address, then just dump the block into a file, > and read metadata with a single mmap system call at that same fixed > address (this is a security hole in general, so it needs to be optional > and off by default) Again, large amount of work to rearrange everything that uses metadata to work with this sort of thing. People keep looking for non-bug "quick fixes" while ignoring the bugs that are the source of the speed issues. Fixing the bugs _is_ the quick fix. It's not super quick, but it'll be faster than any other ideas we've got (except possibly sharding the testsuite, I'm going to wire that into buildbot when I get a free moment). -Graydon From corey at octayn.net Wed Aug 21 19:47:20 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 21 Aug 2013 22:47:20 -0400 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> Message-ID: On Wed, Aug 21, 2013 at 8:53 PM, Bill Myers wrote: > Have you considered the following "non-specific" quick fixes? > > 1. Build on a ramfs/ramdisk > IO and especially disk IO are almost 0 compilation time. All files in a crate are read at once, then compilation happens. > 2. Distribute compilations and tests across a cluster of machines (like > distcc) > Compilation is 99% serial (the only things that happen in parallel are rustpkg and rustdoc etc at the end, and they are almost nothing), though tests could be distributed (and Graydon is working on doing that afaik). > 3. If non-parallelizable code is still the bottleneck, use the fastest CPU > possible (i.e. an overclocked Core i7 4770K, overclocked Core i7 > 4960X/3960X/4930K/3930K, dual Xeon E5 2687W or quad Xeon E5 4650 depending > on whether you need 4, 6, 16 or 32 cores) > > 4. Read metadata only once, in one of these ways: > 4a. Pass all files to a single compiler invocation (per machine or core) This already happens: crates are compiled all-at-once, unlike C/C++'s per-file-and-then-link compilation model. > 4b. Have a long-lived rustc "daemon" (per machine or core) that keeps crate > metadata in memory and gets passed files to compile by fd This wouldn't be that much of a quick fix, and the work to do it would need a betterly-structured metadata that wouldn't suffer from the same problems current metadata does (though this could still be an optimization later). > 4c. Use CRIU suspend/restore (or the unexec from Emacs or whatever) to > suspend a rustc process after metadata is read and restore that image for > each file instead of spawning a new one This is an interesting idea, pursuing it might be warranted. > 4d. Allocate metadata using a special allocator that allocates it from a > block at a fixed memory address, then just dump the block into a file, and > read metadata with a single mmap system call at that same fixed address > (this is a security hole in general, so it needs to be optional and off by > default) Also an interesting idea, though a bit of work. Brian is working on not compressing metadata, which would be a win. Here is my current understanding of the problems with metadata (from scouring some profiles and the code ~3 months ago): - Metadata is large. It is multiple megabytes of data (uncompressed. compressed as of now it is 749K) for libstd. I'm not sure whether we are encoding too much data or if it's exactly what we need, but this is a very large constant that every inefficiency gets scaled by. - Metadata is stored as EBML, always. I'm sure EBML is fine most of the time, but it really hurts us here. Part of the problem is that it is a big endian format. The byte swapping shows up very high (top 5) in a profile. Additionally, *every time we query the stored metadata for something, we decode the EBML*. This turns EBML into a multiplicative slowdown, rather than just an additive if we decoded the entire structure up front and used the native-rust representation. - Metadata is stored in a single blob. To access any part of metadata, we need to load it all, and there is no index. If we could only load the metadata we need, we'd reduce memory usage and do less wasted work. - Metadata is scary. It's a hairy part of the codebase that I sure don't understand. I know its purpose, more or less, but not the specifics of how or why things are encoded. Michael Sullivan could speak more to this, he is the last one to have touched it. The compiler can't help you when you make a mistake, either. I think the solution requires a much more systemic change than your proposes quick fixes. From graydon at mozilla.com Wed Aug 21 19:59:12 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 21 Aug 2013 19:59:12 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> Message-ID: <52157E80.20607@mozilla.com> On 13-08-21 07:47 PM, Corey Richardson wrote: > - Metadata is large. It is multiple megabytes of data (uncompressed. > compressed as of now it is 749K) for libstd. I'm not sure whether we > are encoding too much data or if it's exactly what we need, but this > is a very large constant that every inefficiency gets scaled by. Only because we read all of it. Which is a bug. https://github.com/mozilla/rust/issues/4572 > - Metadata is stored as EBML, always. I'm sure EBML is fine most of > the time, but it really hurts us here. Part of the problem is that it > is a big endian format. The byte swapping shows up very high (top 5) > in a profile. Additionally, *every time we query the stored metadata > for something, we decode the EBML*. This turns EBML into a > multiplicative slowdown, rather than just an additive if we decoded > the entire structure up front and used the native-rust representation. We cache a lot of the results. > - Metadata is stored in a single blob. To access any part of metadata, > we need to load it all, and there is no index. If we could only load > the metadata we need, we'd reduce memory usage and do less wasted > work. There are indexes. But our access patterns are buggy and we read the whole thing even if we only need a little bit. We're going to stop doing this. Patrick is working on it. It's that bug, above. > - Metadata is scary. It's a hairy part of the codebase that I sure > don't understand. I know its purpose, more or less, but not the > specifics of how or why things are encoded. Michael Sullivan could > speak more to this, he is the last one to have touched it. The > compiler can't help you when you make a mistake, either. I contains indexes of particularly salient extracts from the items in the crate, as well as a general module / item tree, their types, and the serialized ASTs of those items that you might want to inline. -Graydon From pwalton at mozilla.com Wed Aug 21 20:03:08 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 21 Aug 2013 20:03:08 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> Message-ID: <52157F6C.30204@mozilla.com> On 8/21/13 7:47 PM, Corey Richardson wrote: > IO and especially disk IO are almost 0 compilation time. All files in > a crate are read at once, then compilation happens. I don't believe this is true, as disk IO from metadata reading hurts. > - Metadata is large. It is multiple megabytes of data (uncompressed. > compressed as of now it is 749K) for libstd. I'm not sure whether we > are encoding too much data or if it's exactly what we need, but this > is a very large constant that every inefficiency gets scaled by. We could probably do a bit better here, but we do have to serialize ASTs for generics. libstd is already 2.3MB of Rust code, so I would expect the serialized ASTs from the generics to be on that order. > - Metadata is stored as EBML, always. I'm sure EBML is fine most of > the time, but it really hurts us here. Part of the problem is that it > is a big endian format. The byte swapping shows up very high (top 5) > in a profile. If I had to do it all over again I'd use atom trees instead of EBML, but I doubt that getting rid of vuints will help that much. I rewrote that routine in optimized asm once and it didn't help. The reason vuint_at shows up so high in the profile is mostly because, algorithmically, we read metadata too much, and reading integers is most of what reading metadata is. > Additionally, *every time we query the stored metadata > for something, we decode the EBML*. This turns EBML into a > multiplicative slowdown, rather than just an additive if we decoded > the entire structure up front and used the native-rust representation. If we decoded the entire structure up front and used native Rust we would lose the index and would suffer a slowdown. I believe Niko tried this and saw massive performance losses. > - Metadata is stored in a single blob. To access any part of metadata, > we need to load it all, and there is no index. If we could only load > the metadata we need, we'd reduce memory usage and do less wasted > work. This is untrue; there is an index. It's just that not every part of the compiler uses it yet. I have a patch that I will try to land tomorrow that converts resolve to be lazy and consult the index and reduces its time on hello world by 10x. Method tables in coherence will require a bit more work to be lazy, but could also reduce its time. Patrick From pwalton at mozilla.com Wed Aug 21 20:06:07 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 21 Aug 2013 20:06:07 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <52157B05.3000805@mozilla.com> References: <5213DE50.6040705@gmail.com>, <5213DF35.7050100@mozilla.com> <52157B05.3000805@mozilla.com> Message-ID: <5215801F.1020201@mozilla.com> On 8/21/13 7:44 PM, Graydon Hoare wrote: > Again, large amount of work to rearrange everything that uses metadata > to work with this sort of thing. This actually isn't that hard, I don't think. It's just incompatible with compression and might require hacking the LLVM ObjectFile interface a bit. I would like to try storing the metadata uncompressed and mmaping it for a disk I/O win on small crates (as it'd only access on disk what you use: an algorithmic complexity improvement!) Of course for it to be a win we need to convert resolve and coherence to use the index. Patrick From corey at octayn.net Wed Aug 21 20:38:55 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 21 Aug 2013 23:38:55 -0400 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <52157F6C.30204@mozilla.com> References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> <52157F6C.30204@mozilla.com> Message-ID: On Wed, Aug 21, 2013 at 11:03 PM, Patrick Walton wrote: > On 8/21/13 7:47 PM, Corey Richardson wrote: >> >> IO and especially disk IO are almost 0 compilation time. All files in >> a crate are read at once, then compilation happens. > > > I don't believe this is true, as disk IO from metadata reading hurts. > I'm not convinced it's false. Our IO patterns are pretty predictable and diskcache friendly. Assuming we're not blowing the cache out of the water with our memory usage, but compiling the tests shouldn't be too much memory (comparatively), ~128MB max I'd expect. But I don't have numbers, this is speculation. > >> - Metadata is large. It is multiple megabytes of data (uncompressed. >> compressed as of now it is 749K) for libstd. I'm not sure whether we >> are encoding too much data or if it's exactly what we need, but this >> is a very large constant that every inefficiency gets scaled by. > > > We could probably do a bit better here, but we do have to serialize ASTs for > generics. libstd is already 2.3MB of Rust code, so I would expect the > serialized ASTs from the generics to be on that order. > Yeah, I don't expect any major wins in this area. One thing that has been on the back of my mind (and I think I've seen Graydon mention it) is splitting metadata out of the object file, similar to how you can split out debuginfo. I'm hesitant about this feature though. I'd hate to require -dev or -devel packages, that's part of the pain of headers. > >> - Metadata is stored as EBML, always. I'm sure EBML is fine most of >> the time, but it really hurts us here. Part of the problem is that it >> is a big endian format. The byte swapping shows up very high (top 5) >> in a profile. > > > If I had to do it all over again I'd use atom trees instead of EBML, but I > doubt that getting rid of vuints will help that much. I rewrote that routine > in optimized asm once and it didn't help. The reason vuint_at shows up so > high in the profile is mostly because, algorithmically, we read metadata too > much, and reading integers is most of what reading metadata is. > I would think it's the fact that the byte swapping is happening at all, though I don't have numbers here either. Experimenting with encoding it as little endian and not doing a swap should be easy to experiment with. > >> Additionally, *every time we query the stored metadata >> for something, we decode the EBML*. This turns EBML into a >> multiplicative slowdown, rather than just an additive if we decoded >> the entire structure up front and used the native-rust representation. > > > If we decoded the entire structure up front and used native Rust we would > lose the index and would suffer a slowdown. I believe Niko tried this and > saw massive performance losses. > That's good to know. > >> - Metadata is stored in a single blob. To access any part of metadata, >> we need to load it all, and there is no index. If we could only load >> the metadata we need, we'd reduce memory usage and do less wasted >> work. > > > This is untrue; there is an index. It's just that not every part of the > compiler uses it yet. I have a patch that I will try to land tomorrow that > converts resolve to be lazy and consult the index and reduces its time on > hello world by 10x. Method tables in coherence will require a bit more work > to be lazy, but could also reduce its time. > Ah, I must have missed it and any code that uses it in my (admittedly brief) look at the code. (I think this also addresses the points Graydon brought up: thanks for correcting my understanding!) From niko at alum.mit.edu Thu Aug 22 03:42:43 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 22 Aug 2013 06:42:43 -0400 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> Message-ID: <20130822104243.GB1330@Mr-Bennet> On Wed, Aug 21, 2013 at 10:47:20PM -0400, Corey Richardson wrote: > - Metadata is scary. It's a hairy part of the codebase that I sure > don't understand. I know its purpose, more or less, but not the > specifics of how or why things are encoded. Michael Sullivan could > speak more to this, he is the last one to have touched it. The > compiler can't help you when you make a mistake, either. FWIW, I had a branch that replaced the type encoding part of metadata with the standard encoder. It did not use an EBML output but rather a very specialized, minimal encoder. This did not improve compile times, though. I think the reason was that I never got around to implementing the "type abbreviations" code that optimizes the case of repeated types. Anyway, I still think the best *long-term* fix for making metadata more approachable and maintainable is to transition to using the standard encoding stuff. Clearly, we'd need to structure the encoder so that we first encode an index and then encode the various bits individually, presumably using gzip. It is unclear to me though whether this would increase perf -- perhaps as a side-effect of general rearchitecting. It might also help more in the general metadata code, where EBML costs something, than in the type encoding code, which is already pretty specialized. Niko From oren at ben-kiki.org Thu Aug 22 06:55:59 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Thu, 22 Aug 2013 16:55:59 +0300 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <20130822104243.GB1330@Mr-Bennet> References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> <20130822104243.GB1330@Mr-Bennet> Message-ID: Perhaps this is a crazy idea, but why not use SQLite or some similar efficient DB format to store the meta-data? This isn't a "quick fix", of course, but on the face of it it should provide efficiency improvements in accessing just what one needs, plus the potential for enabling an ecosystem of analysis/visualization/etc. tools that would run off the meta-data in a sane way. -------------- next part -------------- An HTML attachment was scrubbed... URL: From vadimcn at gmail.com Thu Aug 22 14:04:59 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 22 Aug 2013 14:04:59 -0700 Subject: [rust-dev] Using extern functions from another crate Message-ID: When I try to use an extern function defined in another crate, (specifically, std::libc::funcs::extra::kernel32::OpenProcess in my case), Rust seems to generate a direct call to that function, and then linking fails because of unresolved symbols. My expectation is that the call would go first to the wrapper inside std crate, which then calls the real OpenProces(). Am I getting this right? -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Aug 22 14:44:15 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 22 Aug 2013 14:44:15 -0700 Subject: [rust-dev] Using extern functions from another crate In-Reply-To: References: Message-ID: <5216862F.4050300@mozilla.com> On 08/22/2013 02:04 PM, Vadim wrote: > When I try to use an extern function defined in another crate, > (specifically, std::libc::funcs::extra::kernel32::OpenProcess in my > case), Rust seems to generate a direct call to that function, and then > linking fails because of unresolved symbols. My expectation is that > the call would go first to the wrapper inside std crate, which then > calls the real OpenProces(). > > Am I getting this right? This is fallout from the new model for externs that I at least did not anticipate. From vadimcn at gmail.com Thu Aug 22 15:31:05 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 22 Aug 2013 15:31:05 -0700 Subject: [rust-dev] Using extern functions from another crate In-Reply-To: <5216862F.4050300@mozilla.com> References: <5216862F.4050300@mozilla.com> Message-ID: Oh, ok, so this will be fixed? Any idea when? :-) On Thu, Aug 22, 2013 at 2:44 PM, Brian Anderson wrote: > On 08/22/2013 02:04 PM, Vadim wrote: > >> When I try to use an extern function defined in another crate, >> (specifically, std::libc::funcs::extra::**kernel32::OpenProcess in my >> case), Rust seems to generate a direct call to that function, and then >> linking fails because of unresolved symbols. My expectation is that the >> call would go first to the wrapper inside std crate, which then calls the >> real OpenProces(). >> >> Am I getting this right? >> > > This is fallout from the new model for externs that I at least did not > anticipate. > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Thu Aug 22 18:19:02 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 22 Aug 2013 21:19:02 -0400 Subject: [rust-dev] Using extern functions from another crate In-Reply-To: References: <5216862F.4050300@mozilla.com> Message-ID: <20130823011902.GB7907@Mr-Bennet> On Thu, Aug 22, 2013 at 03:31:05PM -0700, Vadim wrote: > Oh, ok, so this will be fixed? Any idea when? :-) Interesting problem. I guess I don't know enough about how our linking model works to know how to fix this. I thought we'd get the extern fns when we linked in the source crate. In any case, I am not sure when it will be fixed, but the easiest solution in the short term is certainly to make the wrapper in the first crate. You can use the `externfn!` macro to do that. Niko From oren at ben-kiki.org Thu Aug 22 21:49:57 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Fri, 23 Aug 2013 07:49:57 +0300 Subject: [rust-dev] Dynamic in Rust Message-ID: Is it possible to implement something like Haskell's Dynamic value holder in Rust? (This would be similar to supporting C++'s dynamic_cast). Basically, something like this: pub struct Dynamic { ... } impl Dynamic { pub fn put(value: ~T) { ... } pub fn get() -> Option { ... } } I guess this would require unsafe code... even so, it seems to me that Rust pointers don't carry sufficient meta-data for the above to work. A possible workaround would be something like: pub struct Dynamic { type_name: ~str, ... } impl Dynamic { pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: type_name, ... } } pub fn get(&'a self, type_name: &str) -> Option<&'a T> { assert_eq!(type_name, self.type_name); ... } } } And placing the burden on the caller to always use the type name "int" when putting or getting `int` values, etc. This would still require some sort of unsafe code to cast the `~T` pointer into something and back, while ensuring that the storage for the `T` (whatever its size is) is not released until the `Dynamic` itself is. (Why do I need such a monstrosity? Well, I need it to define a `Configuration` container, which holds key/value pairs where whoever sets a value knows its type, whoever gets the value should ask for the same type, and the configuration can hold values of "any" type - not from a predefined list of types). Is such a thing possible, and if so, how? Thanks, Oren Ben-Kiki -------------- next part -------------- An HTML attachment was scrubbed... URL: From abhijeet.gaiha at gmail.com Thu Aug 22 21:54:53 2013 From: abhijeet.gaiha at gmail.com (Abhijeet Gaiha) Date: Fri, 23 Aug 2013 10:24:53 +0530 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: You could define an enum that encapsulates all known types. enum monster { Integer(int), Float(float), .... } Then use a container for this type. On Aug 23, 2013 10:20 AM, "Oren Ben-Kiki" wrote: > Is it possible to implement something like Haskell's Dynamic value holder > in Rust? (This would be similar to supporting C++'s dynamic_cast). > Basically, something like this: > > pub struct Dynamic { ... } > impl Dynamic { > pub fn put(value: ~T) { ... } > pub fn get() -> Option { ... } > } > > I guess this would require unsafe code... even so, it seems to me that > Rust pointers don't carry sufficient meta-data for the above to work. A > possible workaround would be something like: > > pub struct Dynamic { type_name: ~str, ... } > impl Dynamic { > pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: > type_name, ... } } > pub fn get(&'a self, type_name: &str) -> Option<&'a T> { > assert_eq!(type_name, self.type_name); ... } } > } > > And placing the burden on the caller to always use the type name "int" > when putting or getting `int` values, etc. This would still require some > sort of unsafe code to cast the `~T` pointer into something and back, while > ensuring that the storage for the `T` (whatever its size is) is not > released until the `Dynamic` itself is. > > (Why do I need such a monstrosity? Well, I need it to define a > `Configuration` container, which holds key/value pairs where whoever sets a > value knows its type, whoever gets the value should ask for the same type, > and the configuration can hold values of "any" type - not from a predefined > list of types). > > Is such a thing possible, and if so, how? > > Thanks, > > Oren Ben-Kiki > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From oren at ben-kiki.org Thu Aug 22 21:57:17 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Fri, 23 Aug 2013 07:57:17 +0300 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: That would require me to declare up front which types were usable and which weren't. I'm looking for a solution where I don't need to do that; that is, allow me to add new components to the system with new configuration parameter types, without having to go to a central source location and declare these types there. On Fri, Aug 23, 2013 at 7:54 AM, Abhijeet Gaiha wrote: > You could define an enum that encapsulates all known types. > > enum monster { > Integer(int), > Float(float), > .... > } > > Then use a container for this type. > On Aug 23, 2013 10:20 AM, "Oren Ben-Kiki" wrote: > >> Is it possible to implement something like Haskell's Dynamic value holder >> in Rust? (This would be similar to supporting C++'s dynamic_cast). >> Basically, something like this: >> >> pub struct Dynamic { ... } >> impl Dynamic { >> pub fn put(value: ~T) { ... } >> pub fn get() -> Option { ... } >> } >> >> I guess this would require unsafe code... even so, it seems to me that >> Rust pointers don't carry sufficient meta-data for the above to work. A >> possible workaround would be something like: >> >> pub struct Dynamic { type_name: ~str, ... } >> impl Dynamic { >> pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: >> type_name, ... } } >> pub fn get(&'a self, type_name: &str) -> Option<&'a T> { >> assert_eq!(type_name, self.type_name); ... } } >> } >> >> And placing the burden on the caller to always use the type name "int" >> when putting or getting `int` values, etc. This would still require some >> sort of unsafe code to cast the `~T` pointer into something and back, while >> ensuring that the storage for the `T` (whatever its size is) is not >> released until the `Dynamic` itself is. >> >> (Why do I need such a monstrosity? Well, I need it to define a >> `Configuration` container, which holds key/value pairs where whoever sets a >> value knows its type, whoever gets the value should ask for the same type, >> and the configuration can hold values of "any" type - not from a predefined >> list of types). >> >> Is such a thing possible, and if so, how? >> >> Thanks, >> >> Oren Ben-Kiki >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From abhijeet.gaiha at gmail.com Thu Aug 22 22:01:13 2013 From: abhijeet.gaiha at gmail.com (Abhijeet Gaiha) Date: Fri, 23 Aug 2013 10:31:13 +0530 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: I think your second solution is what will work. You can use unsafe code and a void pointer combined with a type descriptor string. I would probably combine the void pointer and string in a struct. On Aug 23, 2013 10:27 AM, "Oren Ben-Kiki" wrote: > That would require me to declare up front which types were usable and > which weren't. I'm looking for a solution where I don't need to do that; > that is, allow me to add new components to the system with new > configuration parameter types, without having to go to a central source > location and declare these types there. > > > On Fri, Aug 23, 2013 at 7:54 AM, Abhijeet Gaiha wrote: > >> You could define an enum that encapsulates all known types. >> >> enum monster { >> Integer(int), >> Float(float), >> .... >> } >> >> Then use a container for this type. >> On Aug 23, 2013 10:20 AM, "Oren Ben-Kiki" wrote: >> >>> Is it possible to implement something like Haskell's Dynamic value >>> holder in Rust? (This would be similar to supporting C++'s dynamic_cast). >>> Basically, something like this: >>> >>> pub struct Dynamic { ... } >>> impl Dynamic { >>> pub fn put(value: ~T) { ... } >>> pub fn get() -> Option { ... } >>> } >>> >>> I guess this would require unsafe code... even so, it seems to me that >>> Rust pointers don't carry sufficient meta-data for the above to work. A >>> possible workaround would be something like: >>> >>> pub struct Dynamic { type_name: ~str, ... } >>> impl Dynamic { >>> pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: >>> type_name, ... } } >>> pub fn get(&'a self, type_name: &str) -> Option<&'a T> { >>> assert_eq!(type_name, self.type_name); ... } } >>> } >>> >>> And placing the burden on the caller to always use the type name "int" >>> when putting or getting `int` values, etc. This would still require some >>> sort of unsafe code to cast the `~T` pointer into something and back, while >>> ensuring that the storage for the `T` (whatever its size is) is not >>> released until the `Dynamic` itself is. >>> >>> (Why do I need such a monstrosity? Well, I need it to define a >>> `Configuration` container, which holds key/value pairs where whoever sets a >>> value knows its type, whoever gets the value should ask for the same type, >>> and the configuration can hold values of "any" type - not from a predefined >>> list of types). >>> >>> Is such a thing possible, and if so, how? >>> >>> Thanks, >>> >>> Oren Ben-Kiki >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From irving at naml.us Thu Aug 22 22:22:40 2013 From: irving at naml.us (Geoffrey Irving) Date: Thu, 22 Aug 2013 22:22:40 -0700 Subject: [rust-dev] parameterizing types and functions by integers Message-ID: Does rust have compile time sized arrays, equivalent to the following C++ definition? template struct array { T x[d]; }; More generally, is it possible to parameterize types by integers, so that types like the above can be built up? Finally, is it possible to parameterize functions over integers, as in fn concat(x : array, y : array) -> array { ... } If integer type arguments aren't built in, is it possible to type the concat function using a type-based encoding of naturals? Thanks! Geoffrey -------------- next part -------------- An HTML attachment was scrubbed... URL: From irving at naml.us Thu Aug 22 22:31:29 2013 From: irving at naml.us (Geoffrey Irving) Date: Thu, 22 Aug 2013 22:31:29 -0700 Subject: [rust-dev] parameterizing types and functions by integers In-Reply-To: References: Message-ID: Thanks for the quick reply (also adding back the list). Geoffrey On Thu, Aug 22, 2013 at 10:28 PM, John wrote: > For the moment, no, that's not possible. > On Aug 22, 2013 10:23 PM, "Geoffrey Irving" wrote: > >> Does rust have compile time sized arrays, equivalent to the following >> C++ definition? >> >> template struct array { >> T x[d]; >> }; >> >> More generally, is it possible to parameterize types by integers, so that >> types like the above can be built up? >> >> Finally, is it possible to parameterize functions over integers, as in >> >> fn concat(x : array, y : array) -> array { >> ... } >> >> If integer type arguments aren't built in, is it possible to type the >> concat function using a type-based encoding of naturals? >> >> Thanks! >> Geoffrey >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From bjzaba at yahoo.com.au Thu Aug 22 23:22:21 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Fri, 23 Aug 2013 16:22:21 +1000 Subject: [rust-dev] parameterizing types and functions by integers In-Reply-To: References: Message-ID: <15549F7C-6D63-4F58-B334-ECF8A845C5CF@yahoo.com.au> This would be amazing. At the moment the [T,..n] types are pretty damn useless when it comes to generics. Mathematics, science and units of measure libs would find constant parametrisation most useful. I could imagine something like: fn dot(a: [T, ..N], b: [T, ..N]) -> T { ? } or // Forgive me if I get these dimensions around the wrong way! fn mul_mat(a: &[[T, ..N], ..M], b: &[[T, ..O], ..M]) -> [[T, ..N],..O] { ? } fn transpose(a: &[[T, ..N], ..M]) -> [[T, ..M], ..N] { ? } ~Brendan On 23/08/2013, at 3:22 PM, Geoffrey Irving wrote: > Does rust have compile time sized arrays, equivalent to the following C++ definition? > > template struct array { > T x[d]; > }; > > More generally, is it possible to parameterize types by integers, so that types like the above can be built up? > > Finally, is it possible to parameterize functions over integers, as in > > fn concat(x : array, y : array) -> array { ... } > > If integer type arguments aren't built in, is it possible to type the concat function using a type-based encoding of naturals? > > Thanks! > Geoffrey > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From me at chrismorgan.info Fri Aug 23 03:44:57 2013 From: me at chrismorgan.info (Chris Morgan) Date: Fri, 23 Aug 2013 20:44:57 +1000 Subject: [rust-dev] Augmented assignment Message-ID: https://github.com/mozilla/rust/issues/5992 (Coming from a Python background I know the concept as augmented assignment; they are also known as assignment operators. Or just +=, ^=, <<= and the like.) I want augmented assignment in Rust for all types, so I had a crack at implementing this. I have an implementation mostly complete in my augmented-assignment branch (https://github.com/chris-morgan/rust/compare/augmented-assignment), but even if I managed to convince the Rust side of rustc that I was competent, LLVM called my bluff. The last state of my branch and what appears to be wrong (extra argument going to the LLVM Call) is documented in #5992. Is there anyone who would be able to look at my patch and get it to work (or even figure out just where the wrong is)? I just rebased it and so it is up to date, but if left for another few weeks it doubtless will continue to bitrot. From niko at alum.mit.edu Fri Aug 23 06:40:22 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 23 Aug 2013 09:40:22 -0400 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: <20130823134022.GB8742@Mr-Bennet> Currently, this is not directly supported, though downcasting in general is something we have contemplated as a feature. It might be possible to create some kind of horrible hack based on objects. A trait like: trait Dynamic { } impl Dynamic for T { } would allow any value to be cast to an object. The type descriptor can then be extracted from the vtable of the object using some rather fragile unsafe code that will doubtless break when we change the vtable format. The real question is what you can do with the type descriptor; they are not canonicalized, after all. Still, it's ... very close. This is basically how dynamic downcasting would work, in any case. Niko On Fri, Aug 23, 2013 at 07:49:57AM +0300, Oren Ben-Kiki wrote: > Is it possible to implement something like Haskell's Dynamic value holder > in Rust? (This would be similar to supporting C++'s dynamic_cast). > Basically, something like this: > > pub struct Dynamic { ... } > impl Dynamic { > pub fn put(value: ~T) { ... } > pub fn get() -> Option { ... } > } > > I guess this would require unsafe code... even so, it seems to me that Rust > pointers don't carry sufficient meta-data for the above to work. A possible > workaround would be something like: > > pub struct Dynamic { type_name: ~str, ... } > impl Dynamic { > pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: > type_name, ... } } > pub fn get(&'a self, type_name: &str) -> Option<&'a T> { > assert_eq!(type_name, self.type_name); ... } } > } > > And placing the burden on the caller to always use the type name "int" when > putting or getting `int` values, etc. This would still require some sort of > unsafe code to cast the `~T` pointer into something and back, while > ensuring that the storage for the `T` (whatever its size is) is not > released until the `Dynamic` itself is. > > (Why do I need such a monstrosity? Well, I need it to define a > `Configuration` container, which holds key/value pairs where whoever sets a > value knows its type, whoever gets the value should ask for the same type, > and the configuration can hold values of "any" type - not from a predefined > list of types). > > Is such a thing possible, and if so, how? > > Thanks, > > Oren Ben-Kiki > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From oren at ben-kiki.org Fri Aug 23 08:04:09 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Fri, 23 Aug 2013 18:04:09 +0300 Subject: [rust-dev] Dynamic in Rust In-Reply-To: <20130823134022.GB8742@Mr-Bennet> References: <20130823134022.GB8742@Mr-Bennet> Message-ID: Yes, this would be similar to the `Typeable` type class in Haskell. It queries the vtable-equivalent, which contains stuff like the name of the type and allows doing `typeof(x)`, dynamic casts, etc. This is heavily magical (that is, depends on the hidden internal representation) and properly belongs in the standard platform and not in a user-level library. On Fri, Aug 23, 2013 at 4:40 PM, Niko Matsakis wrote: > Currently, this is not directly supported, though downcasting in > general is something we have contemplated as a feature. It might be > possible to create some kind of horrible hack based on objects. A > trait like: > > trait Dynamic { } > impl Dynamic for T { } > > would allow any value to be cast to an object. The type descriptor can > then be extracted from the vtable of the object using some rather > fragile unsafe code that will doubtless break when we change the > vtable format. The real question is what you can do with the type > descriptor; they are not canonicalized, after all. Still, it's > ... very close. This is basically how dynamic downcasting would work, > in any case. > > > Niko > > On Fri, Aug 23, 2013 at 07:49:57AM +0300, Oren Ben-Kiki wrote: > > Is it possible to implement something like Haskell's Dynamic value holder > > in Rust? (This would be similar to supporting C++'s dynamic_cast). > > Basically, something like this: > > > > pub struct Dynamic { ... } > > impl Dynamic { > > pub fn put(value: ~T) { ... } > > pub fn get() -> Option { ... } > > } > > > > I guess this would require unsafe code... even so, it seems to me that > Rust > > pointers don't carry sufficient meta-data for the above to work. A > possible > > workaround would be something like: > > > > pub struct Dynamic { type_name: ~str, ... } > > impl Dynamic { > > pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: > > type_name, ... } } > > pub fn get(&'a self, type_name: &str) -> Option<&'a T> { > > assert_eq!(type_name, self.type_name); ... } } > > } > > > > And placing the burden on the caller to always use the type name "int" > when > > putting or getting `int` values, etc. This would still require some sort > of > > unsafe code to cast the `~T` pointer into something and back, while > > ensuring that the storage for the `T` (whatever its size is) is not > > released until the `Dynamic` itself is. > > > > (Why do I need such a monstrosity? Well, I need it to define a > > `Configuration` container, which holds key/value pairs where whoever > sets a > > value knows its type, whoever gets the value should ask for the same > type, > > and the configuration can hold values of "any" type - not from a > predefined > > list of types). > > > > Is such a thing possible, and if so, how? > > > > Thanks, > > > > Oren Ben-Kiki > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Fri Aug 23 09:17:58 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Fri, 23 Aug 2013 18:17:58 +0200 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> Message-ID: One question: Do you only want to retrieve the exact type that was passed in, or would you want to be able to extract an impl that matches the type actually contained ? The latter is more difficult to implement (dynamic_cast goes through hoops to check those things), but it is doable if sufficient information is encoded in the v-table. On Fri, Aug 23, 2013 at 5:04 PM, Oren Ben-Kiki wrote: > Yes, this would be similar to the `Typeable` type class in Haskell. It > queries the vtable-equivalent, which contains stuff like the name of the > type and allows doing `typeof(x)`, dynamic casts, etc. This is heavily > magical (that is, depends on the hidden internal representation) and > properly belongs in the standard platform and not in a user-level library. > > > On Fri, Aug 23, 2013 at 4:40 PM, Niko Matsakis wrote: > >> Currently, this is not directly supported, though downcasting in >> general is something we have contemplated as a feature. It might be >> possible to create some kind of horrible hack based on objects. A >> trait like: >> >> trait Dynamic { } >> impl Dynamic for T { } >> >> would allow any value to be cast to an object. The type descriptor can >> then be extracted from the vtable of the object using some rather >> fragile unsafe code that will doubtless break when we change the >> vtable format. The real question is what you can do with the type >> descriptor; they are not canonicalized, after all. Still, it's >> ... very close. This is basically how dynamic downcasting would work, >> in any case. >> >> >> Niko >> >> On Fri, Aug 23, 2013 at 07:49:57AM +0300, Oren Ben-Kiki wrote: >> > Is it possible to implement something like Haskell's Dynamic value >> holder >> > in Rust? (This would be similar to supporting C++'s dynamic_cast). >> > Basically, something like this: >> > >> > pub struct Dynamic { ... } >> > impl Dynamic { >> > pub fn put(value: ~T) { ... } >> > pub fn get() -> Option { ... } >> > } >> > >> > I guess this would require unsafe code... even so, it seems to me that >> Rust >> > pointers don't carry sufficient meta-data for the above to work. A >> possible >> > workaround would be something like: >> > >> > pub struct Dynamic { type_name: ~str, ... } >> > impl Dynamic { >> > pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: >> > type_name, ... } } >> > pub fn get(&'a self, type_name: &str) -> Option<&'a T> { >> > assert_eq!(type_name, self.type_name); ... } } >> > } >> > >> > And placing the burden on the caller to always use the type name "int" >> when >> > putting or getting `int` values, etc. This would still require some >> sort of >> > unsafe code to cast the `~T` pointer into something and back, while >> > ensuring that the storage for the `T` (whatever its size is) is not >> > released until the `Dynamic` itself is. >> > >> > (Why do I need such a monstrosity? Well, I need it to define a >> > `Configuration` container, which holds key/value pairs where whoever >> sets a >> > value knows its type, whoever gets the value should ask for the same >> type, >> > and the configuration can hold values of "any" type - not from a >> predefined >> > list of types). >> > >> > Is such a thing possible, and if so, how? >> > >> > Thanks, >> > >> > Oren Ben-Kiki >> >> > _______________________________________________ >> > Rust-dev mailing list >> > Rust-dev at mozilla.org >> > https://mail.mozilla.org/listinfo/rust-dev >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From oren at ben-kiki.org Fri Aug 23 09:19:36 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Fri, 23 Aug 2013 19:19:36 +0300 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> Message-ID: That's a really good question. In my specific case, I need the exact same type. But a "proper" implementation would presumably be able to provide "any matching type" (I believe the Haskell implementation does this). On Fri, Aug 23, 2013 at 7:17 PM, Matthieu Monrocq < matthieu.monrocq at gmail.com> wrote: > One question: > > Do you only want to retrieve the exact type that was passed in, or would > you want to be able to extract an impl that matches the type actually > contained ? > > The latter is more difficult to implement (dynamic_cast goes through hoops > to check those things), but it is doable if sufficient information is > encoded in the v-table. > > > On Fri, Aug 23, 2013 at 5:04 PM, Oren Ben-Kiki wrote: > >> Yes, this would be similar to the `Typeable` type class in Haskell. It >> queries the vtable-equivalent, which contains stuff like the name of the >> type and allows doing `typeof(x)`, dynamic casts, etc. This is heavily >> magical (that is, depends on the hidden internal representation) and >> properly belongs in the standard platform and not in a user-level library. >> >> >> On Fri, Aug 23, 2013 at 4:40 PM, Niko Matsakis wrote: >> >>> Currently, this is not directly supported, though downcasting in >>> general is something we have contemplated as a feature. It might be >>> possible to create some kind of horrible hack based on objects. A >>> trait like: >>> >>> trait Dynamic { } >>> impl Dynamic for T { } >>> >>> would allow any value to be cast to an object. The type descriptor can >>> then be extracted from the vtable of the object using some rather >>> fragile unsafe code that will doubtless break when we change the >>> vtable format. The real question is what you can do with the type >>> descriptor; they are not canonicalized, after all. Still, it's >>> ... very close. This is basically how dynamic downcasting would work, >>> in any case. >>> >>> >>> Niko >>> >>> On Fri, Aug 23, 2013 at 07:49:57AM +0300, Oren Ben-Kiki wrote: >>> > Is it possible to implement something like Haskell's Dynamic value >>> holder >>> > in Rust? (This would be similar to supporting C++'s dynamic_cast). >>> > Basically, something like this: >>> > >>> > pub struct Dynamic { ... } >>> > impl Dynamic { >>> > pub fn put(value: ~T) { ... } >>> > pub fn get() -> Option { ... } >>> > } >>> > >>> > I guess this would require unsafe code... even so, it seems to me that >>> Rust >>> > pointers don't carry sufficient meta-data for the above to work. A >>> possible >>> > workaround would be something like: >>> > >>> > pub struct Dynamic { type_name: ~str, ... } >>> > impl Dynamic { >>> > pub fn put(type_name: &str, value: ~T) { Dynamic { type_name: >>> > type_name, ... } } >>> > pub fn get(&'a self, type_name: &str) -> Option<&'a T> { >>> > assert_eq!(type_name, self.type_name); ... } } >>> > } >>> > >>> > And placing the burden on the caller to always use the type name "int" >>> when >>> > putting or getting `int` values, etc. This would still require some >>> sort of >>> > unsafe code to cast the `~T` pointer into something and back, while >>> > ensuring that the storage for the `T` (whatever its size is) is not >>> > released until the `Dynamic` itself is. >>> > >>> > (Why do I need such a monstrosity? Well, I need it to define a >>> > `Configuration` container, which holds key/value pairs where whoever >>> sets a >>> > value knows its type, whoever gets the value should ask for the same >>> type, >>> > and the configuration can hold values of "any" type - not from a >>> predefined >>> > list of types). >>> > >>> > Is such a thing possible, and if so, how? >>> > >>> > Thanks, >>> > >>> > Oren Ben-Kiki >>> >>> > _______________________________________________ >>> > Rust-dev mailing list >>> > Rust-dev at mozilla.org >>> > https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Fri Aug 23 09:31:52 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 23 Aug 2013 09:31:52 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> Message-ID: <52178E78.8000908@mozilla.com> On 8/23/13 8:04 AM, Oren Ben-Kiki wrote: > Yes, this would be similar to the `Typeable` type class in Haskell. It > queries the vtable-equivalent, which contains stuff like the name of the > type and allows doing `typeof(x)`, dynamic casts, etc. This is heavily > magical (that is, depends on the hidden internal representation) and > properly belongs in the standard platform and not in a user-level library. I had always figured we'd copy Haskell's `Data.Typeable` solution more or less exactly. I think we can do it in a library though, as Niko pointed out; in general we aren't afraid of adding deep compiler-specific magic into our libraries. Patrick From danny.gratzer at gmail.com Fri Aug 23 09:44:34 2013 From: danny.gratzer at gmail.com (Danny Gratzer) Date: Fri, 23 Aug 2013 11:44:34 -0500 Subject: [rust-dev] Dynamic in Rust In-Reply-To: <52178E78.8000908@mozilla.com> References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> Message-ID: I guess it's worth pointing out GHC's -XDeriveDataTypeable language extension, this let's the compiler automatically derive the Typeable instance for user defined datatypes. If you want to copy Data.Typeable having something (a macro?) to automagically implemented Typeable goes a long way to aiding usability. I'm not sure if an equivalent to Haskell's `derive` exists in Rust. I'm rather new here :) Cheers, Danny Gratzer -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Fri Aug 23 09:49:29 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 23 Aug 2013 09:49:29 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> Message-ID: <52179299.5050605@mozilla.com> On 8/23/13 9:44 AM, Danny Gratzer wrote: > I guess it's worth pointing out GHC's -XDeriveDataTypeable language > extension, this let's the compiler automatically derive the Typeable > instance for user defined datatypes. If you want to copy Data.Typeable > having something (a macro?) to automagically implemented Typeable goes a > long way to aiding usability. > > I'm not sure if an equivalent to Haskell's `derive` exists in Rust. I'm > rather new here :) Yes, it's called #[deriving] and is a syntax extension. I was assuming that we'd implement it for `Typeable`. Patrick From oren at ben-kiki.org Fri Aug 23 09:49:28 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Fri, 23 Aug 2013 19:49:28 +0300 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> Message-ID: Yes, Rust has a `deriving` attribute one can attach to types (for stuff like `Eq`, `Ord`, etc.). That said, as long as the vtable is already there, I think Rust should do what Haskell is moving to (automatically `derive Typeable`) - that is, automatically place the necessary data in the vtable. Haskell does place a restriction on _using_ the data, though. One must explicitly request the type T has the trait `Typeable` in order to invoke functionality that uses the data. Even though "all types" implement this trait, this explicitly warns the caller that "this function may do strange things". I'm not sure what the right choice would be in Rust here. On Fri, Aug 23, 2013 at 7:44 PM, Danny Gratzer wrote: > I guess it's worth pointing out GHC's -XDeriveDataTypeable language > extension, this let's the compiler automatically derive the Typeable > instance for user defined datatypes. If you want to copy Data.Typeable > having something (a macro?) to automagically implemented Typeable goes a > long way to aiding usability. > > I'm not sure if an equivalent to Haskell's `derive` exists in Rust. I'm > rather new here :) > > > Cheers, > Danny Gratzer > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Aug 23 10:50:02 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 23 Aug 2013 10:50:02 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> Message-ID: <5217A0CA.6040902@mozilla.com> On 13-08-23 09:49 AM, Oren Ben-Kiki wrote: > Yes, Rust has a `deriving` attribute one can attach to types (for stuff > like `Eq`, `Ord`, etc.). > > That said, as long as the vtable is already there, I think Rust should > do what Haskell is moving to (automatically `derive Typeable`) - that > is, automatically place the necessary data in the vtable. Every type descriptor has a visitor-glue method written into it, which provides typeable-like structural reflection (std::reflect) on types, but not (presently) efficient type-equality. We'd need to augment it slightly to provide that, but I think it'd be possible. This code is used in fmt! for example to support printing arbitrary values (std::repr). -Graydon From oren at ben-kiki.org Fri Aug 23 11:08:41 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Fri, 23 Aug 2013 21:08:41 +0300 Subject: [rust-dev] Dynamic in Rust In-Reply-To: <5217A0CA.6040902@mozilla.com> References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> <5217A0CA.6040902@mozilla.com> Message-ID: Interesting - I see std::intrinsics::unstable::get_tydescr -> *TyDescr... Two questions: - Can this be used for a quick type equality check (same pointer <=> same type)? - How can one invoke `get_tydescr()` or `get_tydescr` (when `T` is a type parameter of the current function)? I get a syntax error on the `int` or `T`. On Fri, Aug 23, 2013 at 8:50 PM, Graydon Hoare wrote: > On 13-08-23 09:49 AM, Oren Ben-Kiki wrote: > > Yes, Rust has a `deriving` attribute one can attach to types (for stuff > > like `Eq`, `Ord`, etc.). > > > > That said, as long as the vtable is already there, I think Rust should > > do what Haskell is moving to (automatically `derive Typeable`) - that > > is, automatically place the necessary data in the vtable. > > Every type descriptor has a visitor-glue method written into it, which > provides typeable-like structural reflection (std::reflect) on types, > but not (presently) efficient type-equality. We'd need to augment it > slightly to provide that, but I think it'd be possible. This code is > used in fmt! for example to support printing arbitrary values (std::repr). > > -Graydon > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Aug 23 11:15:08 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 23 Aug 2013 11:15:08 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> <5217A0CA.6040902@mozilla.com> Message-ID: <5217A6AC.4080608@mozilla.com> On 13-08-23 11:08 AM, Oren Ben-Kiki wrote: > Interesting - I see std::intrinsics::unstable::get_tydescr -> *TyDescr... > > Two questions: > > - Can this be used for a quick type equality check (same pointer <=> > same type)? No, as I said, it does not support efficient type-equality. We don't normalize all types. You should be able to count on one-way equality at the moment (same pointer => same type) but not vice-versa. > - How can one invoke `get_tydescr()` or `get_tydescr` (when `T` > is a type parameter of the current function)? I get a syntax error on > the `int` or `T`. get_tydesc::(). This is the foo<> vs foo::<> syntax papercut. Gets everyone, sorry. It's the price of using <> for type parameters rather than []. We need a better error message for it. -Graydon From pwalton at mozilla.com Fri Aug 23 11:16:20 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 23 Aug 2013 11:16:20 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: <5217A6AC.4080608@mozilla.com> References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> <5217A0CA.6040902@mozilla.com> <5217A6AC.4080608@mozilla.com> Message-ID: <5217A6F4.3070402@mozilla.com> On 8/23/13 11:15 AM, Graydon Hoare wrote: > get_tydesc::(). This is the foo<> vs foo::<> syntax papercut. Gets > everyone, sorry. It's the price of using <> for type parameters rather > than []. We need a better error message for it. Actually, [] would have the same problem, because of array indexing. Patrick From oren at ben-kiki.org Fri Aug 23 11:17:54 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Fri, 23 Aug 2013 21:17:54 +0300 Subject: [rust-dev] Dynamic in Rust In-Reply-To: <5217A6AC.4080608@mozilla.com> References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> <5217A0CA.6040902@mozilla.com> <5217A6AC.4080608@mozilla.com> Message-ID: Got it, thanks. I guess that the TyDescr could be extended in the future to support type equality and other things. In the meanwhile, in my case I'll have the user manually annotate the Dynamic with an (interned) string containing the type name, and pray people don't mess it up. Thanks! On Fri, Aug 23, 2013 at 9:15 PM, Graydon Hoare wrote: > On 13-08-23 11:08 AM, Oren Ben-Kiki wrote: > > Interesting - I see std::intrinsics::unstable::get_tydescr -> > *TyDescr... > > > > Two questions: > > > > - Can this be used for a quick type equality check (same pointer <=> > > same type)? > > No, as I said, it does not support efficient type-equality. We don't > normalize all types. You should be able to count on one-way equality at > the moment (same pointer => same type) but not vice-versa. > > > - How can one invoke `get_tydescr()` or `get_tydescr` (when `T` > > is a type parameter of the current function)? I get a syntax error on > > the `int` or `T`. > > get_tydesc::(). This is the foo<> vs foo::<> syntax papercut. Gets > everyone, sorry. It's the price of using <> for type parameters rather > than []. We need a better error message for it. > > -Graydon > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Aug 23 11:22:41 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 23 Aug 2013 11:22:41 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: <5217A6F4.3070402@mozilla.com> References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> <5217A0CA.6040902@mozilla.com> <5217A6AC.4080608@mozilla.com> <5217A6F4.3070402@mozilla.com> Message-ID: <5217A871.1030807@mozilla.com> On 13-08-23 11:16 AM, Patrick Walton wrote: > On 8/23/13 11:15 AM, Graydon Hoare wrote: >> get_tydesc::(). This is the foo<> vs foo::<> syntax papercut. Gets >> everyone, sorry. It's the price of using <> for type parameters rather >> than []. We need a better error message for it. > > Actually, [] would have the same problem, because of array indexing. Naturally, which is why array indexing (way back when) was foo.(index). But it was a throwaway comment; this is all very much water under the bridge, not in any way suggesting we revisit. -Graydon From masklinn at masklinn.net Fri Aug 23 11:28:26 2013 From: masklinn at masklinn.net (Masklinn) Date: Fri, 23 Aug 2013 20:28:26 +0200 Subject: [rust-dev] Augmented assignment In-Reply-To: References: Message-ID: On 23 ao?t 2013, at 12:44, Chris Morgan wrote: > https://github.com/mozilla/rust/issues/5992 > > (Coming from a Python background I know the concept as augmented > assignment; they are also known as assignment operators. Or just +=, > ^=, <<= and the like.) > > I want augmented assignment in Rust for all types, so I had a crack at > implementing this. I have an implementation mostly complete in my > augmented-assignment branch > (https://github.com/chris-morgan/rust/compare/augmented-assignment), > but even if I managed to convince the Rust side of rustc that I was > competent, LLVM called my bluff. > > The last state of my branch and what appears to be wrong (extra > argument going to the LLVM Call) is documented in #5992. > > Is there anyone who would be able to look at my patch and get it to > work (or even figure out just where the wrong is)? I just rebased it > and so it is up to date, but if left for another few weeks it > doubtless will continue to bitrot. For the record, I think augmented assignments are a terrible ideas and one of the worst features of python. From graydon at mozilla.com Fri Aug 23 11:36:43 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 23 Aug 2013 11:36:43 -0700 Subject: [rust-dev] Augmented assignment In-Reply-To: References: Message-ID: <5217ABBB.9020202@mozilla.com> On 13-08-23 11:28 AM, Masklinn wrote: > For the record, I think augmented assignments are a terrible ideas and one of the worst features of python. Could you say more (perhaps more constructively)? I believe we have every intention to support these sorts of overloads longer-term; we removed the previous support only because it wasn't done terribly well. -Graydon From bill_myers at outlook.com Fri Aug 23 11:41:42 2013 From: bill_myers at outlook.com (Bill Myers) Date: Fri, 23 Aug 2013 18:41:42 +0000 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com>, <5213DF35.7050100@mozilla.com>, , Message-ID: > > 2. Distribute compilations and tests across a cluster of machines (like > > distcc) > > > > Compilation is 99% serial (the only things that happen in parallel > are rustpkg and rustdoc etc at the end, and they are almost nothing), > though tests could be distributed (and Graydon is working on doing > that afaik). Are you sure? I'm not an expert on rustc implementation, but I'd expect you could have a sequence of parallel phases and "collection" points: specifically I'd guess you could parse all files in parallel, and once you have the AST for all files, do checking and typing in parallel, and then do codegen in parallel. For comparison, C/C++ can do everything except linking in parallel, except for parsing header files if not using precompiled headers (which is still parallel but repeated for each file); linking can be parallelized to some extent on a single machine with gold. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Fri Aug 23 11:47:42 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Fri, 23 Aug 2013 20:47:42 +0200 Subject: [rust-dev] Augmented assignment In-Reply-To: <5217ABBB.9020202@mozilla.com> References: <5217ABBB.9020202@mozilla.com> Message-ID: On Fri, Aug 23, 2013 at 8:36 PM, Graydon Hoare wrote: > On 13-08-23 11:28 AM, Masklinn wrote: > > > For the record, I think augmented assignments are a terrible ideas and > one of the worst features of python. > > Could you say more (perhaps more constructively)? I believe we have > every intention to support these sorts of overloads longer-term; we > removed the previous support only because it wasn't done terribly well. > > -Graydon > > Not masklinn, but coming from C++ I have seen operator overloading gone wrong. The most trivial mistake is to have `+=` and `+` defined so that `a += 5` has a different result than `a = a + 5`; the error can be subtle, and is generally hard to catch because you expect it to be right (about the same issue than `bool operator<(left, right) { return left.a < right.a && left.b < right.b; }`). If one wants to introduce assignment operators, then, it would be great if this issue was taken care of. It might not be easy though. Especially because of some peculiar issues, such as the fact that `+` can take a constant on either side but `+=` requires a mutable on the left-hand side. I hope you'll have great ideas. -- Matthieu > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From arteme at gmail.com Fri Aug 23 11:52:49 2013 From: arteme at gmail.com (Artem Egorkine) Date: Fri, 23 Aug 2013 21:52:49 +0300 Subject: [rust-dev] Augmented assignment In-Reply-To: References: Message-ID: Augmented assignments are not unique to python. They are found in C, Java, Perl, Go, Ruby, JavaScript etc. One could argue that if they were so terrible, they would never have made it to so many programming languages.... On Aug 23, 2013 9:28 PM, "Masklinn" wrote: > > On 23 ao?t 2013, at 12:44, Chris Morgan wrote: > > > https://github.com/mozilla/rust/issues/5992 > > > > (Coming from a Python background I know the concept as augmented > > assignment; they are also known as assignment operators. Or just +=, > > ^=, <<= and the like.) > > > > I want augmented assignment in Rust for all types, so I had a crack at > > implementing this. I have an implementation mostly complete in my > > augmented-assignment branch > > (https://github.com/chris-morgan/rust/compare/augmented-assignment), > > but even if I managed to convince the Rust side of rustc that I was > > competent, LLVM called my bluff. > > > > The last state of my branch and what appears to be wrong (extra > > argument going to the LLVM Call) is documented in #5992. > > > > Is there anyone who would be able to look at my patch and get it to > > work (or even figure out just where the wrong is)? I just rebased it > > and so it is up to date, but if left for another few weeks it > > doubtless will continue to bitrot. > > For the record, I think augmented assignments are a terrible ideas and one of the worst features of python. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Aug 23 11:55:22 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 23 Aug 2013 11:55:22 -0700 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com>, <5213DF35.7050100@mozilla.com>, , Message-ID: <5217B01A.3090305@mozilla.com> On 13-08-23 11:41 AM, Bill Myers wrote: >> > 2. Distribute compilations and tests across a cluster of machines (like >> > distcc) >> > >> >> Compilation is 99% serial (the only things that happen in parallel >> are rustpkg and rustdoc etc at the end, and they are almost nothing), >> though tests could be distributed (and Graydon is working on doing >> that afaik). > > Are you sure? Pretty sure: - We essentially always do whole-program / link-time optimization in C++ terminology. That is, we run a whole crate through LLVM at once. Which _would_ be ok (I think!) if we weren't generating quite so much code. It is an AOT/runtime trade but one we consciously designed-in to the language. - We are self-hosted so always bootstrap. Stage N comes before stage N+1. Likewise when we cross compile, host comes before target. We have 3 stages and when doing an all-cross it grows to 9. You can't do those in any more parallel. - Parsing, type checking and similar middle-end passes could probably be parallelized eventually -- they were designed to support this in principle -- but in practice it would require a lot of rearchitecture. Also: these aren't the major speed points (possibly with the exception of typechecking, it's a _little_ bottleneck). Here's a normal compile phase-timing: $ rustc -O -Z time-passes syntax.rs time: 0.334 s parsing time: 0.002 s std macros injection time: 0.062 s configuration 1 time: 0.355 s expansion time: 0.109 s configuration 2 time: 0.107 s maybe building test harness time: 0.106 s std injection time: 0.113 s ast indexing time: 0.122 s external crate/lib resolution time: 0.011 s language item collection time: 0.779 s resolution time: 0.000 s looking for entry point time: 0.029 s freevar finding time: 0.064 s region resolution time: 0.017 s region parameterization inference time: 0.059 s type collecting time: 0.241 s coherence checking time: 5.623 s type checking time: 0.153 s const marking time: 0.013 s const checking time: 0.060 s privacy checking time: 0.021 s effect checking time: 0.010 s loop checking time: 0.021 s stack checking time: 0.170 s compute moves time: 0.073 s match checking time: 0.104 s liveness checking time: 0.478 s borrow checking time: 0.068 s kind checking time: 0.028 s reachability checking time: 0.103 s lint checking time: 3.974 s translation time: 33.939 s LLVM passes time: 0.080 s linking As you can see, LLVM dominates. We generate a lot of code (I pointed to several clear culprits at the head of this email thread). -Graydon From kmcallister at mozilla.com Fri Aug 23 12:11:59 2013 From: kmcallister at mozilla.com (Keegan McAllister) Date: Fri, 23 Aug 2013 12:11:59 -0700 (PDT) Subject: [rust-dev] Augmented assignment In-Reply-To: References: Message-ID: <1651884468.1027452.1377285119503.JavaMail.zimbra@mozilla.com> Putting a 'null' value in every type is also a popular language feature, but it's a bad one and Rust deliberately does something different, for safety. Argument by feature popularity doesn't mean much in a world where most languages are just some new syntax for the same (often broken) concepts. As for this specific case, I think allowing overloading += makes sense, but I don't feel strongly. keegan ----- Original Message ----- From: "Artem Egorkine" To: "Masklinn" Cc: rust-dev at mozilla.org Sent: Friday, August 23, 2013 11:52:49 AM Subject: Re: [rust-dev] Augmented assignment Augmented assignments are not unique to python. They are found in C, Java, Perl, Go, Ruby, JavaScript etc. One could argue that if they were so terrible, they would never have made it to so many programming languages.... On Aug 23, 2013 9:28 PM, "Masklinn" < masklinn at masklinn.net > wrote: > > On 23 ao?t 2013, at 12:44, Chris Morgan < me at chrismorgan.info > wrote: > > > https://github.com/mozilla/rust/issues/5992 > > > > (Coming from a Python background I know the concept as augmented > > assignment; they are also known as assignment operators. Or just +=, > > ^=, <<= and the like.) > > > > I want augmented assignment in Rust for all types, so I had a crack at > > implementing this. I have an implementation mostly complete in my > > augmented-assignment branch > > ( https://github.com/chris-morgan/rust/compare/augmented-assignment ), > > but even if I managed to convince the Rust side of rustc that I was > > competent, LLVM called my bluff. > > > > The last state of my branch and what appears to be wrong (extra > > argument going to the LLVM Call) is documented in #5992. > > > > Is there anyone who would be able to look at my patch and get it to > > work (or even figure out just where the wrong is)? I just rebased it > > and so it is up to date, but if left for another few weeks it > > doubtless will continue to bitrot. > > For the record, I think augmented assignments are a terrible ideas and one of the worst features of python. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From simon.sapin at exyr.org Fri Aug 23 12:16:00 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Fri, 23 Aug 2013 20:16:00 +0100 Subject: [rust-dev] Augmented assignment In-Reply-To: References: <5217ABBB.9020202@mozilla.com> Message-ID: <5217B4F0.4000006@exyr.org> Le 23/08/2013 19:47, Matthieu Monrocq a ?crit : > The most trivial mistake is to have `+=` and `+` defined so that `a += > 5` has a different result than `a = a + 5` Would it work to make `a += b` always expand to `a = a + b`, and have that not be overridable? Or am I missing something else? -- Simon Sapin From graydon at mozilla.com Fri Aug 23 12:21:02 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 23 Aug 2013 12:21:02 -0700 Subject: [rust-dev] Augmented assignment In-Reply-To: <5217B4F0.4000006@exyr.org> References: <5217ABBB.9020202@mozilla.com> <5217B4F0.4000006@exyr.org> Message-ID: <5217B61E.8080603@mozilla.com> On 13-08-23 12:16 PM, Simon Sapin wrote: > Le 23/08/2013 19:47, Matthieu Monrocq a ?crit : >> The most trivial mistake is to have `+=` and `+` defined so that `a += >> 5` has a different result than `a = a + 5` > > Would it work to make `a += b` always expand to `a = a + b`, and have > that not be overridable? Or am I missing something else? Generally these operators want to be able to implement optimized versions that do not produce and destroy temporaries. This might be a bit less of an issue when you're working with moved values, but that just (pardon the pun) moves the implementation challenge elsewhere: making sure that plus(&a,&b) as you'd have on non-owned values is the same as plus(a,b) on owned-and-moved values. It's all a bit subtle. -Graydon From robin.kruppe at gmail.com Fri Aug 23 12:23:53 2013 From: robin.kruppe at gmail.com (Robin Kruppe) Date: Fri, 23 Aug 2013 21:23:53 +0200 Subject: [rust-dev] Augmented assignment In-Reply-To: <5217ABBB.9020202@mozilla.com> References: <5217ABBB.9020202@mozilla.com> Message-ID: On Fri, Aug 23, 2013 at 8:36 PM, Graydon Hoare wrote: > On 13-08-23 11:28 AM, Masklinn wrote: > >> For the record, I think augmented assignments are a terrible ideas and one of the worst features of python. > > Could you say more (perhaps more constructively)? I believe we have > every intention to support these sorts of overloads longer-term; we > removed the previous support only because it wasn't done terribly well. Another Python guy here, I feel similar though I wouldn't word it as strongly. The problem with += *overloads* is that its sole motivation, a += b not being simple syntactic sugar for a = a + b, is also very confusing. At least that's the problem in the context of Python. I don't know enough Rust to decide off-hand whether these points also apply to Rust, so I'll use Python examples: Suppose a is a list, b is another list, and c is any non-list iterable (e.g. a tuple which is basically an immutable list). One inconsistency is that a + c throws an exception but a += c works just fine (both work with b in place of c). Another, more tricky, difference is due to Python's data model where everything is a reference type and aliasable. Generally, a = a + b constructs a new and the list a referred to before isn't affected. In contrast, a += b mutates the list a refers to. This is important if the list aliased - e.g., passed a parameter, stored as a field of an object, or something similar. At least the latter of these two inconsistencies applies to several other collection types as well (standard library and third party). Now, of course this behaviour is intentional and quite useful - it's the sole reason there is a += overload in the first place (instead of not defining __iadd__, which means a += b really is equivalent to a = a + b). But it's also quite unexpected for most people, and although I've never been bitten by it personally (I'm try hard not to alias mutable data), it's not hard to see this causing tricky bugs. But then again, the only reason it can be observed at all is aliasing of mutable data. I'm not sure how likely that is in Rust. From lindsey at composition.al Fri Aug 23 12:58:38 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Fri, 23 Aug 2013 15:58:38 -0400 Subject: [rust-dev] Augmented assignment In-Reply-To: References: Message-ID: On Fri, Aug 23, 2013 at 2:28 PM, Masklinn wrote: > For the record, I think augmented assignments are a terrible ideas and one of the worst features of python. rust-dev is probably not the right place for this sort of conversation; several points of the code of conduct (https://github.com/mozilla/rust/wiki/Note-development-policy#conduct) could apply here. In any case, the OP is asking a question about a multi-hundred-line WIP patch on a long-standing bug that has already been nominated and accepted for a maturity milestone. Let's respect the effort they've made, and take it seriously. Lindsey From bill_myers at outlook.com Fri Aug 23 13:16:46 2013 From: bill_myers at outlook.com (Bill Myers) Date: Fri, 23 Aug 2013 20:16:46 +0000 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: <5217B01A.3090305@mozilla.com> References: <5213DE50.6040705@gmail.com>, <5213DF35.7050100@mozilla.com>, , , <5217B01A.3090305@mozilla.com> Message-ID: > - We essentially always do whole-program / link-time optimization > in C++ terminology. That is, we run a whole crate through LLVM at > once. Which _would_ be ok (I think!) if we weren't generating > quite so much code. It is an AOT/runtime trade but one we > consciously designed-in to the language. > time: 33.939 s LLVM passes Maybe this should be changed to optionally do codegen and LLVM passes in parallel, producing an LLVM or native module for each Rust file, and then linking the modules together into the compiled crate. Alternatively, there seems to be some work on running LLVM FunctionPasses in parallel at http://llvm.1065342.n5.nabble.com/LLVM-Dev-Discussion-Function-based-parallel-LLVM-backend-code-generation-td59384.html but it doesn't seem production-ready. Most large C/C++ projects rely on parallel make and distcc to have reasonable build times, and it seems something that Rust needs to support (either via make/distcc or internally) to be a viable replacement for large projects. -------------- next part -------------- An HTML attachment was scrubbed... URL: From sebastian.sylvan at gmail.com Fri Aug 23 15:11:37 2013 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Fri, 23 Aug 2013 15:11:37 -0700 Subject: [rust-dev] Augmented assignment In-Reply-To: <5217B61E.8080603@mozilla.com> References: <5217ABBB.9020202@mozilla.com> <5217B4F0.4000006@exyr.org> <5217B61E.8080603@mozilla.com> Message-ID: On Fri, Aug 23, 2013 at 12:21 PM, Graydon Hoare wrote: > On 13-08-23 12:16 PM, Simon Sapin wrote: > > Le 23/08/2013 19:47, Matthieu Monrocq a ?crit : > >> The most trivial mistake is to have `+=` and `+` defined so that `a += > >> 5` has a different result than `a = a + 5` > > > > Would it work to make `a += b` always expand to `a = a + b`, and have > > that not be overridable? Or am I missing something else? > > Generally these operators want to be able to implement optimized > versions that do not produce and destroy temporaries. > I sympathize with this point, however I think it should be achieved in by means of something like the GHC RULES pragma[1] where programmers are allowed to tell the compiler about simple optimizations (rewrite rules), in their modules. So if you're doing a math module you could detect a*b+c and change it to a fmadd using a rule, and if there's an earlier pass that expands a+=b to a=a+b, you could then have a rules pragma that says a=a+b rewrites to an in-place add. In practice, rewrite rules have been extraordinarily powerful and pretty much essential in certain cases. E.g. efficient stream processing (stream fusion) relies on it. [1] http://www.haskell.org/ghc/docs/latest/html/users_guide/rewrite-rules.html -- Sebastian Sylvan -------------- next part -------------- An HTML attachment was scrubbed... URL: From rexlen at gmail.com Fri Aug 23 15:42:35 2013 From: rexlen at gmail.com (Renato Lenzi) Date: Sat, 24 Aug 2013 00:42:35 +0200 Subject: [rust-dev] Compile error Message-ID: Hi there. I've installed Rust 7 on Windows 7. I'm trying to compile this simple code: fn sum (x: int, y : int) -> int { x + y } fn main() { let x =sum(2, 3); io::println(int::to_str(x)); } but i get: 00015.rs:9:13: 9:24 error: unresolved name 00015.rs:9 io::println(int::to_str(x)); ^~~~~~~~~~~ 00015.rs:9:13: 9:24 error: use of undeclared module `int` 00015.rs:9 io::println(int::to_str(x)); ^~~~~~~~~~~ 00015.rs:9:13: 9:24 error: unresolved name `int::to_str`. 00015.rs:9 io::println(int::to_str(x)); ^~~~~~~~~~~ 00015.rs:9:1: 9:12 error: unresolved name 00015.rs:9 io::println(int::to_str(x)); ^~~~~~~~~~~ 00015.rs:9:1: 9:12 error: use of undeclared module `io` 00015.rs:9 io::println(int::to_str(x)); ^~~~~~~~~~~ 00015.rs:9:1: 9:12 error: unresolved name `io::println`. 00015.rs:9 io::println(int::to_str(x)); ^~~~~~~~~~~ error: aborting due to 6 previous errors I used, until yesterday, Rust 06 and it was all ok. Any ideas on how to fix this problem? Thx. -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Fri Aug 23 15:44:02 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Fri, 23 Aug 2013 15:44:02 -0700 Subject: [rust-dev] Compile error In-Reply-To: References: Message-ID: On Fri, Aug 23, 2013 at 3:42 PM, Renato Lenzi wrote: > Hi there. I've installed Rust 7 on Windows 7. I'm trying to compile this > simple code: > > fn sum (x: int, y : int) -> int > { > x + y > } > > fn main() > { > let x =sum(2, 3); > io::println(int::to_str(x)); > } > > but i get: > > 00015.rs:9:13: 9:24 error: unresolved name > 00015.rs:9 io::println(int::to_str(x)); > ^~~~~~~~~~~ > 00015.rs:9:13: 9:24 error: use of undeclared module `int` > 00015.rs:9 io::println(int::to_str(x)); > ^~~~~~~~~~~ > 00015.rs:9:13: 9:24 error: unresolved name `int::to_str`. > 00015.rs:9 io::println(int::to_str(x)); > ^~~~~~~~~~~ > 00015.rs:9:1: 9:12 error: unresolved name > 00015.rs:9 io::println(int::to_str(x)); > ^~~~~~~~~~~ > 00015.rs:9:1: 9:12 error: use of undeclared module `io` > 00015.rs:9 io::println(int::to_str(x)); > ^~~~~~~~~~~ > 00015.rs:9:1: 9:12 error: unresolved name `io::println`. > 00015.rs:9 io::println(int::to_str(x)); > ^~~~~~~~~~~ > error: aborting due to 6 previous errors > > I used, until yesterday, Rust 06 and it was all ok. > Any ideas on how to fix this problem? In Rust 0.7 you have to import standard library modules explicitly. If you add the following line at the beginning: use std::io; it should compile. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Being queer is not about a right to privacy; it is about the freedom to be public, to just be who we are." -- anonymous, June 1990 From sully at msully.net Fri Aug 23 16:54:01 2013 From: sully at msully.net (Michael Sullivan) Date: Fri, 23 Aug 2013 16:54:01 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: <5217A871.1030807@mozilla.com> References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> <5217A0CA.6040902@mozilla.com> <5217A6AC.4080608@mozilla.com> <5217A6F4.3070402@mozilla.com> <5217A871.1030807@mozilla.com> Message-ID: So, as it turns out, something closely related can be implemented in completely safe rust. (The ideas here are based on http://mlton.org/UniversalType and the presentation of extensible types from my undergrad PL class. The implementation is based on the mlton UniversalType page, but I change the interface to be more like extensible types. If anybody cares, SML code for this is https://gist.github.com/msullivan/6324908.) We can implement a universal type that values of any (cloneable, not containing borrowed pointers) type can be injected to. The catch is that the values aren't actually keyed by the type, but by "tags" that are generated at runtime. This is sometimes useful (you can distinguish between different classes of values of the same type) and sometimes annoying (you have to manage the tags). The implementation here is pretty clever, but also kind of silly. It would probably actually be better in practice to do something unsafe internally with dynamically generated tag values. mod ClosureUniversal { // A value of universal type is a pair of functions. store will // write the underlying value into the associated tag, while clear // will erase the data in the tag to prevent space leaks. pub struct Univ { priv store: @fn(), priv clear: @fn() } // A tag is a mutable option used as a scratch space to write // into when inspecting a tag. pub struct Tag
{ priv r: @mut Option } pub fn new_tag() -> Tag { Tag { r: @mut None } } pub fn inject(tag: Tag, x: A) -> Univ { Univ { store: || *tag.r = Some(x.clone()), clear: || *tag.r = None } } pub fn project(tag: Tag, x: Univ) -> Option { // Cause the value to be written into its tag. If the universal // value was injected with our tag, then it will be in tag.r. (x.store)(); // Read out the value. let res = (*tag.r).clone(); // Clear the value, to prevent space leaks. (x.clear)(); res } } fn main() { use ClosureUniversal::*; // Create some tags let int_tag = new_tag::(); let str_tag = new_tag::<~str>(); // Create some universal values with those tags let u1 = inject(int_tag, 5); let u2 = inject(int_tag, 6); let u3 = inject(str_tag, ~"hello, world"); // Try reading them println(fmt!("%?", project(int_tag, u1))); // Some(5) println(fmt!("%?", project(int_tag, u2))); // Some(6) println(fmt!("%?", project(int_tag, u3))); // None println(fmt!("%?", project(str_tag, u1))); // None println(fmt!("%?", project(str_tag, u2))); // None println(fmt!("%?", project(str_tag, u3))); // Some(~"hello, world") // Try out a *different* int tag. let int_tag2 = new_tag::(); // It can not be used to read things created by the other int tag println(fmt!("%?", project(int_tag2, u1))); // None } (Code is also up at https://gist.github.com/msullivan/6324973) On Fri, Aug 23, 2013 at 11:22 AM, Graydon Hoare wrote: > On 13-08-23 11:16 AM, Patrick Walton wrote: > > On 8/23/13 11:15 AM, Graydon Hoare wrote: > >> get_tydesc::(). This is the foo<> vs foo::<> syntax papercut. Gets > >> everyone, sorry. It's the price of using <> for type parameters rather > >> than []. We need a better error message for it. > > > > Actually, [] would have the same problem, because of array indexing. > > Naturally, which is why array indexing (way back when) was foo.(index). > But it was a throwaway comment; this is all very much water under the > bridge, not in any way suggesting we revisit. > > -Graydon > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sully at msully.net Fri Aug 23 17:10:44 2013 From: sully at msully.net (Michael Sullivan) Date: Fri, 23 Aug 2013 17:10:44 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: <20130823134022.GB8742@Mr-Bennet> <52178E78.8000908@mozilla.com> <5217A0CA.6040902@mozilla.com> <5217A6AC.4080608@mozilla.com> <5217A6F4.3070402@mozilla.com> <5217A871.1030807@mozilla.com> Message-ID: And here is another implementation of the same interface, implemented in a much more brute force way. It is probably more efficient that the above, and also about 5% as elegant. mod UnsafeUniversal { use std::managed; use std::cast; // We use pointers as our tags, since they are easy to generate // uniquely and compare for equality. Uniquely generated integers // might be better, but this is really simple and kind of cute. type InnerTag = @(); fn new_inner_tag() -> InnerTag { @() } fn tag_eq(x: InnerTag, y: InnerTag) -> bool { managed::ptr_eq(x, y) } pub struct Univ { tag: InnerTag, value: @() } pub struct Tag { priv inner: InnerTag } pub fn new_tag() -> Tag { Tag { inner: new_inner_tag() } } pub fn inject(tag: Tag, x: A) -> Univ { Univ { tag: tag.inner, value: unsafe { cast::transmute(@(x.clone())) } } } pub fn project(tag: Tag, x: Univ) -> Option { if tag_eq(tag.inner, x.tag) { let ptr: @A = unsafe { cast::transmute(x.value) }; Some((*ptr).clone()) } else { None } } } On Fri, Aug 23, 2013 at 4:54 PM, Michael Sullivan wrote: > So, as it turns out, something closely related can be implemented in > completely safe rust. > > (The ideas here are based on http://mlton.org/UniversalType and the > presentation of extensible types from my undergrad PL class. The > implementation is based on the mlton UniversalType page, but I change the > interface to be more like extensible types. If anybody cares, SML code for > this is https://gist.github.com/msullivan/6324908.) > > We can implement a universal type that values of any (cloneable, not > containing borrowed pointers) type can be injected to. The catch is that > the values aren't actually keyed by the type, but by "tags" that are > generated at runtime. This is sometimes useful (you can distinguish between > different classes of values of the same type) and sometimes annoying (you > have to manage the tags). > > The implementation here is pretty clever, but also kind of silly. It would > probably actually be better in practice to do something unsafe internally > with dynamically generated tag values. > > mod ClosureUniversal { > // A value of universal type is a pair of functions. store will > // write the underlying value into the associated tag, while clear > // will erase the data in the tag to prevent space leaks. > pub struct Univ { > priv store: @fn(), > priv clear: @fn() > } > > // A tag is a mutable option used as a scratch space to write > // into when inspecting a tag. > pub struct Tag { > priv r: @mut Option > } > > pub fn new_tag() -> Tag { > Tag { r: @mut None } > } > > pub fn inject(tag: Tag, x: A) -> Univ { > Univ { > store: || *tag.r = Some(x.clone()), > clear: || *tag.r = None > } > } > > pub fn project(tag: Tag, x: Univ) -> Option { > // Cause the value to be written into its tag. If the universal > // value was injected with our tag, then it will be in tag.r. > (x.store)(); > // Read out the value. > let res = (*tag.r).clone(); > // Clear the value, to prevent space leaks. > (x.clear)(); > res > } > } > > > fn main() { > use ClosureUniversal::*; > > // Create some tags > let int_tag = new_tag::(); > let str_tag = new_tag::<~str>(); > > // Create some universal values with those tags > let u1 = inject(int_tag, 5); > let u2 = inject(int_tag, 6); > let u3 = inject(str_tag, ~"hello, world"); > > // Try reading them > println(fmt!("%?", project(int_tag, u1))); // Some(5) > println(fmt!("%?", project(int_tag, u2))); // Some(6) > println(fmt!("%?", project(int_tag, u3))); // None > > println(fmt!("%?", project(str_tag, u1))); // None > println(fmt!("%?", project(str_tag, u2))); // None > println(fmt!("%?", project(str_tag, u3))); // Some(~"hello, world") > > // Try out a *different* int tag. > let int_tag2 = new_tag::(); > // It can not be used to read things created by the other int tag > println(fmt!("%?", project(int_tag2, u1))); // None > } > > (Code is also up at https://gist.github.com/msullivan/6324973) > > > On Fri, Aug 23, 2013 at 11:22 AM, Graydon Hoare wrote: > >> On 13-08-23 11:16 AM, Patrick Walton wrote: >> > On 8/23/13 11:15 AM, Graydon Hoare wrote: >> >> get_tydesc::(). This is the foo<> vs foo::<> syntax papercut. Gets >> >> everyone, sorry. It's the price of using <> for type parameters rather >> >> than []. We need a better error message for it. >> > >> > Actually, [] would have the same problem, because of array indexing. >> >> Naturally, which is why array indexing (way back when) was foo.(index). >> But it was a throwaway comment; this is all very much water under the >> bridge, not in any way suggesting we revisit. >> >> -Graydon >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sebastian.sylvan at gmail.com Fri Aug 23 17:30:43 2013 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Fri, 23 Aug 2013 17:30:43 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: On Thu, Aug 22, 2013 at 9:49 PM, Oren Ben-Kiki wrote: > Is it possible to implement something like Haskell's Dynamic value holder > in Rust? > > I'm sure you've all seen it, but C# has something similar but a lot more powerful. Basically, it has support for allowing runtime resolution of types if they are declared as having the "dynamic" type. But it's even better, the specification for how that resolution happens is defined in a library. This way you can work directly with dynamic values without having to cast them first (e.g. imagine just "dotting your way" through a JSON document and parse it on-demand). See For how it's used: http://msdn.microsoft.com/en-us/library/vstudio/dd264736.aspx For how to implement dynamic libraries (e.g. decide what happens when a field is accessed, or a method is called, on your dynamic objects): http://msdn.microsoft.com/en-us/library/vstudio/system.dynamic.dynamicobject.aspx -- Sebastian Sylvan -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Fri Aug 23 18:45:34 2013 From: corey at octayn.net (Corey Richardson) Date: Fri, 23 Aug 2013 21:45:34 -0400 Subject: [rust-dev] Compile error In-Reply-To: References: Message-ID: Additionally, io::println can now just be println, and int::to_str(x) is now x.to_str() On Fri, Aug 23, 2013 at 6:44 PM, Tim Chevalier wrote: > On Fri, Aug 23, 2013 at 3:42 PM, Renato Lenzi wrote: >> Hi there. I've installed Rust 7 on Windows 7. I'm trying to compile this >> simple code: >> >> fn sum (x: int, y : int) -> int >> { >> x + y >> } >> >> fn main() >> { >> let x =sum(2, 3); >> io::println(int::to_str(x)); >> } >> >> but i get: >> >> 00015.rs:9:13: 9:24 error: unresolved name >> 00015.rs:9 io::println(int::to_str(x)); >> ^~~~~~~~~~~ >> 00015.rs:9:13: 9:24 error: use of undeclared module `int` >> 00015.rs:9 io::println(int::to_str(x)); >> ^~~~~~~~~~~ >> 00015.rs:9:13: 9:24 error: unresolved name `int::to_str`. >> 00015.rs:9 io::println(int::to_str(x)); >> ^~~~~~~~~~~ >> 00015.rs:9:1: 9:12 error: unresolved name >> 00015.rs:9 io::println(int::to_str(x)); >> ^~~~~~~~~~~ >> 00015.rs:9:1: 9:12 error: use of undeclared module `io` >> 00015.rs:9 io::println(int::to_str(x)); >> ^~~~~~~~~~~ >> 00015.rs:9:1: 9:12 error: unresolved name `io::println`. >> 00015.rs:9 io::println(int::to_str(x)); >> ^~~~~~~~~~~ >> error: aborting due to 6 previous errors >> >> I used, until yesterday, Rust 06 and it was all ok. >> Any ideas on how to fix this problem? > > In Rust 0.7 you have to import standard library modules explicitly. If > you add the following line at the beginning: > > use std::io; > > it should compile. > > Cheers, > Tim > > -- > Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt > "Being queer is not about a right to privacy; it is about the freedom > to be public, to just be who we are." -- anonymous, June 1990 > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From matthieu.monrocq at gmail.com Sat Aug 24 03:45:40 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sat, 24 Aug 2013 12:45:40 +0200 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> <5217B01A.3090305@mozilla.com> Message-ID: Most C/C++ projects require parallel make because they lack modules. I work on medium-large projects in C++, for which we use Boost as well as about a hundred custom middleware components. A "simple" source file of ~1000 lines ends up generating a preprocessed file in the order of between 100,000 lines and 1,000,000 lines. Each and every TU. This is what makes them so amenable to parallelization. On the other hand, for languages with modules, a ~1000 lines file is a ~1000 lines file; it may depend on ~50 various other modules, but those need not be reparsed each time (a serialized version of the produced AST/ABT can be generated once and for all) and they can also be cached by the compiler (which unlike typical C compilers processes several modules in one pass). As such, there is much less gain here. On the other hand, I do agree with your command, it could possibly be better (temporarily) to run LLVM to cleanup each and every module before combining them into a single crate for optimization; however I feel that in the long term this will be useless once codegen itself is reviewed so that first and foremost a leaner IR is emitted that do not require so much cleanup to start with. -- Matthieu On Fri, Aug 23, 2013 at 10:16 PM, Bill Myers wrote: > > - We essentially always do whole-program / link-time optimization > > in C++ terminology. That is, we run a whole crate through LLVM at > > once. Which _would_ be ok (I think!) if we weren't generating > > quite so much code. It is an AOT/runtime trade but one we > > consciously designed-in to the language. > > > time: 33.939 s LLVM passes > > Maybe this should be changed to optionally do codegen and LLVM passes in > parallel, producing an LLVM or native module for each Rust file, and then > linking the modules together into the compiled crate. > > Alternatively, there seems to be some work on running LLVM FunctionPasses > in parallel at > http://llvm.1065342.n5.nabble.com/LLVM-Dev-Discussion-Function-based-parallel-LLVM-backend-code-generation-td59384.htmlbut it doesn't seem production-ready. > > Most large C/C++ projects rely on parallel make and distcc to have > reasonable build times, and it seems something that Rust needs to support > (either via make/distcc or internally) to be a viable replacement for large > projects. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jens at nockert.se Sat Aug 24 04:04:23 2013 From: jens at nockert.se (Jens Nockert) Date: Sat, 24 Aug 2013 13:04:23 +0200 Subject: [rust-dev] Rust on Arduino Due Message-ID: <7C4DF81B-B7E7-4F1A-80D8-CF83F8D301C6@nockert.se> I spent some time at the lovely Foohack hackathon, and got Rust to run on an Arduino Due. https://github.com/jensnockert/dueboot You can link to the standard Arduino libraries, so it should be about as easy to code and prototype as in C++ with a bit of work. Haven't really done anything except blinking LEDs yet, but it seems to work reasonable for that use case. It's based on the earlier armboot work, and is implemented in essentially the same way (compile for ARM into LLVM IR, then do some massaging before linking). From corey at octayn.net Sat Aug 24 04:05:51 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 24 Aug 2013 07:05:51 -0400 Subject: [rust-dev] cycle time, compile/test performance In-Reply-To: References: <5213DE50.6040705@gmail.com> <5213DF35.7050100@mozilla.com> <5217B01A.3090305@mozilla.com> Message-ID: There's an issue open for incremental compilation: https://github.com/mozilla/rust/issues/2369 On Sat, Aug 24, 2013 at 6:45 AM, Matthieu Monrocq wrote: > Most C/C++ projects require parallel make because they lack modules. I work > on medium-large projects in C++, for which we use Boost as well as about a > hundred custom middleware components. A "simple" source file of ~1000 lines > ends up generating a preprocessed file in the order of between 100,000 lines > and 1,000,000 lines. Each and every TU. This is what makes them so amenable > to parallelization. > > On the other hand, for languages with modules, a ~1000 lines file is a ~1000 > lines file; it may depend on ~50 various other modules, but those need not > be reparsed each time (a serialized version of the produced AST/ABT can be > generated once and for all) and they can also be cached by the compiler > (which unlike typical C compilers processes several modules in one pass). > > As such, there is much less gain here. > > On the other hand, I do agree with your command, it could possibly be better > (temporarily) to run LLVM to cleanup each and every module before combining > them into a single crate for optimization; however I feel that in the long > term this will be useless once codegen itself is reviewed so that first and > foremost a leaner IR is emitted that do not require so much cleanup to start > with. > > -- Matthieu > > > > On Fri, Aug 23, 2013 at 10:16 PM, Bill Myers wrote: >> >> > - We essentially always do whole-program / link-time optimization >> > in C++ terminology. That is, we run a whole crate through LLVM at >> > once. Which _would_ be ok (I think!) if we weren't generating >> > quite so much code. It is an AOT/runtime trade but one we >> > consciously designed-in to the language. >> >> > time: 33.939 s LLVM passes >> >> Maybe this should be changed to optionally do codegen and LLVM passes in >> parallel, producing an LLVM or native module for each Rust file, and then >> linking the modules together into the compiled crate. >> >> Alternatively, there seems to be some work on running LLVM FunctionPasses >> in parallel at >> http://llvm.1065342.n5.nabble.com/LLVM-Dev-Discussion-Function-based-parallel-LLVM-backend-code-generation-td59384.html >> but it doesn't seem production-ready. >> >> Most large C/C++ projects rely on parallel make and distcc to have >> reasonable build times, and it seems something that Rust needs to support >> (either via make/distcc or internally) to be a viable replacement for large >> projects. >> >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From cce at ccs.neu.edu Sat Aug 24 08:28:40 2013 From: cce at ccs.neu.edu (Carl Eastlund) Date: Sat, 24 Aug 2013 11:28:40 -0400 Subject: [rust-dev] Playing around with O(n) sorting in Rust Message-ID: Greetings, everyone. I've been trying out Rust recently and it's been a very pleasant experience. I've been getting used to the type system and the memory management semantics by implementing discriminator-based sorting, a framework for linear-time sorting of a broad range of datatypes [1]. My efforts so far can be found on github [2]. Discriminator-based parsing is based on a generic method that can be implemented for whatever ordered key type K one needs to sort: trait Disc { fn disc( &self, ~[(K,V)] ) -> ~[~[V]]; } This function sorts a set of key/value pairs. It produces an ordered list of sets; the list is produced in the order of the keys, and each set in the list contains all the values that were associated with keys in an equivalence class, although the keys themselves are stripped from the output. This turns out to be a handy signature to use for recursive sorting and to define sorting on new datatypes, but of course for external clients there is a simpler ~[T] -> ~[T] interface. The interesting part of implementing discriminators in Rust has been the trait machinery needed to implement discriminators, because for each new type one needs to implement Disc for a new K, but an arbitrary V. On the other hand, V does not stay fixed during sorting; "pieces" of the key often get shuffled off into V for sorting in subsequent passes, leading to declarations like the following: impl<'self,K:Clone,V,D:Disc,V)>> Disc<&'self[K],V> for VecDisc Here, VecDisc implements sorting for keys that are vectors of a cloneable type K, and the VecDisc must contain a type D that implements sorting for keys of type K and values that combine an iterator over K with a V -- so that after sorting on early members of a vector, one can pick up the remainder and continue lexicographic sorting. By and large, Rust's type system has had everything I've needed for a complex system like this, which is great, especially for such a new language. I've run into a few compiler bugs along the way, and reported them; the biggest showstopper for me was recently fixed, which let me finish what I was writing, so I was happy about that. :) The one thing I might want, if I were to play around with the design of this library a little more, is something more like Haskell's type classes without the OO flavor of traits. That is, the ability to write a generic interface like Disc without a singular "receiver" type. By and large types like VecDisc above are useless placeholders. I have to say things like VecDisc(IntDisc).disc(my_vectors), when I'd really rather just say disc(my_vectors) and let the type system find the instantiation for vectors of integers. I don't know of a good way to make this into my_vectors.disc() because the type of my_vectors isn't an arbitrary type parameter, it's always ~[(K,V)]. Of course its entirely possible I can do what I need with Rust as-is, but if so I haven't found the right way yet. The code as I've written it is just a piece of exploratory programming, it's not really set up as a reusable library yet. There are no public definitions, no documentation, no tests, several useful tools for building new discriminators haven't been added, and I haven't benchmarked it at all. I suspect, though technically O(n), discriminator-based sorting is likely not the best for Rust users in general. It isn't in place, it does lots of allocation, and it doesn't make good use of locality. I'll probably run benchmarks in the near future to see how good it is or isn't, and whether its log(n) speed-up pays for its constant factors or not. Anyway, thanks very much to everyone developing Rust, this is a really exciting language and I plan to keep playing around with it to see what's new. -- Carl Eastlund [1] Henglein, ICFP '08: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.154.2018 [2] http://github.com/carl-eastlund/rusty/blob/master/trait.rs -------------- next part -------------- An HTML attachment was scrubbed... URL: From armin.ronacher at active-4.com Sat Aug 24 14:53:00 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sat, 24 Aug 2013 22:53:00 +0100 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: <52192B3C.6020507@active-4.com> Hi, On 24/08/2013 01:30, Sebastian Sylvan wrote: > I'm sure you've all seen it, but C# has something similar but a lot more > powerful. Dynamic in C# is beautiful. It's an amazing way to work with externally controlled data like JSON that is without equivalent in a strongly typed language currently. I'm not sure how much of that Rust can reproduce, but if there is any way it has a strong +1 from me. Regards, Armin From armin.ronacher at active-4.com Sat Aug 24 15:00:41 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Sat, 24 Aug 2013 23:00:41 +0100 Subject: [rust-dev] Augmented assignment In-Reply-To: <5217ABBB.9020202@mozilla.com> References: <5217ABBB.9020202@mozilla.com> Message-ID: <52192D09.3010607@active-4.com> Hi, On 23/08/2013 19:36, Graydon Hoare wrote: > Could you say more (perhaps more constructively)? I believe we have > every intention to support these sorts of overloads longer-term; we > removed the previous support only because it wasn't done terribly well. I think augmented assignments in Python are fine, but they do have some edge cases. The most famous one (as this is generally brought up as Python WTF on various parts of the interwebs) is the one where a mutable element within an immutable structure is modified: >>> a = ([42],) >>> a[0] += [23] Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment >>> a ([42, 23],) The reason for this is that `a[0] += [23]` expands to `type(a[0]).__iadd__(a[0], [23])` but afterwards a[0] is overridden with a[0]. Aside from that I believe += and friends are just fine. Some people raised concern that `a = a + [2]` makes a new list but `a += [2]` modifies a list in place, but I think that is pretty obvious from looking at the code. Regards, Armin From lindsey at composition.al Sat Aug 24 21:50:28 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Sun, 25 Aug 2013 00:50:28 -0400 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: On Fri, Aug 23, 2013 at 8:30 PM, Sebastian Sylvan wrote: > I'm sure you've all seen it, but C# has something similar but a lot more > powerful. Basically, it has support for allowing runtime resolution of types > if they are declared as having the "dynamic" type. But it's even better, the > specification for how that resolution happens is defined in a library. This > way you can work directly with dynamic values without having to cast them > first (e.g. imagine just "dotting your way" through a JSON document and > parse it on-demand). A more recent approach to this kind of thing is F# type providers (http://msdn.microsoft.com/en-us/library/hh156509.aspx and, for instance, http://fsharp.github.io/FSharp.Data/library/JsonProvider.html). Although I'm not especially familiar with them, they seem relevant and interesting. Lindsey From daetalusun at gmail.com Sun Aug 25 06:39:57 2013 From: daetalusun at gmail.com (Sun) Date: Sun, 25 Aug 2013 21:39:57 +0800 Subject: [rust-dev] rust-0.7 windows build and run Message-ID: <001801cea198$9b728e40$d257aac0$@gmail.com> Hi there, On my Linux computer, rust can work well. But on windows, the rustc could not run, the error message is "The application was unable to start correctly (0xc0000142). Click OK to close the application. Win 8 x64 Mingw 4.7.2 x86(downgrade the libthread for rust) It seem the problem occurs since rust-0.5 and do not fixed it yet? If I try to build rust for myself, for a common reason(I think it is because the GFW, I am a Chinese), we can not connect to the archive server. So the stage0 is failed. How to fix it? Thanks! Regards Sun -------------- next part -------------- An HTML attachment was scrubbed... URL: From eugals at gmail.com Sun Aug 25 07:20:47 2013 From: eugals at gmail.com (Evgeny Sologubov) Date: Sun, 25 Aug 2013 18:20:47 +0400 Subject: [rust-dev] rust-0.7 windows build and run In-Reply-To: <001801cea198$9b728e40$d257aac0$@gmail.com> References: <001801cea198$9b728e40$d257aac0$@gmail.com> Message-ID: <174472482.20130825182047@GMail.Com> On 25 ??????? 2013 ?. 17:39:57 Sun wrote: > Win 8 x64 > Mingw 4.7.2 x86(downgrade the libthread for rust) I managed to make both rust 0.7 from the installer (http://static.rust-lang.org/dist/rust-0.7-install.exe) and rust 0.8-pre-stage0 (~/GitHub/rust/i686-pc-mingw32/stage0/bin) running on my Win7x64 by providing access to these 3 DLLs from the freshly installed MinGW's bin/ directory: - libgcc_s_dw2-1.dll - libstdc++-6.dll - pthreadGC2.dll v 2.9.0.0 RENAMED to libpthread-2.dll. (rust 0.7+ don't seem to work with libpthread==2.8.0-3 anymore) Maybe this solution can work in your case as well. I also had a weird security restriction somehow applied to /stage0/bin/rustc.exe (and causing the 0xc0000022 error). I don't think it's your case, but just for the record I must say that It was probably caused by the Cygwin's python2.7 version I used during the rust build process. Switching to official Python 2.7 for Windows fixes this issue. -- Evgeny From sebastian.sylvan at gmail.com Sun Aug 25 10:29:59 2013 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Sun, 25 Aug 2013 10:29:59 -0700 Subject: [rust-dev] Dynamic in Rust In-Reply-To: References: Message-ID: On Sat, Aug 24, 2013 at 9:50 PM, Lindsey Kuper wrote: > On Fri, Aug 23, 2013 at 8:30 PM, Sebastian Sylvan > wrote: > > I'm sure you've all seen it, but C# has something similar but a lot more > > powerful. Basically, it has support for allowing runtime resolution of > types > > if they are declared as having the "dynamic" type. But it's even better, > the > > specification for how that resolution happens is defined in a library. > This > > way you can work directly with dynamic values without having to cast them > > first (e.g. imagine just "dotting your way" through a JSON document and > > parse it on-demand). > > A more recent approach to this kind of thing is F# type providers > (http://msdn.microsoft.com/en-us/library/hh156509.aspx and, for > instance, http://fsharp.github.io/FSharp.Data/library/JsonProvider.html). > Although I'm not especially familiar with them, they seem relevant > and interesting. > > > I think they're partially non-overlapping approaches. Type providers is about providing static types to dynamic data. I.e. someone has to write down a schema. C# dynamic is about just dealing with dynamic data on the fly. E.g. you could just open up any old JSON doc and start accessing members. The two approaches are probably used for the same thing, much of the time, but there are occasions where you can't define a static type for something, so having an approach where you can do the runtime checks in a less verbose fashion is nice (which I don't think the F# type providers thing does). -- Sebastian Sylvan -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sun Aug 25 15:18:31 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 25 Aug 2013 18:18:31 -0400 Subject: [rust-dev] This Week in Rust Message-ID: Content from http://cmr.github.io/blog/2013/08/25/this-week-in-rust/ -- Hello and welcome to the 12th issue of *This Week in Rust*. Sorry for the brevity, though most weeks are probably going to be like this, as I've started uni and have much less free time than in the summer. # What's cooking in master? A whopping 71 pull requests were merged this week, and issue churn remains negative at -32. ## Breaking changes - [**`yield` is now reserved as a keyword**](https://github.com/mozilla/rust/pull/8560), with the hope of maybe using it for generators. - [The type of `extern fn foo` is now `extern "C" fn`, rather than `*u8`](https://github.com/mozilla/rust/pull/8666). - [Some free functions in `extra::json` were turned into associated functions on the Json enum](https://github.com/mozilla/rust/pull/8679). - [`XorShiftRng::new()` now uses a random seed](https://github.com/mozilla/rust/pull/8558). This is only breaking if you were depending on that constant seed, which you shouldn't have. ## Library changes - [`extra::getopts` aligns based on codepoint count and not byte count](https://github.com/mozilla/rust/pull/8710), as a step towards more correct unicode handling. - [`fprintf` has been added, as well as some `ifmt` cleanup](https://github.com/mozilla/rust/pull/8637). [The new runtime has seen a lot of optimization](https://github.com/mozilla/rust/pull/8740). - [File IO has been added to the new runtime](https://github.com/mozilla/rust/pull/8655). - [Some parsing errors related to ports have been fixed in `extra::url`](https://github.com/mozilla/rust/pull/8616). - [CharIterator has seen some optimization too, with reverse iterators being much closer in performance to forward iterators now](https://github.com/mozilla/rust/pull/8590). - [sysconf named have been added for android](https://github.com/mozilla/rust/pull/8602). - [The new runtime now has threadsafe IO](https://github.com/mozilla/rust/pull/8631). - [A callback optimization has sped up message passing benchmarks to the tune of 40%](https://github.com/mozilla/rust/pull/8566). - [jemalloc is back](https://github.com/mozilla/rust/pull/8584). ## Compiler changes - [gnueabihf actually uses hard floats now](https://github.com/mozilla/rust/pull/8736). - [Frame pointer elimination is no longer disabled](https://github.com/mozilla/rust/pull/8695). - [Some debuginfo fixes landed](https://github.com/mozilla/rust/pull/8684). Supposedly, libstd can now be compiled with `-Z debug-info`. Yay! - [Stack unwinding on 32-bit windows now works](https://github.com/mozilla/rust/pull/8596). This is a major step forward for Windows support, I'm very excited to see it land. - [A handful of default method bugs have been fixed](https://github.com/mozilla/rust/pull/8659). - [Inheriting from kinds now sorta works](https://github.com/mozilla/rust/pull/8562), you can do `trait Foo: Freeze`, for example. - [Supertrait methods can now be used from a trait object](https://github.com/mozilla/rust/pull/8519). - The rest of pnkfelix's visitor trait rewrite series landed. [2](https://github.com/mozilla/rust/pull/8539), [3](https://github.com/mozilla/rust/pull/8619), [4](https://github.com/mozilla/rust/pull/8623), and [5](https://github.com/mozilla/rust/pull/8638). - [Foreign function wrappers have been removed](https://github.com/mozilla/rust/pull/8535). - [LLVM has been updated](https://github.com/mozilla/rust/pull/8328). ## Docs etc - [A new condition tutorial has been added](https://github.com/mozilla/rust/pull/8563). - [Some docs for trait bounds have been added](https://github.com/mozilla/rust/pull/8725). # Meeting The [Tuesday meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-08-20) discussed cycle time and how to fix it. # Projects and discussion - [gl-rs](https://github.com/bjz/gl-rs) is now ready for use, since the foreign function wrappers have been removed! - [msgpack-rust](https://github.com/omasanori/msgpack-rust) has been created. It ties into `extra::serialize`. - [A template for Arduino Due projects](https://github.com/jensnockert/dueboot). - [Parallel cross-language level generation benchmarks](http://www.reddit.com/r/rust/comments/1kxz7y/benchmarks_round_two_parallel_go_rust_d_scala_and/). - [A Week with Rust](http://www.reddit.com/r/rust/comments/1ktjrw/a_week_with_mozillas_rust/). From corey at octayn.net Sun Aug 25 18:59:10 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 25 Aug 2013 21:59:10 -0400 Subject: [rust-dev] Doc comment conventions + straw poll Message-ID: Currently there are a few conventions throughout the codebase, and I think we need to agree which one to use, at least in the stdlib and compilers. This email is the result of me needing to encode some heuristics in rustdoc_ng to strip out the comments and keep the text. So the major conventions I've seen are: A: /*! Summary Body text */ B: /** * Summary * * Body text */ C: //! Summary //! //! Body text Of course, /*! and //! are interchangable with /** and ///. Now, I don't particularly care which one gets picked (B is my favorite for longer blocks, C for <= 3 lines), and I especially dislike A, but consistency is king. From bjzaba at yahoo.com.au Sun Aug 25 19:25:20 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Mon, 26 Aug 2013 12:25:20 +1000 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: Message-ID: brson and the Style Guide seem to favour stacked line comments: https://github.com/mozilla/rust/wiki/Note-style-guide#comments "Reason: it avoids the debate about whether to put stars on every line, etc." is an important point. I was trying to standardise std::num to style C when I was working on it. I would be happy if A and B were removed. /* */ is still useful for commenting out code though, but not for doc comments. ~Brendan On 26/08/2013, at 11:59 AM, Corey Richardson wrote: > Currently there are a few conventions throughout the codebase, and I > think we need to agree which one to use, at least in the stdlib and > compilers. This email is the result of me needing to encode some > heuristics in rustdoc_ng to strip out the comments and keep the text. > > So the major conventions I've seen are: > > A: > > /*! Summary > > Body text > > */ > > B: > > /** > * Summary > * > * Body text > */ > > C: > > //! Summary > //! > //! Body text > > Of course, /*! and //! are interchangable with /** and ///. Now, I > don't particularly care which one gets picked (B is my favorite for > longer blocks, C for <= 3 lines), and I especially dislike A, but > consistency is king. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From corey at octayn.net Sun Aug 25 19:25:35 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 25 Aug 2013 22:25:35 -0400 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: Message-ID: On Sun, Aug 25, 2013 at 9:59 PM, Corey Richardson wrote: > Of course, /*! and //! are interchangable with /** and ///. To clarify, they are stylistically interchangable, not functionally interchangable. The ! applies it to the parent item rather than the following item. From vadimcn at gmail.com Sun Aug 25 23:46:02 2013 From: vadimcn at gmail.com (Vadim) Date: Sun, 25 Aug 2013 23:46:02 -0700 Subject: [rust-dev] rust-0.7 windows build and run In-Reply-To: <001801cea198$9b728e40$d257aac0$@gmail.com> References: <001801cea198$9b728e40$d257aac0$@gmail.com> Message-ID: Did you downgrade your GCC as well? https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust#more-info-for-windows-users https://github.com/mozilla/rust/issues/5878#issuecomment-22838907 On Sun, Aug 25, 2013 at 6:39 AM, Sun wrote: > Hi there,**** > > On my Linux computer, rust can work well. But on windows, the rustc could > not run, the error message is "The application was unable to start > correctly (0xc0000142). Click OK to close the application.**** > > ** ** > > Win 8 x64**** > > Mingw 4.7.2 x86(downgrade the libthread for rust)**** > > ** ** > > It seem the problem occurs since rust-0.5 and do not fixed it yet?**** > > ** ** > > If I try to build rust for myself, for a common reason(I think it is > because the GFW, I am a Chinese), we can not connect to the archive server. > So the stage0 is failed. How to fix it?**** > > ** ** > > Thanks!**** > > Regards**** > > Sun**** > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From daetalusun at gmail.com Mon Aug 26 00:42:17 2013 From: daetalusun at gmail.com (Sun) Date: Mon, 26 Aug 2013 15:42:17 +0800 Subject: [rust-dev] =?gb2312?b?tPC4tDogIHJ1c3QtMC43IHdpbmRvd3MgYnVpbGQg?= =?gb2312?b?YW5kIHJ1bg==?= In-Reply-To: References: <001801cea198$9b728e40$d257aac0$@gmail.com> Message-ID: <001d01cea22f$cd778d90$6866a8b0$@gmail.com> After I downgrade my GCC, and upgrade the libpthread again, it work fine now. Thank you and others! ???: Vadim [mailto:vadimcn at gmail.com] ????: 2013?8?26? 14:46 ???: Sun ??: rust-dev at mozilla.org ??: Re: [rust-dev] rust-0.7 windows build and run Did you downgrade your GCC as well? https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust#mo re-info-for-windows-users https://github.com/mozilla/rust/issues/5878#issuecomment-22838907 On Sun, Aug 25, 2013 at 6:39 AM, Sun > wrote: Hi there, On my Linux computer, rust can work well. But on windows, the rustc could not run, the error message is "The application was unable to start correctly (0xc0000142). Click OK to close the application. Win 8 x64 Mingw 4.7.2 x86(downgrade the libthread for rust) It seem the problem occurs since rust-0.5 and do not fixed it yet? If I try to build rust for myself, for a common reason(I think it is because the GFW, I am a Chinese), we can not connect to the archive server. So the stage0 is failed. How to fix it? Thanks! Regards Sun _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.boggiano at seld.be Mon Aug 26 00:59:15 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 26 Aug 2013 09:59:15 +0200 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: Message-ID: <521B0AD3.1090504@seld.be> On 26.08.2013 04:25, Brendan Zabarauskas wrote: > brson and the Style Guide seem to favour stacked line comments: https://github.com/mozilla/rust/wiki/Note-style-guide#comments > > "Reason: it avoids the debate about whether to put stars on every line, etc." is an important point. That's sort of a valid point indeed, but since we are just doing a style guide from scratch and it's all fairly new ground, if the style guide says "use style B" it also avoids the debate I would say. Anyway my take on it is that C annoys me extremely because my editor does not support it. Regular // or B-style blocks get handled automatically and I can just type away and new lines are formatted as is. C seems to be unique to Rust (?), and poor editor support + being uncommon makes it inferior IMO. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From j.boggiano at seld.be Mon Aug 26 01:03:28 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 26 Aug 2013 10:03:28 +0200 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <521B0AD3.1090504@seld.be> References: <521B0AD3.1090504@seld.be> Message-ID: <521B0BD0.1000105@seld.be> On 26.08.2013 09:59, Jordi Boggiano wrote: > Anyway my take on it is that C annoys me extremely because my editor > does not support it. Regular // or B-style blocks get handled > automatically and I can just type away and new lines are formatted as > is. C seems to be unique to Rust (?), and poor editor support + being > uncommon makes it inferior IMO. A quick search (too late I know:) shows it's a doxygen and C# thing. That'd explain why I never saw it before. My point about editor support still stands though. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From corey at octayn.net Mon Aug 26 04:13:24 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 26 Aug 2013 07:13:24 -0400 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <521B0BD0.1000105@seld.be> References: <521B0AD3.1090504@seld.be> <521B0BD0.1000105@seld.be> Message-ID: On Mon, Aug 26, 2013 at 4:03 AM, Jordi Boggiano wrote: > On 26.08.2013 09:59, Jordi Boggiano wrote: >> Anyway my take on it is that C annoys me extremely because my editor >> does not support it. Regular // or B-style blocks get handled >> automatically and I can just type away and new lines are formatted as >> is. C seems to be unique to Rust (?), and poor editor support + being >> uncommon makes it inferior IMO. > > A quick search (too late I know:) shows it's a doxygen and C# thing. > That'd explain why I never saw it before. My point about editor support > still stands though. > For what it's worth the vim file handles it well. From j.boggiano at seld.be Mon Aug 26 05:51:23 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Mon, 26 Aug 2013 14:51:23 +0200 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: <521B0AD3.1090504@seld.be> <521B0BD0.1000105@seld.be> Message-ID: <521B4F4B.80007@seld.be> On 26.08.2013 13:13, Corey Richardson wrote: > On Mon, Aug 26, 2013 at 4:03 AM, Jordi Boggiano wrote: >> On 26.08.2013 09:59, Jordi Boggiano wrote: >>> Anyway my take on it is that C annoys me extremely because my editor >>> does not support it. Regular // or B-style blocks get handled >>> automatically and I can just type away and new lines are formatted as >>> is. C seems to be unique to Rust (?), and poor editor support + being >>> uncommon makes it inferior IMO. >> >> A quick search (too late I know:) shows it's a doxygen and C# thing. >> That'd explain why I never saw it before. My point about editor support >> still stands though. >> > > For what it's worth the vim file handles it well. Alright alright. Less bitching, more fixing! Sublime Text also handles it well now :) https://github.com/spadgos/sublime-jsdocs/pull/215 Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From armin.ronacher at active-4.com Mon Aug 26 06:21:08 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 26 Aug 2013 14:21:08 +0100 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: Message-ID: <521B5644.9000401@active-4.com> Hi, On 26/08/2013 02:59, Corey Richardson wrote: > C: The nice thing about this solution is that with the whitespace after the three slashes it lines up perfectly with 4 spaces which means the tab key continues working properly with the current rust style of 4 space indentation. This is very useful for nested code in comments. Regards, Armin From niko at alum.mit.edu Mon Aug 26 07:07:34 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Mon, 26 Aug 2013 10:07:34 -0400 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: Message-ID: <20130826140734.GC22367@Mr-Bennet> I find I have surprisingly strong opinions about this. In particular, I don't care for any of the options. Rather I prefer option D, which looks like: fn foo() { /*! * Summary * * Body text */ } My reasoning: - I want the comment INSIDE the function, not outside. Putting the comment outside obscures the names and arguments. My typical use case is browsing code, and I find it very helpful to be able to skim over the names and prototypes, and only dive into the documentation as needed (you'll note that when people render the docs in HTML, they lead with the function name and arguments and only provide the full text when you click on the function). - Option C (`//!`) also places the comments inside, but I just don't like it: I find the repeated `!` is hard to read. - For modules, if there is a long comment, I prefer to move the comment to a distinct `doc.rs` file. All complex modules SHOULD have a long comment introducing them at a high-level; submodules should not (e.g., `borrowck` needs a comment, but `borrowck::check_loans` does not). It is quite possible I am alone in these preferences though. =) Niko On Sun, Aug 25, 2013 at 09:59:10PM -0400, Corey Richardson wrote: > Currently there are a few conventions throughout the codebase, and I > think we need to agree which one to use, at least in the stdlib and > compilers. This email is the result of me needing to encode some > heuristics in rustdoc_ng to strip out the comments and keep the text. > > So the major conventions I've seen are: > > A: > > /*! Summary > > Body text > > */ > > B: > > /** > * Summary > * > * Body text > */ > > C: > > //! Summary > //! > //! Body text > > Of course, /*! and //! are interchangable with /** and ///. Now, I > don't particularly care which one gets picked (B is my favorite for > longer blocks, C for <= 3 lines), and I especially dislike A, but > consistency is king. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From bjzaba at yahoo.com.au Mon Aug 26 08:54:35 2013 From: bjzaba at yahoo.com.au (Brendan Zabarauskas) Date: Tue, 27 Aug 2013 01:54:35 +1000 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <521B5644.9000401@active-4.com> References: <521B5644.9000401@active-4.com> Message-ID: <9E793E78-58B5-497B-ABD4-87D06E9CB6C0@yahoo.com.au> I definitely find this very lovely. Lining up with the tab stops perfectly is a big plus. ~Brendan On 26/08/2013, at 11:21 PM, Armin Ronacher wrote: > Hi, > > On 26/08/2013 02:59, Corey Richardson wrote: >> C: > The nice thing about this solution is that with the whitespace after the three slashes it lines up perfectly with 4 spaces which means the tab key continues working properly with the current rust style of 4 space indentation. This is very useful for nested code in comments. > > > Regards, > Armin > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From graydon at mozilla.com Mon Aug 26 09:59:21 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 26 Aug 2013 09:59:21 -0700 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: Message-ID: <521B8969.1020503@mozilla.com> On 13-08-25 07:25 PM, Brendan Zabarauskas wrote: > brson and the Style Guide seem to favour stacked line comments: https://github.com/mozilla/rust/wiki/Note-style-guide#comments > > "Reason: it avoids the debate about whether to put stars on every line, etc." is an important point. I was trying to standardise std::num to style C when I was working on it. I would be happy if A and B were removed. /* */ is still useful for commenting out code though, but not for doc comments. There were a couple other arguments in favour of //-style: - Consistency: one-line comments invariably start this way; switching style at some threshold makes for yet another axis of inconsistency. - Non-nesting of /**/: to keep our lexical grammar regular, /**/ do not nest. This means that if someone wants to comment-out a block with /**/ (rather than ignore!()) they cannot do so if it has /**/-style comments inside it, only //-style. Personally I don't have a strong opinion but I am habitually very poor at documenting my code, so even if I did it probably shouldn't count :( -Graydon From banderson at mozilla.com Mon Aug 26 12:53:07 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 26 Aug 2013 12:53:07 -0700 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <20130826140734.GC22367@Mr-Bennet> References: <20130826140734.GC22367@Mr-Bennet> Message-ID: <521BB223.1050505@mozilla.com> On 08/26/2013 07:07 AM, Niko Matsakis wrote: > I find I have surprisingly strong opinions about this. In particular, > I don't care for any of the options. Rather I prefer option D, which > looks like: > > fn foo() { > /*! > * Summary > * > * Body text > */ > } I like this too in theory. There was some reason I never did it though - probably emacs mode was treating it incorrectly or something. That's the same reason I made all those awful-looking doc comments like /** Foo bar */ I tend to just do whatever is auto-formatted correctly. From corey at octayn.net Mon Aug 26 12:54:30 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 26 Aug 2013 15:54:30 -0400 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <20130826140734.GC22367@Mr-Bennet> References: <20130826140734.GC22367@Mr-Bennet> Message-ID: On Mon, Aug 26, 2013 at 10:07 AM, Niko Matsakis wrote: > It is quite possible I am alone in these preferences though. =) > Yeah, I think I prefer D to the others as well. I didn't see it in any of the code I went through. From armin.ronacher at active-4.com Mon Aug 26 14:11:44 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 26 Aug 2013 22:11:44 +0100 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <20130826140734.GC22367@Mr-Bennet> References: <20130826140734.GC22367@Mr-Bennet> Message-ID: <521BC490.4020808@active-4.com> Hi, On 26/08/2013 15:07, Niko Matsakis wrote: > I find I have surprisingly strong opinions about this. In particular, > I don't care for any of the options. Rather I prefer option D, which > looks like: To be honest, I think moving docs into the function body is the strongest point of Python's docstrings. Primarily because they implicitly nest away with the function and if you quickly search for a function (def funcname) you don't skip past the docs. I kinda wish "/// " was for the parent object and the only way to document things, but I can see how people don't like that. That would also make it work automatically the same for modules and functions and no confusion about different documentation comments would arise. Generally though, I think it would look very clean: pub struct HashMap { /// A hash map implementation which uses linear probing along /// with the SipHash hash function for internal state. This means /// that the order of all hash maps is randomized by keying each /// hash map randomly on creation. priv k0: u64, priv k1: u64, priv resize_at: uint, priv size: uint, priv buckets: ~[Option>], } impl HashMap { #[inline] fn expand(&mut self) { /// Expand the capacity of the array to the next power of two /// and re-insert each of the existing buckets. let new_capacity = self.buckets.len() * 2; self.resize(new_capacity); } } Regards, Armin From kevin at sb.org Mon Aug 26 14:27:34 2013 From: kevin at sb.org (Kevin Ballard) Date: Mon, 26 Aug 2013 14:27:34 -0700 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <521BC490.4020808@active-4.com> References: <20130826140734.GC22367@Mr-Bennet> <521BC490.4020808@active-4.com> Message-ID: <06C2E568-1A92-44A9-9A08-0D2F3CD593E3@sb.org> If /// was for the parent and the only way to document things, that would make it rather problematic to document struct fields and statics. -Kevin On Aug 26, 2013, at 2:11 PM, Armin Ronacher wrote: > Hi, > > On 26/08/2013 15:07, Niko Matsakis wrote: >> I find I have surprisingly strong opinions about this. In particular, >> I don't care for any of the options. Rather I prefer option D, which >> looks like: > To be honest, I think moving docs into the function body is the strongest point of Python's docstrings. Primarily because they implicitly nest away with the function and if you quickly search for a function (def funcname) you don't skip past the docs. > > I kinda wish "/// " was for the parent object and the only way to document things, but I can see how people don't like that. That would also make it work automatically the same for modules and functions and no confusion about different documentation comments would arise. > > Generally though, I think it would look very clean: > > > pub struct HashMap { > /// A hash map implementation which uses linear probing along > /// with the SipHash hash function for internal state. This means > /// that the order of all hash maps is randomized by keying each > /// hash map randomly on creation. > priv k0: u64, > priv k1: u64, > priv resize_at: uint, > priv size: uint, > priv buckets: ~[Option>], > } > > impl HashMap { > > #[inline] > fn expand(&mut self) { > /// Expand the capacity of the array to the next power of two > /// and re-insert each of the existing buckets. > let new_capacity = self.buckets.len() * 2; > self.resize(new_capacity); > } > } > > > Regards, > Armin > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From armin.ronacher at active-4.com Mon Aug 26 14:31:05 2013 From: armin.ronacher at active-4.com (Armin Ronacher) Date: Mon, 26 Aug 2013 22:31:05 +0100 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <06C2E568-1A92-44A9-9A08-0D2F3CD593E3@sb.org> References: <20130826140734.GC22367@Mr-Bennet> <521BC490.4020808@active-4.com> <06C2E568-1A92-44A9-9A08-0D2F3CD593E3@sb.org> Message-ID: <521BC919.8060706@active-4.com> Hi, On 26/08/2013 22:27, Kevin Ballard wrote: > If /// was for the parent and the only way to document things, that > would make it rather problematic to document struct fields and statics. That's a good point. In Python "#:" is generally used for documenting of things of that sort. Somehow my mind missed that. Regards, Armin From flaper87 at gmail.com Mon Aug 26 14:36:29 2013 From: flaper87 at gmail.com (Flaper87) Date: Mon, 26 Aug 2013 23:36:29 +0200 Subject: [rust-dev] Augmented assignment In-Reply-To: <52192D09.3010607@active-4.com> References: <5217ABBB.9020202@mozilla.com> <52192D09.3010607@active-4.com> Message-ID: 2013/8/25 Armin Ronacher > Hi, > > > On 23/08/2013 19:36, Graydon Hoare wrote: > >> Could you say more (perhaps more constructively)? I believe we have >> every intention to support these sorts of overloads longer-term; we >> removed the previous support only because it wasn't done terribly well. >> > I think augmented assignments in Python are fine, but they do have some > edge cases. The most famous one (as this is generally brought up as Python > WTF on various parts of the interwebs) is the one where a mutable element > within an immutable structure is modified: > > >>> a = ([42],) > >>> a[0] += [23] > Traceback (most recent call last): > File "", line 1, in > TypeError: 'tuple' object does not support item assignment > >>> a > ([42, 23],) > > The reason for this is that `a[0] += [23]` expands to > `type(a[0]).__iadd__(a[0], [23])` but afterwards a[0] is overridden with > a[0]. > > Aside from that I believe += and friends are just fine. Some people > raised concern that `a = a + [2]` makes a new list but `a += [2]` modifies > a list in place, but I think that is pretty obvious from looking at the > code. > I also think Python's argumented assignments are fine and both a += b vs a + b should behave differently. I personally read a += b as an atomic, thread-safe operation whereas a + b isn't and I beleive that's the way it shoud be. Expanding a += b to a + b doesn't sound right to me. Anyway, that's my $0.02. FF -- Flavio (@flaper87) Percoco http://www.flaper87.org http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From flaper87 at gmail.com Mon Aug 26 14:45:03 2013 From: flaper87 at gmail.com (Flaper87) Date: Mon, 26 Aug 2013 23:45:03 +0200 Subject: [rust-dev] Augmented assignment In-Reply-To: References: <5217ABBB.9020202@mozilla.com> <52192D09.3010607@active-4.com> Message-ID: 2013/8/26 Flaper87 > argumented augmented* T_T -- Flavio (@flaper87) Percoco http://www.flaper87.org http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Mon Aug 26 14:46:21 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 26 Aug 2013 17:46:21 -0400 Subject: [rust-dev] Augmented assignment In-Reply-To: References: <5217ABBB.9020202@mozilla.com> <52192D09.3010607@active-4.com> Message-ID: On Mon, Aug 26, 2013 at 5:36 PM, Flaper87 wrote: > I also think Python's argumented assignments are fine and both a += b vs a + > b should behave differently. I personally read a += b as an atomic, > thread-safe operation whereas a + b isn't and I beleive that's the way it > shoud be. Expanding a += b to a + b doesn't sound right to me. > > Anyway, that's my $0.02. > > FF In C/C++/Python/Rust, `+=` isn't an atomic operation. Although, in the safe subset of Rust code there's no way to race on mutable data due to the inability to share it without locking. From flaper87 at gmail.com Mon Aug 26 14:58:29 2013 From: flaper87 at gmail.com (Flaper87) Date: Mon, 26 Aug 2013 23:58:29 +0200 Subject: [rust-dev] Augmented assignment In-Reply-To: References: <5217ABBB.9020202@mozilla.com> <52192D09.3010607@active-4.com> Message-ID: 2013/8/26 Daniel Micay > On Mon, Aug 26, 2013 at 5:36 PM, Flaper87 wrote: > > I also think Python's argumented assignments are fine and both a += b vs > a + > > b should behave differently. I personally read a += b as an atomic, > > thread-safe operation whereas a + b isn't and I beleive that's the way it > > shoud be. Expanding a += b to a + b doesn't sound right to me. > > > > Anyway, that's my $0.02. > > > > FF > > In C/C++/Python/Rust, `+=` isn't an atomic operation. T_T, I knew that, bad wording from my side. > Although, in the > safe subset of Rust code there's no way to race on mutable data due to > the inability to share it without locking. > I believe this is good, I wasn't sure though. FF -- Flavio (@flaper87) Percoco http://www.flaper87.org http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin at sb.org Mon Aug 26 17:39:51 2013 From: kevin at sb.org (Kevin Ballard) Date: Mon, 26 Aug 2013 17:39:51 -0700 Subject: [rust-dev] Augmented assignment In-Reply-To: References: <5217ABBB.9020202@mozilla.com> <52192D09.3010607@active-4.com> Message-ID: On Aug 26, 2013, at 2:46 PM, Daniel Micay wrote: > On Mon, Aug 26, 2013 at 5:36 PM, Flaper87 wrote: >> I also think Python's argumented assignments are fine and both a += b vs a + >> b should behave differently. I personally read a += b as an atomic, >> thread-safe operation whereas a + b isn't and I beleive that's the way it >> shoud be. Expanding a += b to a + b doesn't sound right to me. >> >> Anyway, that's my $0.02. >> >> FF > > In C/C++/Python/Rust, `+=` isn't an atomic operation. Although, in the > safe subset of Rust code there's no way to race on mutable data due to > the inability to share it without locking. My understanding of Python's GIL is that += is indeed atomic because the GIL only locks/unlocks around statements (though I don't believe this is intentional). Though this certainly isn't the case for C/C++. -Kevin From danielmicay at gmail.com Mon Aug 26 17:50:07 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 26 Aug 2013 20:50:07 -0400 Subject: [rust-dev] Augmented assignment In-Reply-To: References: <5217ABBB.9020202@mozilla.com> <52192D09.3010607@active-4.com> Message-ID: >On Mon, Aug 26, 2013 at 8:39 PM, Kevin Ballard wrote: > On Aug 26, 2013, at 2:46 PM, Daniel Micay wrote: > >> On Mon, Aug 26, 2013 at 5:36 PM, Flaper87 wrote: >>> I also think Python's argumented assignments are fine and both a += b vs a + >>> b should behave differently. I personally read a += b as an atomic, >>> thread-safe operation whereas a + b isn't and I beleive that's the way it >>> shoud be. Expanding a += b to a + b doesn't sound right to me. >>> >>> Anyway, that's my $0.02. >>> >>> FF >> >> In C/C++/Python/Rust, `+=` isn't an atomic operation. Although, in the >> safe subset of Rust code there's no way to race on mutable data due to >> the inability to share it without locking. > > My understanding of Python's GIL is that += is indeed atomic because the GIL only locks/unlocks around statements (though I don't believe this is intentional). Though this certainly isn't the case for C/C++. > > -Kevin The GIL is an implementation detail of CPython, and doesn't exist in Jython or IronPython since it's not part of the language. From robin.kruppe at gmail.com Mon Aug 26 17:57:17 2013 From: robin.kruppe at gmail.com (Robin Kruppe) Date: Tue, 27 Aug 2013 02:57:17 +0200 Subject: [rust-dev] Augmented assignment In-Reply-To: References: <5217ABBB.9020202@mozilla.com> <52192D09.3010607@active-4.com> Message-ID: On Tue, Aug 27, 2013 at 2:39 AM, Kevin Ballard wrote: [snip] > My understanding of Python's GIL is that += is indeed atomic because the GIL only locks/unlocks around statements (though I don't believe this is intentional). Though this certainly isn't the case for C/C++. No, that's incorrect. The GIL locks/unlocks around bytecodes, ans ALSO in the middle of C functions (built-in or extension module) if whoever wrote that function thought it might be beneficial. += is compiled into several bytecode ops: First load what you want to add to, then call __iadd__ (assuming it is defined) on it, then storing the result of that (usually the same object) back. The GIL might be released between any of these steps. The last step happens because __iadd__ might not be defined (__add__ is the fallback), but even if that disappeared it still wouldn't be thread-safe. All this is CPython-specific. AFAIK PyPy tries hard to match this behavior, but Jython and IronPython probably give even fewer guarantees. Threading in Python is ugly. In any case, it isn't too relevant for augmented assignment in Rust, for a broad range of reasons. From niko at alum.mit.edu Tue Aug 27 02:36:18 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 27 Aug 2013 05:36:18 -0400 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <521BB223.1050505@mozilla.com> References: <20130826140734.GC22367@Mr-Bennet> <521BB223.1050505@mozilla.com> Message-ID: <20130827093618.GA9051@Mr-Bennet> It is true that the emacs mode doesn't handle the formatting of `/*` comments correctly. The same is unforunately true of a number of edge cases; I keep meaning to try my hand at improving the indentation routine but I haven't gotten around to it. Niko On Mon, Aug 26, 2013 at 12:53:07PM -0700, Brian Anderson wrote: > On 08/26/2013 07:07 AM, Niko Matsakis wrote: > >I find I have surprisingly strong opinions about this. In particular, > >I don't care for any of the options. Rather I prefer option D, which > >looks like: > > > > fn foo() { > > /*! > > * Summary > > * > > * Body text > > */ > > } > > I like this too in theory. There was some reason I never did it > though - probably emacs mode was treating it incorrectly or > something. That's the same reason I made all those awful-looking doc > comments like > > /** Foo > > bar > */ > > I tend to just do whatever is auto-formatted correctly. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Tue Aug 27 02:44:13 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 27 Aug 2013 05:44:13 -0400 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <521BB223.1050505@mozilla.com> References: <20130826140734.GC22367@Mr-Bennet> <521BB223.1050505@mozilla.com> Message-ID: <20130827094413.GB9051@Mr-Bennet> https://github.com/mozilla/rust/issues/8787 On Mon, Aug 26, 2013 at 12:53:07PM -0700, Brian Anderson wrote: > On 08/26/2013 07:07 AM, Niko Matsakis wrote: > >I find I have surprisingly strong opinions about this. In particular, > >I don't care for any of the options. Rather I prefer option D, which > >looks like: > > > > fn foo() { > > /*! > > * Summary > > * > > * Body text > > */ > > } > > I like this too in theory. There was some reason I never did it > though - probably emacs mode was treating it incorrectly or > something. That's the same reason I made all those awful-looking doc > comments like > > /** Foo > > bar > */ > > I tend to just do whatever is auto-formatted correctly. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From oren at ben-kiki.org Tue Aug 27 07:06:35 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Tue, 27 Aug 2013 17:06:35 +0300 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: <20130827094413.GB9051@Mr-Bennet> References: <20130826140734.GC22367@Mr-Bennet> <521BB223.1050505@mozilla.com> <20130827094413.GB9051@Mr-Bennet> Message-ID: I prefer using /// for comments before functions and types, and ///! for comments following fields: /// ... pub struct Foo { foo: int, //! ... } (BTW, it would be nice to document function arguments: /// ... pub fn foo( foo: int, //! ... ) { ... } But rustdoc doesn't have the concept of a doc for an argument. Oh well.) At any rate, //! allows structs to stay compact but still document the fields, as opposed to having a /// before each one which takes double the amount of lines. I actually use /// for struct fields, because rustdoc doesn't using allow //! this way today (it says "expected outer comment"). A bug, I guess? So I only use //! at the top to document the whole module. The main reason I use //-style everywhere is that this way I can safely use /* ... */ to comment out chunks of code. I don't comment code chunks a lot, but when I need to, it is good to know one can just do it without worrying about nesting /* ... */. If /* ... */ allowed nesting, I'd probably still prefer //-style - The '*' seem visually noisy, it takes up extra lines (in multi-line comments), and I'm never comfortable when I see: /*! * foo */ Whether it would end up meaning: // * foo Or (more likely): /// foo -------------- next part -------------- An HTML attachment was scrubbed... URL: From olson.jeffery at gmail.com Tue Aug 27 08:30:14 2013 From: olson.jeffery at gmail.com (Jeffery Olson) Date: Tue, 27 Aug 2013 08:30:14 -0700 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: <20130826140734.GC22367@Mr-Bennet> <521BB223.1050505@mozilla.com> <20130827094413.GB9051@Mr-Bennet> Message-ID: I like ///, although I would like to standardize on comments before/after the method declaration. For people who know more about emacs than me: could we get rust-mode support for placing a '///' on the newline? One point in favor of putting the docs before the signature is that it'd be consistent with how comments would appear on fields.. On Tue, Aug 27, 2013 at 7:06 AM, Oren Ben-Kiki wrote: > I prefer using /// for comments before functions and types, and ///! for > comments following fields: > > /// ... > pub struct Foo { > foo: int, //! ... > } > > (BTW, it would be nice to document function arguments: > > /// ... > pub fn foo( > foo: int, //! ... > ) { > ... > } > > But rustdoc doesn't have the concept of a doc for an argument. Oh well.) > > At any rate, //! allows structs to stay compact but still document the > fields, as opposed to having a /// before each one which takes double the > amount of lines. I actually use /// for struct fields, because rustdoc > doesn't using allow //! this way today (it says "expected outer comment"). > A bug, I guess? So I only use //! at the top to document the whole module. > > The main reason I use //-style everywhere is that this way I can safely > use /* ... */ to comment out chunks of code. I don't comment code chunks a > lot, but when I need to, it is good to know one can just do it without > worrying about nesting /* ... */. > > If /* ... */ allowed nesting, I'd probably still prefer //-style - The '*' > seem visually noisy, it takes up extra lines (in multi-line comments), and > I'm never comfortable when I see: > > /*! > * foo > */ > > Whether it would end up meaning: > // * foo > > Or (more likely): > /// foo > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From flaper87 at gmail.com Tue Aug 27 08:56:11 2013 From: flaper87 at gmail.com (Flaper87) Date: Tue, 27 Aug 2013 17:56:11 +0200 Subject: [rust-dev] Doc comment conventions + straw poll In-Reply-To: References: <20130826140734.GC22367@Mr-Bennet> <521BB223.1050505@mozilla.com> <20130827094413.GB9051@Mr-Bennet> Message-ID: 2013/8/27 Jeffery Olson > I like ///, although I would like to standardize on comments before/after > the method declaration. > I'm in favor of having it in the function's body. -- Flavio (@flaper87) Percoco http://www.flaper87.org http://github.com/FlaPer87 -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at minhdo.org Mon Aug 26 09:43:46 2013 From: m at minhdo.org (Minh Do) Date: Tue, 27 Aug 2013 00:43:46 +0800 Subject: [rust-dev] Working on rusti as final year project Message-ID: <521B85C2.8060804@minhdo.org> My name is Do Nhat Minh, currently a final year Computer Science student at Nanyang Technological University in Singapore. I have played with Rust and found the experience to be very pleasant. I think Rust make sensible trade-offs and managed to stay small, compared to C++. I have been granted permission by my university supervisor to work on rusti as my final year project. I hope with this contribution, Rust will be even stronger a competitor to Go and D. This will be my first time working on something this size and this long a duration. I would love to hear your advice or experience implementing rusti. Thank you for your time. Regards, Minh From catamorphism at gmail.com Tue Aug 27 10:36:36 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Tue, 27 Aug 2013 10:36:36 -0700 Subject: [rust-dev] Working on rusti as final year project In-Reply-To: <521B85C2.8060804@minhdo.org> References: <521B85C2.8060804@minhdo.org> Message-ID: On Mon, Aug 26, 2013 at 9:43 AM, Minh Do wrote: > My name is Do Nhat Minh, currently a final year Computer Science student at > Nanyang Technological University in Singapore. I have played with Rust and > found the experience to be very pleasant. I think Rust make sensible > trade-offs and managed to stay small, compared to C++. > > I have been granted permission by my university supervisor to work on rusti > as my final year project. I hope with this contribution, Rust will be even > stronger a competitor to Go and D. > > This will be my first time working on something this size and this long a > duration. I would love to hear your advice or experience implementing rusti. > Hi, Minh -- It's great that you want to work on rusti! Making rusti easier to use is something we all want, but as far as I know none of us on the core team have time to work on it anytime soon, making it a great project for a student. If you don't already, I recommend hanging out on #rust on irc.mozilla.org. Don't be afraid to ask questions, and if you can identify the author of the code you have a question about with git blame, feel free to ask them directly on IRC. https://github.com/mozilla/rust/wiki/Note-development-policy explains how to get on the IRC channel. Feel free to ask questions here on the mailing list if you don't get an immediate answer on IRC, but IRC is the best for quick questions, and most of the Rust devs are online during working hours in the Pacific timezone. I also recommend that you document your code extensively as you go along, as well as documenting existing code when you learn about it! You will probably learn many things about existing code and you can help the next person to touch the code by writing down what you learn. There are only a few rusti bugs in the issue tracker -- https://github.com/mozilla/rust/issues?direction=desc&labels=A-rusti&milestone=&page=1&sort=created&state=open -- but I'm sure you will discover more issues to fix as you start diving into the code. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Being queer is not about a right to privacy; it is about the freedom to be public, to just be who we are." -- anonymous, June 1990 From danielmicay at gmail.com Tue Aug 27 10:45:35 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 27 Aug 2013 13:45:35 -0400 Subject: [rust-dev] Working on rusti as final year project In-Reply-To: References: <521B85C2.8060804@minhdo.org> Message-ID: On Tue, Aug 27, 2013 at 1:36 PM, Tim Chevalier wrote: > > There are only a few rusti bugs in the issue tracker -- > https://github.com/mozilla/rust/issues?direction=desc&labels=A-rusti&milestone=&page=1&sort=created&state=open > -- but I'm sure you will discover more issues to fix as you start > diving into the code. There are limitations of the current implementation since it actually recompiles the whole output each time. It would be really nice to look at what `cling` (C++ interpreter built on libclang) does and copy the strategy. From catamorphism at gmail.com Tue Aug 27 11:09:57 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Tue, 27 Aug 2013 11:09:57 -0700 Subject: [rust-dev] Inviting community contributions to rustpkg Message-ID: Hi all -- rustpkg, the nascent Rust package manager and build system, is now at the point where community contributions would be quite helpful. rustpkg is not ready for use yet by people who just want to write and distribute code in Rust, but it is ready for contributions by people who are interested in hacking on the Rust infrastructure but perhaps want to start with something a little smaller than the compiler and more-or-less self-contained (rustpkg does call into rustc as a library, but the interface is pretty limited). https://github.com/mozilla/rust/wiki/Rustpkg-schedule reflects our priorities for bugs to fix. I'm focusing my efforts on the first set of bugs on the list (those under "ready for use"), so it would be a great time for anyone interested to work on, particularly, the bugs listed under Milestones 3 and 5 on that list. If there's a bug you'd like to work on, even it's assigned to me (catamorphism on github), feel free to just leave a comment and ask if it's available to work on. Feel free to ping me on IRC (tjc) with questions. Thanks, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Being queer is not about a right to privacy; it is about the freedom to be public, to just be who we are." -- anonymous, June 1990 From bill_myers at outlook.com Tue Aug 27 15:58:43 2013 From: bill_myers at outlook.com (Bill Myers) Date: Tue, 27 Aug 2013 22:58:43 +0000 Subject: [rust-dev] Structural enums for datasort refinements Message-ID: I was reading a proposal about adding "datasort refinements" to make enum variants first-class types, and it seems to me there is a simpler and more effective way of solving the problem. The idea is that if A, B and C are types, then "A | B | C" is a "structural" enum type that can be either A, B or C. In addition, A can be implicitly converted to "A | B", "A | B" can be implicitly converted to "A | B | C", and also "(A | B) | C" and "A | (B | C)" are equivalent to "A | B | C", and finally "C | B | A" is equivalent to "A | B | C" (to support the latter, the implementation needs to sort variants in some arbitrary total order before assigning tag numbers). Furthermore, a way to bind variables to an "or" pattern is introduced to allow to convert "A | B | C" to "A | B" in the case that it holds an A or a B. This way, one can rewrite Option as a type alias like this: struct Some(T); struct None; type Option = None | Some; Which is like the current Option, but also makes None and Some first-class types. The current enum syntax can remain as syntax sugar for the above code. The only issue I see is what to do for code such as "let mut x = Some(3); x = None;": with this proposal, Some and None are separate unrelated types, so we either have this code emit an error, or x must be given the type "Some | None" automatically, which however can lead to obscure error messages if one mistakenly attempts to assign a string to it causing the type to become "Some | None | ~str" (i.e. the user might be told than a match is not exhaustive because it does not handle the "~str" case, rather than that they assigned a ~str to an Option-typed variable). It should be possible to allow this, and make the error-emitting code use heuristics to figure out whether it is more likely that the user assigned a value of the wrong type, or used an enum improperly (for example, by looking at whether the implicitly created enum type is ever written explicitly in the source, and whether the deduced structural enum type is being used in places that require a non-enum type). Alternatively, one can stipulate that only types that are structs, or that are structs marked "enum struct" or "case struct" or similar can become part of an inferred structural enum, but this seems unappealing. Note that some structural enums can change representations depending generic instantiation, since "T | int" becomes just "int" if T = int, while it is "~str | int" if T = ~str (and similar for "Some | Some"), but this should not be a problem. -------------- next part -------------- An HTML attachment was scrubbed... URL: From erick.tryzelaar at gmail.com Tue Aug 27 16:20:00 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Tue, 27 Aug 2013 16:20:00 -0700 Subject: [rust-dev] Structural enums for datasort refinements In-Reply-To: References: Message-ID: This sounds very similar to O'Caml's polymorphic variants, which you can read about here: http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html#toc36. That link goes through some of the positives and negatives with the approach. On Tue, Aug 27, 2013 at 3:58 PM, Bill Myers wrote: > I was reading a proposal about adding "datasort refinements" to make enum > variants first-class types, and it seems to me there is a simpler and more > effective way of solving the problem. > > The idea is that if A, B and C are types, then "A | B | C" is a > "structural" enum type that can be either A, B or C. > > In addition, A can be implicitly converted to "A | B", "A | B" can be > implicitly converted to "A | B | C", and also "(A | B) | C" and "A | (B | > C)" are equivalent to "A | B | C", and finally "C | B | A" is equivalent to > "A | B | C" (to support the latter, the implementation needs to sort > variants in some arbitrary total order before assigning tag numbers). > > Furthermore, a way to bind variables to an "or" pattern is introduced to > allow to convert "A | B | C" to "A | B" in the case that it holds an A or a > B. > > This way, one can rewrite Option as a type alias like this: > struct Some(T); > struct None; > > type Option = None | Some; > > Which is like the current Option, but also makes None and Some > first-class types. > > The current enum syntax can remain as syntax sugar for the above code. > > The only issue I see is what to do for code such as "let mut x = Some(3); > x = None;": with this proposal, Some and None are separate unrelated types, > so we either have this code emit an error, or x must be given the type > "Some | None" automatically, which however can lead to obscure error > messages if one mistakenly attempts to assign a string to it causing the > type to become "Some | None | ~str" (i.e. the user might be told than > a match is not exhaustive because it does not handle the "~str" case, > rather than that they assigned a ~str to an Option-typed variable). > > It should be possible to allow this, and make the error-emitting code use > heuristics to figure out whether it is more likely that the user assigned a > value of the wrong type, or used an enum improperly (for example, by > looking at whether the implicitly created enum type is ever written > explicitly in the source, and whether the deduced structural enum type is > being used in places that require a non-enum type). > > Alternatively, one can stipulate that only types that are structs, or that > are structs marked "enum struct" or "case struct" or similar can become > part of an inferred structural enum, but this seems unappealing. > > Note that some structural enums can change representations depending > generic instantiation, since "T | int" becomes just "int" if T = int, while > it is "~str | int" if T = ~str (and similar for "Some | Some"), but > this should not be a problem. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Wed Aug 28 03:13:22 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Wed, 28 Aug 2013 12:13:22 +0200 Subject: [rust-dev] Structural enums for datasort refinements In-Reply-To: References: Message-ID: <521DCD42.1060500@mozilla.com> Bill (cc'ing rust-dev)- [Executive summary: the provided proposal needs further work.] I do not know which discussion of data sort refinements you had been reading; I would have liked context about where you were coming from. I assume it was either Niko's blog post [1] or issue #1679 [2], but I would prefer not to make any assumption at all. [1]: http://smallcultfollowing.com/babysteps/blog/2012/08/24/datasort-refinements/ [2]: https://github.com/mozilla/rust/issues/1679 Some immediate thoughts: * This strikes me as an extreme change to the language, but perhaps my gut is overly conservative. -- (At first I thought you were suggesting adding headers to every struct, but then I realized that the compiler should be able to insert the tags at the points where a struct is passed into an evaluation context expecting a structural-enum. So its not as extreme a change as I had initially worried; but I still worry.) -- I think one of Niko's points in his blog post was that his proposal was not an extreme change. * You have not addressed in your proposal how you would change the match syntax to deal with non-struct variants, such as ~str or int. -- (I would probably just sidestep this by including the hypothetical stipulation that you mentioned, where only structs can be part of a structural enum; then I think the match syntax can remain largely unchanged, but see caveats with next bullet.) * Finally, I think your note at the end about generic instantiation is a bigger problem than you make it out to be. -- For example, can I actually expect to be able to write code that processes arguments of type "A | B | S(Y)" ? struct S { y: Y } fn (x: A | B | S) { match x { ... what could go here ? ..., // early case clauses, maybe to handle A S{ y: the_y } => { ... handle the_y ... }, ... and what goes here ? ... // late case clauses, maybe to handle B } } There is the issue you already pointed out, where a type variables might be instantiated to S. But could they also be instantiated to S? (Do the tags on the variants need to encode the whole type, and not just which struct it is?) And what about the poor user who didn't think about the fact that they might alias each other, and thought that all the clauses in the code for A | B| S were disjoint, but in fact they potentially overlap due to the potential aliasing, and thus the order of the cases in the above is now crucial, yes? -- Another example: Can/should I now just throw seemingly unrelated struct's into a match, in order to anticipate that the parameters will be instantiated with that struct? Consider the following: struct S { y: Y } struct T { z: Z } fn (x: A | B | S, f(ab: A | B) -> int) -> int { match x { T{ z: the_z } => { who knows, maybe A or B were instantiated with T, handle it }, S{ y: the_y } => [ ... handle the_y ... }, other => return f(other) } -- Perhaps I am misunderstanding your proposal, and your hypothetical type system would reject the T clause in the latter example, and the *only* option for handling parametric variants in structural-enums is via a catch all clause (that can pass the problem off to another function, as illustrated by the final clause in the latter example). I do not want to spend too much time trying to infer the fine details of what you propose; this e-mail may be prohibitively long as it is. I just wanted to put down my initial thoughts. It is possible that a more conservative approach would be easier for me to swallow. (And it is also possible that other developers will be enthused about tackling these issues, rather than worried.) Cheers, -Felix On 28/08/2013 00:58, Bill Myers wrote: > I was reading a proposal about adding "datasort refinements" to make > enum variants first-class types, and it seems to me there is a simpler > and more effective way of solving the problem. > > The idea is that if A, B and C are types, then "A | B | C" is a > "structural" enum type that can be either A, B or C. > > In addition, A can be implicitly converted to "A | B", "A | B" can be > implicitly converted to "A | B | C", and also "(A | B) | C" and "A | > (B | C)" are equivalent to "A | B | C", and finally "C | B | A" is > equivalent to "A | B | C" (to support the latter, the implementation > needs to sort variants in some arbitrary total order before assigning > tag numbers). > > Furthermore, a way to bind variables to an "or" pattern is introduced > to allow to convert "A | B | C" to "A | B" in the case that it holds > an A or a B. > > This way, one can rewrite Option as a type alias like this: > struct Some(T); > struct None; > > type Option = None | Some; > > Which is like the current Option, but also makes None and Some > first-class types. > > The current enum syntax can remain as syntax sugar for the above code. > > The only issue I see is what to do for code such as "let mut x = > Some(3); x = None;": with this proposal, Some and None are separate > unrelated types, so we either have this code emit an error, or x must > be given the type "Some | None" automatically, which however can > lead to obscure error messages if one mistakenly attempts to assign a > string to it causing the type to become "Some | None | ~str" > (i.e. the user might be told than a match is not exhaustive because it > does not handle the "~str" case, rather than that they assigned a ~str > to an Option-typed variable). > > It should be possible to allow this, and make the error-emitting code > use heuristics to figure out whether it is more likely that the user > assigned a value of the wrong type, or used an enum improperly (for > example, by looking at whether the implicitly created enum type is > ever written explicitly in the source, and whether the deduced > structural enum type is being used in places that require a non-enum > type). > > Alternatively, one can stipulate that only types that are structs, or > that are structs marked "enum struct" or "case struct" or similar can > become part of an inferred structural enum, but this seems unappealing. > > Note that some structural enums can change representations depending > generic instantiation, since "T | int" becomes just "int" if T = int, > while it is "~str | int" if T = ~str (and similar for "Some | > Some"), but this should not be a problem. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Wed Aug 28 05:34:19 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 28 Aug 2013 08:34:19 -0400 Subject: [rust-dev] University of Virginia using Rust in a CS course Message-ID: See here: http://www.cs.virginia.edu/~evans/cs4414-fall2013/pages/ps1.html Strikes me as a bit of a bad idea, but I'll give the professor points for audacity. Apparently they're mandating 0.7. Perhaps we should reach out and offer support to the students? If we can establish a relationship, it could offer some really interesting data on how difficult it is to grok concepts like regions and linear types for the first time. -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Wed Aug 28 05:38:31 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 28 Aug 2013 08:38:31 -0400 Subject: [rust-dev] University of Virginia using Rust in a CS course In-Reply-To: References: Message-ID: On Wed, Aug 28, 2013 at 8:34 AM, Benjamin Striegel wrote: > See here: > > http://www.cs.virginia.edu/~evans/cs4414-fall2013/pages/ps1.html > > Strikes me as a bit of a bad idea I don't think it's a bad idea, but it's definitely going to be challenging. I think it's exciting! > Perhaps we should reach out and offer support to the students? +1 From till at tillschneidereit.net Wed Aug 28 06:01:35 2013 From: till at tillschneidereit.net (Till Schneidereit) Date: Wed, 28 Aug 2013 15:01:35 +0200 Subject: [rust-dev] University of Virginia using Rust in a CS course In-Reply-To: References: Message-ID: See this mailing list thread for background: https://mail.mozilla.org/pipermail/rust-dev/2013-June/004545.html On Wed, Aug 28, 2013 at 2:38 PM, Corey Richardson wrote: > On Wed, Aug 28, 2013 at 8:34 AM, Benjamin Striegel > wrote: > > See here: > > > > http://www.cs.virginia.edu/~evans/cs4414-fall2013/pages/ps1.html > > > > Strikes me as a bit of a bad idea > > I don't think it's a bad idea, but it's definitely going to be > challenging. I think it's exciting! > > > Perhaps we should reach out and offer support to the students? > > +1 > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bill_myers at outlook.com Wed Aug 28 09:25:40 2013 From: bill_myers at outlook.com (Bill Myers) Date: Wed, 28 Aug 2013 16:25:40 +0000 Subject: [rust-dev] Structural enums for datasort refinements In-Reply-To: References: , Message-ID: The issues in O'Caml seem to be due to the fact that in O'Caml function parameter and return types are inferred, and thus "accidentally oversized" enum types can propagate through them. In Rust, they must specified by the user, so those oversized enum types will cause an error as they are passed as a parameter or return value with an user-specified type that is "smaller" than the inferred type. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bill_myers at outlook.com Wed Aug 28 10:13:44 2013 From: bill_myers at outlook.com (Bill Myers) Date: Wed, 28 Aug 2013 17:13:44 +0000 Subject: [rust-dev] x;RE: Structural enums for datasort refinements In-Reply-To: <521DCD42.1060500@mozilla.com> References: , <521DCD42.1060500@mozilla.com> Message-ID: I was talking about http://smallcultfollowing.com/babysteps/blog/2012/08/24/datasort-refinements/, which essentially introduces structural enums but only for variants belonging to the same named enum. > * This strikes me as an extreme change to the language, but perhaps my gut is overly conservative. Well, to some extent: it does indeed cause a fundamental change in type inference, since now any finite set of types can be "unified" as a structural enum type. That said, I think this needs to be done anyway in something like Matsakis' proposal, since otherwise you can't pass an x declared as "let mut x = A; if(foo) {x = B;}" to something taking a Enum[A, B] if Enum also has a C case, so it only really changes how frequently the expanded type inference would be used. BTW, it should be allowed to call impl methods, trait methods and access fields that are common to A, B, C on "A | B | C", effectively adding a new "closed" polymorphism system that can be used by just switching a types from Trait to A | B | C if the only possible Trait implementations in that code are A, B, C, with the rest of the code being unchanged. > You have not addressed in your proposal how you would change the match syntax to deal with non-struct variants, such as ~str or int. Scala uses "x: int" to match an int (or type pattern in general) an assign it to x, and "x @ " to assign x to something matched by a pattern (since Scala distinguishes between "value" patterns and type patterns). In Rust distinguishing between value and type patterns might not be necessary, so one can probably use the same character for both cases. > Do the tags on the variants need to encode the whole type, and not just which struct it is? They of course need to identify the whole type, and they probably will change numerically depending on generic instantiation if some can unify under some generic instantiations. > And what about the poor user who didn't think about the fact that they might alias each other, and > thought that all the clauses in the code for A | B| S were disjoint, but in fact they potentially overlap > due to the potential aliasing, and thus the order of the cases in the above is now crucial, yes? Well, the poor user's thought process turns out to be incorrect, since any enum including a naked type parameter is obviously not disjoint in all cases. > -- Another example: Can/should I now just throw seemingly unrelated struct's into a match, in order to > anticipate that the parameters will be instantiated with that struct? Consider the following: Yes: the compiler can potentially emit an error or warning if the match will never match under any generic instantiation. This also allows a form of internal "partial specialization" of functions, where a function can have specialized behavior for some subsets of generic instantiations. -------------- next part -------------- An HTML attachment was scrubbed... URL: From qwertie256 at gmail.com Wed Aug 28 10:19:29 2013 From: qwertie256 at gmail.com (David Piepgrass) Date: Wed, 28 Aug 2013 11:19:29 -0600 Subject: [rust-dev] Structural enums for datasort refinements Message-ID: > From: Bill Myers > > I was reading a proposal about adding "datasort refinements" to make enum > variants first-class types, and it seems to me there is a simpler and more > effective way of solving the problem. > > The idea is that if A, B and C are types, then "A | B | C" is a > "structural" enum type that can be either A, B or C. > > In addition, A can be implicitly converted to "A | B", "A | B" can be > implicitly converted to "A | B | C", and also "(A | B) | C" and "A | (B | > C)" are equivalent to "A | B | C", and finally "C | B | A" is equivalent to > "A | B | C" (to support the latter, the implementation needs to sort > variants in some arbitrary total order before assigning tag numbers). > > Furthermore, a way to bind variables to an "or" pattern is introduced to > allow to convert "A | B | C" to "A | B" in the case that it holds an A or a > B. > > This way, one can rewrite Option as a type alias like this: > struct Some(T); > struct None; > > type Option = None | Some; > > Which is like the current Option, but also makes None and Some > first-class types. > > The current enum syntax can remain as syntax sugar for the above code. > Hi, I'm just your friendly everyday lurker... Assuming there's nothing in this proposal that fundamentally breaks the language, I just wanted to say I think this idea is fantastic. You almost don't need Some(T) since Option could just be None|T. I would add that I recall recently some people were discussing how to do a "variant" type in Rust. If all struct types in a program are assigned a unique tag, this very same feature could support a variant type, which is defined as the union of all types. Then any struct converts implicitly to variant (oh, and since I just wrote a parser generator that supports inverted sets like ~('a'..'z'), it occurs to me that the type system could readily support "any type except A | B" as well.) The tag could either be a unique integer index, or a pointer to a global variable that contains type information (the latter, it seems to me, automatically solves the dynamic linking problem "how do we ensure two unrelated DLLs have unique tags?" DLL loaders already support relocation in case of conflicts.) The only issue I see is what to do for code such as "let mut x = Some(3); > x = None;": with this proposal, Some and None are separate unrelated types, > so we either have this code emit an error, or x must be given the type > "Some | None" automatically, which however can lead to obscure error > messages if one mistakenly attempts to assign a string to it causing the > type to become "Some | None | ~str" (i.e. the user might be told than > a match is not exhaustive because it does not handle the "~str" case, > rather than that they assigned a ~str to an Option-typed variable). > > It should be possible to allow this, and make the error-emitting code use > heuristics to figure out whether it is more likely that the user assigned a > value of the wrong type, or used an enum improperly (for example, by > looking at whether the implicitly created enum type is ever written > explicitly in the source, and whether the deduced structural enum type is > being used in places that require a non-enum type). > > Alternatively, one can stipulate that only types that are structs, or that > are structs marked "enum struct" or "case struct" or similar can become > part of an inferred structural enum, but this seems unappealing. To keep the feature more conservative it's not unreasonable to (initially, at least) restrict the members of the union to be struct types; any non-struct type can still be used with Some(T). But the restriction doesn't entirely solve this particular problem; yeah, the compiler will complain if you assign ~str to a variable intended to be an Option, but it still won't complain if you assign some struct type to it. > Note that some structural enums can change representations depending > generic instantiation, since "T | int" becomes just "int" if T = int, while > it is "~str | int" if T = ~str (and similar for "Some | Some"), but > this should not be a problem. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at minhdo.org Wed Aug 28 02:48:16 2013 From: m at minhdo.org (Do Nhat Minh) Date: Wed, 28 Aug 2013 17:48:16 +0800 Subject: [rust-dev] Working on rusti as final year project In-Reply-To: References: <521B85C2.8060804@minhdo.org> Message-ID: Thanks, I will look into cling for inspiration. On Aug 28, 2013 1:46 AM, "Daniel Micay" wrote: > On Tue, Aug 27, 2013 at 1:36 PM, Tim Chevalier > wrote: > > > > There are only a few rusti bugs in the issue tracker -- > > > https://github.com/mozilla/rust/issues?direction=desc&labels=A-rusti&milestone=&page=1&sort=created&state=open > > -- but I'm sure you will discover more issues to fix as you start > > diving into the code. > > There are limitations of the current implementation since it actually > recompiles the whole output each time. It would be really nice to look > at what `cling` (C++ interpreter built on libclang) does and copy the > strategy. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From m at minhdo.org Wed Aug 28 02:50:53 2013 From: m at minhdo.org (Do Nhat Minh) Date: Wed, 28 Aug 2013 17:50:53 +0800 Subject: [rust-dev] Working on rusti as final year project In-Reply-To: References: <521B85C2.8060804@minhdo.org> Message-ID: Thank you for the advice. I will try my best on the documentation front. I go by the name MrOrdinaire on #rust irc. On Aug 28, 2013 1:36 AM, "Tim Chevalier" wrote: > On Mon, Aug 26, 2013 at 9:43 AM, Minh Do wrote: > > My name is Do Nhat Minh, currently a final year Computer Science student > at > > Nanyang Technological University in Singapore. I have played with Rust > and > > found the experience to be very pleasant. I think Rust make sensible > > trade-offs and managed to stay small, compared to C++. > > > > I have been granted permission by my university supervisor to work on > rusti > > as my final year project. I hope with this contribution, Rust will be > even > > stronger a competitor to Go and D. > > > > This will be my first time working on something this size and this long a > > duration. I would love to hear your advice or experience implementing > rusti. > > > > Hi, Minh -- > > It's great that you want to work on rusti! Making rusti easier to use > is something we all want, but as far as I know none of us on the core > team have time to work on it anytime soon, making it a great project > for a student. > > If you don't already, I recommend hanging out on #rust on > irc.mozilla.org. Don't be afraid to ask questions, and if you can > identify the author of the code you have a question about with git > blame, feel free to ask them directly on IRC. > https://github.com/mozilla/rust/wiki/Note-development-policy explains > how to get on the IRC channel. Feel free to ask questions here on the > mailing list if you don't get an immediate answer on IRC, but IRC is > the best for quick questions, and most of the Rust devs are online > during working hours in the Pacific timezone. > > I also recommend that you document your code extensively as you go > along, as well as documenting existing code when you learn about it! > You will probably learn many things about existing code and you can > help the next person to touch the code by writing down what you learn. > > There are only a few rusti bugs in the issue tracker -- > > https://github.com/mozilla/rust/issues?direction=desc&labels=A-rusti&milestone=&page=1&sort=created&state=open > -- but I'm sure you will discover more issues to fix as you start > diving into the code. > > Cheers, > Tim > > > -- > Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt > "Being queer is not about a right to privacy; it is about the freedom > to be public, to just be who we are." -- anonymous, June 1990 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From amitava.shee at gmail.com Wed Aug 28 16:39:24 2013 From: amitava.shee at gmail.com (Amitava Shee) Date: Wed, 28 Aug 2013 19:39:24 -0400 Subject: [rust-dev] Bus error: 10 Message-ID: I am getting a Bus error - please see the following.Should I file this as an issue in github? amitava:learn amitava$ cat app.rs // vi:ts=4:sw=4:nu fn main() { // should not compile - infinite size, needs redirection struct Foo { child: Option }; let c = Foo {child: None}; let p = Foo {child : Some(c) }; //printfln!("%?", p); } amitava:learn amitava$ make rustc -Z debug-info -o app app.rs app.rs:10:5: 10:6 warning: unused variable: `p` [-W unused-variable (default)] app.rs:10 let p = Foo {child : Some(c) }; ^ make: *** [app] Bus error: 10 amitava:learn amitava$ rustc --version rustc 0.8-pre (da96b3e 2013-08-28 14:15:37 -0700) host: x86_64-apple-darwin amitava:learn amitava$ uname -a Darwin amitava.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 Thanks & Regards, Amitava -------------- next part -------------- An HTML attachment was scrubbed... URL: From josh at joshmatthews.net Wed Aug 28 16:43:01 2013 From: josh at joshmatthews.net (Josh Matthews) Date: Wed, 28 Aug 2013 19:43:01 -0400 Subject: [rust-dev] Bus error: 10 In-Reply-To: References: Message-ID: That's covered by https://github.com/mozilla/rust/issues/4363https://github.com/mozilla/rust/issues/4363in the issue tracker. Cheers, Josh On 28 August 2013 19:39, Amitava Shee wrote: > I am getting a Bus error - please see the following.Should I file this as > an issue in github? > > amitava:learn amitava$ cat app.rs > // vi:ts=4:sw=4:nu > > fn main() { > // should not compile - infinite size, needs redirection > struct Foo { > child: Option > }; > > let c = Foo {child: None}; > let p = Foo {child : Some(c) }; > //printfln!("%?", p); > } > > amitava:learn amitava$ make > rustc -Z debug-info -o app app.rs > app.rs:10:5: 10:6 warning: unused variable: `p` [-W unused-variable > (default)] > app.rs:10 let p = Foo {child : Some(c) }; > ^ > make: *** [app] Bus error: 10 > > amitava:learn amitava$ rustc --version > rustc 0.8-pre (da96b3e 2013-08-28 14:15:37 -0700) > host: x86_64-apple-darwin > > amitava:learn amitava$ uname -a > Darwin amitava.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 > 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 > > Thanks & Regards, > Amitava > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Wed Aug 28 16:44:12 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Wed, 28 Aug 2013 16:44:12 -0700 Subject: [rust-dev] Bus error: 10 In-Reply-To: References: Message-ID: This is a known bug: https://github.com/mozilla/rust/issues/3779 The fix, which you probably realized, is to change Option to Option<~Foo> or Option<@Foo>. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Being queer is not about a right to privacy; it is about the freedom to be public, to just be who we are." -- anonymous, June 1990 From catamorphism at gmail.com Wed Aug 28 16:45:15 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Wed, 28 Aug 2013 16:45:15 -0700 Subject: [rust-dev] Bus error: 10 In-Reply-To: References: Message-ID: On Wed, Aug 28, 2013 at 4:43 PM, Josh Matthews wrote: > That's covered by > https://github.com/mozilla/rust/issues/4363https://github.com/mozilla/rust/issues/4363 > in the issue tracker. > That one is a little bit different. https://github.com/mozilla/rust/issues/3779 is actually the same struct. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Being queer is not about a right to privacy; it is about the freedom to be public, to just be who we are." -- anonymous, June 1990 From nicholasbishop at gmail.com Wed Aug 28 20:22:57 2013 From: nicholasbishop at gmail.com (Nicholas Bishop) Date: Wed, 28 Aug 2013 23:22:57 -0400 Subject: [rust-dev] Questions about linked lists in Rust Message-ID: Hi, I'm new to Rust, currently trying out a few simple tests to get a handle on things. I have a few questions about linked lists. I see there are two list modules in extra, one for ~ pointers and one for @ pointers. (I'm using the current trunk rather than 0.7 if that makes a difference.) The interfaces between the two look quite different however. Is this because one is newer and the other hasn't caught up yet, or are the differences by design and the two interfaces will stay more or less as they are? In extra::list, I don't see methods to append or remove a single element. Intentional or todo? In extra::dlist, there are methods to remove the back or front element, but not an arbitrary link? On a related note, I'd be interested to read about implementing data structures in Rust. The examples of structs in the tutorial are mostly very simple (Point, Circle, etc). The use of Rust's pointers get much more complicated when dealing with non-tree structures. For example, extra::dlist uses raw pointers rather than @ pointers for links. An overview of what the tradeoffs look like (code clarity, memory-leak/memory-corruption issues, performance numbers, memory usage) and some cookbook patterns could be quite helpful. Thanks, -Nicholas From vadimcn at gmail.com Thu Aug 29 12:35:13 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 29 Aug 2013 12:35:13 -0700 Subject: [rust-dev] Slow rustc startup on Windows Message-ID: ... is apparantly caused by pseudo-relocations (#8859). Does anybody here know anything about that? -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Fri Aug 30 04:40:40 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Fri, 30 Aug 2013 13:40:40 +0200 Subject: [rust-dev] Slow rustc startup on Windows In-Reply-To: References: Message-ID: Intriguing... I googled a bit to check what this was about and found: - pseudo-reloc.c, the part of mingw handling pseudo-relocations => http://www.oschina.net/code/explore/mingw-runtime-3.18-1/pseudo-reloc.c - the patch for pseudo-reloc v2 support => http://permalink.gmane.org/gmane.comp.gnu.mingw.announce/1953 At a glance I would say the problem is more on mingw side, however there might be something that can be done on rust side to mitigate or work-around the issue. -- Matthieu On Thu, Aug 29, 2013 at 9:35 PM, Vadim wrote: > ... is apparantly caused by pseudo-relocations (#8859). > Does anybody here know anything about that? > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Fri Aug 30 15:39:46 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 30 Aug 2013 15:39:46 -0700 Subject: [rust-dev] RFC: Stealing: lexically-scoped temporary violation of linearity Message-ID: <52211DE7.7050909@mozilla.com> Hi everyone, I've been tossing around an idea for a library utility designed to make unique pointers easier to use, especially for balanced binary search trees and the like. The core of the idea is that I conjecture it's safe to temporarily violate linearity *while the locations in question are borrowed*, as long as linearity is *dynamically* preserved once the borrow ends. First off, let me motivate this with an example, showing that this generalizes "swap": struct Test { a: ~str, b: ~str, } fn main() { let mut test = Test { a: ~"Burma", b: ~"Shave", }; { let (a, a_loc) = steal(&mut test.a); let (b, b_loc) = steal(&mut test.b); println(a); // prints "Burma" println(b); // prints "Shave" a_loc.put_back(b); b_loc.put_back(a); } println(test.a); // prints "Shave" println(test.b); // prints "Burma" } Concretely, what "steal" does is that it takes a mutable borrow and returns two things: (1) a shallow copy of the referent, temporarily violating linearity; (2) a "stolen location" which must be filled with a value of the same type as the referent via the `put_back` method before the scope ends. If the scope ends (i.e. the borrow expires) without calling `put_back` on a stolen location, then task failure occurs. For example, this program fails (with the above definition of `Test`): fn main() { let mut test = Test { a: ~"Burma", b: ~"Shave", }; { let (a, a_loc) = steal(&mut test.a); let (b, b_loc) = steal(&mut test.b); a_loc.put_back(b); } // dynamic failure: "b_loc" was not filled } The idea behind this is to allow complex "pointer rewirings" such as those that self-balancing binary search trees want to be expressed in a natural way without a tricky series of swaps. The thing that initially seems questionable for soundness is that, while borrowed and while linearity is violated, the original value is still readable (although not immutably or mutably borrowable). I believe this is OK, even in the fact of LLVM alias optimizations, because while something is borrowed linearity is no longer guaranteed anyhow. The implementation is quite small and simple and fits here: struct Stolen<'self,T> { priv location: &'self mut T, } #[unsafe_destructor] impl<'self,T> Drop for Stolen<'self,T> { fn drop(&self) { fail!("stolen") } } impl<'self,T> Stolen<'self,T> { fn put_back(self, value: T) { unsafe { intrinsics::move_val_init(self.location, value); cast::forget(self) } } } fn steal<'a,T>(value: &'a mut T) -> (T, Stolen<'a,T>) { unsafe { (cast::transmute_copy(value), Stolen { location: value, }) } } Thoughts? Does this seem useful? Are there soundness issues I didn't notice? Patrick From oren at ben-kiki.org Fri Aug 30 16:54:25 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Sat, 31 Aug 2013 02:54:25 +0300 Subject: [rust-dev] RFC: Stealing: lexically-scoped temporary violation of linearity In-Reply-To: <52211DE7.7050909@mozilla.com> References: <52211DE7.7050909@mozilla.com> Message-ID: I just tested this in my code, it solved a sticky problem I had with updating owned data nested deep inside a tree-ish container. My original solution wasn't very nice (it just compromised on efficiency and copied too much data around). The new code is shorter and more efficient (no copies! yey!). So, +1 for usefulness, and thanks! I wish I could also attest to the correctness, but that is harder to prove... On Sat, Aug 31, 2013 at 1:39 AM, Patrick Walton wrote: > Hi everyone, > > I've been tossing around an idea for a library utility designed to make > unique pointers easier to use, especially for balanced binary search trees > and the like. The core of the idea is that I conjecture it's safe to > temporarily violate linearity *while the locations in question are > borrowed*, as long as linearity is *dynamically* preserved once the borrow > ends. > > First off, let me motivate this with an example, showing that this > generalizes "swap": > > struct Test { > a: ~str, > b: ~str, > } > > fn main() { > let mut test = Test { > a: ~"Burma", > b: ~"Shave", > }; > { > let (a, a_loc) = steal(&mut test.a); > let (b, b_loc) = steal(&mut test.b); > println(a); // prints "Burma" > println(b); // prints "Shave" > a_loc.put_back(b); > b_loc.put_back(a); > } > println(test.a); // prints "Shave" > println(test.b); // prints "Burma" > } > > Concretely, what "steal" does is that it takes a mutable borrow and > returns two things: (1) a shallow copy of the referent, temporarily > violating linearity; (2) a "stolen location" which must be filled with a > value of the same type as the referent via the `put_back` method before the > scope ends. If the scope ends (i.e. the borrow expires) without calling > `put_back` on a stolen location, then task failure occurs. For example, > this program fails (with the above definition of `Test`): > > fn main() { > let mut test = Test { > a: ~"Burma", > b: ~"Shave", > }; > { > let (a, a_loc) = steal(&mut test.a); > let (b, b_loc) = steal(&mut test.b); > a_loc.put_back(b); > } // dynamic failure: "b_loc" was not filled > } > > The idea behind this is to allow complex "pointer rewirings" such as those > that self-balancing binary search trees want to be expressed in a natural > way without a tricky series of swaps. > > The thing that initially seems questionable for soundness is that, while > borrowed and while linearity is violated, the original value is still > readable (although not immutably or mutably borrowable). I believe this is > OK, even in the fact of LLVM alias optimizations, because while something > is borrowed linearity is no longer guaranteed anyhow. > > The implementation is quite small and simple and fits here: > > struct Stolen<'self,T> { > priv location: &'self mut T, > } > > #[unsafe_destructor] > impl<'self,T> Drop for Stolen<'self,T> { > fn drop(&self) { > fail!("stolen") > } > } > > impl<'self,T> Stolen<'self,T> { > fn put_back(self, value: T) { > unsafe { > intrinsics::move_val_init(**self.location, value); > cast::forget(self) > } > } > } > > fn steal<'a,T>(value: &'a mut T) -> (T, Stolen<'a,T>) { > unsafe { > (cast::transmute_copy(value), Stolen { > location: value, > }) > } > } > > Thoughts? Does this seem useful? Are there soundness issues I didn't > notice? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Aug 30 17:05:19 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 30 Aug 2013 17:05:19 -0700 Subject: [rust-dev] changing roles Message-ID: <5221333F.1040501@mozilla.com> Hi, As I'm sure many of you who know me are aware, my role as technical lead on Rust has been quite draining over the years. Both to myself and to those I've worked with, it just isn't a great fit for me. In recognition of this, I am stepping aside to work elsewhere in the organization, and Brian will be assuming the role of technical lead of Rust. Brian is one of the most skilled, judicious, professional and productive developers I've ever worked with. Along with the exceptional skill and dedication of the rest of the Rust team, I have complete confidence in the remaining path to a successful 1.x series of what has shaped up to be an excellent language. It has been a rare pleasure and privilege to work with the Rust team, both those inside Mozilla and in the broader community. Thanks, -Graydon From pwalton at mozilla.com Fri Aug 30 17:50:40 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 30 Aug 2013 17:50:40 -0700 Subject: [rust-dev] RFC: Stealing: lexically-scoped temporary violation of linearity In-Reply-To: <52211DE7.7050909@mozilla.com> References: <52211DE7.7050909@mozilla.com> Message-ID: <52213DE0.2000109@mozilla.com> On 8/30/13 3:39 PM, Patrick Walton wrote: > Thoughts? Does this seem useful? Are there soundness issues I didn't > notice? Brian pointed out a massive soundness hole in this, unfortunately. The problem is that you can read from the original locations; the right to read is not "shut off" during the borrow. I think the fix would have to be to replace this with some sort of "generalized swap" operation. Patrick From oren at ben-kiki.org Fri Aug 30 17:58:57 2013 From: oren at ben-kiki.org (Oren Ben-Kiki) Date: Sat, 31 Aug 2013 03:58:57 +0300 Subject: [rust-dev] RFC: Stealing: lexically-scoped temporary violation of linearity In-Reply-To: <52213DE0.2000109@mozilla.com> References: <52211DE7.7050909@mozilla.com> <52213DE0.2000109@mozilla.com> Message-ID: Sigh, I guess it was too good to be true :-( I'd settle for the ability to say: update_in_place(foo.owned_pointer, &fn(~T) -> ~T) - surely this would be safe? Speaking of which, a secondary problem I encountered when doing this sort of thing, is the "Once function" issue listed in https://github.com/mozilla/rust/wiki/Doc-under-construction-FAQ. Wouldn't it be possible to say, for example, that ~fn can only be invoked once to resolve this issue? On Sat, Aug 31, 2013 at 3:50 AM, Patrick Walton wrote: > On 8/30/13 3:39 PM, Patrick Walton wrote: > >> Thoughts? Does this seem useful? Are there soundness issues I didn't >> notice? >> > > Brian pointed out a massive soundness hole in this, unfortunately. The > problem is that you can read from the original locations; the right to read > is not "shut off" during the borrow. I think the fix would have to be to > replace this with some sort of "generalized swap" operation. > > > Patrick > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Fri Aug 30 18:40:03 2013 From: corey at octayn.net (Corey Richardson) Date: Fri, 30 Aug 2013 21:40:03 -0400 Subject: [rust-dev] changing roles In-Reply-To: <5221333F.1040501@mozilla.com> References: <5221333F.1040501@mozilla.com> Message-ID: Will you still be working on the Rust project, or elsewhere in Mozilla? On Fri, Aug 30, 2013 at 8:05 PM, Graydon Hoare wrote: > Hi, > > As I'm sure many of you who know me are aware, my role as technical lead on > Rust has been quite draining over the years. Both to myself and to those > I've worked with, it just isn't a great fit for me. > > In recognition of this, I am stepping aside to work elsewhere in the > organization, and Brian will be assuming the role of technical lead of Rust. > > Brian is one of the most skilled, judicious, professional and productive > developers I've ever worked with. Along with the exceptional skill and > dedication of the rest of the Rust team, I have complete confidence in the > remaining path to a successful 1.x series of what has shaped up to be an > excellent language. > > It has been a rare pleasure and privilege to work with the Rust team, both > those inside Mozilla and in the broader community. > > Thanks, > > -Graydon > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From banderson at mozilla.com Fri Aug 30 18:57:45 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 30 Aug 2013 18:57:45 -0700 Subject: [rust-dev] changing roles In-Reply-To: <5221333F.1040501@mozilla.com> References: <5221333F.1040501@mozilla.com> Message-ID: <52214D99.3070603@mozilla.com> On 08/30/2013 05:05 PM, Graydon Hoare wrote: > Hi, > > As I'm sure many of you who know me are aware, my role as technical > lead on Rust has been quite draining over the years. Both to myself > and to those I've worked with, it just isn't a great fit for me. > > In recognition of this, I am stepping aside to work elsewhere in the > organization, and Brian will be assuming the role of technical lead of > Rust. This news is bittersweet to say the least. The language that you invented and that I adore has come so very far under your leadership, and I hope that we can continue to build on the example you have set. It's been an enriching experience working with you, Graydon, and I wish you the best on your next project. -Brian From thadguidry at gmail.com Fri Aug 30 20:25:28 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Fri, 30 Aug 2013 22:25:28 -0500 Subject: [rust-dev] changing roles In-Reply-To: <52214D99.3070603@mozilla.com> References: <5221333F.1040501@mozilla.com> <52214D99.3070603@mozilla.com> Message-ID: Graydon, So what does not drain you ? What kicks you into high gear and keeps you salivating for more ? Many of us do not know you personally, and knowing a bit more about what really interests you, would open a few of our eyes on the list. (thanks for your efforts) On Fri, Aug 30, 2013 at 8:57 PM, Brian Anderson wrote: > On 08/30/2013 05:05 PM, Graydon Hoare wrote: > >> Hi, >> >> As I'm sure many of you who know me are aware, my role as technical lead >> on Rust has been quite draining over the years. Both to myself and to those >> I've worked with, it just isn't a great fit for me. >> >> In recognition of this, I am stepping aside to work elsewhere in the >> organization, and Brian will be assuming the role of technical lead of Rust. >> > > This news is bittersweet to say the least. The language that you invented > and that I adore has come so very far under your leadership, and I hope > that we can continue to build on the example you have set. > > It's been an enriching experience working with you, Graydon, and I wish > you the best on your next project. > > -Brian > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad Thad on Freebase.com Thad on LinkedIn -------------- next part -------------- An HTML attachment was scrubbed... URL: From amitava.shee at gmail.com Sat Aug 31 05:59:30 2013 From: amitava.shee at gmail.com (Amitava Shee) Date: Sat, 31 Aug 2013 08:59:30 -0400 Subject: [rust-dev] make check fails Message-ID: make check fails as follows. amitava:rust amitava$ make check cfg: build triple x86_64-apple-darwin cfg: host triples x86_64-apple-darwin cfg: target triples x86_64-apple-darwin cfg: host for x86_64-apple-darwin is x86_64 cfg: os for x86_64-apple-darwin is apple-darwin cfg: using gcc cfg: including dist rules cfg: including test rules check: formatting /Users/amitava/opt/rust/src/rust/src/librustc/middle/trans/foreign.rs:98: NOTE These API constants ought to be more specific /Users/amitava/opt/rust/src/rust/src/libstd/rt/uv/file.rs:283: NOTE: need defs for S_**GRP|S_**OTH in libc:: ... /Users/amitava/opt/rust/src/rust/src/libsyntax/ext/expand.rs:961: NOTE(acrichto): start removing this after the next snapshot /Users/amitava/opt/rust/src/rust/src/libsyntax/ext/expand.rs:971: NOTE(acrichto): start removing this after the next snapshot /Users/amitava/opt/rust/src/rust/src/libsyntax/ext/expand.rs:994: NOTE: use this after a snapshot lands to abstract the details version-info: doc/version_info.html sed -e "s/VERSION/0.8-pre/; s/SHORT_HASH/bb35e23f/;\ s/STAMP/bb35e23f1ca63eba4a3ea25ecdf68a393871ed18/;" /Users/amitava/opt/rust/src/rust/doc/version_info.html.template >doc/version_info.html pandoc: doc/rust.html version-stamp: doc/version.md pandoc: doc/rust.tex pandoc: doc/rustpkg.html pandoc: doc/tutorial.html pandoc: doc/tutorial-macros.html pandoc: doc/tutorial-container.html pandoc: doc/tutorial-ffi.html pandoc: doc/tutorial-borrowed-ptr.html pandoc: doc/tutorial-tasks.html pandoc: doc/tutorial-conditions.html pdflatex: doc/rust.pdf This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012) restricted \write18 enabled. entering extended mode run rpass [x86_64-apple-darwin]: x86_64-apple-darwin/stage2/bin/compiletest running 1310 tests /bin/sh: line 1: 2415 Abort trap: 6 x86_64-apple-darwin/stage2/bin/compiletest --compile-lib-path x86_64-apple-darwin/stage2/lib --run-lib-path x86_64-apple-darwin/stage2/lib/rustc/x86_64-apple-darwin/lib --rustc-path x86_64-apple-darwin/stage2/bin/rustc --clang-path /usr/bin/clang++ --llvm-bin-path /Users/amitava/opt/rust/src/rust/llvm/x86_64-apple-darwin/Release+Asserts/bin --aux-base /Users/amitava/opt/rust/src/rust/src/test/auxiliary/ --stage-id stage2-x86_64-apple-darwin --target x86_64-apple-darwin --adb-path=/usr/local/bin/adb --adb-test-dir= --rustcflags " --cfg rtopt -O --target=x86_64-apple-darwin" --src-base /Users/amitava/opt/rust/src/rust/src/test/run-pass/ --build-base x86_64-apple-darwin/test/run-pass/ --ratchet-metrics tmp/check-stage2-T-x86_64-apple-darwin-H-x86_64-apple-darwin-rpass-metrics.json --mode run-pass --logfile tmp/check-stage2-T-x86_64-apple-darwin-H-x86_64-apple-darwin-rpass.log make: *** [tmp/check-stage2-T-x86_64-apple-darwin-H-x86_64-apple-darwin-rpass.ok] Error 134 amitava:rust amitava$ ==================== amitava:rust amitava$ git log -1 --pretty=oneline bb35e23f1ca63eba4a3ea25ecdf68a393871ed18 auto merge of #8896 : lightcatcher/rust/default_eq_fix, r=thestinger amitava:rust amitava$ rust --version rust 0.8-pre (bb35e23 2013-08-30 21:40:32 -0700) host: x86_64-apple-darwin amitava:rust amitava$ uname -a Darwin amitava.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at kevincantu.org Sat Aug 31 11:12:13 2013 From: me at kevincantu.org (Kevin Cantu) Date: Sat, 31 Aug 2013 11:12:13 -0700 Subject: [rust-dev] make check fails In-Reply-To: References: Message-ID: I see that, too. Filed an issue for it: seems like some kind of libc::pipe problem on OS X with that that function. https://github.com/mozilla/rust/issues/8904 Kevin On Sat, Aug 31, 2013 at 5:59 AM, Amitava Shee wrote: > make check fails as follows. > > amitava:rust amitava$ make check > cfg: build triple x86_64-apple-darwin > cfg: host triples x86_64-apple-darwin > cfg: target triples x86_64-apple-darwin > cfg: host for x86_64-apple-darwin is x86_64 > cfg: os for x86_64-apple-darwin is apple-darwin > cfg: using gcc > cfg: including dist rules > cfg: including test rules > check: formatting > /Users/amitava/opt/rust/src/rust/src/librustc/middle/trans/foreign.rs:98: > NOTE These API constants ought to be more specific > /Users/amitava/opt/rust/src/rust/src/libstd/rt/uv/file.rs:283: NOTE: need > defs for S_**GRP|S_**OTH in libc:: ... > /Users/amitava/opt/rust/src/rust/src/libsyntax/ext/expand.rs:961: > NOTE(acrichto): start removing this after the next snapshot > /Users/amitava/opt/rust/src/rust/src/libsyntax/ext/expand.rs:971: > NOTE(acrichto): start removing this after the next snapshot > /Users/amitava/opt/rust/src/rust/src/libsyntax/ext/expand.rs:994: NOTE: use > this after a snapshot lands to abstract the details > version-info: doc/version_info.html > sed -e "s/VERSION/0.8-pre/; s/SHORT_HASH/bb35e23f/;\ > s/STAMP/bb35e23f1ca63eba4a3ea25ecdf68a393871ed18/;" > /Users/amitava/opt/rust/src/rust/doc/version_info.html.template >>doc/version_info.html > pandoc: doc/rust.html > version-stamp: doc/version.md > pandoc: doc/rust.tex > pandoc: doc/rustpkg.html > pandoc: doc/tutorial.html > pandoc: doc/tutorial-macros.html > pandoc: doc/tutorial-container.html > pandoc: doc/tutorial-ffi.html > pandoc: doc/tutorial-borrowed-ptr.html > pandoc: doc/tutorial-tasks.html > pandoc: doc/tutorial-conditions.html > pdflatex: doc/rust.pdf > This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012) > restricted \write18 enabled. > entering extended mode > run rpass [x86_64-apple-darwin]: x86_64-apple-darwin/stage2/bin/compiletest > > running 1310 tests > /bin/sh: line 1: 2415 Abort trap: 6 > x86_64-apple-darwin/stage2/bin/compiletest --compile-lib-path > x86_64-apple-darwin/stage2/lib --run-lib-path > x86_64-apple-darwin/stage2/lib/rustc/x86_64-apple-darwin/lib --rustc-path > x86_64-apple-darwin/stage2/bin/rustc --clang-path /usr/bin/clang++ > --llvm-bin-path > /Users/amitava/opt/rust/src/rust/llvm/x86_64-apple-darwin/Release+Asserts/bin > --aux-base /Users/amitava/opt/rust/src/rust/src/test/auxiliary/ --stage-id > stage2-x86_64-apple-darwin --target x86_64-apple-darwin > --adb-path=/usr/local/bin/adb --adb-test-dir= --rustcflags " --cfg rtopt > -O --target=x86_64-apple-darwin" --src-base > /Users/amitava/opt/rust/src/rust/src/test/run-pass/ --build-base > x86_64-apple-darwin/test/run-pass/ --ratchet-metrics > tmp/check-stage2-T-x86_64-apple-darwin-H-x86_64-apple-darwin-rpass-metrics.json > --mode run-pass --logfile > tmp/check-stage2-T-x86_64-apple-darwin-H-x86_64-apple-darwin-rpass.log > make: *** > [tmp/check-stage2-T-x86_64-apple-darwin-H-x86_64-apple-darwin-rpass.ok] > Error 134 > amitava:rust amitava$ > > ==================== > amitava:rust amitava$ git log -1 --pretty=oneline > bb35e23f1ca63eba4a3ea25ecdf68a393871ed18 auto merge of #8896 : > lightcatcher/rust/default_eq_fix, r=thestinger > amitava:rust amitava$ rust --version > rust 0.8-pre (bb35e23 2013-08-30 21:40:32 -0700) > host: x86_64-apple-darwin > > amitava:rust amitava$ uname -a > Darwin amitava.local 12.4.0 Darwin Kernel Version 12.4.0: Wed May 1 > 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64 > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From jon.mb at proinbox.com Sat Aug 31 12:22:11 2013 From: jon.mb at proinbox.com (John Mija) Date: Sat, 31 Aug 2013 20:22:11 +0100 Subject: [rust-dev] App runtime based on Servo Message-ID: <52224263.4010902@proinbox.com> From my point of view, there is no technology related to User Interfaces more advanced than web-based (HTML5/CSS3). Besides, it is a standard, it's widely known by the Web developers, and it continues to improve with emerging web standards (Custom Elements, Shadow DOM, etc.): + Web Animations (http://dev.w3.org/fxtf/web-animations/) Web Animations is a new specification for animated content on the web. It?s being developed as a W3C specification as part of the CSS and SVG working groups. It aims to address the deficiencies inherent in these four specifications. Web Animations also aims to replace the underlying implementations of CSS Transitions, CSS Animations and SVG Animations. + Pointer Events (https://dvcs.w3.org/hg/pointerevents/raw-file/tip/pointerEvents.html) Mouse events and Touch events are different beasts in browsers today, and that makes it hard to write cross-platform apps. + Shadow DOM (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html) Shadow DOM is designed to provide encapsulation by hiding DOM subtrees under shadow roots. + Custom Elements (https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html) Custom Elements let authors define their own elements. Authors associate JavaScript code with custom tag names, and then use those custom tag names as they would any standard tag. --- Well, some guys of Intel Open Source Technology Center think so and they have built an app runtime based on Chromium and node.js, which opens new possibilities for native applications written using Web technologies and being cross-platform. https://github.com/rogerwang/node-webkit See the list of apps built with such tecnology: https://github.com/rogerwang/node-webkit/wiki/List-of-apps-and-companies-using-node-webkit Today, the main issue is the lack of a unified GUI widget set but I'm sure that it will be solved at some point; at least, the Dart team is working in something like. Now, what do think about to have a similar technology but using Servo? To being able to develop desktop apps in Rust (or Go via bindings to Rust libraris) and JS or Dart for the UI. From micah at micahchalmer.net Sat Aug 31 16:12:16 2013 From: micah at micahchalmer.net (Micah Chalmer) Date: Sat, 31 Aug 2013 19:12:16 -0400 Subject: [rust-dev] RFC: Stealing: lexically-scoped temporary violation of linearity In-Reply-To: References: <52211DE7.7050909@mozilla.com> <52213DE0.2000109@mozilla.com> Message-ID: <90AA603E-AC35-41C8-B70F-EC99B46CBA77@micahchalmer.net> > I'd settle for the ability to say: update_in_place(foo.owned_pointer, &fn(~T) -> ~T) - surely this would be safe? That would interact with Drop in a way that could cause a memory violation after a task failure. The problem is that if you allow a moved value to be destroyed before something else is swapped into an owned pointer, the task could fail before the new value got put back in. Then a drop function could try to access the destroyed value during unwind. Depending on how owned boxes work, it still might try to free the memory twice, even if Drop was not implemented. An illustration--if the update_in_place function existed, this code would violate memory safety without an "unsafe": use std::cast; fn move_out(x:~T) { // do stuff with x...or not--either way, we're not returning it out, so x is // destroyed at the end of this function } struct Bomb { x:~str } impl Drop for Bomb { fn drop(&self) { println(x); } } fn violate_memory() { // If the update_in_place function existed, it could cause a memory // violation like so: let mut b = ~Bomb{x: ~"Kaboom"} do update_in_place(&mut b) |t| { move_out(t); // At this point the memory pointed to by the owned pointer b.x is // destroyed...but nothing else has been put its place! The // compiler will prevent us from accessing b or t here, but... fail!(); // The stack will be unwound, and the Bomb's drop function will // be called. It will attempt to access the owned value that // was already destroyed. } } On Aug 30, 2013, at 8:58 PM, Oren Ben-Kiki wrote: > Sigh, I guess it was too good to be true :-( > > > Speaking of which, a secondary problem I encountered when doing this sort of thing, is the "Once function" issue listed in https://github.com/mozilla/rust/wiki/Doc-under-construction-FAQ. > > Wouldn't it be possible to say, for example, that ~fn can only be invoked once to resolve this issue? > > > On Sat, Aug 31, 2013 at 3:50 AM, Patrick Walton wrote: > On 8/30/13 3:39 PM, Patrick Walton wrote: > Thoughts? Does this seem useful? Are there soundness issues I didn't > notice? > > Brian pointed out a massive soundness hole in this, unfortunately. The problem is that you can read from the original locations; the right to read is not "shut off" during the borrow. I think the fix would have to be to replace this with some sort of "generalized swap" operation. > > > Patrick > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sat Aug 31 17:21:40 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 31 Aug 2013 20:21:40 -0400 Subject: [rust-dev] Disabling LLVM Asserts Message-ID: https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-08-27#llvm-asserts discusses disabling LLVM assertions. I don't think it just risks segfaults, doesn't it also run the risk of invalid codegen for incorrect uses? OTOH, distributing LLVM snapshots is a very good idea IMO.