From niko at alum.mit.edu Wed May 1 03:51:14 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 06:51:14 -0400 Subject: [rust-dev] Dynamically sized types, revisited Message-ID: <20130501105114.GA1611@Mr-Bennet> Hello everyone, I just thought I'd point out a recent blog post that I think may be of general interest: http://smallcultfollowing.com/babysteps/blog/2013/04/30/dynamically-sized-types/ I'm kind of excited about this idea. Maybe one of you can poke a hole in it. In any case, it describes a way to improve our vector/string types so that they are more composable. I'll just post the summary here: > In summary, I think we can have our cake and eat it too. If we > change the representation of vectors and slices, we can have > composable types *and* all the efficiency and flexibility of the > current system. The price is that we must distinguish "sized" from > "unsized" type parameters. I argue thta this is likely to be a minor > cost, since most of the time parameters that would require a `Sized` > bound will already have a `Copy` or `Clone` bound anyhow. I think > that's pretty exciting, since the non-composability of vector types > has always seemed like a language wart in the making. Niko From illissius at gmail.com Wed May 1 05:39:12 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Wed, 1 May 2013 14:39:12 +0200 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <518019E7.70501@mozilla.com> References: <517D6020.9080307@mozilla.com> <517D6312.7030203@gmail.com> <517D66F5.1020703@mozilla.com> <518019E7.70501@mozilla.com> Message-ID: On Tue, Apr 30, 2013 at 9:22 PM, Graydon Hoare wrote: > On 30/04/2013 11:26 AM, G?bor Lehel wrote: > > Couldn't this be relaxed? In other words allow dynamically sized `str` >> as a type (and perhaps similarly for other dynamically sized types), but >> prohibit those things specifically which would be problematic, i.e. >> using it in ways that would require knowing its size? >> > > This option was considered at ... great length, a year ago during the > vector-reform conversations. > > https://mail.mozilla.org/pipermail/rust-dev/2012-April/001742.html > https://mail.mozilla.org/pipermail/rust-dev/2012-April/001772.html > https://mail.mozilla.org/pipermail/rust-dev/2012-June/001951.html > https://mail.mozilla.org/pipermail/rust-dev/2012-July/002114.html > > I'm not sure anyone ever reduced those threads to their essence, but > re-reading them I think I can articulate the fundamental difficulty with > what you're suggesting: > > - Any object has a real size. Some sizes are statically known, > some must be discovered dynamically (by reading a size field > or carrying a size value in a (ptr,size) pair) > > - When T is static-size, &T and ~T and @T should be 1-word > pointers. The compiler knows the size. > > - To operate on a vector of statically-unknown size, you > need to get its dynamically-known size from somewhere. > This means pointers to vectors need to carry bounds. > > - So ~[] and @[] and &[] are not the same representation as > ~T, @T and &T in general. They have to have a size stuck > on them somewhere. > > - We want to be able to take sub-slices and have slices that > point to fixed-size vectors in C structs. This means > slices can't have their length in the pointee, and have to be > (ptr,len) pairs. > > So about the only wiggle room away from where we are now is that we might > be able to make ~[] represented by (ptr,len) pairs too, like slices are, > rather than 1 ptr that points to a [len,data...] buffer. But it's not clear > if that would buy us anything. Maybe a bit more genericity in impls, though > I don't know how; Niko might. There might be a bit more room for > improvement here, but it's an _extremely_ constrained space to work in. > > -Graydon > > Thanks for the explanation! That makes a lot of sense. I also just read Niko's blog post, and I'm not sure which thread to reply in (or who to reply to), but I guess I'll do it here. Niko's message here beforehand was kind of expectations-downplaying, but reading the blog post, his proposed scheme seems to allow more or less the same as what I was asking about here (perhaps minus the user-defined dynamically sized types, but that was icing). So *if* the plan ends up working out, then taking the second part of my earlier proposal: > You might also have a rule whereby dereferencing a variable when the > result would be a dynamically-sized type is allowed *if* the result is > immediately borrowed. Then instead of `impl Eq for {@str, ~str, &str}`, > you would have just `impl Eq for str`, and if you want to compare an > ~str you dereference it. Would that work? Would it be a good solution? -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Wed May 1 07:50:07 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 10:50:07 -0400 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: References: <517D6020.9080307@mozilla.com> <517D6312.7030203@gmail.com> <517D66F5.1020703@mozilla.com> <518019E7.70501@mozilla.com> Message-ID: <20130501145007.GA27185@Mr-Bennet> On Wed, May 01, 2013 at 02:39:12PM +0200, G?bor Lehel wrote: > I also just read Niko's blog post, and I'm not sure which thread to reply > in (or who to reply to), but I guess I'll do it here. Niko's message here > beforehand was kind of expectations-downplaying, but reading the blog post, > his proposed scheme seems to allow more or less the same as what I was > asking about here (perhaps minus the user-defined dynamically sized types, > but that was icing). Yeah, I wasn't sure how well that idea of changing the representation for all vecs/strings would work out, but then in the process of writing the post I decided it worked out quite well. It was an idea I first had last summer when we were hashing this out the first time, and have been meaning to chew on for some time, so I'm glad we had this thread on the mailing list to bring it back to my mind. > So *if* the plan ends up working out, then taking the second part of my > earlier proposal: > > > You might also have a rule whereby dereferencing a variable when the > > result would be a dynamically-sized type is allowed *if* the result is > > immediately borrowed. Then instead of `impl Eq for {@str, ~str, &str}`, > > you would have just `impl Eq for str`, and if you want to compare an > > ~str you dereference it. > > Would that work? Would it be a good solution? I believe that would be the plan, yes. Most of these "apply-to-almost-everything" traits, like `Eq` or `Ord`, could be implemented in a similar fashion. I'm not sure what problem you are proposing this as a solution *for*, though. Do you mean the problem of comparing strings using `==`? I suppose it is true that under this proposal you could write let str1: ~str = ~"hi"; let str2: &str = "hi"; *str1 == *str2 and it would work fine. That is a nice side-effect I hadn't considered. *An aside:* Note that dereferencing a pointer to an unsized object is only allowed in an "lvalue" context (that is, when we are taking its address): let str1: ~str = ~"hi"; let foo = *str1; // ERROR let bar = &*str1; // OK Here, `foo` is an error because `*str1` is being evaluated in an rvalue context, but `bar` is fine, because `*str1` is being evaluted in an lvalue context. In the case of `==`, this works out because the arguments to overloaded operators are always passed by reference. *A further aside:* don't be misled by my use of the term "lvalue context" into thinking that a program like this would be legal: let mut str1: ~str = ~"Hello"; *str1 = "World"; // ERROR This is illegal because assigning to an lvalue of unsized type is illegal, even though `*str1` appears in an lvalue context. regards, Niko From clements at brinckerhoff.org Wed May 1 09:44:35 2013 From: clements at brinckerhoff.org (John Clements) Date: Wed, 1 May 2013 09:44:35 -0700 Subject: [rust-dev] Fwd: [racket] Planet2 questions References: <20130430162441.5365F65010D@mail-svr1.cs.utah.edu> Message-ID: <00B7E4FF-6A81-4A61-B04E-3FEE35F30B64@brinckerhoff.org> Forgive me for cross-posting. The message below sheds light on some hard-earned lessons about versioning in the Racket package system. There may well be large differences between Rust and Racket in this regard, but the decoupling of version numbers from in-code dependencies was, I believe, an insight that took about five years to emerge. Apologies if this is well-known or off-topic. John Begin forwarded message: > From: Matthew Flatt > Subject: Re: [racket] Planet2 questions > Date: April 30, 2013 9:24:39 AM PDT > To: Berthold B?uml > Cc: Racket Mailing List , Matthias Felleisen > > At Tue, 9 Apr 2013 18:18:35 +0200, Berthold B?uml wrote: >> I hope to find time to write up the model this weekend. But what is >> absolutely clear to us is that a package management system has to >> have a notion of versions (or variants as I called them) for a >> package at the lowest level -- otherwise such simple things as >> roll-backs or composing a system from packages in a deterministic way >> (i.e., by precisely specifying a version for all packages) is not >> possible. Of course, on top of such a low level system one can add >> more convenient interfaces for users for the more standard use cases, >> e.g., mimicking the version disregarding behavior of planet2 -- but >> it is not possible to do it the other way round. > > I have been working with Jay on the package manager recently, and so I > have some further info on this point. > > Building versions into the lowest level could mean different things: > > 1. It could mean that a packages are referenced in programs with a > specific version number. > > 2. It could mean that the package system has a built-in way to declare > dependencies not only on a particular package, but on a particular > revision of a package --- either to ensure that certain features > are available or that certain bugs are not available. > > 3. It could mean that there's a fine-grained way to say which > implementation of a package should be used in a given > installation/configuration. > > #1 was a prominent feature of Planet1 that we've dropped in the new > package manager. In fact, packages are not referenced at all in program > sources; only collections are referenced, and some collections turn out > to be supplied by packages in a given installation/configuration. That > is, package management and program execution are more separate. > > #2 is built into the new package system, though in an intentionally > simplified form compared to Planet1. All version X specifications in > dependencies mean "at least version X", and those specifications are > intended to ensure the availability of new functionality or fixes that > were added in a backwards-compatible way. Backwards incompatibility is > handled by creating a new package name. > > #3 is at the core of the new package system, and the rest of this > message is about that one. I think it's probably close to what you have > in mind; I'm interested to hear more about whether you mean something > different. > > ---------------------------------------- > > To be clear about #3, we have to distinguish "package name" from > "package implementation". A package name is something like "mischief", > which you use for installing and declaring dependencies. A package > implementation is something that you download from, say, > > https://github.com/carl-eastlund/mischief/tarball/ fe7119517a4dcd3f5c509735a7b5a5664151c14f > > Note that a package implementation in this sense corresponds to > specific revision of a pile of code, such as a particular commit in a > git repository. The package manager includes the concepts of a "package > source" and a "checksum", which together tell you how to get a package > implementation. (That implementation may have its own version number, > which corresponds to #2 above, but such a version number is in > principle orthogonal to the package implementation's checksum.) > > The mapping from a package name to a package implementation is provided > by a "catalog". (This is recent terminology; until last week, a > "catalog" was variously called a "package name resolver" or "index".) > PLT provides a catalog server at pkg.racket-lang.org, but you can make > your catalog (as a server or on a local filesystem), and so you can > precisely control the mapping from package names to packages. > > Furthermore, we've recently added tools to `raco pkg' to make it easier > to manage catalogs. For example, if you want to take a snapshot of the > current pkg.racket-lang.org and use that from now on (so that the > mapping from package names to packages doesn't change), use these > commands: > > raco pkg catalog-copy https://pkg.racket-lang.org /full/path/to/catalog/ > raco pkg config --set catalogs file:///full/path/to/catalog/ > > You can modify the files generated at "/full/path/to/catalog/" by hand > in a fairly obvious way. Or you can upload the directory to a > file-serving HTTP site and point installations to the uploaded > directory as the catalog. There's also an option to use an SQLite > database as the format for a catalog, which is a better option if you > want to modify the catalog programmatically via `pkg/db', but an SQLite > database is less easy to use from a file-serving HTTP site. > > In particular, I can imagine having a project whose source code > includes a package catalog. To upgrade a particular package, I'd change > the catalog and `raco pkg update'. When I commit a particular revision > of the source code to a git repository, the package catalog is saved; > then, I can roll pack the project (including its references to specific > package implementations) to any previous version with its associated > package implementation via a `git checkout' (or whatever) plus `raco > pkg update'. Working this way, the package catalog acts a lot like git > submodules. > > > ____________________ > Racket Users list: > http://lists.racket-lang.org/users From clements at brinckerhoff.org Wed May 1 10:29:45 2013 From: clements at brinckerhoff.org (John Clements) Date: Wed, 1 May 2013 10:29:45 -0700 Subject: [rust-dev] should '///' be a doc comment? Message-ID: Currently, the set of doc comments includes (among other things) lines beginning with three slashes, *unless* they're entirely slashes. Presumably, this is to ensure that things like ///////////// // Time to go get some coffee! //////////// ... aren't parsed as two doc comments consisting entirely of slashes (with an ignored comment in between. This makes sense to me. However, it also means that things like /// My awesome procedure /// /// - does everything, /// /// - is kinda slow. is parsed as three lines of doc comments, rather than five. I propose that '///' should be treated as a doc comment, essentially by special-casing it. The risk is that certain existing normal-comments would be changed into doc-comments, causing compilation failure. If people think this change is (otherwise) sensible, I'll naturally check it locally on my tree before inflicting it on anyone else. Best, John From pwalton at mozilla.com Wed May 1 10:32:01 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 01 May 2013 10:32:01 -0700 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: Message-ID: <51815191.8050702@mozilla.com> On 5/1/13 10:29 AM, John Clements wrote: > Currently, the set of doc comments includes (among other things) > lines beginning with three slashes, *unless* they're entirely > slashes. Presumably, this is to ensure that things like > > ///////////// // Time to go get some coffee! //////////// > > ... aren't parsed as two doc comments consisting entirely of slashes > (with an ignored comment in between. > > This makes sense to me. > > However, it also means that things like > > /// My awesome procedure /// /// - does everything, /// /// - is > kinda slow. > > is parsed as three lines of doc comments, rather than five. > > I propose that '///' should be treated as a doc comment, essentially > by special-casing it. > > The risk is that certain existing normal-comments would be changed > into doc-comments, causing compilation failure. If people think this > change is (otherwise) sensible, I'll naturally check it locally on my > tree before inflicting it on anyone else. +1. The current behavior just plain seems like a bug. Patrick From lucian.branescu at gmail.com Wed May 1 10:32:50 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Wed, 1 May 2013 18:32:50 +0100 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: <51815191.8050702@mozilla.com> References: <51815191.8050702@mozilla.com> Message-ID: Is it too late/undesirable to have an explicit, separate syntax for docstrings, a bit like Lisps/Python? On 1 May 2013 18:32, Patrick Walton wrote: > On 5/1/13 10:29 AM, John Clements wrote: > >> Currently, the set of doc comments includes (among other things) >> lines beginning with three slashes, *unless* they're entirely >> slashes. Presumably, this is to ensure that things like >> >> ///////////// // Time to go get some coffee! //////////// >> >> ... aren't parsed as two doc comments consisting entirely of slashes >> (with an ignored comment in between. >> >> This makes sense to me. >> >> However, it also means that things like >> >> /// My awesome procedure /// /// - does everything, /// /// - is >> kinda slow. >> >> is parsed as three lines of doc comments, rather than five. >> >> I propose that '///' should be treated as a doc comment, essentially >> by special-casing it. >> >> The risk is that certain existing normal-comments would be changed >> into doc-comments, causing compilation failure. If people think this >> change is (otherwise) sensible, I'll naturally check it locally on my >> tree before inflicting it on anyone else. >> > > +1. The current behavior just plain seems like a bug. > > 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 steve at steveklabnik.com Wed May 1 10:33:48 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Wed, 1 May 2013 11:33:48 -0600 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: <51815191.8050702@mozilla.com> Message-ID: I'm for this. From niko at alum.mit.edu Wed May 1 10:51:58 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 13:51:58 -0400 Subject: [rust-dev] immutability, aliasing guarantees, and optimization Message-ID: <20130501175158.GB7495@Mr-Bennet> Hello, Unfortunately, I accidentally deleted a message from Vadim that I wanted to reply to. However, it had strayed from the topic of the thread anyhow (which was called "sub-grammar for range pattern constants") so I'll just startup a new thread here. Vadim wrote: > - Does "immutable" mean that the referenced object cannot change > forever, even after current function has returned? It means that the referenced object cannot change for the lifetime of that reference. > Is it possible in Rust to create a hash that stores its' keys by > borrowed reference (assuming that the hash does not outlive > contained keys) and be assured that the keys will not get changed > after having been added to the hash? That would be possible, but the hash would have to be parameterized by the lifetime of the keys. What we typically do instead is to have the hash own the keys. > - Can Rust actually guarantee that &mut are not aliased, - in the > face of all indirection that may happen in a typical program? Yes. That is the job of the borrow checker, and the soundness of the Rust type system depends on it. If you do not make use of managed data (i.e., no `@`), this guarantee is static. Otherwise the guarantee is enforced dynamically. The example program you gave is not supposed to execute without error; the reason that it does is due to bugs. I am about to land (next day or so) a branch fixing a number of such bugs. When I run that program on my branch, I get a compilation failure. This is because, even though you are using `@`, the compiler can clearly see that the dynamic check would fail, and so it flags the error statically. If you modify the program slightly you can evade this static check, but an error should still occur dynamically. Currently it does not (even on my branch), this is issue #5910. Niko From someone at mearie.org Wed May 1 10:56:51 2013 From: someone at mearie.org (Kang Seonghoon) Date: Thu, 2 May 2013 02:56:51 +0900 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: <51815191.8050702@mozilla.com> Message-ID: Oops, it seems like my patch (6d98ca9) had a bug. For anyone interested, a small update to `parse::lexer::is_line_non_doc_comment` function will fix it. (Right now I don't have a compilation environment, so it's my guess.) That said, I don't like doc comments being translated to decorators at all, mainly because comments are otherwise freeform and similar problems may arise later. In fact a possibility of a long run of `/`s being mistranslated to doc comment was hinted by the very patch introducing this syntax. [1] My patch is by no means permanent but rather ad hoc solution to the problem. [1] https://github.com/mozilla/rust/issues/2498 2013/5/2 Steve Klabnik : > I'm for this. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- -- Kang Seonghoon | Software Engineer, iPlateia Inc. | http://mearie.org/ -- Opinions expressed in this email do not necessarily represent the views of my employer. -- From graydon at mozilla.com Wed May 1 10:57:48 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 01 May 2013 10:57:48 -0700 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: <51815191.8050702@mozilla.com> Message-ID: <5181579C.6080704@mozilla.com> On 13-05-01 10:32 AM, Lucian Branescu wrote: > Is it too late/undesirable to have an explicit, separate syntax for > docstrings, a bit like Lisps/Python? We have one: #[doc="..."] Doc comments are an alternative syntax for the same attribute because nobody liked that. -Graydon From graydon at mozilla.com Wed May 1 11:49:10 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 01 May 2013 11:49:10 -0700 Subject: [rust-dev] Dynamically sized types, revisited In-Reply-To: <20130501105114.GA1611@Mr-Bennet> References: <20130501105114.GA1611@Mr-Bennet> Message-ID: <518163A6.80009@mozilla.com> On 13-05-01 03:51 AM, Niko Matsakis wrote: > Hello everyone, > > I just thought I'd point out a recent blog post that I think may be of > general interest: > > http://smallcultfollowing.com/babysteps/blog/2013/04/30/dynamically-sized-types/ > > I'm kind of excited about this idea. Maybe one of you can poke a hole > in it. In any case, it describes a way to improve our vector/string > types so that they are more composable. Sounds like a nice completion of the factoring we were trying to get right last summer. Nice work. Three questions: 1. Why _exactly_ (if it's possible to reconstruct) did this factoring not work last time, and what has changed since? 2. What ballpark amount-of-effort do you think the work entails in implementation, and how much do you think it will perturb code? It _looks_ to me like .. relatively little on both counts, but it's hard to know. 3. Are any capabilities lost? I don't see any, but I'm a little slow on the implications, often. It seems like maybe the GC will no longer be able to track sizes by looking in pointees, but that's not so bad; there's a digital trie that already covers that. Hopeful, anyways. -Graydon From vadimcn at gmail.com Wed May 1 14:37:05 2013 From: vadimcn at gmail.com (Vadim) Date: Wed, 1 May 2013 14:37:05 -0700 Subject: [rust-dev] immutability, aliasing guarantees, and optimization In-Reply-To: <20130501175158.GB7495@Mr-Bennet> References: <20130501175158.GB7495@Mr-Bennet> Message-ID: Thanks for your response Niko. A couple more questions if you don't mind: On Wed, May 1, 2013 at 10:51 AM, Niko Matsakis wrote: > Hello, > > Unfortunately, I accidentally deleted a message from Vadim that I > wanted to reply to. However, it had strayed from the topic of the > thread anyhow (which was called "sub-grammar for range pattern > constants") so I'll just startup a new thread here. > > Vadim wrote: > > > - Does "immutable" mean that the referenced object cannot change > > forever, even after current function has returned? > > It means that the referenced object cannot change for the lifetime > of that reference. > > > Is it possible in Rust to create a hash that stores its' keys by > > borrowed reference (assuming that the hash does not outlive > > contained keys) and be assured that the keys will not get changed > > after having been added to the hash? > > That would be possible, but the hash would have to be parameterized by > the lifetime of the keys. What we typically do instead is to have the > hash own the keys. > Not sure how this would prevent mutation of keys after they've been placed in the hash. Could you please point me to an example? I agree that owning keys would simplify everything, but on more than one occasion I've had to index existing large objects to speed-up some lookup operation. For example, let's say you need to de-dupe a vector of objects. In C++, I'd just create a hash_set of pointers to objects, but in Rust those would have to be borrowed references, right? (assuming I don't want to resort to using raw pointers) > - Can Rust actually guarantee that &mut are not aliased, - in the > > face of all indirection that may happen in a typical program? > > Yes. That is the job of the borrow checker, and the soundness of the > Rust type system depends on it. If you do not make use of managed data > (i.e., no `@`), this guarantee is static. Otherwise the guarantee is > enforced dynamically. > > The example program you gave is not supposed to execute without error; > the reason that it does is due to bugs. I am about to land (next day > or so) a branch fixing a number of such bugs. When I run that program > on my branch, I get a compilation failure. This is because, even > though you are using `@`, the compiler can clearly see that the > dynamic check would fail, and so it flags the error statically. If you > modify the program slightly you can evade this static check, but an > error should still occur dynamically. Currently it does not (even on > my branch), this is issue #5910. > Would it be the same kind of error I am getting in Rust 0.6 if I use owned vector instead of a managed one? This code fails to compile even if I'm borrowing distinct elements of z: fn add(x:&mut int, y:&mut int) { *x = *x + *y; } pub fn main() { let mut z = ~[1,2,3]; add(&mut z[0], &mut z[1]); print(fmt!("%d\n", z[0])); } So this sort of code will not be possible? (again, without raw pointers) Vadim -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Wed May 1 14:44:16 2013 From: clements at brinckerhoff.org (John Clements) Date: Wed, 1 May 2013 14:44:16 -0700 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: <5181579C.6080704@mozilla.com> References: <51815191.8050702@mozilla.com> <5181579C.6080704@mozilla.com> Message-ID: <4E36583E-E1D3-4BA0-826C-AD446B490F16@brinckerhoff.org> On May 1, 2013, at 10:57 AM, Graydon Hoare wrote: > On 13-05-01 10:32 AM, Lucian Branescu wrote: >> Is it too late/undesirable to have an explicit, separate syntax for >> docstrings, a bit like Lisps/Python? > > We have one: #[doc="..."] > > Doc comments are an alternative syntax for the same attribute because > nobody liked that. I would have, but... c'est la vie. John From danielmicay at gmail.com Wed May 1 14:45:42 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 1 May 2013 17:45:42 -0400 Subject: [rust-dev] immutability, aliasing guarantees, and optimization In-Reply-To: References: <20130501175158.GB7495@Mr-Bennet> Message-ID: On Wed, May 1, 2013 at 5:37 PM, Vadim wrote: > Thanks for your response Niko. A couple more questions if you don't mind: > > On Wed, May 1, 2013 at 10:51 AM, Niko Matsakis wrote: >> >> Hello, >> >> Unfortunately, I accidentally deleted a message from Vadim that I >> wanted to reply to. However, it had strayed from the topic of the >> thread anyhow (which was called "sub-grammar for range pattern >> constants") so I'll just startup a new thread here. >> >> Vadim wrote: >> >> > - Does "immutable" mean that the referenced object cannot change >> > forever, even after current function has returned? >> >> It means that the referenced object cannot change for the lifetime >> of that reference. >> >> > Is it possible in Rust to create a hash that stores its' keys by >> > borrowed reference (assuming that the hash does not outlive >> > contained keys) and be assured that the keys will not get changed >> > after having been added to the hash? >> >> That would be possible, but the hash would have to be parameterized by >> the lifetime of the keys. What we typically do instead is to have the >> hash own the keys. > > > Not sure how this would prevent mutation of keys after they've been placed > in the hash. Could you please point me to an example? > > I agree that owning keys would simplify everything, but on more than one > occasion I've had to index existing large objects to speed-up some lookup > operation. For example, let's say you need to de-dupe a vector of objects. > In C++, I'd just create a hash_set of pointers to objects, but in Rust those > would have to be borrowed references, right? (assuming I don't want to > resort to using raw pointers) > >> > - Can Rust actually guarantee that &mut are not aliased, - in the >> > face of all indirection that may happen in a typical program? >> >> Yes. That is the job of the borrow checker, and the soundness of the >> Rust type system depends on it. If you do not make use of managed data >> (i.e., no `@`), this guarantee is static. Otherwise the guarantee is >> enforced dynamically. >> >> The example program you gave is not supposed to execute without error; >> the reason that it does is due to bugs. I am about to land (next day >> or so) a branch fixing a number of such bugs. When I run that program >> on my branch, I get a compilation failure. This is because, even >> though you are using `@`, the compiler can clearly see that the >> dynamic check would fail, and so it flags the error statically. If you >> modify the program slightly you can evade this static check, but an >> error should still occur dynamically. Currently it does not (even on >> my branch), this is issue #5910. > > > Would it be the same kind of error I am getting in Rust 0.6 if I use owned > vector instead of a managed one? This code fails to compile even if I'm > borrowing distinct elements of z: > > fn add(x:&mut int, y:&mut int) > { > *x = *x + *y; > } > pub fn main() > { > let mut z = ~[1,2,3]; > add(&mut z[0], &mut z[1]); > print(fmt!("%d\n", z[0])); > } > > So this sort of code will not be possible? (again, without raw pointers) > > > Vadim Immutable borrowed pointers guarantee that the object is immutable as long as they exist (statically for Owned types, dynamically for @mut) and &mut is unique. You can already use borrowed pointers as the keys in maps/sets like this example with a set: pub fn bfs<'r, N: Eq + IterBytes + Hash, M: Map>(graph: &'r M, start: &'r N, f: &fn(node: &'r N) -> bool) { let mut visited = HashSet::new(); let mut q = Deque::new(); q.add_back(start); while !q.is_empty() { let node = q.pop_front(); visited.insert(node); for graph.find(node).unwrap().each |next| { if !visited.contains(&next) { f(next); q.add_back(next); visited.insert(next); } } } } @mut is basically an opt-out for most of the mutability/ownership system and it won't prevent keys from being mutated externally. @ and @mut are pretty much comparable to immutable/mutable objects in Python, and Python doesn't allow mutable objects to be used as map keys at all to avoid that edge case. From danielmicay at gmail.com Wed May 1 14:47:29 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 1 May 2013 17:47:29 -0400 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: <4E36583E-E1D3-4BA0-826C-AD446B490F16@brinckerhoff.org> References: <51815191.8050702@mozilla.com> <5181579C.6080704@mozilla.com> <4E36583E-E1D3-4BA0-826C-AD446B490F16@brinckerhoff.org> Message-ID: On Wed, May 1, 2013 at 5:44 PM, John Clements wrote: > > On May 1, 2013, at 10:57 AM, Graydon Hoare wrote: > >> On 13-05-01 10:32 AM, Lucian Branescu wrote: >>> Is it too late/undesirable to have an explicit, separate syntax for >>> docstrings, a bit like Lisps/Python? >> >> We have one: #[doc="..."] >> >> Doc comments are an alternative syntax for the same attribute because >> nobody liked that. > > I would have, but... c'est la vie. > > John The attribute syntax would get ugly pretty quickly for multi-line docstrings (which is hopefully eventually most, when they have examples). From graydon at mozilla.com Wed May 1 15:13:52 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 01 May 2013 15:13:52 -0700 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: <51815191.8050702@mozilla.com> <5181579C.6080704@mozilla.com> <4E36583E-E1D3-4BA0-826C-AD446B490F16@brinckerhoff.org> Message-ID: <518193A0.3080408@mozilla.com> On 13-05-01 02:47 PM, Daniel Micay wrote: > On Wed, May 1, 2013 at 5:44 PM, John Clements wrote: >> >> On May 1, 2013, at 10:57 AM, Graydon Hoare wrote: >> >>> On 13-05-01 10:32 AM, Lucian Branescu wrote: >>>> Is it too late/undesirable to have an explicit, separate syntax for >>>> docstrings, a bit like Lisps/Python? >>> >>> We have one: #[doc="..."] >>> >>> Doc comments are an alternative syntax for the same attribute because >>> nobody liked that. >> >> I would have, but... c'est la vie. >> >> John > > The attribute syntax would get ugly pretty quickly for multi-line > docstrings (which is hopefully eventually most, when they have > examples). Sorry, I didn't mean to say the attribute syntax looked very good for docs; clearly it didn't. I just ... don't know what else we're looking for here. Yet another attribute syntax, or a still-special-case docs-only syntax that's specifically _not_ comment-like? -Graydon From danielmicay at gmail.com Wed May 1 15:34:12 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 1 May 2013 18:34:12 -0400 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: <518193A0.3080408@mozilla.com> References: <51815191.8050702@mozilla.com> <5181579C.6080704@mozilla.com> <4E36583E-E1D3-4BA0-826C-AD446B490F16@brinckerhoff.org> <518193A0.3080408@mozilla.com> Message-ID: On Wed, May 1, 2013 at 6:13 PM, Graydon Hoare wrote: > On 13-05-01 02:47 PM, Daniel Micay wrote: >> On Wed, May 1, 2013 at 5:44 PM, John Clements wrote: >>> >>> On May 1, 2013, at 10:57 AM, Graydon Hoare wrote: >>> >>>> On 13-05-01 10:32 AM, Lucian Branescu wrote: >>>>> Is it too late/undesirable to have an explicit, separate syntax for >>>>> docstrings, a bit like Lisps/Python? >>>> >>>> We have one: #[doc="..."] >>>> >>>> Doc comments are an alternative syntax for the same attribute because >>>> nobody liked that. >>> >>> I would have, but... c'est la vie. >>> >>> John >> >> The attribute syntax would get ugly pretty quickly for multi-line >> docstrings (which is hopefully eventually most, when they have >> examples). > > Sorry, I didn't mean to say the attribute syntax looked very good for > docs; clearly it didn't. I just ... don't know what else we're looking > for here. Yet another attribute syntax, or a still-special-case > docs-only syntax that's specifically _not_ comment-like? > > -Graydon > I'm voicing my support for the nice docstring comments :). I'd be all for only having // comments and /// docstrings though, but I have a feeling a lot of people would strongly disagree. From wmatyjewicz at fastmail.fm Wed May 1 15:47:32 2013 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Thu, 02 May 2013 00:47:32 +0200 Subject: [rust-dev] Converting an owning pointer to a borrowed one inside a pattern Message-ID: <1367448452.30837.140661225395793.14AA4B7B@webmail.messagingengine.com> Hello everybody, I am to new to this list (and to the very promising language that Rust definitely is). While learning Rust and writing my first applications in it I stumbled upon the problem of matching an owned box to a variable pattern. I am wondering if there is any syntax to convert an owning pointer to a borrowed one when binding to a variable pattern. Please consider the following enum: enum Foobar { Foo(~str), Bar(~str) } Now, I would like to write a function fn f<'a>(fb: &'a Foobar) -> &'a str that takes a borrowed pointer to Foobar and returns a borrowed pointer to a string from either Foo or Bar. I know I can write it this way: fn f<'a>(fb: &'a Foobar) -> &'a str { let rs = match *fb { Foo(ref rs) => rs, Bar(ref rs) => rs }; let s : &'a str = *rs; s } However, is there an alternative that does not introduce (ref) indirection? Something that would make s in the code below be of type &str instead of ~str? fn f<'a>(fb: &'a Foobar) -> &'a str { match *fb { Foo(s) => s, Bar(s) => s } } Wojciech From lindsey at composition.al Wed May 1 16:12:38 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Wed, 1 May 2013 19:12:38 -0400 Subject: [rust-dev] rusti: a call to action Message-ID: Hi everyone, I'd like to give rusti more attention and make it actually useful and usable. As I'm sure we're all aware, a good REPL is especially valuable for a new and not-yet-well-documented language. Various open bugs [0, 1, 2] illustrate some of the current problems with rusti, and astrieanna recently volunteered to work on rusti, so I've been thinking about what it needs. To start with, there are no rusti tests [3]. This means that even when it's working, it doesn't stay that way for long; for instance, as strcat pointed out on IRC today, rusti is more broken now than it was in the 0.6 release, due to the last LLVM version bump. A `make check-stage[N]-rusti` build target does exist (and since there are no tests, it passes with flying colors, with 0 of 0 tests failing). We'll work on ameliorating this situation. Another problem seems to be social and circular: rusti doesn't work very well, so people don't use it, so bugs don't surface as fast as they would otherwise, so rusti doesn't work very well, so ... . I want to try to break that circularity by doing what we can to encourage a culture of rusti use, once we've made the initial effort to make it halfway tolerable. So, this is mostly just a call to action: please file rusti bugs, or comment on the existing bugs tagged with 'A-rusti' (a tag I just created) if you can shed any light on the issues therein. Thanks! Lindsey [0]: https://github.com/mozilla/rust/issues/5675 [1]: https://github.com/mozilla/rust/issues/5774 [2]: https://github.com/mozilla/rust/issues/5803 [3]: https://github.com/mozilla/rust/issues/5469 From illissius at gmail.com Wed May 1 16:25:43 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Thu, 2 May 2013 01:25:43 +0200 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <20130501145007.GA27185@Mr-Bennet> References: <517D6020.9080307@mozilla.com> <517D6312.7030203@gmail.com> <517D66F5.1020703@mozilla.com> <518019E7.70501@mozilla.com> <20130501145007.GA27185@Mr-Bennet> Message-ID: On Wed, May 1, 2013 at 4:50 PM, Niko Matsakis wrote: > On Wed, May 01, 2013 at 02:39:12PM +0200, G?bor Lehel wrote: > > > So *if* the plan ends up working out, then taking the second part of my > > earlier proposal: > > > > > You might also have a rule whereby dereferencing a variable when the > > > result would be a dynamically-sized type is allowed *if* the result is > > > immediately borrowed. Then instead of `impl Eq for {@str, ~str, &str}`, > > > you would have just `impl Eq for str`, and if you want to compare an > > > ~str you dereference it. > > > > Would that work? Would it be a good solution? > > I believe that would be the plan, yes. Most of these > "apply-to-almost-everything" > traits, like `Eq` or `Ord`, could be implemented in a similar fashion. > > I'm not sure what problem you are proposing this as a solution *for*, > though. Do you mean the problem of comparing strings using `==`? > Yeah. Which was the original topic of this thread... :) > > I suppose it is true that under this proposal you could write > > let str1: ~str = ~"hi"; > let str2: &str = "hi"; > *str1 == *str2 > > and it would work fine. That is a nice side-effect I hadn't > considered. > Right. That was the intent. And similarly(?) for comparing against string literals. (Though I'm not completely clear about when auto-borrowing does or doesn't happen, and how that would interact with this.) > > *An aside:* Note that dereferencing a pointer to an unsized object is > only allowed in an "lvalue" context (that is, when we are taking its > address): > > let str1: ~str = ~"hi"; > let foo = *str1; // ERROR > let bar = &*str1; // OK > > Here, `foo` is an error because `*str1` is being evaluated in an > rvalue context, but `bar` is fine, because `*str1` is being evaluted > in an lvalue context. In the case of `==`, this works out because the > arguments to overloaded operators are always passed by reference. > Yep, that's what I was figuring. I'm not sure what "lvalue context" means precisely -- it's not actually on the left hand side of anything here, and the other example below where it *is* on the LHS is illegal -- but the shape of things matches what I was expecting. > > *A further aside:* don't be misled by my use of the term > "lvalue context" into thinking that a program like this would > be legal: > > let mut str1: ~str = ~"Hello"; > *str1 = "World"; // ERROR > > This is illegal because assigning to an lvalue of unsized type is > illegal, even though `*str1` appears in an lvalue context. > Hmm. If I'm thinking right this is because the size of the string is stored in the pointer, which, if the string gets changed behind its back, would become invalid? > > > > regards, > Niko > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Wed May 1 16:57:22 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 19:57:22 -0400 Subject: [rust-dev] Dynamically sized types, revisited In-Reply-To: <518163A6.80009@mozilla.com> References: <20130501105114.GA1611@Mr-Bennet> <518163A6.80009@mozilla.com> Message-ID: <20130501235722.GA18317@Mr-Bennet> On Wed, May 01, 2013 at 11:49:10AM -0700, Graydon Hoare wrote: > 1. Why _exactly_ (if it's possible to reconstruct) did this factoring > not work last time, and what has changed since? AFAIK we never looked deeply into changing the representation of ~[] and @[] such that they are represented by a pair rather than a single pointer. In fact, I originally had it as an explicit goal that ~T for any T was always a pointer, whereas in this proposal, ~T may be a single pointer (for sized types) or a pair (for unsized types). In some of my original proposals I also considered a new kind (what I called `Sized`) to be non-tenable, so I had some severe limitations on what you could do with an unsized type, which made them kind of useless. With the benefit of hindsight, I am of the opinion that having a `Sized` kind is certainly no *more* confusing than the current non-compositionality of `~[T]`, and it enables more programs to boot. It is a bit unclear how often we will need to use `Sized` in practice. I argued that a lot of code may not need it, becaues it is implied by Copy and Clone, but certainly a fair amount will. For example, to define a standard `map` function over vectors, one would probably write: fn map(v: &[A], f: &fn(&A) -> B) -> ~[B] { ... } Here the kind on `A` is needed because `A` appears inside `&[A]`, and you can only have slices of sized types; the kind on `B` is needed because a `B` is returned by `f` and because it appears within a vector on the RHS. > 2. What ballpark amount-of-effort do you think the work entails in > implementation, and how much do you think it will perturb code? > It _looks_ to me like .. relatively little on both counts, but it's > hard to know. It seems like a relatively straightforward change, actually, but it is somewhat...extensive. The representation of types within the compiler will want to change, which will trickle through various parts of the code, and we'll have to update trans of course (but that's probably the easy part). One tricky part might be dealing with the various bits of unsafe code that think they know what the representation of a ~[T] is, but I imagine we'll find most of those crashes pretty quickly. > 3. Are any capabilities lost? I don't see any, but I'm a little > slow on the implications, often. It seems like maybe the GC will > no longer be able to track sizes by looking in pointees, but > that's not so bad; there's a digital trie that already covers > that. A very good question. I don't think any capabilities are lost from an expressiveness point-of-view. I hadn't thought about the implications for garbage collection. I think that all the information that the GC could need is still present, but it has moved around, and the new approach would be somewhat less amenable to a conservative scan. Whereas before everything you needed was present in the `@[T]` box, in the new world, the length of the array would be found next to the pointer that led you to the `@[T]` box in the first place. And of course in a conservative GC you can't be sure that it really was a pointer and not some random int, so you can't trust that. So we'd have to find a way to stash the data somewhere else to handle that case, perhaps in a side-table as you suggest---or else we could duplicate the information in the GC header, taking the place of the ref count. Niko From niko at alum.mit.edu Wed May 1 17:13:06 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 20:13:06 -0400 Subject: [rust-dev] immutability, aliasing guarantees, and optimization In-Reply-To: References: <20130501175158.GB7495@Mr-Bennet> Message-ID: <20130502001306.GB18317@Mr-Bennet> > Not sure how this would prevent mutation of keys after they've been placed > in the hash. Could you please point me to an example? strcat's example is fine. Basically, when you create an immutable, borrowed pointer, you also promise to keep that data immutable for the lifetime of the pointer---and the compiler holds you to it. > Would it be the same kind of error I am getting in Rust 0.6 if I use owned > vector instead of a managed one? This code fails to compile even if I'm > borrowing distinct elements of z: Yes, same sort of error. The checks do not distinguish between the indices of the vector. To address this particular case, I think we will eventually add a variety of methods that take in an `&mut [T]` and allow you to slice it up in various ways. For example, this would be perfectly sound, although the implementation would be unsafe: /// Returns `v[0:index]` and `v[index:]`, to use Python notation fn split_mut<'a, T>(v: &'a mut [T], index: uint) -> (&'a mut [T], &'a mut [T]); This would then be sufficient to implement your example, if awkwardly: > fn add(x:&mut int, y:&mut int) > { > *x = *x + *y; > } > pub fn main() > { > let mut z = ~[1,2,3]; > { // the block contains the scope of the split > let (z1, z2) = z.split_mut(1); > add(&mut z1[0], &mut z2[0]); > } > print(fmt!("%d\n", z[0])); > } Presumably we'd then make more nice wrappers around `split_mut` to handle various common cases. Niko From graydon at mozilla.com Wed May 1 17:45:58 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 01 May 2013 17:45:58 -0700 Subject: [rust-dev] Dynamically sized types, revisited In-Reply-To: <20130501235722.GA18317@Mr-Bennet> References: <20130501105114.GA1611@Mr-Bennet> <518163A6.80009@mozilla.com> <20130501235722.GA18317@Mr-Bennet> Message-ID: <5181B746.8060605@mozilla.com> On 13-05-01 04:57 PM, Niko Matsakis wrote: > On Wed, May 01, 2013 at 11:49:10AM -0700, Graydon Hoare wrote: >> 1. Why _exactly_ (if it's possible to reconstruct) did this factoring >> not work last time, and what has changed since? > > AFAIK we never looked deeply into changing the representation of ~[] > and @[] such that they are represented by a pair rather than a single > pointer. In fact, I originally had it as an explicit goal that ~T for > any T was always a pointer, whereas in this proposal, ~T may be a > single pointer (for sized types) or a pair (for unsized types). Ok. Makes sense. > It is a bit unclear how often we will need to use `Sized` in practice. > I argued that a lot of code may not need it, becaues it is implied by > Copy and Clone, but certainly a fair amount will. For example, to > define a standard `map` function over vectors, one would probably > write: > > fn map(v: &[A], f: &fn(&A) -> B) -> ~[B] { ... } > > Here the kind on `A` is needed because `A` appears inside `&[A]`, and > you can only have slices of sized types; the kind on `B` is needed > because a `B` is returned by `f` and because it appears within a > vector on the RHS. Concerning the 'Sized' kind, I wonder if it can ever be implied, somehow, due to the use of T in [T]. Like it's pretty much mandatory if you do: impl foo for [T] { } that the there actually be right? You can't denote the [T] type for any non-Sized T. Not that I'm really keen on any additional inference rules that a user needs to remember. Hmm. >> 2. What ballpark amount-of-effort do you think the work entails in >> implementation, and how much do you think it will perturb code? >> It _looks_ to me like .. relatively little on both counts, but it's >> hard to know. > > It seems like a relatively straightforward change, actually, but it is > somewhat...extensive. The representation of types within the compiler > will want to change, which will trickle through various parts of the > code, and we'll have to update trans of course (but that's probably > the easy part). One tricky part might be dealing with the various bits > of unsafe code that think they know what the representation of a ~[T] > is, but I imagine we'll find most of those crashes pretty quickly. > >> 3. Are any capabilities lost? I don't see any, but I'm a little >> slow on the implications, often. It seems like maybe the GC will >> no longer be able to track sizes by looking in pointees, but >> that's not so bad; there's a digital trie that already covers >> that. > > A very good question. I don't think any capabilities are lost from an > expressiveness point-of-view. I hadn't thought about the implications > for garbage collection. I think that all the information that the GC > could need is still present, but it has moved around, and the new > approach would be somewhat less amenable to a conservative > scan. Whereas before everything you needed was present in the `@[T]` > box, in the new world, the length of the array would be found next to > the pointer that led you to the `@[T]` box in the first place. And of > course in a conservative GC you can't be sure that it really was a > pointer and not some random int, so you can't trust that. So we'd have > to find a way to stash the data somewhere else to handle that case, > perhaps in a side-table as you suggest---or else we could duplicate > the information in the GC header, taking the place of the ref count. Sizes are already tracked in the digital trie since we have to do a nearest-value-less-than-P search for each possible pointer. So it's not actually a risk / problem; just makes us a tiny bit more committed to that structure. -Graydon From swede at earthling.net Wed May 1 18:50:18 2013 From: swede at earthling.net (Erik S) Date: Wed, 01 May 2013 19:50:18 -0600 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: Message-ID: <5181C65A.10501@earthling.net> John, I would suggest requiring *exactly* three slashes for a doc comment (or *exactly* two stars for a /** -- */ style doc comment). This matches with Doxygen's parsing (I think), and makes both the examples below parse correctly. Erik On 5/1/2013 11:29 AM, John Clements wrote: > Currently, the set of doc comments includes (among other things) lines beginning with three slashes, *unless* they're entirely slashes. Presumably, this is to ensure that things like > > ///////////// > // Time to go get some coffee! > //////////// > > ... aren't parsed as two doc comments consisting entirely of slashes (with an ignored comment in between. > > This makes sense to me. > > However, it also means that things like > > /// My awesome procedure > /// > /// - does everything, > /// > /// - is kinda slow. > > is parsed as three lines of doc comments, rather than five. > > I propose that '///' should be treated as a doc comment, essentially by special-casing it. > > The risk is that certain existing normal-comments would be changed into doc-comments, causing compilation failure. If people think this change is (otherwise) sensible, I'll naturally check it locally on my tree before inflicting it on anyone else. > > Best, > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From niko at alum.mit.edu Wed May 1 19:06:50 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 22:06:50 -0400 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: References: <517D6020.9080307@mozilla.com> <517D6312.7030203@gmail.com> <517D66F5.1020703@mozilla.com> <518019E7.70501@mozilla.com> <20130501145007.GA27185@Mr-Bennet> Message-ID: <20130502020650.GA2285@Mr-Bennet> On Thu, May 02, 2013 at 01:25:43AM +0200, G?bor Lehel wrote: > Yep, that's what I was figuring. I'm not sure what "lvalue context" means > precisely -- it's not actually on the left hand side of anything here, and > the other example below where it *is* on the LHS is illegal -- but the > shape of things matches what I was expecting. Lvalues refer to values that have addresses. So by "lvalue context" I mean a context where you evaluate the expression to determine the address where it resides. > > *A further aside:* don't be misled by my use of the term > > "lvalue context" into thinking that a program like this would > > be legal: > > > > let mut str1: ~str = ~"Hello"; > > *str1 = "World"; // ERROR > > > > This is illegal because assigning to an lvalue of unsized type is > > illegal, even though `*str1` appears in an lvalue context. > > > > Hmm. If I'm thinking right this is because the size of the string is stored > in the pointer, which, if the string gets changed behind its back, would > become invalid? The main reason for this is that there is no guarantee that the length of the string you are writing in matches the length of the string you are overwriting. In the example above, `str1` is allocated to a string of 5 characters---so what happens if you do `*str1 = "a very long string"`? Memory overruns...? Niko From niko at alum.mit.edu Wed May 1 19:09:05 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 22:09:05 -0400 Subject: [rust-dev] Dynamically sized types, revisited In-Reply-To: <5181B746.8060605@mozilla.com> References: <20130501105114.GA1611@Mr-Bennet> <518163A6.80009@mozilla.com> <20130501235722.GA18317@Mr-Bennet> <5181B746.8060605@mozilla.com> Message-ID: <20130502020905.GB2285@Mr-Bennet> > Concerning the 'Sized' kind, I wonder if it can ever be implied, > somehow, due to the use of T in [T]. Like it's pretty much mandatory if > you do: > > impl foo for [T] { > } > > that the there actually be right? You can't denote the [T] > type for any non-Sized T. Not that I'm really keen on any additional > inference rules that a user needs to remember. Hmm. Yes, conceivably we could try to do smarter defaulting in this case. I didn't propose it so as to keep things simple. Niko From niko at alum.mit.edu Wed May 1 19:11:14 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 1 May 2013 22:11:14 -0400 Subject: [rust-dev] Converting an owning pointer to a borrowed one inside a pattern In-Reply-To: <1367448452.30837.140661225395793.14AA4B7B@webmail.messagingengine.com> References: <1367448452.30837.140661225395793.14AA4B7B@webmail.messagingengine.com> Message-ID: <20130502021114.GC2285@Mr-Bennet> > However, is there an alternative that does not introduce (ref) > indirection? Something that would make s in the code below be of type > &str instead of ~str? There is not, today. This is precisely what the recent thread "dynamically sized types, revisited" is discussing, however. If that proposal were to go through, one could do the following: > fn f<'a>(fb: &'a Foobar) -> &'a str { > match *fb { > Foo(~ref s) => s, > Bar(~ref s) => s > } > } Niko From thadguidry at gmail.com Wed May 1 20:34:03 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 1 May 2013 22:34:03 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: <25622438.109751367223000089.JavaMail.weblogic@epml21> <517EC8AA.8030308@mozilla.com> Message-ID: Thanks to the incredible outpouring of support from the community on IRC to help me get Cygwin supported, tonight I had somewhat better success... as I have been patching my way through Rust's source with the help from those incredible IRC folks. Thanks guys and gals ! We have been adding if define's etc... for __CYGWIN__ such as... #if defined(__WIN32__)|| defined(__CYGWIN__) etc... and also patched rust_task.h to support Cygwin RED_ZONE_SIZE, all of which might need further tweaks... but anyways... We have hit a snag that we are not sure what to do about... error during make with GCC 4.5.3 (not Clang, since there will be other issues to address there later) on Cygwin ... http://pastebin.mozilla.org/2367675 Thoughts ? -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Wed May 1 20:47:05 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 1 May 2013 23:47:05 -0400 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: <25622438.109751367223000089.JavaMail.weblogic@epml21> <517EC8AA.8030308@mozilla.com> Message-ID: On Wed, May 1, 2013 at 11:34 PM, Thad Guidry wrote: > Thanks to the incredible outpouring of support from the community on IRC to > help me get Cygwin supported, tonight I had somewhat better success... as I > have been patching my way through Rust's source with the help from those > incredible IRC folks. Thanks guys and gals ! > > We have been adding if define's etc... for __CYGWIN__ such as... #if > defined(__WIN32__)|| defined(__CYGWIN__) etc... and also patched rust_task.h > to support Cygwin RED_ZONE_SIZE, all of which might need further tweaks... > but anyways... > > We have hit a snag that we are not sure what to do about... error during > make with GCC 4.5.3 (not Clang, since there will be other issues to address > there later) on Cygwin ... > > http://pastebin.mozilla.org/2367675 > > Thoughts ? > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > It seems libuv has no support for cygwin as a platform. Is it possible to compile native win32 apps using cygwin, as one would with mingw? I am unfamiliar with cygwin and windows in general. From thadguidry at gmail.com Wed May 1 20:49:42 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 1 May 2013 22:49:42 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: <25622438.109751367223000089.JavaMail.weblogic@epml21> <517EC8AA.8030308@mozilla.com> Message-ID: This FAQ has most of those answers, Corey, just scroll down it to see the API and Programming Questions : http://cygwin.com/faq/ On Wed, May 1, 2013 at 10:47 PM, Corey Richardson wrote: > On Wed, May 1, 2013 at 11:34 PM, Thad Guidry wrote: > > Thanks to the incredible outpouring of support from the community on IRC > to > > help me get Cygwin supported, tonight I had somewhat better success... > as I > > have been patching my way through Rust's source with the help from those > > incredible IRC folks. Thanks guys and gals ! > > > > We have been adding if define's etc... for __CYGWIN__ such as... #if > > defined(__WIN32__)|| defined(__CYGWIN__) etc... and also patched > rust_task.h > > to support Cygwin RED_ZONE_SIZE, all of which might need further > tweaks... > > but anyways... > > > > We have hit a snag that we are not sure what to do about... error during > > make with GCC 4.5.3 (not Clang, since there will be other issues to > address > > there later) on Cygwin ... > > > > http://pastebin.mozilla.org/2367675 > > > > Thoughts ? > > > > -- > > -Thad > > http://www.freebase.com/view/en/thad_guidry > > > > It seems libuv has no support for cygwin as a platform. Is it possible > to compile native win32 apps using cygwin, as one would with mingw? I > am unfamiliar with cygwin and windows in general. > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Wed May 1 20:56:43 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 1 May 2013 23:56:43 -0400 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: <25622438.109751367223000089.JavaMail.weblogic@epml21> <517EC8AA.8030308@mozilla.com> Message-ID: On Wed, May 1, 2013 at 11:49 PM, Thad Guidry wrote: > This FAQ has most of those answers, Corey, just scroll down it to see the > API and Programming Questions : http://cygwin.com/faq/ > So from http://cygwin.com/faq/faq-nochunks.html#faq.programming.win32-no-cygwin, perhaps you should try using mingw-gcc, and see how far that gets you. From thadguidry at gmail.com Wed May 1 21:03:25 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 1 May 2013 23:03:25 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: <25622438.109751367223000089.JavaMail.weblogic@epml21> <517EC8AA.8030308@mozilla.com> Message-ID: I have mingw64 installed. See my Cygwin Setup screenshot here: https://docs.google.com/file/d/0B533WzlrxWraSHgzdVpGM29WQ1k/edit?usp=sharing On Wed, May 1, 2013 at 10:56 PM, Corey Richardson wrote: > On Wed, May 1, 2013 at 11:49 PM, Thad Guidry wrote: > > This FAQ has most of those answers, Corey, just scroll down it to see the > > API and Programming Questions : http://cygwin.com/faq/ > > > > So from > http://cygwin.com/faq/faq-nochunks.html#faq.programming.win32-no-cygwin, > perhaps you should try using mingw-gcc, and see how far that gets you. > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Wed May 1 21:05:15 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 1 May 2013 23:05:15 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: <25622438.109751367223000089.JavaMail.weblogic@epml21> <517EC8AA.8030308@mozilla.com> Message-ID: Sorry... in the screenshot "Current" column shows what I have installed "currently". On Wed, May 1, 2013 at 11:03 PM, Thad Guidry wrote: > I have mingw64 installed. See my Cygwin Setup screenshot here: > https://docs.google.com/file/d/0B533WzlrxWraSHgzdVpGM29WQ1k/edit?usp=sharing > > > On Wed, May 1, 2013 at 10:56 PM, Corey Richardson wrote: > >> On Wed, May 1, 2013 at 11:49 PM, Thad Guidry >> wrote: >> > This FAQ has most of those answers, Corey, just scroll down it to see >> the >> > API and Programming Questions : http://cygwin.com/faq/ >> > >> >> So from >> http://cygwin.com/faq/faq-nochunks.html#faq.programming.win32-no-cygwin, >> perhaps you should try using mingw-gcc, and see how far that gets you. >> > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Thu May 2 03:18:44 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 2 May 2013 06:18:44 -0400 Subject: [rust-dev] rustdoc feature request: grouping methods Message-ID: <20130502101844.GF2285@Mr-Bennet> I often find when writing code that I want to introduce "sections" into my file. Typically I do this like: //////////////////////////////////////////////////////// // Node construction // // Methods for constructing new nodes. I find this helpful when browsing through the code. I imagine something similar would be helpful when browsing through rustdocs. Maybe we can find a way to incorporate some sort of "section" to use when grouping items, methods, fields, etc. I imagine we could draw on Markdown's `#`, `##`, `###` notation to define sections, subsections, and so forth, but I'm just not sure how we would let rustdoc know about it, since there is nothing in particular to attach the attribute to. Any thoughts? Is this something other people would like? Niko From lists at dhardy.name Thu May 2 05:27:52 2013 From: lists at dhardy.name (Diggory Hardy) Date: Thu, 02 May 2013 14:27:52 +0200 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: <518193A0.3080408@mozilla.com> Message-ID: <4175584.8s2hqS3Dao@l10036> > I'm voicing my support for the nice docstring comments :). > > I'd be all for only having // comments and /// docstrings though, but > I have a feeling a lot of people would strongly disagree. > _______________________________________________ Use /// to start a doc-string and / to continue one. This seemed like a reasonable tradeoff between minimal typing on each line and avoiding the problems of requiring a terminating */ when I last thought about this. /// Factorial / / Returns n*n(n-1)*...*1 fn fact(n: int) ... From lucian.branescu at gmail.com Thu May 2 05:31:43 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Thu, 2 May 2013 13:31:43 +0100 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: <51815191.8050702@mozilla.com> <5181579C.6080704@mozilla.com> <4E36583E-E1D3-4BA0-826C-AD446B490F16@brinckerhoff.org> Message-ID: Not necessarily: #[doc=""" Actual docs, free to contain almost any characters, without the need for a leading character every line and with optional manual wrapping. """] But since C, C++, Java tend to have comment docstrings, I do realise I'm in the minority. On 1 May 2013 22:47, Daniel Micay wrote: > On Wed, May 1, 2013 at 5:44 PM, John Clements > wrote: > > > > On May 1, 2013, at 10:57 AM, Graydon Hoare wrote: > > > >> On 13-05-01 10:32 AM, Lucian Branescu wrote: > >>> Is it too late/undesirable to have an explicit, separate syntax for > >>> docstrings, a bit like Lisps/Python? > >> > >> We have one: #[doc="..."] > >> > >> Doc comments are an alternative syntax for the same attribute because > >> nobody liked that. > > > > I would have, but... c'est la vie. > > > > John > > The attribute syntax would get ugly pretty quickly for multi-line > docstrings (which is hopefully eventually most, when they have > examples). > _______________________________________________ > 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 steven at ashley.net.nz Thu May 2 05:39:56 2013 From: steven at ashley.net.nz (Steven Ashley) Date: Fri, 3 May 2013 00:39:56 +1200 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: <5181C65A.10501@earthling.net> References: <5181C65A.10501@earthling.net> Message-ID: On Thu, May 2, 2013 at 1:50 PM, Erik S wrote: > John, > I would suggest requiring *exactly* three slashes for a doc comment (or > *exactly* two stars for a /** -- */ style doc comment). This matches > with Doxygen's parsing (I think), and makes both the examples below > parse correctly. > > Erik > I am a fan of this proposal. Its simple, predicable and similar to doc-comments in Doxygen, Java, and C#. Steve > > On 5/1/2013 11:29 AM, John Clements wrote: > > Currently, the set of doc comments includes (among other things) lines > beginning with three slashes, *unless* they're entirely slashes. > Presumably, this is to ensure that things like > > > > ///////////// > > // Time to go get some coffee! > > //////////// > > > > ... aren't parsed as two doc comments consisting entirely of slashes > (with an ignored comment in between. > > > > This makes sense to me. > > > > However, it also means that things like > > > > /// My awesome procedure > > /// > > /// - does everything, > > /// > > /// - is kinda slow. > > > > is parsed as three lines of doc comments, rather than five. > > > > I propose that '///' should be treated as a doc comment, essentially by > special-casing it. > > > > The risk is that certain existing normal-comments would be changed into > doc-comments, causing compilation failure. If people think this change is > (otherwise) sensible, I'll naturally check it locally on my tree before > inflicting it on anyone else. > > > > Best, > > > > John > > > > _______________________________________________ > > 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 Thu May 2 05:50:52 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 2 May 2013 08:50:52 -0400 Subject: [rust-dev] rustdoc feature request: grouping methods In-Reply-To: <20130502101844.GF2285@Mr-Bennet> References: <20130502101844.GF2285@Mr-Bennet> Message-ID: Are explicit `mod`s too heavyweight for this? On Thu, May 2, 2013 at 6:18 AM, Niko Matsakis wrote: > I often find when writing code that I want to introduce "sections" > into my file. Typically I do this like: > > //////////////////////////////////////////////////////// > // Node construction > // > // Methods for constructing new nodes. > > I find this helpful when browsing through the code. I imagine > something similar would be helpful when browsing through rustdocs. > Maybe we can find a way to incorporate some sort of "section" > to use when grouping items, methods, fields, etc. I imagine > we could draw on Markdown's `#`, `##`, `###` notation to > define sections, subsections, and so forth, but I'm just > not sure how we would let rustdoc know about it, since there > is nothing in particular to attach the attribute to. > > Any thoughts? Is this something other people would like? > > > 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 fredrik at haard.se Thu May 2 06:03:56 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Thu, 2 May 2013 15:03:56 +0200 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: References: <51815191.8050702@mozilla.com> <5181579C.6080704@mozilla.com> <4E36583E-E1D3-4BA0-826C-AD446B490F16@brinckerhoff.org> Message-ID: FWIW, I am very much in favor of having 'proper' docstrings instead of comment docstrings. I don't really see any upside to comment docstrings at all... 2013/5/2 Lucian Branescu : > Not necessarily: > > #[doc=""" > Actual docs, free to contain almost any characters, without the need for a > leading > character every line and with optional manual wrapping. > """] > > But since C, C++, Java tend to have comment docstrings, I do realise I'm in > the minority. > > > > On 1 May 2013 22:47, Daniel Micay wrote: >> >> On Wed, May 1, 2013 at 5:44 PM, John Clements >> wrote: >> > >> > On May 1, 2013, at 10:57 AM, Graydon Hoare wrote: >> > >> >> On 13-05-01 10:32 AM, Lucian Branescu wrote: >> >>> Is it too late/undesirable to have an explicit, separate syntax for >> >>> docstrings, a bit like Lisps/Python? >> >> >> >> We have one: #[doc="..."] >> >> >> >> Doc comments are an alternative syntax for the same attribute because >> >> nobody liked that. >> > >> > I would have, but... c'est la vie. >> > >> > John >> >> The attribute syntax would get ugly pretty quickly for multi-line >> docstrings (which is hopefully eventually most, when they have >> examples). >> _______________________________________________ >> 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 > -- /f I reject your reality and substitute my own. http://courteous.ly/yp3Zgd From niko at alum.mit.edu Thu May 2 07:01:53 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 2 May 2013 10:01:53 -0400 Subject: [rust-dev] rustdoc feature request: grouping methods In-Reply-To: References: <20130502101844.GF2285@Mr-Bennet> Message-ID: <20130502140153.GG2285@Mr-Bennet> On Thu, May 02, 2013 at 08:50:52AM -0400, Benjamin Striegel wrote: > Are explicit `mod`s too heavyweight for this? When I wrote the e-mail, I considered mods and rejected them, but now that I think about it some more, it is a tempting alternative. Downsides to mods (and counterpoints) are: - Rightward drift - could be addressed by changing indentation conventions - You are forced to use the mod when you call fn - maybe good - can often be avoided by `pub use` anyhow - More `use` statements - not such a big deal, maybe even good, since dependencies are more fine-grained - Doesn't apply to structs and impls of methods - you can declare substructs, and you can declare multiple `pub impl` declarations The last point about declaring substructs is actually particularly important for working happily within the borrow checker: that is, having all your fields grouped into one big struct is an active anti-pattern. Dividing your fields into substructs and declaring methods on those substructs is much more borrowck-friendly. (I plan to write a blog post on this at some point...) So maybe I'll try mods for a while and see how it feels. Niko From clements at brinckerhoff.org Thu May 2 09:34:05 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 2 May 2013 09:34:05 -0700 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: <5181C65A.10501@earthling.net> References: <5181C65A.10501@earthling.net> Message-ID: <4B75971F-77C3-4359-80B2-92C416D388CF@brinckerhoff.org> On May 1, 2013, at 6:50 PM, Erik S wrote: > John, > I would suggest requiring *exactly* three slashes for a doc comment (or > *exactly* two stars for a /** -- */ style doc comment). This matches > with Doxygen's parsing (I think), and makes both the examples below > parse correctly. Both of these restrictions make sense to me. I took a quick look at the current tree, grepping for '////'. Here's what I got: jclements-09740:~/tryrust clements> git grep '////' * src/librustc/middle/subst.rs://///////////////////////////////////////////////////////////////////////// src/librustc/middle/subst.rs://///////////////////////////////////////////////////////////////////////// src/librustc/middle/subst.rs://///////////////////////////////////////////////////////////////////////// src/librustc/middle/trans/debuginfo.rs://////////////// src/rt/msvc/inttypes.h://///////////////////////////////////////////////////////////////////////////// src/rt/msvc/stdint.h://///////////////////////////////////////////////////////////////////////////// src/test/pretty/doc-comments.rs:////////////////////////////////// src/test/pretty/doc-comments.rs:////////////////////////////////// None of these include any non-slash characters, and are therefore parsed correctly (based on my inspection) as non-doc-comments. They would also be parsed correctly by the restricted form (doc comments must have exactly three slashes. I took a look at '/***', as well, and got even more interesting results: jclements-09740:~/tryrust clements> git grep '/\*\*\*' * doc/prep.js:/*** src/libcore/cast.rs:/**************************************************************************** src/libcore/unstable.rs:/**************************************************************************** src/libcore/unstable.rs:/****************************************************************************/ src/libstd/arc.rs:/**************************************************************************** src/libstd/arc.rs:/**************************************************************************** src/libstd/arc.rs:/**************************************************************************** src/libstd/arc.rs:/**************************************************************************** src/libstd/sync.rs:/**************************************************************************** src/libstd/sync.rs:/**************************************************************************** src/libstd/sync.rs:/**************************************************************************** src/libstd/sync.rs:/**************************************************************************** src/libstd/sync.rs:/**************************************************************************** src/libstd/sync.rs: /************************************************************************ src/libstd/sync.rs: /************************************************************************ src/libstd/sync.rs: /************************************************************************ src/rt/rust_upcall.cpp:/********************************************************************** src/rt/rust_upcall.cpp:/**********************************************************************/ src/rt/rust_upcall.cpp:/********************************************************************** src/rt/rust_upcall.cpp:/********************************************************************** src/rt/rust_upcall.cpp:/**********************************************************************/ src/test/pretty/doc-comments.rs:/********************************/ src/test/pretty/doc-comments.rs:/********************************/ The first of these is apparently intended to be a docstring, so putting the restriction in place would have missed this one. On the other hand, all of the ones that start with a lot of stars but don't end with a slash *are* currently parsed as docstrings, and (at least in the cases I looked at) almost certainly shouldn't be. So, I think that this restriction would also improve the quality of our code. Anyone object to changing the parser in this way? To be clear, these two restrictions are (in my view) orthogonal to other possible changes. I'd still be delighted to get rid of some of the doc-string forms. John > > Erik > > On 5/1/2013 11:29 AM, John Clements wrote: >> Currently, the set of doc comments includes (among other things) lines beginning with three slashes, *unless* they're entirely slashes. Presumably, this is to ensure that things like >> >> ///////////// >> // Time to go get some coffee! >> //////////// >> >> ... aren't parsed as two doc comments consisting entirely of slashes (with an ignored comment in between. >> >> This makes sense to me. >> >> However, it also means that things like >> >> /// My awesome procedure >> /// >> /// - does everything, >> /// >> /// - is kinda slow. >> >> is parsed as three lines of doc comments, rather than five. >> >> I propose that '///' should be treated as a doc comment, essentially by special-casing it. >> >> The risk is that certain existing normal-comments would be changed into doc-comments, causing compilation failure. If people think this change is (otherwise) sensible, I'll naturally check it locally on my tree before inflicting it on anyone else. >> >> Best, >> >> John >> >> _______________________________________________ >> 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 fredrik at haard.se Thu May 2 13:36:25 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Thu, 2 May 2013 22:36:25 +0200 Subject: [rust-dev] String codecs Message-ID: Since there are no encoding support in Rust beyond utf-8/16, I've been toying around with str<->[u8] codec generation using the specifications from unicode.org (inspired by the cpython implementation) as my first learning-Rust project. I'm now at the point where I can successfully generate a charmaps and use them to decode and encode strings; the source, horrible as it may be, is available at https://github.com/haard/rust-codecs. Since I've solved the problem I set out to do (for a given value of 'solve'), I wonder if an approach like this is anything that would be interesting to include in std-that-will-be-named-something-else? If that is the case I'd be happy to clean up, make it less slow, and take directions on what a Rust API should look like. Otherwise, I'll just find something else to look at =) /fredrik -- /f CAPS LOCK IS CRUISE CONTROL FOR COOL! From banderson at mozilla.com Thu May 2 15:10:05 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 02 May 2013 15:10:05 -0700 Subject: [rust-dev] rustdoc feature request: grouping methods In-Reply-To: <20130502101844.GF2285@Mr-Bennet> References: <20130502101844.GF2285@Mr-Bennet> Message-ID: <5182E43D.1000807@mozilla.com> On 05/02/2013 03:18 AM, Niko Matsakis wrote: > I often find when writing code that I want to introduce "sections" > into my file. Typically I do this like: > > //////////////////////////////////////////////////////// > // Node construction > // > // Methods for constructing new nodes. > > I find this helpful when browsing through the code. I imagine > something similar would be helpful when browsing through rustdocs. > Maybe we can find a way to incorporate some sort of "section" > to use when grouping items, methods, fields, etc. I imagine > we could draw on Markdown's `#`, `##`, `###` notation to > define sections, subsections, and so forth, but I'm just > not sure how we would let rustdoc know about it, since there > is nothing in particular to attach the attribute to. > > Any thoughts? Is this something other people would like? > Right now rustdoc does not care about the order that things appear in the source, instead sorting items by AST node type. I guess that if we did add a way to break modules into sections then rustdoc could only do that sorting within sections. As you say though, there's no way currently to attach this sort of information to the AST, which is where rustdoc gets its documentation from. If we *were* to allow rustdoc to interpret this sort of standalone comment, then that throws into question the entire strategy of attaching doc comments to AST nodes. Tangentially, I do think that rustdoc needs to be rethought generally. What I would like to do is create an HTML prototype that demonstrates what we would like for the docs to look like (encompassing both the standalone docs and the rustdocs) and then adapt rustdoc to output those docs. I don't know if I personally will get to that any time soon though. From niko at alum.mit.edu Thu May 2 16:53:39 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 2 May 2013 19:53:39 -0400 Subject: [rust-dev] should '///' be a doc comment? In-Reply-To: <4B75971F-77C3-4359-80B2-92C416D388CF@brinckerhoff.org> References: <5181C65A.10501@earthling.net> <4B75971F-77C3-4359-80B2-92C416D388CF@brinckerhoff.org> Message-ID: <20130502235339.GA25898@Mr-Bennet> > Anyone object to changing the parser in this way? To be clear, > these two restrictions are (in my view) orthogonal to other possible > changes. I'd still be delighted to get rid of some of the doc-string > forms. Makes sense to me. Niko From pwalton at mozilla.com Thu May 2 18:12:58 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 02 May 2013 18:12:58 -0700 Subject: [rust-dev] RFC: Pattern matching binding operator Message-ID: <51830F1A.9030708@mozilla.com> Hi everyone, There's consensus that `@` (imported from Haskell) is a bad binding operator for patterns, because it leads to the confusing-looking `@@` in, for example: struct Foo { field: int } ... match foo { foo@@Foo { field: x } => ... } However, there is not consensus as to what to change it to. Suggestions are `=` and `as`. The problem with `=` is that, if implemented naively, it makes our grammar ambiguous: let x = y = 3; // is x the result of evaluating `y = 3` (i.e. unit) // or are x and y bound to 3? The easiest way to fix this problem is to forbid `=` in irrefutable patterns, such as those introduced by `let`. However, this bifurcates the pattern grammar into the irrefutable-pattern grammar and the refutable-pattern grammar, with some conceptually-ugly overlap. The alternative is `as`, like OCaml. However, this conflicts with `as` in the expression grammar. A subset of the expression grammar is part of the pattern grammar in order to permit matching against constants. Removing `as` expressions from the subset of expression productions permitted in patterns would mean that this would no longer do what you expect: match 22.0f32 / 7.0f32 { math::PI as f32 => println("Good grief!"), _ => {} } So both `=` and `as` have drawbacks. I don't really have any preference at all; I just need to know what to implement. Opinions? Patrick From catamorphism at gmail.com Thu May 2 18:16:43 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Thu, 2 May 2013 18:16:43 -0700 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <51830F1A.9030708@mozilla.com> References: <51830F1A.9030708@mozilla.com> Message-ID: I don't particularly like any of the options here, but "as" seems like the least bad one. Matching on a casted constant seems like a pretty rare case, and you can always use if instead of match. I agree that the existing @ syntax is ugly, and I think using '=' for pattern binding muddies the waters (besides the ambiguity). Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Too much to carry, too much to let go Time goes fast, learning goes slow." -- Bruce Cockburn From jack at metajack.im Thu May 2 18:49:29 2013 From: jack at metajack.im (Jack Moffitt) Date: Thu, 2 May 2013 19:49:29 -0600 Subject: [rust-dev] rustdoc feature request: grouping methods In-Reply-To: <20130502101844.GF2285@Mr-Bennet> References: <20130502101844.GF2285@Mr-Bennet> Message-ID: > Maybe we can find a way to incorporate some sort of "section" > to use when grouping items, methods, fields, etc. I imagine > we could draw on Markdown's `#`, `##`, `###` notation to > define sections, subsections, and so forth, but I'm just > not sure how we would let rustdoc know about it, since there > is nothing in particular to attach the attribute to. > > Any thoughts? Is this something other people would like? Why not just do it with an annotation and support arbitrary tags? Like: #[doc(section="Node construction")] Or something like that. Then the doc generator can do whatever it likes with the tags, allowing all kinds of nice extensions later. jack. From erick.tryzelaar at gmail.com Thu May 2 20:25:21 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Thu, 2 May 2013 20:25:21 -0700 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: References: <51830F1A.9030708@mozilla.com> Message-ID: I'm not sure what I think about this, but we could do away with the `as` cast operator and replace it with `.to_f32()`. I was already planning on adding a ToInt/FromInt for casting to and from enums, so we'll probably grow `.to_f32()` and etc anyway. I doubt we could use `.to_f32()` in a pattern. Or we could change the cast operator. ` : ` has some nice symmetry with the rest of the syntax. I'm not sure if that would be ambiguous though. Scala uses this syntax: val x = 1 x: Int = 1 val y = x: Float y: Float = 1.0 O'Caml uses ` :> ` to cast polymorphic variants, as in: # let x = `A;; val x : [> `A ] = `A # let b = (x :> [> `A | `B]);; val b : [> `A | `B ] = `A I'm not sure if either of these options is the right way to go though. On Thu, May 2, 2013 at 6:16 PM, Tim Chevalier wrote: > I don't particularly like any of the options here, but "as" seems like > the least bad one. Matching on a casted constant seems like a pretty > rare case, and you can always use if instead of match. I agree that > the existing @ syntax is ugly, and I think using '=' for pattern > binding muddies the waters (besides the ambiguity). > > Cheers, > Tim > > > > -- > Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt > "Too much to carry, too much to let go > Time goes fast, learning goes slow." -- Bruce Cockburn > _______________________________________________ > 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 sh4.seo at samsung.com Thu May 2 23:33:55 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Fri, 03 May 2013 06:33:55 +0000 (GMT) Subject: [rust-dev] RFC: Pattern matching binding operator Message-ID: <10940299.218901367562835742.JavaMail.weblogic@epml16> > I don't really have any preference at all; I just need to know what to > implement. Opinions? I propose "ident for pat" for current "ident @ pat" syntax. From o.renaud at gmx.fr Fri May 3 01:19:38 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Fri, 03 May 2013 10:19:38 +0200 Subject: [rust-dev] Re : RFC: Pattern matching binding operator Message-ID: <20130503081938.10750@gmx.com> Maybe we can consider `:=`, if `=` alone is ambiguous. ? ----- Message d'origine ----- De : Patrick Walton Envoy?s : 03.05.13 03:12 ? : rust-dev at mozilla.org Objet : [rust-dev] RFC: Pattern matching binding operator Hi everyone, There's consensus that `@` (imported from Haskell) is a bad binding operator for patterns, because it leads to the confusing-looking `@@` in, for example: struct Foo { field: int } ... match foo { foo@@Foo { field: x } => ... } However, there is not consensus as to what to change it to. Suggestions are `=` and `as`. The problem with `=` is that, if implemented naively, it makes our grammar ambiguous: let x = y = 3; // is x the result of evaluating `y = 3` (i.e. unit) // or are x and y bound to 3? The easiest way to fix this problem is to forbid `=` in irrefutable patterns, such as those introduced by `let`. However, this bifurcates the pattern grammar into the irrefutable-pattern grammar and the refutable-pattern grammar, with some conceptually-ugly overlap. The alternative is `as`, like OCaml. However, this conflicts with `as` in the expression grammar. A subset of the expression grammar is part of the pattern grammar in order to permit matching against constants. Removing `as` expressions from the subset of expression productions permitted in patterns would mean that this would no longer do what you expect: match 22.0f32 / 7.0f32 { math::PI as f32 => println("Good grief!"), _ => {} } So both `=` and `as` have drawbacks. I don't really have any preference at all; I just need to know what to implement. Opinions? Patrick From illissius at gmail.com Fri May 3 02:20:43 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Fri, 3 May 2013 11:20:43 +0200 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <51830F1A.9030708@mozilla.com> References: <51830F1A.9030708@mozilla.com> Message-ID: On Fri, May 3, 2013 at 3:12 AM, Patrick Walton wrote: > > The alternative is `as`, like OCaml. However, this conflicts with `as` in > the expression grammar. A subset of the expression grammar is part of the > pattern grammar in order to permit matching against constants. Removing > `as` expressions from the subset of expression productions permitted in > patterns would mean that this would no longer do what you expect: > > match 22.0f32 / 7.0f32 { > math::PI as f32 => println("Good grief!"), > _ => {} > } > You could emit a warning or an error if the bound name is the same as the name of a type. -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucian.branescu at gmail.com Fri May 3 02:58:51 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Fri, 3 May 2013 10:58:51 +0100 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: References: <51830F1A.9030708@mozilla.com> Message-ID: I like using ":" for casts and "as" for binding (perhaps reversed, like Python's with statement) the most, and I believe it has been proposed before https://mail.mozilla.org/pipermail/rust-dev/2012-May/001825.html On 3 May 2013 04:25, Erick Tryzelaar wrote: > I'm not sure what I think about this, but we could do away with the `as` > cast operator and replace it with `.to_f32()`. I was already planning on > adding a ToInt/FromInt for casting to and from enums, so we'll probably > grow `.to_f32()` and etc anyway. I doubt we could use `.to_f32()` in a > pattern. > > Or we could change the cast operator. ` : ` has some nice > symmetry with the rest of the syntax. I'm not sure if that would be > ambiguous though. Scala uses this syntax: > > val x = 1 > > > > x: Int = 1 > > val y = x: Float > > y: Float = 1.0 > > > O'Caml uses ` :> ` to cast polymorphic variants, as in: > > # let x = `A;; > val x : [> `A ] = `A > # let b = (x :> [> `A | `B]);; > val b : [> `A | `B ] = `A > > I'm not sure if either of these options is the right way to go though. > > > On Thu, May 2, 2013 at 6:16 PM, Tim Chevalier wrote: > >> I don't particularly like any of the options here, but "as" seems like >> the least bad one. Matching on a casted constant seems like a pretty >> rare case, and you can always use if instead of match. I agree that >> the existing @ syntax is ugly, and I think using '=' for pattern >> binding muddies the waters (besides the ambiguity). >> >> Cheers, >> Tim >> >> >> >> -- >> Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt >> "Too much to carry, too much to let go >> Time goes fast, learning goes slow." -- Bruce Cockburn >> _______________________________________________ >> 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 pnkfelix at mozilla.com Fri May 3 03:12:31 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Fri, 03 May 2013 12:12:31 +0200 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <51830F1A.9030708@mozilla.com> References: <51830F1A.9030708@mozilla.com> Message-ID: <51838D8F.40500@mozilla.com> Patrick (cc'ing rust-dev)- Between the two options Patrick presented, my vote is for bifurcating the grammar into irrefutable and refutable variants. I like having one operator to denote binding (even if it also sometimes means mutation). However, my (potentially-wrong) intuition is that the problem Patrick describes is stemming from a not-particularly useful special case of pattern binding. In particular, I wonder whether the problem could be resolved by not allowing a binding `=` at the topmost level of the pattern. I mentioned this on IRC last night, but it was late and I'm not convinced I explained myself properly. More concretely, what I'm suggesting is the following: What we now write as: fn main() { enum Foo { A((int, int)), B((&'static str, &'static str)) }; fn visit (x:Foo) { match x { i @ A(j@(k,l)) => io::println(fmt!("an A %? %? %? %?", i, j, k, l)), m @ B(n@(o,p)) => io::println(fmt!("a B %? %? %? %?", m, n, o, p)) } } visit(A((1,2))); visit(B(("three", "four"))); } would become illegal. In particular, the bindings for `i` and `m` would be disallowed. But the other bindings would continue to be allowed, and we would switch to the `=` operator for binding, yieldign: fn main() { enum Foo { A((int, int)), B((&'static str, &'static str)) }; fn visit (x:Foo) { match x { A(j=(k,l)) => io::println(fmt!("an A %? %? %? %?", x, j, k, l)), B(n=(o,p)) => io::println(fmt!("a B %? %? %? %?", x, n, o, p)) } } visit(A((1,2))); visit(B(("three", "four"))); } patrick: Does this get rid of the problem, since the `=`'s could only occur beneath pattern structure? Or does it leave the grammar just as ugly as bifurcating it with irrefutable and refutable variants? (Although at least now, even though the grammar is a little more complex, it at least might be *consistent* across both let and match.) Cheers, -Felix On 03/05/2013 03:12, Patrick Walton wrote: > Hi everyone, > > There's consensus that `@` (imported from Haskell) is a bad binding > operator for patterns, because it leads to the confusing-looking `@@` > in, for example: > > struct Foo { > field: int > } > > ... > > match foo { > foo@@Foo { field: x } => ... > } > > However, there is not consensus as to what to change it to. > Suggestions are `=` and `as`. > > The problem with `=` is that, if implemented naively, it makes our > grammar ambiguous: > > let x = y = 3; // is x the result of evaluating `y = 3` (i.e. unit) > // or are x and y bound to 3? > > The easiest way to fix this problem is to forbid `=` in irrefutable > patterns, such as those introduced by `let`. However, this bifurcates > the pattern grammar into the irrefutable-pattern grammar and the > refutable-pattern grammar, with some conceptually-ugly overlap. > > The alternative is `as`, like OCaml. However, this conflicts with `as` > in the expression grammar. A subset of the expression grammar is part > of the pattern grammar in order to permit matching against constants. > Removing `as` expressions from the subset of expression productions > permitted in patterns would mean that this would no longer do what you > expect: > > match 22.0f32 / 7.0f32 { > math::PI as f32 => println("Good grief!"), > _ => {} > } > > So both `=` and `as` have drawbacks. > > I don't really have any preference at all; I just need to know what to > implement. Opinions? > > Patrick > _______________________________________________ > 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.org From garethdanielsmith at gmail.com Fri May 3 08:20:59 2013 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Fri, 3 May 2013 16:20:59 +0100 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <51830F1A.9030708@mozilla.com> References: <51830F1A.9030708@mozilla.com> Message-ID: There might be something obviously wrong with this, but how about: match foo { let foo = Foo { field: x } => ... } Gareth On 3 May 2013 02:12, Patrick Walton wrote: > Hi everyone, > > There's consensus that `@` (imported from Haskell) is a bad binding > operator for patterns, because it leads to the confusing-looking `@@` in, > for example: > > struct Foo { > field: int > } > > ... > > match foo { > foo@@Foo { field: x } => ... > } > > However, there is not consensus as to what to change it to. Suggestions > are `=` and `as`. > > The problem with `=` is that, if implemented naively, it makes our grammar > ambiguous: > > let x = y = 3; // is x the result of evaluating `y = 3` (i.e. unit) > // or are x and y bound to 3? > > The easiest way to fix this problem is to forbid `=` in irrefutable > patterns, such as those introduced by `let`. However, this bifurcates the > pattern grammar into the irrefutable-pattern grammar and the > refutable-pattern grammar, with some conceptually-ugly overlap. > > The alternative is `as`, like OCaml. However, this conflicts with `as` in > the expression grammar. A subset of the expression grammar is part of the > pattern grammar in order to permit matching against constants. Removing > `as` expressions from the subset of expression productions permitted in > patterns would mean that this would no longer do what you expect: > > match 22.0f32 / 7.0f32 { > math::PI as f32 => println("Good grief!"), > _ => {} > } > > So both `=` and `as` have drawbacks. > > I don't really have any preference at all; I just need to know what to > implement. Opinions? > > 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 dbau.pp at gmail.com Fri May 3 08:28:43 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sat, 04 May 2013 01:28:43 +1000 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks Message-ID: <5183D7AB.4050707@gmail.com> Hi all, Aatch, Kimundi and I (and maybe some others... sorry if I've forgotten you) came up with a bit of proposal on IRC for handling fmt!. It's possibly been considered already, but whatever, we'd like some comments on it. There would one trait for each format specifier (probably excluding `?'), e.g. FormatC for %c, FormatD for %d/%i, FormatF for %f, and format would just require that the value for each format specifier implements the correct trait. (Presumably this check can be done "automatically" by attempting to call the appropriate method and using the type checker.) In code, trait FormatC { fn format_c(&self, w: &Writer, flags: Flags); } impl FormatC for char { fn format_c(&self, w: &Writer, _: Flags) { w.write_char(*self) } } struct MyChar(char); impl FormatC for MyChar { fn format_c(&self, w: &Writer, _: Flags) { w.write_char(**self) } } fmt!("%c%c%c", 'a', MyChar('a'), ~"str") // becomes 'a'.format_c(w, {}); MyChar('a').format_c(w, {}); ~"str".format_c(w, {}); And the first two would resolve/type-check fine, but the last would not. (`Flags' would contain the width and precision specifiers and all that.) This could then be extended to have a dynamic formatter, which allows types to format for any specifier at runtime (i.e. get around compile time restrictions). Our thoughts were to add an extra flag to indicate this (e.g. !), so that it is entirely and explicitly opt-in. (Similar to Python's __format__ and Go's fmt (I think).) trait DynamicFormat { fn format_dynamic(&self, w: &Writer, spec: FormatSpec); } fmt!("%!s %!10.3f", a, b) // becomes a.format_dynamic(w, {flags: {}, type: 's'}); w.write_str(" "); b.format_dynamic(w, {flags: {width: 10, prec: 3}, type: 'f'}); (Presumably this could also have a lint mode, to give an error or warning if dynamic formatting is used.) There were also some other discussions about the fmt! syntax, e.g. it was suggested that the following could be equivalent to each other fmt!("%{2}[0].[1]f %{2}e", 10, 3, 1.01); fmt!("%10.3f %e", 1.01, 1.01); This is an explicit divergence from printf's slightly archane */'n$' placeholder syntax. One could use `[*]` to just refer to the next argument, like * does by default. (Aatch has a format spec parser[1] in the works that supports this syntax.) Huon [1]: https://gist.github.com/Aatch/fb94960ab770c7df5718 From niko at alum.mit.edu Fri May 3 09:04:24 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 3 May 2013 12:04:24 -0400 Subject: [rust-dev] rustdoc feature request: grouping methods In-Reply-To: References: <20130502101844.GF2285@Mr-Bennet> Message-ID: <20130503160424.GC18950@Mr-Bennet> The problem I guess is that there is no AST node to hang those tags off of, unless I introduce artifical mods. I still want to try this. It seems to make sense that the best way to structure the docs is also the best way to structure the code. Niko On Thu, May 02, 2013 at 07:49:29PM -0600, Jack Moffitt wrote: > > Maybe we can find a way to incorporate some sort of "section" > > to use when grouping items, methods, fields, etc. I imagine > > we could draw on Markdown's `#`, `##`, `###` notation to > > define sections, subsections, and so forth, but I'm just > > not sure how we would let rustdoc know about it, since there > > is nothing in particular to attach the attribute to. > > > > Any thoughts? Is this something other people would like? > > Why not just do it with an annotation and support arbitrary tags? Like: > #[doc(section="Node construction")] > > Or something like that. Then the doc generator can do whatever it > likes with the tags, allowing all kinds of nice extensions later. > > jack. From niko at alum.mit.edu Fri May 3 11:32:16 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 3 May 2013 14:32:16 -0400 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <51838D8F.40500@mozilla.com> References: <51830F1A.9030708@mozilla.com> <51838D8F.40500@mozilla.com> Message-ID: <20130503183216.GD18950@Mr-Bennet> It is legitimately useful to have bindings at the top-level of patterns in match statements. Here are two examples. I'm not so sure about `let` bindings, but I guess that reason (1) could still apply. (1) Today, it's sometimes nice when matching against an rvalue, where you want to both take the value as a whole and extract some little piece: match some_func_call() { s @ Foo(Bar(z, _), _) => { ... } ... } (2) In the future, if we support enum refinement types---as I hope to do post-Rust-1.0---then bindings could be used as follows: match opt { s @ Some(_) => { /* type of `s` is Option[Some] */ } ... } Not helpful, I know. Niko On Fri, May 03, 2013 at 12:12:31PM +0200, Felix S. Klock II wrote: > Patrick (cc'ing rust-dev)- > > Between the two options Patrick presented, my vote is for > bifurcating the grammar into irrefutable and refutable variants. I > like having one operator to denote binding (even if it also > sometimes means mutation). > > However, my (potentially-wrong) intuition is that the problem > Patrick describes is stemming from a not-particularly useful special > case of pattern binding. > > In particular, I wonder whether the problem could be resolved by not > allowing a binding `=` at the topmost level of the pattern. > > I mentioned this on IRC last night, but it was late and I'm not > convinced I explained myself properly. > > More concretely, what I'm suggesting is the following: > > What we now write as: > > fn main() { > enum Foo { A((int, int)), B((&'static str, &'static str)) }; > fn visit (x:Foo) { > match x { > i @ A(j@(k,l)) => io::println(fmt!("an A %? %? %? %?", > i, j, k, l)), > m @ B(n@(o,p)) => io::println(fmt!("a B %? %? %? %?", > m, n, o, p)) > } > } > > visit(A((1,2))); > visit(B(("three", "four"))); > } > > would become illegal. In particular, the bindings for `i` and `m` > would be disallowed. But the other bindings would continue to be > allowed, and we would switch to the `=` operator for binding, > yieldign: > > fn main() { > enum Foo { A((int, int)), B((&'static str, &'static str)) }; > fn visit (x:Foo) { > match x { > A(j=(k,l)) => io::println(fmt!("an A %? %? %? %?", x, j, > k, l)), > B(n=(o,p)) => io::println(fmt!("a B %? %? %? %?", x, n, o, p)) > } > } > > visit(A((1,2))); > visit(B(("three", "four"))); > } > > > patrick: Does this get rid of the problem, since the `=`'s could > only occur beneath pattern structure? Or does it leave the grammar > just as ugly as bifurcating it with irrefutable and refutable > variants? (Although at least now, even though the grammar is a > little more complex, it at least might be *consistent* across both > let and match.) > > Cheers, > -Felix > > On 03/05/2013 03:12, Patrick Walton wrote: > >Hi everyone, > > > >There's consensus that `@` (imported from Haskell) is a bad > >binding operator for patterns, because it leads to the > >confusing-looking `@@` in, for example: > > > > struct Foo { > > field: int > > } > > > > ... > > > > match foo { > > foo@@Foo { field: x } => ... > > } > > > >However, there is not consensus as to what to change it to. > >Suggestions are `=` and `as`. > > > >The problem with `=` is that, if implemented naively, it makes our > >grammar ambiguous: > > > > let x = y = 3; // is x the result of evaluating `y = 3` (i.e. unit) > > // or are x and y bound to 3? > > > >The easiest way to fix this problem is to forbid `=` in > >irrefutable patterns, such as those introduced by `let`. However, > >this bifurcates the pattern grammar into the irrefutable-pattern > >grammar and the refutable-pattern grammar, with some > >conceptually-ugly overlap. > > > >The alternative is `as`, like OCaml. However, this conflicts with > >`as` in the expression grammar. A subset of the expression grammar > >is part of the pattern grammar in order to permit matching against > >constants. Removing `as` expressions from the subset of expression > >productions permitted in patterns would mean that this would no > >longer do what you expect: > > > > match 22.0f32 / 7.0f32 { > > math::PI as f32 => println("Good grief!"), > > _ => {} > > } > > > >So both `=` and `as` have drawbacks. > > > >I don't really have any preference at all; I just need to know > >what to implement. Opinions? > > > >Patrick > >_______________________________________________ > >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.org > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Fri May 3 11:33:52 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 3 May 2013 14:33:52 -0400 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: References: <51830F1A.9030708@mozilla.com> Message-ID: <20130503183352.GE18950@Mr-Bennet> On Thu, May 02, 2013 at 08:25:21PM -0700, Erick Tryzelaar wrote: > I'm not sure what I think about this, but we could do away with the `as` > cast operator and replace it with `.to_f32()`. I was already planning on > adding a ToInt/FromInt for casting to and from enums, so we'll probably > grow `.to_f32()` and etc anyway. I doubt we could use `.to_f32()` in a > pattern. Using a method would disallow casts from appearing in constants, unless we had some sort of variation on constexpr. > Or we could change the cast operator. ` : ` has some nice > symmetry with the rest of the syntax. I'm not sure if that would be > ambiguous though. Scala uses this syntax: Yes, this is reasonable, though pcwalton wanted to make `:` be *type ascription* (meaning, say what you expected the type to be, vs coercing the type). Niko From banderson at mozilla.com Fri May 3 13:00:13 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 03 May 2013 13:00:13 -0700 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <10940299.218901367562835742.JavaMail.weblogic@epml16> References: <10940299.218901367562835742.JavaMail.weblogic@epml16> Message-ID: <5184174D.2000300@mozilla.com> On 05/02/2013 11:33 PM, Sanghyeon Seo wrote: >> I don't really have any preference at all; I just need to know what to >> implement. Opinions? > I propose "ident for pat" for current "ident @ pat" syntax. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev This is a good candidate. From walter at waltertetzner.net Fri May 3 13:06:21 2013 From: walter at waltertetzner.net (Walter Tetzner) Date: Fri, 3 May 2013 16:06:21 -0400 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <5184174D.2000300@mozilla.com> References: <10940299.218901367562835742.JavaMail.weblogic@epml16> <5184174D.2000300@mozilla.com> Message-ID: Here are a couple other ideas. The downsides to these are introducing new keywords/symbols, and that they're a little verbose. ident is pat ident <- pat -Walter On Fri, May 3, 2013 at 4:00 PM, Brian Anderson wrote: > On 05/02/2013 11:33 PM, Sanghyeon Seo wrote: >>> >>> I don't really have any preference at all; I just need to know what to >>> implement. Opinions? >> >> I propose "ident for pat" for current "ident @ pat" syntax. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > This is a good candidate. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From banderson at mozilla.com Fri May 3 13:12:03 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 03 May 2013 13:12:03 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <5183D7AB.4050707@gmail.com> References: <5183D7AB.4050707@gmail.com> Message-ID: <51841A13.6050103@mozilla.com> On 05/03/2013 08:28 AM, Huon Wilson wrote: > Hi all, > > Aatch, Kimundi and I (and maybe some others... sorry if I've forgotten > you) came up with a bit of proposal on IRC for handling fmt!. It's > possibly been considered already, but whatever, we'd like some > comments on it. I'm glad you are thinking about this. fmt! is in desperate need of an overhaul, both in design and implementation. > > > There would one trait for each format specifier (probably excluding > `?'), e.g. FormatC for %c, FormatD for %d/%i, FormatF for %f, and > format would just require that the value for each format specifier > implements the correct trait. (Presumably this check can be done > "automatically" by attempting to call the appropriate method and > using the type checker.) > > In code, > > > trait FormatC { > fn format_c(&self, w: &Writer, flags: Flags); > } > > impl FormatC for char { > fn format_c(&self, w: &Writer, _: Flags) { w.write_char(*self) } > } > > struct MyChar(char); > impl FormatC for MyChar { > fn format_c(&self, w: &Writer, _: Flags) { w.write_char(**self) } > } Good call using Writer here. This is one of the crucial changes that must be made. > > fmt!("%c%c%c", 'a', MyChar('a'), ~"str") > > // becomes > > 'a'.format_c(w, {}); > MyChar('a').format_c(w, {}); > ~"str".format_c(w, {}); > > > And the first two would resolve/type-check fine, but the last would > not. (`Flags' would contain the width and precision specifiers and all > that.) For these pre-existing format specifiers this would allow arbitrary types to be formatted as i.e. characters. This may be overkill. What we *definitely* need though is for all types that are e.g. signed integers to implement `%i`. `FormatC` I would probably prefer to be `FormatChar`, etc. for clarity. > > > This could then be extended to have a dynamic formatter, which allows > types to format for any specifier at runtime (i.e. get around compile > time restrictions). Our thoughts were to add an extra flag to indicate > this (e.g. !), so that it is entirely and explicitly opt-in. (Similar > to Python's __format__ and Go's fmt (I think).) > > > trait DynamicFormat { > fn format_dynamic(&self, w: &Writer, spec: FormatSpec); > } > > fmt!("%!s %!10.3f", a, b) > > // becomes > > a.format_dynamic(w, {flags: {}, type: 's'}); > w.write_str(" "); > b.format_dynamic(w, {flags: {width: 10, prec: 3}, type: 'f'}); > > > (Presumably this could also have a lint mode, to give an error or > warning if dynamic formatting is used.) I don't understand the use case for this. I would understand (and want) a generic format specifier that defers to some trait, but without specifically using type 's' or 'f'. Something like "%!" that becomes `a.format(w, flags)`, but doesn't try to coerce arbitrary types to print as other arbitrary types. > > > There were also some other discussions about the fmt! syntax, e.g. it > was suggested that the following could be equivalent to each other > > fmt!("%{2}[0].[1]f %{2}e", 10, 3, 1.01); > fmt!("%10.3f %e", 1.01, 1.01); > > This is an explicit divergence from printf's slightly archane */'n$' > placeholder syntax. One could use `[*]` to just refer to the next > argument, like * does by default. (Aatch has a format spec parser[1] > in the works that supports this syntax.) I agree with reconsidering the inconsistent, underspecified printf syntax, but don't have any specific thoughts on this at this time. Nice work. I look forward to seeing where this goes. From banderson at mozilla.com Fri May 3 13:15:45 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 03 May 2013 13:15:45 -0700 Subject: [rust-dev] rustdoc feature request: grouping methods In-Reply-To: <20130503160424.GC18950@Mr-Bennet> References: <20130502101844.GF2285@Mr-Bennet> <20130503160424.GC18950@Mr-Bennet> Message-ID: <51841AF1.2040009@mozilla.com> On 05/03/2013 09:04 AM, Niko Matsakis wrote: > The problem I guess is that there is no AST node to hang those tags > off of, unless I introduce artifical mods. I still want to try this. > It seems to make sense that the best way to structure the docs is also > the best way to structure the code. > I agree with this sentiment, though how well it works in practice relates directly to how well-structured the code is. I wonder how to balance letting the coder structure the docs with making individual nodes easily discoverable. Maybe present items in the order they are defined but index them in sorted order. From graydon at mozilla.com Fri May 3 13:21:53 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 03 May 2013 13:21:53 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <51841A13.6050103@mozilla.com> References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> Message-ID: <51841C61.705@mozilla.com> On 13-05-03 01:12 PM, Brian Anderson wrote: > I agree with reconsidering the inconsistent, underspecified printf > syntax, but don't have any specific thoughts on this at this time. Note that I made a page collecting links to existing format libraries a little while back: https://github.com/mozilla/rust/wiki/Lib-fmt I'm similarly excited to see someone taking charge of this. Thanks! -Graydon From graydon at mozilla.com Fri May 3 13:24:40 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 03 May 2013 13:24:40 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <51841C61.705@mozilla.com> References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> Message-ID: <51841D08.7090303@mozilla.com> On 13-05-03 01:21 PM, Graydon Hoare wrote: > On 13-05-03 01:12 PM, Brian Anderson wrote: > >> I agree with reconsidering the inconsistent, underspecified printf >> syntax, but don't have any specific thoughts on this at this time. > > Note that I made a page collecting links to existing format libraries a > little while back: (Erm, it might also be worthwhile to consider message catalogues and locale-facets at this point; the two are closely related. We do not have a library page on that topic yet, but ought to. Or include it in the lib-fmt page.) -Graydon From illissius at gmail.com Fri May 3 19:11:01 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sat, 4 May 2013 04:11:01 +0200 Subject: [rust-dev] sub-grammar for range pattern constants? In-Reply-To: <51800FB9.1010100@mozilla.com> References: <9C0DF66F-B470-4F39-915A-18EFBC6C0D30@brinckerhoff.org> <39FDCB3F-FC88-4ADC-AA78-6CB253824713@brinckerhoff.org> <517ED168.80703@mozilla.com> <517F48DC.4070705@earthling.net> <51800FB9.1010100@mozilla.com> Message-ID: So this has been bouncing around in the back of my head, and now actual thoughts have congealed there. Essentially, while I think this is a very good defense of why Rust doesn't have purity, it's not so convincing to me as a defense of why it *shouldn't* have purity. (I don't know if it was intended as one.) On Tue, Apr 30, 2013 at 8:38 PM, Graydon Hoare wrote: > On 30/04/2013 10:08 AM, Max Cantor wrote: > > I know this will be an unpopular opinion, but pure functions would be a >> massive win for Rust, especially if the eventual goal is high >> performance, highly parallelizable (browser rendering engines..) >> development. >> > > Careful. It's important to understand that "purity" seems like it has a > simple definition but in languages with mutable memory, state, time and IO, > it gets hard to be exact. > > Things you can throw at a SIMD unit or GPU and get parallel kernels out of > them will almost certainly be a different version of "pure" than things you > can evaluate at compile time. Or, as in our previous attempts at defining > it, things that won't break existing borrows or existing typestates. Each > of these is a static approximation of the > set-of-all-things-a-function-might-do. Since our functions can generally do > quite a lot, the set of possible subsets you might mean by "pure" is > correspondingly much larger. > > > The typestate system did seme very complex but isn't there a middle >> ground via annotations perhaps? A subset of primitives and core >> functions can be annotated as pure and then any function calling only >> pure functions can itself be annotated as pure. >> > > This gets difficult fast. You wind up dividing your functions up into > groups and then getting annoyed that one that's "mostly almost pure" or > "essentially pure, for my purposes" that you wanted to call actually isn't > (someone forgot to mark it as such, or some sub-function, or some > trait-implied function) and then you can't. Or is pure using one way of > thinking about purity, but not another. Or is pure except for the bit where > it calls unsafe but promises it's going to maintain purity, just knows > better than you (oops, that can't be done at compile time, nor on a GPU, > etc.) > Yeah, this is definitely a valid observation. Even Haskell is bitten by this (if something always has the same value in a single run of the program but may have different values in different runs, is it pure?). > > C++ has multiple concepts for this, each a not-entirely-obvious subset of > the others, each affecting the others, and causing quite a lot of work just > to get things to compile, much less reuse code. > C++ is C++. It has multiple concepts for *everything*. That something is complicated in C++ does not imply that it has to be complicated by necessity. > > They have const methods (don't mutate the object, unless you lie and > override it) and constexpr (can be evaluated at compile time), and macros > (can only operate on tokens), and template evaluation (can only operate on > certain non-type args), and the openCL __kernel extension for > GPU-applicable functions: > This is unfair even to C++. Const methods are the same thing in spirit as `&self` versus `&mut self` in Rust. Macros in C++ and Rust alike are for code generation, not computation. I wasn't familiar with __kernel, but I looked into it[1] and found this: "The function using the __kernel qualifier can only have return type void in the source code". If that has a common intersection with any other definition of purity, it's `return ();`. That leaves templates and constexpr. Which, indeed, have a lot of overlap, and neither is a subset of the other (constexpr functions can't do types while templates can't do values of user-defined types other than enums, for example). Both are restricted to dealing in things that can be evaluated at compile time.* The part of templates that deals in types corresponds to Rust's generics, while the part of templates that can calculate the Fibonacci numbers is a historical semi-accident. Constexpr expressions (and hence functions) correspond to Rust's attempts to define a constant expression subgrammar. The only really legitimate notion of purity in C++ to my mind is constexpr. [1] http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/restrictions.html * Actually, constexpr functions *may* contain non-constexpr expressions, but only as long as they are in the branch of a conditional which isn't taken at compile time. Which is actually useful. C++ for you. > "Which purity do you mean" is a very real question, not one you can just > brush aside. The combinations are worse, in that they tend to cause (or > require) subtyping relationships, that touch _everything_ in the language, > from inference and mandatory syntax (which types get inferred when you just > write a lambda?) to type checking (which calls are legal, which impls and > delegations are legal) to codegen (which LLVM attributes are legal? which > things can we inline and how?) [...] A long time ago we had an effect system and we made pure the default (since > we didn't want people accidentally leaving it out due to sloth) and we made > the impure specifier a very small and reasonable keyword: "io". It was > still a heavy complexity bill (required a full extra dimension of > subtyping, parametricity, etc.) and _still_ had people breaking the rule > with `unsafe`, which meant that the putative benefits like "can do compile > time evaluation" or "can spread on a GPU" weren't there anyways. And people > couldn't do simple things like "put a printf in here for logging" (much > like in haskell). > > Eventually people just took to making everything io, at which point it was > a noise word and we decided to remove it (along with 'pred', which just > meant pure, bool, and tracked by the typestate layer). Again this is something I can definitely accept. Can't argue with history. It would be nice to know for context how the old system worked. Is there documentation anywhere? > > Coming from the Haskell world, not having pure functions would be a >> considerable deficit in the language that is so close to being a best of >> both worlds descendant of C and Haskell. >> > > The "direct descendant" aspect here is probably inaccurate. We're more of > a descendant of ML with its mutable ref cells, eager evaluation and such. > Haskell was willing to force its users to segregate all variants of > impurity outside the most conservative intersection into monad > representation[1]. FWIW it's not really a most conservative intersection. They can't run it on the GPU or evaluate it at compile time either (except by compiling and running it, which is what Template Haskell does). What they have is a semantic notion of purity. If there's no way for pure code to observe different values (or the user running the program different effects) at different times, it's good to go, even if it requires unsafePerformIO to implement. Using unsafePerformIO to cheat is frowned upon* and more importantly isn't reliable. * Except for Debug.Trace.trace[2], which has been called "a refreshing desert in the oasis of referential transparency". [2] http://www.haskell.org/ghc/docs/latest/html/libraries/base/Debug-Trace.html#v:trace > But this costs heavily in all code that doesn't fit that intersection, > which is a lot of systems code; so we've decided against it. The split is > too much for C programmers to accept; anywhere we try to draw the line > appears to cause a lot of anger and resentment over mandatory type-system > fighting. > Right. As above I can readily accept that it's not an easy question, that the right design hasn't been found, and that earlier attempts haven't worked out. What I find harder to accept is that there doesn't exist *any* definition of purity that would be superior to nothing at all. C++ derives some benefit from constexpr. Haskell derives a lot of benefit from enforced purity. Surely there is some point in the design space which would be beneficial for Rust. Perhaps a wiki page collecting the various options with their applications, benefits, and drawbacks would be helpful? (FWIW I sorta suspect the presence of mutability and lifetimes in the type system might make an observable notion of purity a la Haskell easier to define, but I haven't thought it all the way through.) > > -Graydon > > > [1] This is why they could "implement STM in a weekend" -- by excluding > almost all functions -- but I think this characterization is really unfair > anyway. What they really have is just "do notation", which means > constructing a suspended execution-tree is _slightly_ less miserable than a > deeply nested tree of constructor calls and lambdas. But not really a lot. > The interface-points with the rest of the language involve pervasive > lifting, lowering, wrapping and unwrapping. See the "simple STM example" on > their website: http://www.haskell.org/haskellwiki/Simple_STM_example Are we looking at the same thing? The only lifting, lowering, wrapping and unwrapping I see there is `atomically`. Any language with STM is going to need some way to delineate transactions (ye olde atomic { }). Perhaps other languages can get away with eliding it for single statements, but that's not a tremendous amount of difference. I also don't see "excluding almost all functions": it excludes all functions except for those which are pure and those which only manipulate transactional data... in other words those which do non-transactional I/O... in other words exactly the ones it has to! What am I missing? -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Fri May 3 21:24:24 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Fri, 3 May 2013 23:24:24 -0500 Subject: [rust-dev] What parts of libuv are used ? why ? Message-ID: Looks like libuv is a showstopper currently for me on Windows Cygwin building. Why is it used ? Should it be ? Will it be in the future ? Can someone throw up a quick paragraph or 2 about this on the wiki and let me know ? Thanks in advance ! -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From mikhail.zabaluev at gmail.com Sat May 4 00:31:41 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Sat, 4 May 2013 10:31:41 +0300 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <51841D08.7090303@mozilla.com> References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> Message-ID: Hi, 2013/5/3 Graydon Hoare > > (Erm, it might also be worthwhile to consider message catalogues and > locale-facets at this point; the two are closely related. We do not have a > library page on that topic yet, but ought to. Or include it in the lib-fmt > page.) If you are talking about gettext-like functionality, usually this and format strings are thought of as independent processing layers: format strings are translated as such and then fed to the formatting function. This brings some ramifications, as the order of parameters in the translated template can change, so the format syntax has to support positional parameters. But this also allows to account for data-derived context such as numeral cases, without complicating the printf-like functions too much. There are other difficulties with localizing formatted messages that are never systematically solved, for example, accounting for gender. In all, it looks like an interesting area for library research, beyond the basic "stick this value pretty-printed into a string" problem. Cheers, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Sat May 4 01:47:52 2013 From: pnkfelix at mozilla.com (Felix Klock) Date: Sat, 4 May 2013 01:47:52 -0700 (PDT) Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <20130503183216.GD18950@Mr-Bennet> Message-ID: <2110252982.14377134.1367657272044.JavaMail.root@mozilla.com> Niko (cc'ing rust-dev)- I know about (1), and I can appreciate (2). I had dismissed (1) because it did not seem like a huge burden to add the extra line binding `s = some_func_call()` immediately preceding `match s { ... }`; that's why I classified this case as "not-particularly useful." Likewise, for (2) one could try to adopt something like "occurrence types" [^1] to get the effect you want even for code of the form `s = some_func_call(); match s { ... }` But you might see more value than I do in keeping the scope of `s` strictly contained to the single match-clause, versus overloading a (non-`=`) operator/keyword to denote binding. I have no counter-argument for that. ---- As another variant on my proposal: we could just disallow top-level =-binding for `let` alone, but leave top-level =-binding for `match`. That's a little ugly, but still preferable to me over abusing other keywords. Would that suit you, as a language user? Cheers, -Felix [^1] http://www.ccs.neu.edu/racket/pubs/popl08-thf.pdf The Design and Implementation of Typed Scheme POPL 2008 : Tobin-Hochstadt, Felleisen ----- Original Message ----- From: "Niko Matsakis" To: "Felix S. Klock II" Cc: "Patrick Walton" , "rus >> \"rust-dev at mozilla.org\"" Sent: Friday, May 3, 2013 8:32:16 PM Subject: Re: [rust-dev] RFC: Pattern matching binding operator It is legitimately useful to have bindings at the top-level of patterns in match statements. Here are two examples. I'm not so sure about `let` bindings, but I guess that reason (1) could still apply. (1) Today, it's sometimes nice when matching against an rvalue, where you want to both take the value as a whole and extract some little piece: match some_func_call() { s @ Foo(Bar(z, _), _) => { ... } ... } (2) In the future, if we support enum refinement types---as I hope to do post-Rust-1.0---then bindings could be used as follows: match opt { s @ Some(_) => { /* type of `s` is Option[Some] */ } ... } Not helpful, I know. Niko On Fri, May 03, 2013 at 12:12:31PM +0200, Felix S. Klock II wrote: > Patrick (cc'ing rust-dev)- > > Between the two options Patrick presented, my vote is for > bifurcating the grammar into irrefutable and refutable variants. I > like having one operator to denote binding (even if it also > sometimes means mutation). > > However, my (potentially-wrong) intuition is that the problem > Patrick describes is stemming from a not-particularly useful special > case of pattern binding. > > In particular, I wonder whether the problem could be resolved by not > allowing a binding `=` at the topmost level of the pattern. > > I mentioned this on IRC last night, but it was late and I'm not > convinced I explained myself properly. > > More concretely, what I'm suggesting is the following: > > What we now write as: > > fn main() { > enum Foo { A((int, int)), B((&'static str, &'static str)) }; > fn visit (x:Foo) { > match x { > i @ A(j@(k,l)) => io::println(fmt!("an A %? %? %? %?", > i, j, k, l)), > m @ B(n@(o,p)) => io::println(fmt!("a B %? %? %? %?", > m, n, o, p)) > } > } > > visit(A((1,2))); > visit(B(("three", "four"))); > } > > would become illegal. In particular, the bindings for `i` and `m` > would be disallowed. But the other bindings would continue to be > allowed, and we would switch to the `=` operator for binding, > yieldign: > > fn main() { > enum Foo { A((int, int)), B((&'static str, &'static str)) }; > fn visit (x:Foo) { > match x { > A(j=(k,l)) => io::println(fmt!("an A %? %? %? %?", x, j, > k, l)), > B(n=(o,p)) => io::println(fmt!("a B %? %? %? %?", x, n, o, p)) > } > } > > visit(A((1,2))); > visit(B(("three", "four"))); > } > > > patrick: Does this get rid of the problem, since the `=`'s could > only occur beneath pattern structure? Or does it leave the grammar > just as ugly as bifurcating it with irrefutable and refutable > variants? (Although at least now, even though the grammar is a > little more complex, it at least might be *consistent* across both > let and match.) > > Cheers, > -Felix > > On 03/05/2013 03:12, Patrick Walton wrote: > >Hi everyone, > > > >There's consensus that `@` (imported from Haskell) is a bad > >binding operator for patterns, because it leads to the > >confusing-looking `@@` in, for example: > > > > struct Foo { > > field: int > > } > > > > ... > > > > match foo { > > foo@@Foo { field: x } => ... > > } > > > >However, there is not consensus as to what to change it to. > >Suggestions are `=` and `as`. > > > >The problem with `=` is that, if implemented naively, it makes our > >grammar ambiguous: > > > > let x = y = 3; // is x the result of evaluating `y = 3` (i.e. unit) > > // or are x and y bound to 3? > > > >The easiest way to fix this problem is to forbid `=` in > >irrefutable patterns, such as those introduced by `let`. However, > >this bifurcates the pattern grammar into the irrefutable-pattern > >grammar and the refutable-pattern grammar, with some > >conceptually-ugly overlap. > > > >The alternative is `as`, like OCaml. However, this conflicts with > >`as` in the expression grammar. A subset of the expression grammar > >is part of the pattern grammar in order to permit matching against > >constants. Removing `as` expressions from the subset of expression > >productions permitted in patterns would mean that this would no > >longer do what you expect: > > > > match 22.0f32 / 7.0f32 { > > math::PI as f32 => println("Good grief!"), > > _ => {} > > } > > > >So both `=` and `as` have drawbacks. > > > >I don't really have any preference at all; I just need to know > >what to implement. Opinions? > > > >Patrick > >_______________________________________________ > >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.org > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From james at mansionfamily.plus.com Sat May 4 03:55:23 2013 From: james at mansionfamily.plus.com (james) Date: Sat, 04 May 2013 11:55:23 +0100 Subject: [rust-dev] Counting users (was: Update on I/O progress) In-Reply-To: References: <518060AE.8020605@cantrip.org> Message-ID: <5184E91B.5040405@mansionfamily.plus.com> On 01/05/2013 01:25, Tim Chevalier wrote: > Let's drop this thread, as per the code of conduct at > https://github.com/mozilla/rust/wiki/Note-development-policy : > > "Please keep unstructured critique to a minimum. If you have solid > ideas you want to experiment with, make a fork and see how it works." It might be development policy, but it seems to me a terrible idea. How do you fork a requirement? (or discussion thereof?) How do you fork a design? (or discussion thereof?) It seems to be the old 'show me the code'. :-( James -------------- next part -------------- An HTML attachment was scrubbed... URL: From o.renaud at gmx.fr Sat May 4 04:15:37 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Sat, 04 May 2013 13:15:37 +0200 Subject: [rust-dev] Re : Re: RFC: User-implementable format specifiers w/ compile-time checks Message-ID: <20130504111537.279780@gmx.com> > Hi, > > 2013/5/3 Graydon Hoare > > > (Erm, it might also be worthwhile to consider message catalogues and > > locale-facets at this point; the two are closely related. We do not have a > > library page on that topic yet, but ought to. Or include it in the lib-fmt > > page.) > > If you are talking about gettext-like functionality, usually this and > format strings are thought of as independent processing layers: format > strings are translated as such and then fed to the formatting function. > This brings some ramifications, as the order of parameters in the > translated template can change, so the format syntax has to support > positional parameters. But this also allows to account for data-derived > context such as numeral cases, without complicating the printf-like > functions too much. > There are other difficulties with localizing formatted messages that are > never systematically solved, for example, accounting for gender. In all, it > looks like an interesting area for library research, beyond the basic > "stick this value pretty-printed into a string" problem. > > Cheers, > ? Mikhail Gettext is indeed dependent on the fact that the format syntax allows positional parameters. I'd like to point out that gettext also makes use of a "feature" of the formatting function. Namely, the fact that it is not an error to call this function with more arguments than what the format string expects. In C, printf("%d", 1, 2) outputs "1". In Rust, fmt!("%d", 1, 2) is a compilation error. The use case for using this feature is briefly explained here http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms A simple example is that, given the string "there are %d frogs", the translator may want to translate it to "il n'y a aucune grenouille" instead of "il y a 0 grenouilles". In this case, the resulting function call would be printf("il n'y a aucune grenouille", 0), which is valid since the unused argument will be ignored. By the way, it occurs to me that fmt! requires a string literal as its first argument. How could a system like gettext, whose role is to substitute the format string at runtime, could work with fmt! ? From matthieu.monrocq at gmail.com Sat May 4 06:35:58 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sat, 4 May 2013 15:35:58 +0200 Subject: [rust-dev] Re : Re: RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <20130504111537.279780@gmx.com> References: <20130504111537.279780@gmx.com> Message-ID: On Sat, May 4, 2013 at 1:15 PM, Olivier Renaud wrote: > > Hi, > > > > 2013/5/3 Graydon Hoare > > > > > (Erm, it might also be worthwhile to consider message catalogues and > > > locale-facets at this point; the two are closely related. We do not > have a > > > library page on that topic yet, but ought to. Or include it in the > lib-fmt > > > page.) > > > > If you are talking about gettext-like functionality, usually this and > > format strings are thought of as independent processing layers: format > > strings are translated as such and then fed to the formatting function. > > This brings some ramifications, as the order of parameters in the > > translated template can change, so the format syntax has to support > > positional parameters. But this also allows to account for data-derived > > context such as numeral cases, without complicating the printf-like > > functions too much. > > There are other difficulties with localizing formatted messages that are > > never systematically solved, for example, accounting for gender. In all, > it > > looks like an interesting area for library research, beyond the basic > > "stick this value pretty-printed into a string" problem. > > > > Cheers, > > Mikhail > > Gettext is indeed dependent on the fact that the format syntax allows > positional parameters. > > I'd like to point out that gettext also makes use of a "feature" of the > formatting function. Namely, the fact that it is not an error to call this > function with more arguments than what the format string expects. > > In C, printf("%d", 1, 2) outputs "1". In Rust, fmt!("%d", 1, 2) is a > compilation error. > > The use case for using this feature is briefly explained here > http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms > > A simple example is that, given the string "there are %d frogs", the > translator may want to translate it to "il n'y a aucune grenouille" instead > of "il y a 0 grenouilles". In this case, the resulting function call would > be printf("il n'y a aucune grenouille", 0), which is valid since the unused > argument will be ignored. > > By the way, it occurs to me that fmt! requires a string literal as its > first argument. How could a system like gettext, whose role is to > substitute the format string at runtime, could work with fmt! ? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > Maybe we are taking this a bit backward ? I understand that things like gettext, at the moment, only substitute the "text"; but that may be seen as mistake rather than a feature. Instead, we could perfectly imagine a "gettext-like" equivalent that takes both an "original" format string (to be translated) *and* its arguments and then will use fmt! under the hood to produce a fully translated string to be fed to the Writer instance. Note that anyway for a proper translation gettext requires access to certain elements; for example for correct plural forms to be picked (esp in Polish). With this out of the way, not only are positional arguments not required any longer, but we can also avoid ignoring a mismatch between the number of arguments supplied (and their types) and those expected by the original format-string. There is no point in being as loose as C. -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From masklinn at masklinn.net Sat May 4 06:48:34 2013 From: masklinn at masklinn.net (Masklinn) Date: Sat, 4 May 2013 15:48:34 +0200 Subject: [rust-dev] Re : Re: RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <20130504111537.279780@gmx.com> References: <20130504111537.279780@gmx.com> Message-ID: <91A77485-52E5-4F21-9E7E-38B02840FF20@masklinn.net> On 2013-05-04, at 13:15 , Olivier Renaud wrote: > > Gettext is indeed dependent on the fact that the format syntax allows positional parameters. Not really, since gettext does not do formatting it does not care and because different languages may need to reorder parameters it's usually better to have either named or explicitly indexable parameters. Gettext pluralization takes specific count arguments to handle dispatching between multiple forms, but that's orthogonal to formatting as this example from the documentation shows: puts (ngettext ("Delete the selected file?", "Delete the selected files?", n)); Gettext's documentation specifically recommends making use of a POSIX/XSH indexing extension to printf-style formats to handle reordering: http://www.gnu.org/software/gettext/manual/gettext.html#c_002dformat but any other (better) scheme can be used instead e.g. Python's keyword-based cformat extension, java's MessageFormat. > I'd like to point out that gettext also makes use of a "feature" of the formatting function. It's not gettext doing that either, since gettext doesn't do any formatting. It can be a useful feature when paired with gettext as translations may or may not need all original format arguments, but it's orthogonal to gettext's behavior and features. From jeanpierreda at gmail.com Sat May 4 06:54:10 2013 From: jeanpierreda at gmail.com (Devin Jeanpierre) Date: Sat, 4 May 2013 09:54:10 -0400 Subject: [rust-dev] lib: regular expressions in std Message-ID: With regards to < https://github.com/mozilla/rust/issues/3591 >, I'd like to write a regular expression module for Rust. I've written a couple of regular expression engines in Python for fun in the past[*], and #rust pressured me to utilize my perverse sense of fun to write the same for Rust. Actually, the reason I learned Rust was to port a bunch of my regex code to a nice language. :) I'm writing this email because https://github.com/mozilla/rust/wiki/Library-editing told me to. I don't know much about the process, but as I understand it this marks the beginning of a one week discussion period where Rust-Dev fleshes out ideas for such a module, and whether or not it deserves to be written, and whether or not I should be the one writing it. I've also added this library page to the wiki: https://github.com/mozilla/rust/wiki/Lib-re I've already discussed this somewhat with some people in #rust, especially Marvin L?bel (kimundi) has been interested in helping me come up with a nice API. Hopefully we can put that down in writing here so that it isn't just in our memory. Some questions to start off with: - Should rust have a new regex engine written in Rust, or should it just have bindings for e.g. RE2 or similar? A point brought up in #rust: if we use RE2 or similar, we may not be able to have a re!() syntax extension that compiles regexps at the same time as the surrounding rust code. I prefer the former, because I wanted to write a new regex engine regardless. I would be perfectly happy to write some nice bindings for something like RE2, but I am probably not the best person to do it. - What syntax/semantics are important? I would propose supporting the "usual" PCRE syntax and semantics (including submatch extraction), but with the exception of backreferences and any other features which cannot be implemented efficiently (i.e. polynomial time). RE2 has a good summary of regex syntax, although it doesn't specify for PCRE-family syntax whether it comes from perl, libpcre, python, or something else. http://code.google.com/p/re2/wiki/Syntax Note: if rust's re module is efficient, syntaxes for things like possessive quantifiers is pointless and can be dropped. It may be desirable to include alternate parse disambiguation strategies. Using "efficient" RE, it's fairly easy to support POSIX-style longest match, as well as PCRE-style matches and even shortest match. For example, RE2 offers support for PCRE-style and also POSIX style regex matching. - How important is Unicode support and how broad should that support be? My understanding is that, at least as long as it can be added later, this is not crucial to get right correct right away. Unicode TR-18 defines 3 levels of Unicode support in regex implementations, of which only the first two are relevant. I think the only thing missing from core::unicode to give level 1 support is simple case folding. * https://github.com/mozilla/rust/issues/5820 * http://www.unicode.org/reports/tr18/ That's probably enough to start off with, especially since the answer to question 1 ties our hands on everything afterwards. Also since my hands hurt from typing. However, there's a lot of other topics, like what the API should look like, whether or not to support various syntaxes, etc.. I've added a lot of links and a few additional topics to the library proposal page. link again: https://github.com/mozilla/rust/wiki/Lib-re Let me know if there's something I've left out of here or of the library proposal page. When there's more discussion / I have more energy, I will suggest some of my personal ideas of what I'd like in a regex module, but somehow I don't feel that's appropriate at the top level post. -- Devin Jeanpierre .. [*] Here's the work I did before https://bitbucket.org/devin.jeanpierre/re0/ an attempt at getting "everything", it failed at the end since I couldn't do assertions in O(1) space) https://bitbucket.org/devin.jeanpierre/replay/ "CS" style regexps _without_ submatch extraction; this was me exploring lots of implementation strategies to get ideas for solving the above problem. Still not complete. From thadguidry at gmail.com Sat May 4 08:00:08 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sat, 4 May 2013 10:00:08 -0500 Subject: [rust-dev] lib: regular expressions in std In-Reply-To: References: Message-ID: Devin, I personally would like to see a Rust regex engine. It could also serve as a new reference standard going forward with the language design where additional tests could be bound to it. A win - win in my opinion for proving the language design in the first place. Java, Python, and Ruby, to name a few...share very similar syntax styles or flavors. You can scroll down this page to see the subtle differences between all the flavors, including those 3. http://www.regular-expressions.info/refflavors.html I am sure you have intentions to develop the Rust regex engine to have a very similar flavor, so I am not worried personally. Just cover the basics with that aligned Rust regex flavor and most folks will be quite happy, everything else can be easily looked up in a reference, as is usually the case for most developers, unless you live and breath regex everyday. Unicode Level 1 and with most of Level 2 would be a requirement in my opinion. It is the world we live in today, thankfully, at last. :) On Sat, May 4, 2013 at 8:54 AM, Devin Jeanpierre wrote: > With regards to < https://github.com/mozilla/rust/issues/3591 >, I'd > like to write a regular expression module for Rust. I've written a > couple of regular expression engines in Python for fun in the past[*], > and #rust pressured me to utilize my perverse sense of fun to write > the same for Rust. Actually, the reason I learned Rust was to port a > bunch of my regex code to a nice language. :) > > I'm writing this email because > https://github.com/mozilla/rust/wiki/Library-editing told me to. I > don't know much about the process, but as I understand it this marks > the beginning of a one week discussion period where Rust-Dev fleshes > out ideas for such a module, and whether or not it deserves to be > written, and whether or not I should be the one writing it. > > I've also added this library page to the wiki: > https://github.com/mozilla/rust/wiki/Lib-re > > > I've already discussed this somewhat with some people in #rust, > especially Marvin L?bel (kimundi) has been interested in helping me > come up with a nice API. Hopefully we can put that down in writing > here so that it isn't just in our memory. > > > Some questions to start off with: > > - Should rust have a new regex engine written in Rust, or should it > just have bindings for e.g. RE2 or similar? > > A point brought up in #rust: if we use RE2 or similar, we may not > be able to have a re!() syntax extension that compiles regexps at > the same time as the surrounding rust code. > > I prefer the former, because I wanted to write a new regex engine > regardless. I would be perfectly happy to write some nice bindings > for something like RE2, but I am probably not the best person to do it. > > - What syntax/semantics are important? > > I would propose supporting the "usual" PCRE syntax and semantics > (including submatch extraction), but with the exception of > backreferences and any other features which cannot be implemented > efficiently (i.e. polynomial time). > > RE2 has a good summary of regex syntax, although it doesn't > specify for PCRE-family syntax whether it comes from perl, libpcre, > python, or something else. > > http://code.google.com/p/re2/wiki/Syntax > > Note: if rust's re module is efficient, syntaxes for things like > possessive quantifiers is pointless and can be dropped. > > It may be desirable to include alternate parse disambiguation > strategies. Using "efficient" RE, it's fairly easy to support > POSIX-style longest match, as well as PCRE-style matches and even > shortest match. For example, RE2 offers support for PCRE-style and > also POSIX style regex matching. > > - How important is Unicode support and how broad should that support be? > > My understanding is that, at least as long as it can be added > later, this is not crucial to get right correct right away. > > Unicode TR-18 defines 3 levels of Unicode support in regex > implementations, of which only the first two are relevant. I think the > only thing missing from core::unicode to give level 1 support is > simple case folding. > > * https://github.com/mozilla/rust/issues/5820 > * http://www.unicode.org/reports/tr18/ > > > That's probably enough to start off with, especially since the answer > to question 1 ties our hands on everything afterwards. Also since my > hands hurt from typing. However, there's a lot of other topics, like > what the API should look like, whether or not to support various > syntaxes, etc.. I've added a lot of links and a few additional topics > to the library proposal page. > > link again: https://github.com/mozilla/rust/wiki/Lib-re > > Let me know if there's something I've left out of here or of the > library proposal page. When there's more discussion / I have more > energy, I will suggest some of my personal ideas of what I'd like in a > regex module, but somehow I don't feel that's appropriate at the top > level post. > > -- Devin Jeanpierre > > .. [*] Here's the work I did before > > https://bitbucket.org/devin.jeanpierre/re0/ > an attempt at getting "everything", it failed at the end since > I couldn't do assertions in O(1) space) > > https://bitbucket.org/devin.jeanpierre/replay/ > "CS" style regexps _without_ submatch extraction; this was me > exploring lots of implementation strategies to get ideas for > solving > the above problem. Still not complete. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnathan at vandals.uidaho.edu Sat May 4 08:14:33 2013 From: pnathan at vandals.uidaho.edu (Paul Nathan) Date: Sat, 4 May 2013 08:14:33 -0700 Subject: [rust-dev] lib: regular expressions in std In-Reply-To: References: Message-ID: <518525D9.4090500@vandals.uidaho.edu> - In my mind, there is no question that Rust should have a RE engine. I should hate to see you blocked. If written in in Rust, macros could come out to play. Please see CL-PPCRE for some ideas on how this has been previously done. - I would suggest that the "standard" Perl regexes be used. Backreferences can be useful, and I don't think that precluding them from later additions is a good idea, even if not released initially. - I have not had to do much with Unicode besides hiss rudely at it: doing it well would mean its inclusion should not affect ANSI development as we happily wander down our 7-bit rural ways. ;) On 5/4/13 6:54 AM, Devin Jeanpierre wrote: > With regards to < https://github.com/mozilla/rust/issues/3591 >, I'd > like to write a regular expression module for Rust. I've written a > couple of regular expression engines in Python for fun in the past[*], > and #rust pressured me to utilize my perverse sense of fun to write > the same for Rust. Actually, the reason I learned Rust was to port a > bunch of my regex code to a nice language. :) > > I'm writing this email because > https://github.com/mozilla/rust/wiki/Library-editing told me to. I > don't know much about the process, but as I understand it this marks > the beginning of a one week discussion period where Rust-Dev fleshes > out ideas for such a module, and whether or not it deserves to be > written, and whether or not I should be the one writing it. > > I've also added this library page to the wiki: > https://github.com/mozilla/rust/wiki/Lib-re > > > I've already discussed this somewhat with some people in #rust, > especially Marvin L?bel (kimundi) has been interested in helping me > come up with a nice API. Hopefully we can put that down in writing > here so that it isn't just in our memory. > > > Some questions to start off with: > > - Should rust have a new regex engine written in Rust, or should it > just have bindings for e.g. RE2 or similar? > > A point brought up in #rust: if we use RE2 or similar, we may not > be able to have a re!() syntax extension that compiles regexps at > the same time as the surrounding rust code. > > I prefer the former, because I wanted to write a new regex engine > regardless. I would be perfectly happy to write some nice bindings > for something like RE2, but I am probably not the best person to do it. > > - What syntax/semantics are important? > > I would propose supporting the "usual" PCRE syntax and semantics > (including submatch extraction), but with the exception of > backreferences and any other features which cannot be implemented > efficiently (i.e. polynomial time). > > RE2 has a good summary of regex syntax, although it doesn't > specify for PCRE-family syntax whether it comes from perl, libpcre, > python, or something else. > > http://code.google.com/p/re2/wiki/Syntax > > Note: if rust's re module is efficient, syntaxes for things like > possessive quantifiers is pointless and can be dropped. > > It may be desirable to include alternate parse disambiguation > strategies. Using "efficient" RE, it's fairly easy to support > POSIX-style longest match, as well as PCRE-style matches and even > shortest match. For example, RE2 offers support for PCRE-style and > also POSIX style regex matching. > > - How important is Unicode support and how broad should that support be? > > My understanding is that, at least as long as it can be added > later, this is not crucial to get right correct right away. > > Unicode TR-18 defines 3 levels of Unicode support in regex > implementations, of which only the first two are relevant. I think the > only thing missing from core::unicode to give level 1 support is > simple case folding. > > * https://github.com/mozilla/rust/issues/5820 > * http://www.unicode.org/reports/tr18/ > > > That's probably enough to start off with, especially since the answer > to question 1 ties our hands on everything afterwards. Also since my > hands hurt from typing. However, there's a lot of other topics, like > what the API should look like, whether or not to support various > syntaxes, etc.. I've added a lot of links and a few additional topics > to the library proposal page. > > link again: https://github.com/mozilla/rust/wiki/Lib-re > > Let me know if there's something I've left out of here or of the > library proposal page. When there's more discussion / I have more > energy, I will suggest some of my personal ideas of what I'd like in a > regex module, but somehow I don't feel that's appropriate at the top > level post. > > -- Devin Jeanpierre > > .. [*] Here's the work I did before > > https://bitbucket.org/devin.jeanpierre/re0/ > an attempt at getting "everything", it failed at the end since > I couldn't do assertions in O(1) space) > > https://bitbucket.org/devin.jeanpierre/replay/ > "CS" style regexps _without_ submatch extraction; this was me > exploring lots of implementation strategies to get ideas for solving > the above problem. Still not complete. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Regards, Paul From mikhail.zabaluev at gmail.com Sat May 4 08:25:25 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Sat, 4 May 2013 18:25:25 +0300 Subject: [rust-dev] Re : Re: RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <20130504111537.279780@gmx.com> Message-ID: Hi, 2013/5/4 Matthieu Monrocq > > Gettext is indeed dependent on the fact that the format syntax allows >> positional parameters. >> >> I'd like to point out that gettext also makes use of a "feature" of the >> formatting function. Namely, the fact that it is not an error to call this >> function with more arguments than what the format string expects. >> >> In C, printf("%d", 1, 2) outputs "1". In Rust, fmt!("%d", 1, 2) is a >> compilation error. >> >> The use case for using this feature is briefly explained here >> http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms >> >> A simple example is that, given the string "there are %d frogs", the >> translator may want to translate it to "il n'y a aucune grenouille" instead >> of "il y a 0 grenouilles". In this case, the resulting function call would >> be printf("il n'y a aucune grenouille", 0), which is valid since the unused >> argument will be ignored. >> >> By the way, it occurs to me that fmt! requires a string literal as its >> first argument. How could a system like gettext, whose role is to >> substitute the format string at runtime, could work with fmt! ? >> > > Maybe we are taking this a bit backward ? > > I understand that things like gettext, at the moment, only substitute the > "text"; but that may be seen as mistake rather than a feature. > > Instead, we could perfectly imagine a "gettext-like" equivalent that takes > both an "original" format string (to be translated) *and* its arguments and > then will use fmt! under the hood to produce a fully translated string to > be fed to the Writer instance. > > Note that anyway for a proper translation gettext requires access to > certain elements; for example for correct plural forms to be picked (esp in > Polish). > In fact, there is nothing preventing fully flexible logic in translations if they are themselves written in Rust (penging some variadic trait mojo in the macro that will invoke the translation): pub static messages: &'static [Tr] = &[ Tr("Simple text", &Text("??????? ?????") as &Message), Tr("%d elements", &Fmt(|n: int| { match (ru::num_case(n)) { ru::NumCaseNone => ~"?? ?????? ????????", ru::NumCase1 => fmt!("%d ???????", n), ru::NumCase2 => fmt!("%d ????????", n), _ => fmt!("%d ?????????", n) } }) as &Message) ]; Gettext is for C programmers B-) -- Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Sat May 4 08:26:21 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Sat, 4 May 2013 08:26:21 -0700 Subject: [rust-dev] Counting users (was: Update on I/O progress) In-Reply-To: <5184E91B.5040405@mansionfamily.plus.com> References: <518060AE.8020605@cantrip.org> <5184E91B.5040405@mansionfamily.plus.com> Message-ID: On Sat, May 4, 2013 at 3:55 AM, james wrote: > On 01/05/2013 01:25, Tim Chevalier wrote: > > Let's drop this thread, as per the code of conduct at > https://github.com/mozilla/rust/wiki/Note-development-policy : > > "Please keep unstructured critique to a minimum. If you have solid > ideas you want to experiment with, make a fork and see how it works." > > It might be development policy, but it seems to me a terrible idea. > > How do you fork a requirement? (or discussion thereof?) > > How do you fork a design? (or discussion thereof?) > > It seems to be the old 'show me the code'. :-( The development policy is not negotiable and not up for discussion. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Too much to carry, too much to let go Time goes fast, learning goes slow." -- Bruce Cockburn From mikhail.zabaluev at gmail.com Sat May 4 08:44:43 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Sat, 4 May 2013 18:44:43 +0300 Subject: [rust-dev] Re : Re: RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <20130504111537.279780@gmx.com> Message-ID: Ideation continues below... 2013/5/4 Mikhail Zabaluev > In fact, there is nothing preventing fully flexible logic in translations > if they are themselves written in Rust (penging some variadic trait mojo in > the macro that will invoke the translation): > > pub static messages: &'static [Tr] = &[ > Tr("Simple text", > &Text("??????? ?????") as &Message), > Tr("%d elements", > &Fmt(|n: int| { > match (ru::num_case(n)) { > ru::NumCaseNone => ~"?? ?????? ????????", > ru::NumCase1 => fmt!("%d ???????", n), > ru::NumCase2 => fmt!("%d ????????", n), > _ => fmt!("%d ?????????", n) > } > }) as &Message) > ]; > This looks boilerplatey, but: 1) I tried to make it legal in my limited understanding of the current Rust; 2) this looks like a perfect application for macros; 3) for a proper i18n system, there would be a tool that would extract tr!() macro invocations from the program source and generate the message catalog boilerplate including properly typed lambdas, with unedited placeholder values marked as untranslated!(), fuzzy!(), etc. to perform later updates gettext-style. Cheers, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sat May 4 11:08:35 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 04 May 2013 11:08:35 -0700 Subject: [rust-dev] lib: regular expressions in std In-Reply-To: References: Message-ID: <51854EA3.5040209@mozilla.com> On 5/4/13 6:54 AM, Devin Jeanpierre wrote: > A point brought up in #rust: if we use RE2 or similar, we may not > be able to have a re!() syntax extension that compiles regexps at > the same time as the surrounding rust code. I like the re!() extension idea, just for performance reasons. If you look at regexp-dna in the shootout, V8 is at the top, significantly ahead of C: this is because it JITs regexes. Regex performance is important for Web servers, because of routes. > RE2 has a good summary of regex syntax, although it doesn't > specify for PCRE-family syntax whether it comes from perl, libpcre, > python, or something else. Note that, as far as I'm aware, RE2 has pretty bad performance in general (see Go's performance in regexp-dna). I'm actually personally somewhat skeptical of the practical advantages of the Thompson NFA algorithm compared to recursive backtracking: it makes pathological regexes much faster, but at the cost of significant overhead for non-pathological regexes (which are 99% of regexes used in reality). To me the hybrid approach is interesting: try recursive backtracking first, and if it takes too long fall back to the Thompson NFA, to avoid the DoS problem. Patrick From pwalton at mozilla.com Sat May 4 11:31:58 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 04 May 2013 11:31:58 -0700 Subject: [rust-dev] Counting users (was: Update on I/O progress) In-Reply-To: <5184E91B.5040405@mansionfamily.plus.com> References: <518060AE.8020605@cantrip.org> <5184E91B.5040405@mansionfamily.plus.com> Message-ID: <5185541E.4070307@mozilla.com> On 5/4/13 3:55 AM, james wrote: > It might be development policy, but it seems to me a terrible idea. > > How do you fork a requirement? (or discussion thereof?) > > How do you fork a design? (or discussion thereof?) > > It seems to be the old 'show me the code'. :-( I think it's totally fine to bring up design issues if people see legitimate, fixable problems in the language. I for one encourage it! I'd like to know about potential language issues, so that we can fix them if they are indeed problems. An excellent example is commenter SteveMcQwark's post about an earlier version of lifetime syntax that pointed out that there were indeed serious mistakes (which have since been fixed): http://www.reddit.com/r/rust/comments/17ka3b/meeting_weekly_20130129_region_syntax_impl_type/ However, there are a couple of important caveats: 1. Some requirements just *are* and can't be changed without jeopardizing the applications that Rust is designed for (most notably Servo). A common example is the requirement for Rust to support manual memory management. Many people think that manual memory management adds too much cognitive and syntactic overhead (what are all these smart pointer sigils all over my code?) and would like to see Rust move to a mandatory, global concurrent garbage collector like Java, throwing away unique pointers, lifetimes, borrow checking, and references in the process. This, however, would be in direct contradiction to the systems-oriented, low-level nature of Rust (which is the reason Rust is starting to find a niche in graphical-intensive apps and games) and so couldn't really be changed without a fork. 2. Sometimes there are issues with perfectly legitimate arguments on both sides, and someone will be disappointed with *any* decision. An example is the requirement that statements be separated by semicolons instead of using whitespace like Python or performing automatic semicolon insertion like JavaScript or Go. Many C and C++ programmers like semicolons; many Python programmers and Ruby programmers detest them. But if we changed this, we'd probably hear just as much criticism from the other side. So arguing doesn't seem really productive to me; a fork is about the only thing that can be done here. Patrick From mozilla at mcpherrin.ca Sat May 4 12:23:38 2013 From: mozilla at mcpherrin.ca (Matthew McPherrin) Date: Sat, 4 May 2013 15:23:38 -0400 Subject: [rust-dev] lib: regular expressions in std In-Reply-To: <51854EA3.5040209@mozilla.com> References: <51854EA3.5040209@mozilla.com> Message-ID: I had started playing around with this when I was learning Rust, but got caught up in exams and didn't finish. You can find my notes and some (probably non-functional) code here: https://github.com/mcpherrinm/rerust I was interested in using the thompson NFA construction so that LLVM could generate native code to match the regular expressions, hopefully reducing some of the overhead Patrick mentioned. On Sat, May 4, 2013 at 2:08 PM, Patrick Walton wrote: > On 5/4/13 6:54 AM, Devin Jeanpierre wrote: > >> A point brought up in #rust: if we use RE2 or similar, we may not >> be able to have a re!() syntax extension that compiles regexps at >> the same time as the surrounding rust code. >> > > I like the re!() extension idea, just for performance reasons. If you look > at regexp-dna in the shootout, V8 is at the top, significantly ahead of C: > this is because it JITs regexes. Regex performance is important for Web > servers, because of routes. > > > RE2 has a good summary of regex syntax, although it doesn't >> specify for PCRE-family syntax whether it comes from perl, libpcre, >> python, or something else. >> > > Note that, as far as I'm aware, RE2 has pretty bad performance in general > (see Go's performance in regexp-dna). I'm actually personally somewhat > skeptical of the practical advantages of the Thompson NFA algorithm > compared to recursive backtracking: it makes pathological regexes much > faster, but at the cost of significant overhead for non-pathological > regexes (which are 99% of regexes used in reality). > > To me the hybrid approach is interesting: try recursive backtracking > first, and if it takes too long fall back to the Thompson NFA, to avoid the > DoS problem. > > 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 o.renaud at gmx.fr Sat May 4 12:34:50 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Sat, 04 May 2013 21:34:50 +0200 Subject: [rust-dev] Re : Re: RFC: User-implementable format specifiers w/ compile-time checks Message-ID: <20130504193451.308850@gmx.com> > On 2013-05-04, at 13:15 , Olivier Renaud wrote: > > Gettext is indeed dependent on the fact that the format syntax allows > > positional parameters. > Not really, since gettext does not do formatting it does not care and > because different languages may need to reorder parameters it's usually > better to have either named or explicitly indexable parameters Granted, I should have said "gettext is dependent on the fact that the format syntax allows parameters reordering". This is precisely because, as you said, ? gettext does not do formatting on its own. > Gettext pluralization takes specific count arguments to handle dispatching > between multiple forms, but that's orthogonal to formatting as this > example from the documentation shows: > > ? ? puts (ngettext ("Delete the selected file?", > ? ? ? ? ? ? ? ? ? ? "Delete the selected files?", > ? ? ? ? ? ? ? ? ? ? n)); What you say is true, but I'm afraid I don't see the relation with the current discussion. > > I'd like to point out that gettext also makes use of a "feature" of the > > formatting function. > It's not gettext doing that either, since gettext doesn't do any > formatting. It can be a useful feature when paired with gettext as > translations may or may not need all original format arguments, but it's > orthogonal to gettext's behavior and features. Again, you are right. Gettext will do its job happily, no matter what the content of the string is. The problem is for the translator : - If the format string provided by the language doesn't support parameters reordering, then the translator is forced to produce a translation where the parameters appear in the same order than in english - if the formatting function provided by the language doesn't support a way to ignore certain parameters, then the translator is forced to use all parameters to produce its translation. From ncm at cantrip.org Sat May 4 12:49:14 2013 From: ncm at cantrip.org (Nathan Myers) Date: Sat, 04 May 2013 12:49:14 -0700 Subject: [rust-dev] Counting users (was: Update on I/O progress) In-Reply-To: <5184E91B.5040405@mansionfamily.plus.com> References: <518060AE.8020605@cantrip.org> <5184E91B.5040405@mansionfamily.plus.com> Message-ID: <5185663A.8060204@cantrip.org> On 05/04/2013 03:55 AM, james wrote: > On 01/05/2013 01:25, Tim Chevalier wrote: >> "Please keep unstructured critique to a minimum. If you have solid >> ideas you want to experiment with, make a fork and see how it works." > It might be development policy, but it seems to me a terrible idea. For the record, I consider this a completely sensible policy. My purpose in the original essay was _not_ to provoke discussion, particularly about user counts. It was to suggest that reasoning about individual features based on user count, real or imagined, is a fundamental error. I can explain briefly what worked best in the C++ standardization process, but will not without invitation from the principals. Nathan Myers ncm at cantrip.org From o.renaud at gmx.fr Sat May 4 12:57:29 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Sat, 04 May 2013 21:57:29 +0200 Subject: [rust-dev] Re : Re: RFC: User-implementable format specifiers w/ compile-time checks Message-ID: <20130504195729.308840@gmx.com> > Instead, we could perfectly imagine a "gettext-like" equivalent that takes > both an "original" format string (to be translated) *and* its arguments and > then will use fmt! under the hood to produce a fully translated string to > be fed to the Writer instance. I'm sorry, but I don't see how your description differs from gettext's behavior. > There is no point in being as loose as C. Being able to check at compile time wether the format string matches the number of arguments is great ! I'm definitely not in favor of being as loose as C on this aspect. So, we can choose to say that this particular use case is so much exceptional that it is not worth trying to support it. I'm sure it would be a reasonable choice. Or we can find a way to declare explicitely, in the format string, that one or more parameters should be ignored. Maybe a %ignore at the end of the string ? From aatch at aatch.net Sat May 4 16:58:50 2013 From: aatch at aatch.net (James Miller) Date: Sun, 5 May 2013 11:58:50 +1200 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <5183D7AB.4050707@gmail.com> References: <5183D7AB.4050707@gmail.com> Message-ID: <20130504235847.GA28308@tyr.home.aatch.net> On 2013-05-04 01:28:43, Huon Wilson wrote: > Hi all, > > Aatch, Kimundi and I (and maybe some others... sorry if I've forgotten > you) came up with a bit of proposal on IRC for handling fmt!. It's > possibly been considered already, but whatever, we'd like some > comments on it. > > > There would one trait for each format specifier (probably excluding > `?'), e.g. FormatC for %c, FormatD for %d/%i, FormatF for %f, and > format would just require that the value for each format specifier > implements the correct trait. (Presumably this check can be done > "automatically" by attempting to call the appropriate method and > using the type checker.) > > In code, > > > trait FormatC { > fn format_c(&self, w: &Writer, flags: Flags); > } > > impl FormatC for char { > fn format_c(&self, w: &Writer, _: Flags) { w.write_char(*self) } > } > > struct MyChar(char); > impl FormatC for MyChar { > fn format_c(&self, w: &Writer, _: Flags) { w.write_char(**self) } > } > > fmt!("%c%c%c", 'a', MyChar('a'), ~"str") > > // becomes > > 'a'.format_c(w, {}); > MyChar('a').format_c(w, {}); > ~"str".format_c(w, {}); > > > And the first two would resolve/type-check fine, but the last would > not. (`Flags' would contain the width and precision specifiers and all > that.) > > > This could then be extended to have a dynamic formatter, which allows > types to format for any specifier at runtime (i.e. get around compile > time restrictions). Our thoughts were to add an extra flag to indicate > this (e.g. !), so that it is entirely and explicitly opt-in. (Similar > to Python's __format__ and Go's fmt (I think).) > > > trait DynamicFormat { > fn format_dynamic(&self, w: &Writer, spec: FormatSpec); > } > > fmt!("%!s %!10.3f", a, b) > > // becomes > > a.format_dynamic(w, {flags: {}, type: 's'}); > w.write_str(" "); > b.format_dynamic(w, {flags: {width: 10, prec: 3}, type: 'f'}); > > > (Presumably this could also have a lint mode, to give an error or > warning if dynamic formatting is used.) > > > There were also some other discussions about the fmt! syntax, e.g. it > was suggested that the following could be equivalent to each other > > fmt!("%{2}[0].[1]f %{2}e", 10, 3, 1.01); > fmt!("%10.3f %e", 1.01, 1.01); > > This is an explicit divergence from printf's slightly archane */'n$' > placeholder syntax. One could use `[*]` to just refer to the next > argument, like * does by default. (Aatch has a format spec parser[1] > in the works that supports this syntax.) > > > Huon > > [1]: https://gist.github.com/Aatch/fb94960ab770c7df5718 > _______________________________________________ Hi All, Me and dbaupp have done some preliminary implementation[1] on the formatting side of things. During discussion on IRC we have come up with a few extra details that should probably be mentioned. Using a writer for format strings is useful for efficiency, especially when doing things like writing to the terminal or a file. So there are 3 syntax extensions that would be used in order to make this work and be nice: * fmt! which is essentially the same as now, returns a ~str * printf! which writes straight to stdout (effectively replacing `io::print(fmt!(...))`) * writef! which would take an io::Writer as it's first argument fmt! and printf! would simply be written in terms of writef! with pre-supplied Writers. The actual format string has, unsurprisingly, created a lot of discussion mostly around it's relative power. The current placeholder format is as follows: % position flags width precision numeric_arg conversion_specifier With all except the '%' and conversion specifier being optional. The specific format of the fields is detailed in the string parser. Currently we have identified 4 conversion specifiers: 'd', 'f', 's' and '?'. These are interpreted as "convert as" specifiers so '%d' means "convert this argument as a number" and the argument type itself knows how to do this. For flags, we have '0', '-', '=', ' ', '+' and '\'' which have the same meaning as standard printf (where they exist in standard printf). * '0' means zero-pad * '-' means left-justified in the field * '=' means center in the field * ' ' means that a blank should always be before a signed number * '+' means that a '-' or '+' should always be placed before a signed number Width and precision fields are similar to the standard printf fields, just with minor syntax changes in the case of using the next or a specific argument. The numeric arg field is formatted like this: `<[0-9]+>` and is used for supplying a base to 'd' conversions, with the default being 10. This means that '%x', '%o' and '%t' can all be replaced with this format: '%<16>d', '%<8>d' and '%<2>d'. You could obviously specify other bases to print in up to 36. I'm in favor of keeping printf-style strings. For one, they are what we already have, so in that sense it's merely not changing that. Also, I am struggling to see the objective advantages of other implementations, while they aren't worse, I don't see a reason to use them over what we alrady have. Many people want more power in the format strings, but I am reluctant to include it for a couple reasons. * Turning format specifiers into a mini-language (more than it already is) seems to add too much complexity for not enough return. In practice I have rarely seen many of the complex features of other formatting systems be used, since they are often too simplistic for many cases, or the resulting string is too complex to be clear any more. This is the issue with regex, but without the advantages that regex gives you. * Adding more power is the perfect way to introduce undefined or unspecified behaviour. It forces the definition of further syntax rules and then limitations. Eventually you either end up with something that is so complex nobody uses it, or so ham-strung that it isn't worth using. I would much rather spend time implementing common features that are likely to be used (centering for example) than obscure features that only look good in examples. So that's my update and opinion. -- James Miller [1]: https://github.com/Aatch/rust-fmt From banderson at mozilla.com Sat May 4 17:16:15 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 04 May 2013 17:16:15 -0700 Subject: [rust-dev] What parts of libuv are used ? why ? In-Reply-To: References: Message-ID: <5185A4CF.3030409@mozilla.com> On 05/03/2013 09:24 PM, Thad Guidry wrote: > Looks like libuv is a showstopper currently for me on Windows Cygwin > building. > > Why is it used ? Should it be ? Will it be in the future ? > > Can someone throw up a quick paragraph or 2 about this on the wiki and > let me know ? libuv is Rust's I/O abstraction layer. It provides efficient asynchronous I/O that works on all platforms, including windows (but apparently excluding cygwin). The I/O layer is somewhat tightly integrated with the new scheduler, but the scheduler is being designed with the intent that the I/O implementation be dynamically pluggable, allowing for alternatives to libuv. Making libuv truly optional requires fixing a few blockers, ripping out and refactoring a lot of code. If you are someone else is interested I can point in the direction necessary, but it is a significant amount of work. Under the *current* runtime libuv is not strictly necessary, so it may be possible to carve out everything that depends on libuv and still get it to compile, but it would be very ugly. The path of least resistance here is probably to port libuv to cygwin. Some details here: https://github.com/mozilla/rust/issues/4419 From jeanpierreda at gmail.com Sat May 4 17:49:48 2013 From: jeanpierreda at gmail.com (Devin Jeanpierre) Date: Sat, 4 May 2013 20:49:48 -0400 Subject: [rust-dev] lib: regular expressions in std In-Reply-To: <51854EA3.5040209@mozilla.com> References: <51854EA3.5040209@mozilla.com> Message-ID: On Sat, May 4, 2013 at 2:08 PM, Patrick Walton wrote: > On 5/4/13 6:54 AM, Devin Jeanpierre wrote: >> >> A point brought up in #rust: if we use RE2 or similar, we may not >> be able to have a re!() syntax extension that compiles regexps at >> the same time as the surrounding rust code. > > > I like the re!() extension idea, just for performance reasons. If you look > at regexp-dna in the shootout, V8 is at the top, significantly ahead of C: > this is because it JITs regexes. Regex performance is important for Web > servers, because of routes. Any reason it's important that this be a syntax extension? One could easily imagine writing a JIT compiler using LLVM (at least, if Rust supported calling C function pointers); however, I am not sure if std, or even a regex module outside of std, is allowed to depend on LLVM. > Note that, as far as I'm aware, RE2 has pretty bad performance in general > (see Go's performance in regexp-dna). I'm actually personally somewhat > skeptical of the practical advantages of the Thompson NFA algorithm compared > to recursive backtracking: it makes pathological regexes much faster, but at > the cost of significant overhead for non-pathological regexes (which are 99% > of regexes used in reality). FWIW, there are techniques to get around this: - One can classify a family of regexps for which backtracking is very fast, and special-case them. RE2 special-cases the regexps for which backtracking never produces a match, and can run these faster than a backtracking engine, since it doesn't waste time backtracking uselessly. - It is possible in general to remove the overhead of NFA, by compiling to DFA instead of emulating the NFA. Caveats: * The algorithm for doing this for tagged NFA (NFA that keep track of submatch extraction) is not well studied. Ville Laurikari wrote a paper on it, but the paper has some errors, and there is no public implementation of this algorithm. (I meant to implement it before, but haven't gotten around to it yet.) * I actually am not sure if his paper describes POSIX style matching or PCRE style matching. However, it should be possible to make it use either one, since the principle is the same. * DFA can consume exponential space in the size of the NFA, which itself consumes exponential space in the size of the regexp. There are many cases of regexps that are reasonable enough but can't be sensibly represented as a DFA. This is the reason why the algorithm is not well studied -- most people (in relevant academic circles, at least) can't use it as a result of the state explosion. - There are approaches that attempt to get "most of the time" performance like DFA, but without the huge memory cost. These are pretty cutting edge though, and therefore also not well studied. * http://link.springer.com/chapter/10.1007%2F978-3-642-15512-3_4 (without submatch extraction) * http://www.hpl.hp.com/techreports/2012/HPL-2012-215.pdf (with) I don't know how it /really/ compares performance wise with NFA and backtracking implementations (the paper authors cannot be trusted to give reliable performance data ;). What I can do is implement this and some benchmarks, and then decide based on that how significant a technique it is. I am slightly skeptical of this technique compared to Thompson NFA, because OBDDs don't have great worst-case performance (although it still beats exponential time). However, that might be an advantage, considering your concern. People use OBDDs for the performance they actually give, rather than the performance they give in the worst case. They're a very popular data structure in certain circles these days because they are usually very fast. I expect that the kinds of regexes that OBDD based regex would perform well on would be unrelated (neither a subset nor superset) to the kinds of regex backtracking search performs well on, so this probably isn't a perfect solution. However, I haven't thought about it much. > To me the hybrid approach is interesting: try recursive backtracking first, > and if it takes too long fall back to the Thompson NFA, to avoid the DoS > problem. I'm personally biased against this, since for a naively written regex, Thompson NFA is a far more reliable method. How about defaulting to Thompson NFA, but letting people that know the performance characteristics of their regex explicitly use backtracking search? Going with backtracking search is not without other downsides. You lose the ability to have POSIX-style regexp matches, which are useful in some circumstances (especially lexing). -- Devin From heri16 at gmail.com Sat May 4 19:31:56 2013 From: heri16 at gmail.com (heri16 at gmail.com) Date: Sat, 04 May 2013 19:31:56 -0700 (PDT) Subject: [rust-dev] Nodejs Event Loop - Stack Overflow Message-ID: <5185c49c.4557440a.0d4b.1f5c@mx.google.com> An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sat May 4 20:32:18 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sat, 4 May 2013 23:32:18 -0400 Subject: [rust-dev] Nodejs Event Loop - Stack Overflow In-Reply-To: <5185c49c.4557440a.0d4b.1f5c@mx.google.com> References: <5185c49c.4557440a.0d4b.1f5c@mx.google.com> Message-ID: On Sat, May 4, 2013 at 10:31 PM, wrote: > http://stackoverflow.com/questions/10680601/nodejs-event-loop > > Is libev good enough for abstraction in rust? > > Heri libuv/node is no longer using libev internally on *nix, it was replaced with an internal implementation for better performance. libev isn't good enough for Rust because it doesn't provide the ability to use the Windows async I/O support (IOCP). It's also not nearly as comprehensive as a platform abstraction layer, so more work would probably have to be done in Rust's runtime. I don't think there's any need to get rid of it. From thadguidry at gmail.com Sat May 4 22:05:01 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sun, 5 May 2013 00:05:01 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: <25622438.109751367223000089.JavaMail.weblogic@epml21> <517EC8AA.8030308@mozilla.com> Message-ID: OK. Cygwin does not seem to be the best option for Windows users building Rust. I am recanting. It is not a best option for us, after having more discussion with the MingGW folks and looking at other options. So back to MinGW, I go...and try to setup the Mingw64 toolchain correctly there, since I initially had better luck. (ending this thread) -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Sat May 4 22:13:47 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sun, 5 May 2013 00:13:47 -0500 Subject: [rust-dev] MinGW and Rust for Windows Users Message-ID: So, I went back to MinGW and managed to get a compiler chain for Windows 7 64bit working with mingw64 and using MingGW / Msys and additionally I was able to get the Wget gui to actually work correctly... so in essence, Windows users will have a nice gui like interface to install the Unix tools they need for the compiler chain. In the Msys terminal window, you just type "mingw-get" and it launches the gui. The only thing that is not packaged up in the gui as a mouse click away is the actual headers and CRT for Mingw64 for gcc to use. The headers/CRT is currently a separate download and has to be unzipped into the C:\MinGW folder. LLVM seemed to get built just fine under Release+Asserts it says. Libuv is a different matter... it can't find uv.h for whatever dasterdly reason, even though it is sitting right there under its foot C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv-private (folder) C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv.h (file) Here's the paste and asking the community for help on what next ? .. http://pastebin.mozilla.org/2375997 -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Sun May 5 11:55:45 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sun, 5 May 2013 13:55:45 -0500 Subject: [rust-dev] MinGW and Rust for Windows Users In-Reply-To: References: Message-ID: I asked the libuv folks on their IRC channel and this was Mr. Fontaine's response: tjfontaine for some reason that compile line doesn't have the include directory, you should really take that up with the rust folk. On Sun, May 5, 2013 at 12:13 AM, Thad Guidry wrote: > > So, I went back to MinGW and managed to get a compiler chain for Windows 7 > 64bit working with mingw64 and using MingGW / Msys and additionally I was > able to get the Wget gui to actually work correctly... so in essence, > Windows users will have a nice gui like interface to install the Unix tools > they need for the compiler chain. In the Msys terminal window, you just > type "mingw-get" and it launches the gui. > > The only thing that is not packaged up in the gui as a mouse click away is > the actual headers and CRT for Mingw64 for gcc to use. The headers/CRT is > currently a separate download and has to be unzipped into the C:\MinGW > folder. > > LLVM seemed to get built just fine under Release+Asserts it says. > > Libuv is a different matter... it can't find uv.h for whatever dasterdly > reason, even though it is sitting right there under its foot > > C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv-private (folder) > C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv.h (file) > > Here's the paste and asking the community for help on what next ? .. > > http://pastebin.mozilla.org/2375997 > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Sun May 5 12:59:15 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sun, 5 May 2013 14:59:15 -0500 Subject: [rust-dev] MinGW and Rust for Windows Users In-Reply-To: References: Message-ID: Worked with Mr. Fontaine on ensuring that it was a Rust issue and not Libuv issue ... we built and tested Libuv under my Mingw sys and tested just fine with this output and verified by him as OK. http://pastebin.mozilla.org/2377431 On Sun, May 5, 2013 at 1:55 PM, Thad Guidry wrote: > I asked the libuv folks on their IRC channel and this was Mr. Fontaine's > response: > > tjfontaine for some reason that compile line doesn't have the include > directory, you should really take that up with the rust folk. > > > On Sun, May 5, 2013 at 12:13 AM, Thad Guidry wrote: > >> >> So, I went back to MinGW and managed to get a compiler chain for Windows >> 7 64bit working with mingw64 and using MingGW / Msys and additionally I was >> able to get the Wget gui to actually work correctly... so in essence, >> Windows users will have a nice gui like interface to install the Unix tools >> they need for the compiler chain. In the Msys terminal window, you just >> type "mingw-get" and it launches the gui. >> >> The only thing that is not packaged up in the gui as a mouse click away >> is the actual headers and CRT for Mingw64 for gcc to use. The headers/CRT >> is currently a separate download and has to be unzipped into the C:\MinGW >> folder. >> >> LLVM seemed to get built just fine under Release+Asserts it says. >> >> Libuv is a different matter... it can't find uv.h for whatever dasterdly >> reason, even though it is sitting right there under its foot >> >> C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv-private (folder) >> C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv.h (file) >> >> Here's the paste and asking the community for help on what next ? .. >> >> http://pastebin.mozilla.org/2375997 >> >> -- >> -Thad >> http://www.freebase.com/view/en/thad_guidry >> > > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From noamraph at gmail.com Sun May 5 13:19:11 2013 From: noamraph at gmail.com (Noam Yorav-Raphael) Date: Sun, 5 May 2013 23:19:11 +0300 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length Message-ID: Hello, My name is Noam Yorav-Raphael. I find Rust to be a really exciting language! I have a simple suggestion: the current implementation of zip() returns an iterator which stops whenever one of the two iterators it gets stop. I use zip() in python quite a bit. I always have a few lists, where the i'th value in each corresponds to the same thing. I use zip in python to iterate over a few of those lists in parallel. I think this is the usual use case. In this use case, when the two lists have a different length it means that I have a bug. it seems to me that Python's behavior, and current Rust behavior, is contrary to "Errors should never pass silently" from the zen of Python. What do you think of changing this, so that zip() will fail in such a case? Another iterator, say, "zipcut" can implement the current behavior if needed. It will be my pleasure to implement this, if the suggestion is found useful. Thanks, and have a nice day, Noam -------------- next part -------------- An HTML attachment was scrubbed... URL: From masklinn at masklinn.net Sun May 5 13:49:44 2013 From: masklinn at masklinn.net (Masklinn) Date: Sun, 5 May 2013 22:49:44 +0200 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: Message-ID: <8485CE92-BB17-42E2-A5E8-1E10E331FD26@masklinn.net> On 2013-05-05, at 22:19 , Noam Yorav-Raphael wrote: > Hello, > > My name is Noam Yorav-Raphael. I find Rust to be a really exciting language! > > I have a simple suggestion: the current implementation of zip() returns an > iterator which stops whenever one of the two iterators it gets stop. > I use zip() in python quite a bit. I always have a few lists, where the > i'th value in each corresponds to the same thing. I use zip in python to > iterate over a few of those lists in parallel. > > I think this is the usual use case. In this use case, when the two lists > have a different length it means that I have a bug. it seems to me that > Python's behavior, and current Rust behavior, is contrary to "Errors should > never pass silently" from the zen of Python. > > What do you think of changing this, so that zip() will fail in such a case? > Another iterator, say, "zipcut" can implement the current behavior if > needed. > > It will be my pleasure to implement this, if the suggestion is found useful. FWIW there are languages falling either way, Haskell's zip is "shortest": Prelude> zip [1..3] [1..4] [(1,1),(2,2),(3,3)] Prelude> zip [1..5] [1..4] [(1,1),(2,2),(3,3),(4,4)] while erlang's is strict: 1> lists:zip([1, 2, 3], [1, 2]). ** exception error: no function clause matching lists:zip([3],[]) (lists.erl, line 372) in function lists:zip/2 (lists.erl, line 372) in call from lists:zip/2 (lists.erl, line 372) 2> lists:zip([1, 2, 3], [1, 2, 3, 4]). ** exception error: no function clause matching lists:zip([],[4]) (lists.erl, line 372) in function lists:zip/2 (lists.erl, line 372) in call from lists:zip/2 (lists.erl, line 372) I've never had issues one way or an other, but note one thing: zip "shortest" is the most useful one when the language has infinite sequences (infinite lazy lists in Haskell, infinite generators/iterators in Python) as it allows zipping an infinite and a finite and get a sensible (and terminating) result, e.g. zip(itertools.count(), collection) thus it is not an error to do it that way but an extremely useful property. Because Erlang's lists are strict and finite, an assertion of equal length makes sense: there are no infinite streams to zip to, zipping of lists of different length can pretty much only be a bug. Now here's the question, to which I don't have an answer but which will tell you whether your suggestion makes sense ? at least when compared to existing languages: is it possible to have an infinite vector in Rust, or to zip finite and infinite datastructures (iterators?) together? From danielmicay at gmail.com Sun May 5 13:51:44 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 5 May 2013 16:51:44 -0400 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: <8485CE92-BB17-42E2-A5E8-1E10E331FD26@masklinn.net> References: <8485CE92-BB17-42E2-A5E8-1E10E331FD26@masklinn.net> Message-ID: On Sun, May 5, 2013 at 4:49 PM, Masklinn wrote: > > Now here's the question, to which I don't have an answer but which will > tell you whether your suggestion makes sense ? at least when compared > to existing languages: is it possible to have an infinite vector in Rust, > or to zip finite and infinite datastructures (iterators?) together? Yes, you can make infinite generators implementing the Iterator trait. One example of that is `iterator::Counter::new(1, 2)` which is the same as `[1,3..]` in Haskell. From noamraph at gmail.com Sun May 5 14:00:51 2013 From: noamraph at gmail.com (Noam Yorav-Raphael) Date: Mon, 6 May 2013 00:00:51 +0300 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: <8485CE92-BB17-42E2-A5E8-1E10E331FD26@masklinn.net> Message-ID: Indeed you can. But do you think of a useful, common use case? Starting to count from 0 is indeed very useful, but you can use enumerate() for this. It seems to me that in the rare cases where it's useful, a special version like "zipcut" should be used, so that the usual use case will be checked for errors. Noam On 5 May 2013 23:51, Daniel Micay wrote: > On Sun, May 5, 2013 at 4:49 PM, Masklinn wrote: > > > > Now here's the question, to which I don't have an answer but which will > > tell you whether your suggestion makes sense ? at least when compared > > to existing languages: is it possible to have an infinite vector in Rust, > > or to zip finite and infinite datastructures (iterators?) together? > > Yes, you can make infinite generators implementing the Iterator trait. > One example of that is `iterator::Counter::new(1, 2)` which is the > same as `[1,3..]` in Haskell. > _______________________________________________ > 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 masklinn at masklinn.net Sun May 5 14:18:43 2013 From: masklinn at masklinn.net (Masklinn) Date: Sun, 5 May 2013 23:18:43 +0200 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: <8485CE92-BB17-42E2-A5E8-1E10E331FD26@masklinn.net> Message-ID: On 5 mai 2013, at 22:51, Daniel Micay wrote: > On Sun, May 5, 2013 at 4:49 PM, Masklinn wrote: >> >> Now here's the question, to which I don't have an answer but which will >> tell you whether your suggestion makes sense ? at least when compared >> to existing languages: is it possible to have an infinite vector in Rust, >> or to zip finite and infinite datastructures (iterators?) together? > > Yes, you can make infinite generators implementing the Iterator trait. > One example of that is `iterator::Counter::new(1, 2)` which is the > same as `[1,3..]` in Haskell. I know you can create infinite iterators but can you *zip* to one was the question. From masklinn at masklinn.net Sun May 5 14:21:08 2013 From: masklinn at masklinn.net (Masklinn) Date: Sun, 5 May 2013 23:21:08 +0200 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: <8485CE92-BB17-42E2-A5E8-1E10E331FD26@masklinn.net> Message-ID: <15DBD78D-2521-4741-89D6-9EEE9056610B@masklinn.net> On 5 mai 2013, at 23:00, Noam Yorav-Raphael wrote: > Indeed you can. But do you think of a useful, common use case? I think it's a useful feature. "Common" is not really relevant and will depend on your coding style. > Starting to count from 0 is indeed very useful, but you can use enumerate() for this. It was an example. > It seems to me that in the rare cases where it's useful, a special version like "zipcut" should be used, so that the usual use case will be checked for errors. From fabian.deutsch at gmx.de Sun May 5 03:35:33 2013 From: fabian.deutsch at gmx.de (Fabian Deutsch) Date: Sun, 5 May 2013 12:35:33 +0200 (CEST) Subject: [rust-dev] Fedora package for rust Message-ID: Hey, just to give the interested Fedora user a hint: I've created a copr ("Fedora PPAs") for rust [0]. I'll keep builds for stable releases of rust around. Greetings fabian --- [0] http://dummdida.blogspot.de/2013/05/mozillas-rust-in-fedoras-ppa-copr.html From lindsey at composition.al Sun May 5 14:54:01 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Sun, 5 May 2013 17:54:01 -0400 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: Message-ID: On Sun, May 5, 2013 at 4:19 PM, Noam Yorav-Raphael wrote: > I have a simple suggestion: the current implementation of zip() returns an > iterator which stops whenever one of the two iterators it gets stop. > I use zip() in python quite a bit. I always have a few lists, where the i'th > value in each corresponds to the same thing. I use zip in python to iterate > over a few of those lists in parallel. > > I think this is the usual use case. In this use case, when the two lists > have a different length it means that I have a bug. it seems to me that > Python's behavior, and current Rust behavior, is contrary to "Errors should > never pass silently" from the zen of Python. > > What do you think of changing this, so that zip() will fail in such a case? > Another iterator, say, "zipcut" can implement the current behavior if > needed. For what it's worth, in Wikipedia's comparison of implementations of zip for various languages [0], none of them raise an error when the lists are different lengths; they all either stop with the shorter of the two lists, or fill in the missing values with a nil value. Lindsey [0] https://en.wikipedia.org/wiki/Convolution_%28computer_science%29#Language_comparison From rossberg at mpi-sws.org Sun May 5 15:17:45 2013 From: rossberg at mpi-sws.org (Andreas Rossberg) Date: Mon, 6 May 2013 00:17:45 +0200 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: Message-ID: On May 5, 2013, at 23:54 , Lindsey Kuper wrote: > On Sun, May 5, 2013 at 4:19 PM, Noam Yorav-Raphael wrote: >> I have a simple suggestion: the current implementation of zip() returns an >> iterator which stops whenever one of the two iterators it gets stop. >> I use zip() in python quite a bit. I always have a few lists, where the i'th >> value in each corresponds to the same thing. I use zip in python to iterate >> over a few of those lists in parallel. >> >> I think this is the usual use case. In this use case, when the two lists >> have a different length it means that I have a bug. it seems to me that >> Python's behavior, and current Rust behavior, is contrary to "Errors should >> never pass silently" from the zen of Python. >> >> What do you think of changing this, so that zip() will fail in such a case? >> Another iterator, say, "zipcut" can implement the current behavior if >> needed. > > For what it's worth, in Wikipedia's comparison of implementations of > zip for various languages [0], none of them raise an error when the > lists are different lengths; they all either stop with the shorter of > the two lists, or fill in the missing values with a nil value. That may be coincidence, however, since the page lists only a handful of languages. As a counter example, OCaml, which calls it 'combine', throws. Standard ML even provides two variants, 'zip' and 'zipEq', the latter throwing. (And as an additional data point, nowhere in my SML code have I ever had a need for the non-throwing version.) /Andreas From lindsey at composition.al Sun May 5 15:28:19 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Sun, 5 May 2013 18:28:19 -0400 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: Message-ID: On Sun, May 5, 2013 at 6:17 PM, Andreas Rossberg wrote: > On May 5, 2013, at 23:54 , Lindsey Kuper wrote: >> On Sun, May 5, 2013 at 4:19 PM, Noam Yorav-Raphael wrote: >>> I have a simple suggestion: the current implementation of zip() returns an >>> iterator which stops whenever one of the two iterators it gets stop. >>> I use zip() in python quite a bit. I always have a few lists, where the i'th >>> value in each corresponds to the same thing. I use zip in python to iterate >>> over a few of those lists in parallel. >>> >>> I think this is the usual use case. In this use case, when the two lists >>> have a different length it means that I have a bug. it seems to me that >>> Python's behavior, and current Rust behavior, is contrary to "Errors should >>> never pass silently" from the zen of Python. >>> >>> What do you think of changing this, so that zip() will fail in such a case? >>> Another iterator, say, "zipcut" can implement the current behavior if >>> needed. >> >> For what it's worth, in Wikipedia's comparison of implementations of >> zip for various languages [0], none of them raise an error when the >> lists are different lengths; they all either stop with the shorter of >> the two lists, or fill in the missing values with a nil value. > > That may be coincidence, however, since the page lists only a handful of languages. As a counter example, OCaml, which calls it 'combine', throws. Standard ML even provides two variants, 'zip' and 'zipEq', the latter throwing. (And as an additional data point, nowhere in my SML code have I ever had a need for the non-throwing version.) Fair point. Perhaps Rust should also provide both. I like the SML names, too. Lindsey From graydon at mozilla.com Sun May 5 20:04:47 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 05 May 2013 20:04:47 -0700 Subject: [rust-dev] Counting users (was: Update on I/O progress) In-Reply-To: <5184E91B.5040405@mansionfamily.plus.com> References: <518060AE.8020605@cantrip.org> <5184E91B.5040405@mansionfamily.plus.com> Message-ID: <51871DCF.9070404@mozilla.com> On 04/05/2013 3:55 AM, james wrote: >> "Please keep unstructured critique to a minimum. If you have solid >> ideas you want to experiment with, make a fork and see how it works." > It might be development policy, but it seems to me a terrible idea. I'm sorry to hear it. We thought it a policy aimed mostly at maintaining civility and nipping in the bud patterns of hostility and unproductive yelling we've seen elsewhere in the free-software space. Especially around languages. > How do you fork a requirement? (or discussion thereof?) > > How do you fork a design? (or discussion thereof?) It depends. If there's something specific to comment on, we don't mean to discourage discussion thereof. Specificity is in the eye of the beholder I guess. Tim's judgment (that, in this case, I quite agreed with) was that this thread had gone well off the rails into abstract lecturing. I did some of it -- I probably should have sent a shorter and more polite email in the one-previous -- you did some, Nathan did some. It wasn't getting anywhere, and it's exactly the sort of thread that policy was intended to remind us to hold our tongues during. They just make everyone's blood boil, produce nothing useful. > It seems to be the old 'show me the code'. :-( It's a plea to remain constructive and focused on actual problems; and if none can be seen through the fog of abstraction, invented numbers and straw-men, to go experiment long enough until something specific can be seen and described. Language design has a tendency to get very abstract, hypothetical and philosophical very quickly; what starts as a discussion about IO libraries quickly turns into a discussion of the relative numerical distribution of programmer productivity. This gets us no closer to shipping a compiler. -Graydon From graydon at mozilla.com Sun May 5 20:06:17 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 05 May 2013 20:06:17 -0700 Subject: [rust-dev] Counting users (was: Update on I/O progress) In-Reply-To: <5185663A.8060204@cantrip.org> References: <518060AE.8020605@cantrip.org> <5184E91B.5040405@mansionfamily.plus.com> <5185663A.8060204@cantrip.org> Message-ID: <51871E29.7020808@mozilla.com> On 04/05/2013 12:49 PM, Nathan Myers wrote: > I can explain briefly what worked best in the C++ standardization > process, but will not without invitation from the principals. I'd be interested in hearing this if it can be made concise, descriptive and constructive. It'd be remarkable to me if no weight was given to the relative frequency of a particular problem / API / idiom when standardizing C++. -Graydon From james at mansionfamily.plus.com Mon May 6 07:05:00 2013 From: james at mansionfamily.plus.com (james) Date: Mon, 06 May 2013 15:05:00 +0100 Subject: [rust-dev] Counting users In-Reply-To: <51871DCF.9070404@mozilla.com> References: <518060AE.8020605@cantrip.org> <5184E91B.5040405@mansionfamily.plus.com> <51871DCF.9070404@mozilla.com> Message-ID: <5187B88C.8090604@mansionfamily.plus.com> On 06/05/2013 04:04, Graydon Hoare wrote: > >> How do you fork a requirement? (or discussion thereof?) >> >> How do you fork a design? (or discussion thereof?) > > It depends. If there's something specific to comment on, we don't mean > to discourage discussion thereof. Specificity is in the eye of the > beholder I guess. Tim's judgment (that, in this case, I quite agreed > with) was that this thread had gone well off the rails into abstract > lecturing. I did some of it -- I probably should have sent a shorter > and more polite email in the one-previous -- you did some, Nathan did > some. It wasn't getting anywhere, and it's exactly the sort of thread > that policy was intended to remind us to hold our tongues during. They > just make everyone's blood boil, produce nothing useful. I think the issue here is that it is not entirely clear what kind of problem the libraries are trying to solve, and who for. Plenty of us have experience writing server processes and this has historically involved quite low-level coding. Its quite reasonable for Rust to target something else (its not as if Ruby does, for example) and yet be useful. I thought this was a real discussion about what the requirement (or multiple diverse requirements sets) are. Maybe I'm old fashioned, but I can't imagine day-job being materially different to: - requirement - analysis - estimation - sponsorship - resourcing - implementation and testing Its clear that there are iterations to be had in much of this, but with something very fundamental, failing to understand and agree and record and publicise the requirements is a basis for later pain. And I would expect that to hold whether or not the later phases occur formally in a less formal environment. In this particular case, it is not easy to see how a reliance on lightweight switching at a task layer can work in practice on all interesting platforms; but its also true that it doesn't matter whether the behaviour now is 'good enough' so long as there is some clarity about what the expected goal is. If the reality is a desire to make it easy to solve server scalability that will work for most problems, most of the time - and that there is no ambition that this framework would solve more extreme requirements - then that's fine, but I think it worth stating clearly if so. (I also think its a shame, because everything layered upon it like address resolution and http server loops and codec pipelines etc that will surely come will also have the same inherited limitations, but that might just be tough.) >> It seems to be the old 'show me the code'. :-( > > It's a plea to remain constructive and focused on actual problems; In this case I think the problem is very much 'what is the requirement?' And that _is_ necessarily abstract for something like this, but that does not preclude clarity. James -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Mon May 6 09:46:23 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Mon, 6 May 2013 18:46:23 +0200 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: Message-ID: On Mon, May 6, 2013 at 12:28 AM, Lindsey Kuper wrote: > On Sun, May 5, 2013 at 6:17 PM, Andreas Rossberg > wrote: > > On May 5, 2013, at 23:54 , Lindsey Kuper wrote: > >> On Sun, May 5, 2013 at 4:19 PM, Noam Yorav-Raphael > wrote: > >>> I have a simple suggestion: the current implementation of zip() > returns an > >>> iterator which stops whenever one of the two iterators it gets stop. > >>> I use zip() in python quite a bit. I always have a few lists, where > the i'th > >>> value in each corresponds to the same thing. I use zip in python to > iterate > >>> over a few of those lists in parallel. > >>> > >>> I think this is the usual use case. In this use case, when the two > lists > >>> have a different length it means that I have a bug. it seems to me that > >>> Python's behavior, and current Rust behavior, is contrary to "Errors > should > >>> never pass silently" from the zen of Python. > >>> > >>> What do you think of changing this, so that zip() will fail in such a > case? > >>> Another iterator, say, "zipcut" can implement the current behavior if > >>> needed. > >> > >> For what it's worth, in Wikipedia's comparison of implementations of > >> zip for various languages [0], none of them raise an error when the > >> lists are different lengths; they all either stop with the shorter of > >> the two lists, or fill in the missing values with a nil value. > > > > That may be coincidence, however, since the page lists only a handful of > languages. As a counter example, OCaml, which calls it 'combine', throws. > Standard ML even provides two variants, 'zip' and 'zipEq', the latter > throwing. (And as an additional data point, nowhere in my SML code have I > ever had a need for the non-throwing version.) > > Fair point. Perhaps Rust should also provide both. I like the SML names, > too. > > Lindsey > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > In the name of preventing obvious mistakes I would strongly suggest implementing the reverse logic from SML: it's best when the shortest name provides the safe behavior and "unsafe" behaviors have more descriptive names indicating in what they are unsafe. It forces people to consciously choose the unsafe alternatives. I would therefore propose: - zip: only on collections of equal length - zipcut: stop iteration as soon as the shortest collection is exhausted - zipfill: fill the "void" (somehow: default value, Option, ...) This way we have all 3 variants, with descriptive names for those 2 who introduce specific behavior. -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From brendan at kublai.com Mon May 6 10:36:31 2013 From: brendan at kublai.com (Brendan Cully) Date: Mon, 6 May 2013 10:36:31 -0700 Subject: [rust-dev] rust in fink for OSX Message-ID: <20130506173631.GD4643@casa.int.convergent.io> Hi, Just FYI, I've packaged up rust 0.6 for the OS X apt-like package management system "fink". I'll keep it updated as releases come out. I also maintain an unofficial fink binary distribution at deb http://brendan.users.finkproject.org/10.8 stable main for 10.8 users, so if you add that to your sources.list, you can pick up rust with "apt-get install rust" From graydon at mozilla.com Mon May 6 10:36:48 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 10:36:48 -0700 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: Message-ID: <5187EA30.8050306@mozilla.com> On 13-05-06 09:46 AM, Matthieu Monrocq wrote: > I would therefore propose: > > - zip: only on collections of equal length > - zipcut: stop iteration as soon as the shortest collection is exhausted > - zipfill: fill the "void" (somehow: default value, Option, ...) > > This way we have all 3 variants, with descriptive names for those 2 who > introduce specific behavior. This seems to me exactly the sort of "customize how you continue in the face of a rare event that has multiple reasonable forms of recovery" that conditions are made for. Do you think they'd be appropriate? -Graydon From graydon at mozilla.com Mon May 6 10:40:52 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 10:40:52 -0700 Subject: [rust-dev] rust in fink for OSX In-Reply-To: <20130506173631.GD4643@casa.int.convergent.io> References: <20130506173631.GD4643@casa.int.convergent.io> Message-ID: <5187EB24.3030908@mozilla.com> On 13-05-06 10:36 AM, Brendan Cully wrote: > Just FYI, I've packaged up rust 0.6 for the OS X apt-like package > management system "fink". I'll keep it updated as releases come out. > I also maintain an unofficial fink binary distribution at > > deb http://brendan.users.finkproject.org/10.8 stable main > > for 10.8 users, so if you add that to your sources.list, you can pick > up rust with "apt-get install rust" Thanks! I've added these to the wiki page tracking such things: https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools -Graydon From matthieu.monrocq at gmail.com Mon May 6 10:59:35 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Mon, 6 May 2013 19:59:35 +0200 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: <5187EA30.8050306@mozilla.com> References: <5187EA30.8050306@mozilla.com> Message-ID: On Mon, May 6, 2013 at 7:36 PM, Graydon Hoare wrote: > On 13-05-06 09:46 AM, Matthieu Monrocq wrote: > > > I would therefore propose: > > > > - zip: only on collections of equal length > > - zipcut: stop iteration as soon as the shortest collection is exhausted > > - zipfill: fill the "void" (somehow: default value, Option, ...) > > > > This way we have all 3 variants, with descriptive names for those 2 who > > introduce specific behavior. > > This seems to me exactly the sort of "customize how you continue in the > face of a rare event that has multiple reasonable forms of recovery" > that conditions are made for. Do you think they'd be appropriate? > > -Graydon > > > I am not so sure. I was thinking a bit more how "zipfill" could be implemented but it's a mess. You really have to choose between "default" (but not everything has sensible defaults!) and Option (but then you have to pattern-match/dereference the Option every time). Option seems better (no magic value), but apart from the awkwardness it is also incompatible with conditions: it changes the return type (unless zip systematically return Options ? but that's crazy!). And then I realized that "zipfill" can be expressed much more cleanly with composition instead: - zip(cycle(short), long) => cycle through short until long is exhausted, needs a "stop" - zip(cycle(short, long.size()), long) => cycle through short until long.size() elements were served - zip(fill(short, defval), long) ... So maybe we could use conditions with a "zip" that is strict by default and leaves it up to a condition to signal whether to "Stop" or "Fail" when one list is too short. However there is the issue of "choosing" what that list is, namely what if I want to "Stop" if the first list is too short, but would rather "Fail" if it is the second ? Furthermore, there is also the issue of the transitive behavior of conditions. Since "zip" wraps arbitrary iterators, it might wrap an iterator itself implemented in terms of "zip", and in this case the "condition" set for the outer "zip" would also be used (unless cancelled) by the inner "zip". I find it non-obvious. It might point at a more general issue about (potentially) recursive functions and conditions by the way. So, instead, maybe composition should be used for "zipcut" too. I can imagine the "take" function of Haskell fitting neatly here: - zip(short, take(long, short.size())) => only consider the first "short.size()" elements of "long" (fails if long is not long enough thus!) Though I find it difficult to catter to the case where one list is shorter than the other, but we cannot know their sizes in advance (I am thinking streams here). In the end, I would favor having "zip" and "zipcut", and not using conditions. But maybe that's me :) -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From lindsey at composition.al Mon May 6 11:05:28 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Mon, 6 May 2013 14:05:28 -0400 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: <5187EA30.8050306@mozilla.com> References: <5187EA30.8050306@mozilla.com> Message-ID: On Mon, May 6, 2013 at 1:36 PM, Graydon Hoare wrote: > On 13-05-06 09:46 AM, Matthieu Monrocq wrote: > >> I would therefore propose: >> >> - zip: only on collections of equal length >> - zipcut: stop iteration as soon as the shortest collection is exhausted >> - zipfill: fill the "void" (somehow: default value, Option, ...) >> >> This way we have all 3 variants, with descriptive names for those 2 who >> introduce specific behavior. > > This seems to me exactly the sort of "customize how you continue in the > face of a rare event that has multiple reasonable forms of recovery" > that conditions are made for. Do you think they'd be appropriate? Hm, interesting. Out of curiosity, what is the status of the condition system? Is it being used anywhere yet? Is there any documentation? A tracking bug? Thanks, Lindsey From corey at octayn.net Mon May 6 11:09:38 2013 From: corey at octayn.net (Corey Richardson) Date: Mon, 6 May 2013 14:09:38 -0400 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: <5187EA30.8050306@mozilla.com> Message-ID: On Mon, May 6, 2013 at 1:59 PM, Matthieu Monrocq wrote: > > And then I realized that "zipfill" can be expressed much more cleanly with > composition instead: > > - zip(cycle(short), long) => cycle through short until long is exhausted, > needs a "stop" > - zip(cycle(short, long.size()), long) => cycle through short until > long.size() elements were served > - zip(fill(short, defval), long) > ... > > > So maybe we could use conditions with a "zip" that is strict by default and > leaves it up to a condition to signal whether to "Stop" or "Fail" when one > list is too short. However there is the issue of "choosing" what that list > is, namely what if I want to "Stop" if the first list is too short, but > would rather "Fail" if it is the second ? > > Furthermore, there is also the issue of the transitive behavior of > conditions. Since "zip" wraps arbitrary iterators, it might wrap an iterator > itself implemented in terms of "zip", and in this case the "condition" set > for the outer "zip" would also be used (unless cancelled) by the inner > "zip". I find it non-obvious. It might point at a more general issue about > (potentially) recursive functions and conditions by the way. > > > So, instead, maybe composition should be used for "zipcut" too. I can > imagine the "take" function of Haskell fitting neatly here: > > - zip(short, take(long, short.size())) => only consider the first > "short.size()" elements of "long" (fails if long is not long enough thus!) > > Though I find it difficult to catter to the case where one list is shorter > than the other, but we cannot know their sizes in advance (I am thinking > streams here). > > > In the end, I would favor having "zip" and "zipcut", and not using > conditions. But maybe that's me :) > Please consider us mere mortals who know what we want but not all these fancy concepts like "take" and "cycle" and such. Slightly tongue-in-cheek, but in all seriousness, it seems like a complex way express something relatively simple. zipfill, zipcut, and zip make sense to me just by their names. zip(short, take(long, short.size())) makes me think about it. Even just having zipcut be a wrapper over that would make me happy. Not to say anything about conditions; I know nothing about them. From graydon at mozilla.com Mon May 6 11:33:13 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 11:33:13 -0700 Subject: [rust-dev] Counting users In-Reply-To: <5187B88C.8090604@mansionfamily.plus.com> References: <518060AE.8020605@cantrip.org> <5184E91B.5040405@mansionfamily.plus.com> <51871DCF.9070404@mozilla.com> <5187B88C.8090604@mansionfamily.plus.com> Message-ID: <5187F769.2070902@mozilla.com> On 13-05-06 07:05 AM, james wrote: > I think the issue here is that it is not entirely clear what kind of > problem the libraries are trying to solve, and who for. Plenty of us > have experience writing server processes and this has historically > involved quite low-level coding. Its quite reasonable for Rust to > target something else (its not as if Ruby does, for example) and yet be > useful. I thought this was a real discussion about what the requirement > (or multiple diverse requirements sets) are. Ok. If so, let me put forth a few that may have been implicit in this conversation, but that have emerged over previous iterations of the IO system (and tasking system -- they are related) and are presently informing the design Brian's working on. - A serial interface to IO that doesn't block other tasks during the IO operation. This is for users who want to treat tasks as serial logic -- "thread-like" -- and have the IO-and-tasking system multiplex their activities in a best-effort fashion, exploiting whatever parallelism an concurrency it can find. - A single event loop responsible for issuing/scheduling tasks and IO, rather than >1. This is to simplify implementation and improve performance, correctness and ease of use over previous attempts where the two were disconnected (and fighting with one another). - A _replaceable_ event loop. This is to permit running rust code -- with the task and IO multiplexing model in the second point -- under "external" event loops such as those in GUI toolkits, larger "hosting" applications, game engines, etc. It sounds to me like you're adding, or asking to add, a 4th requirement: - A convenient, stable, well-crafted way to program the event loop directly, without using the abstraction of a task to encapsulate sequential logic. This is on the argument (correct me if I'm wrong) that the task abstraction will always be too costly and to get the maximum performance a server-writer will need access to this API. If so, I don't object to it. I personally do not know -- and I was claiming in earlier messages that I doubt any of us can know yet -- that the numerical argument ("tasks can't be fast enough") is true, or how significant it is. But to the extent that it's true, I don't mind this requirement being pursued in parallel. So long as it's not at the expense of the others. I should also reiterate, as I mentioned up-thread, that this "convenient and stable" event-loop API is likely to emerge anyways, in the process of meeting the first 3 goals: a replaceable interface-point at which one can switch out IO-and-task event loops is very likely to develop a "nice" interface, just to make it pleasant to implement the task model on top of it. I think most of the sketching Brian's been doing is along these lines. > Maybe I'm old fashioned, but I can't imagine day-job being materially > different to: > - requirement > - analysis > - estimation > - sponsorship > - resourcing > - implementation and testing We (here I'm speaking as a mozilla employee, as we're discussing day-jobs) iterate through such things relatively often, rather than in a single pass; and scheduling is pretty ad-hoc, depending on who has effort, interest and ideas at any given time, and depending on inter-group schedule commitments made. We discover a lot of requirements as we go. For example, the 2nd and 3rd requirements above really only emerged with experience. And the 1st has just been deferred while we sort out the others; synchronous IO via libc / stdio works well enough during development. > Its clear that there are iterations to be had in much of this, but with > something very fundamental, failing to understand and agree and record > and publicise the requirements is a basis for later pain. Fair enough. Have I missed any more, aside from the attempt made at summarizing yours above? > In this particular case, it is not easy to see how a reliance on > lightweight switching at a task layer can work in practice on all > interesting platforms; but its also true that it doesn't matter whether > the behaviour now is 'good enough' so long as there is some clarity > about what the expected goal is. I'm curious why you think it wouldn't _work_. The relevant context-switch function is very short, essentially the old posix.1 swapcontext() call. It consists of saving registers into a structure and then restoring them from another. I find it difficult to think of a platform it _doesn't_ work on. I'll grant it may not be _fast_ enough (in terms of integrating with kernel knowledge of threads, IO subsystems, CPU affinity, power management and whatnot) which is why I mentioned up-thread that we intend to have a variant that also maps 1:1 onto normal OS threads. Beyond that, we're getting into the debate about "maximum efficiency" kernel IO interfaces. I claimed (and still claim) that it's probably platform dependent, and even kernel-dependent (in the sense that different iterations of the same IO API will run at different speeds over different kernel releases, sometimes radically different) and hardware-dependent. Very hard to generalize. If, beyond such discussion, you're still convinced you need to code to the underlying async API, I am perfectly happy with acquiring the 4th requirement above, again assuming it doesn't compromise the first 3. > And that _is_ necessarily abstract for something like this, but that > does not preclude clarity. I appreciate your attempts at at provoking that clarity, and hope I can be similarly lucid in my reply. -Graydon From graydon at mozilla.com Mon May 6 11:42:12 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 11:42:12 -0700 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: References: <5187EA30.8050306@mozilla.com> Message-ID: <5187F984.1060109@mozilla.com> On 13-05-06 11:05 AM, Lindsey Kuper wrote: > Hm, interesting. Out of curiosity, what is the status of the > condition system? Is it being used anywhere yet? Is there any > documentation? A tracking bug? Implemented and working. It has a number of shortcomings I wish to fix up eventually. It's not getting much use yet, though there are plenty of places where it's a much more pleasant option than the alternatives. I should write more documentation on it; currently there's nothing much beyond the test code in core::condition. But there are several APIs in the libraries that should probably be redone in terms of conditions. -Graydon From graydon at mozilla.com Mon May 6 11:48:25 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 11:48:25 -0700 Subject: [rust-dev] Fedora package for rust In-Reply-To: References: Message-ID: <5187FAF9.7080907@mozilla.com> On 13-05-05 03:35 AM, Fabian Deutsch wrote: > Hey, > > just to give the interested Fedora user a hint: I've created a copr ("Fedora PPAs") for rust [0]. I'll keep builds for stable releases of rust around. Thanks! I've added it to the page tracking such things: https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools -Graydon From danielmicay at gmail.com Mon May 6 12:19:28 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 6 May 2013 15:19:28 -0400 Subject: [rust-dev] Nightly builds of incoming for Arch Linux Message-ID: If you're an Arch user you may have noticed the rust package I already put in the repositories[1], and I now have a cronjob set up on Arch's build server to generate a daily build of incoming, originally for the rusti bot in #rust to use. You can add it with the following snippet: [thestinger] SigLevel = Optional Server = http://pkgbuild.com/~thestinger/repo/$arch In theory it generates deltas every day to make the upgrades small, but they're turning out to be pretty huge :). [1] https://www.archlinux.org/packages/community/x86_64/rust/ From graydon at mozilla.com Mon May 6 12:29:40 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 12:29:40 -0700 Subject: [rust-dev] sub-grammar for range pattern constants? In-Reply-To: References: <9C0DF66F-B470-4F39-915A-18EFBC6C0D30@brinckerhoff.org> <39FDCB3F-FC88-4ADC-AA78-6CB253824713@brinckerhoff.org> <517ED168.80703@mozilla.com> <517F48DC.4070705@earthling.net> <51800FB9.1010100@mozilla.com> Message-ID: <518804A4.2070502@mozilla.com> On 13-05-03 07:11 PM, G?bor Lehel wrote: > So this has been bouncing around in the back of my head, and now actual > thoughts have congealed there. Essentially, while I think this is a very > good defense of why Rust doesn't have purity, it's not so convincing to > me as a defense of why it *shouldn't* have purity. (I don't know if it > was intended as one.) It was intended as an explanation for why we (those who've been trying-and-failing on this front for a while -- in my case over 7 years now) are tired of trying and don't much want to retry. I feel there are more fruitful areas for us to spend our effort. That's subjective of course. > C++ is C++. It has multiple concepts for *everything*. That something is > complicated in C++ does not imply that it has to be complicated by > necessity. Agreed. I'm arguing that I don't want to follow them down certain paths into complexity. Note: they expanded the definition of constexpr in a non-backwards-compatible way in c++1y. > This is unfair even to C++. Const methods are the same thing in spirit > as `&self` versus `&mut self` in Rust. Macros in C++ and Rust alike are > for code generation, not computation. I don't think that's a meaningful distinction when we're looking at the applications "at compile-time". If it were, it'd be a lot easier to characterize "templates". But it's not. They may run during compliation; but they're all turing complete. > That leaves templates and constexpr. Which, indeed, have a lot of > overlap, and neither is a subset of the other (constexpr functions can't > do types while templates can't do values of user-defined types other > than enums, for example). Both are restricted to dealing in things that > can be evaluated at compile time.* The part of templates that deals in > types corresponds to Rust's generics, while the part of templates that > can calculate the Fibonacci numbers is a historical semi-accident. > Constexpr expressions (and hence functions) correspond to Rust's > attempts to define a constant expression subgrammar. I agree with this characterization. And I think the constant expression subgrammar + macros probably fits most of the compile-time needs constexpr-as-a-function-qualifier is pointed at. Maybe not all, but I suspect close-to enough to be tolerable. > Again this is something I can definitely accept. Can't argue with > history. It would be nice to know for context how the old system worked. > Is there documentation anywhere? Hm. Probably not a singular form of it aside from "our older manuals". We've had _a_ manual (of varying degrees of accuracy) online since we published in 2010. It's mutated over time. I'm not sure which point is the best to inspect the effect system. Somewhere around spring 2011 maybe? > FWIW it's not really a most conservative intersection. They can't run it > on the GPU or evaluate it at compile time either (except by compiling > and running it, which is what Template Haskell does). What they have is > a semantic notion of purity. If there's no way for pure code to observe > different values (or the user running the program different effects) at > different times, it's good to go, even if it requires unsafePerformIO to > implement. Using unsafePerformIO to cheat is frowned upon* and more > importantly isn't reliable. Ok. Then its purpose is the same as our 'io' qualifier was, more or less. We first set it to the default, then non-default (changing the required annotation to 'pure') and then removed it entirely. Because almost everything wound up non-pure, in an honest program, or the intersection-points were too much of a hassle (pure wanting to call impure). > Right. As above I can readily accept that it's not an easy question, > that the right design hasn't been found, and that earlier attempts > haven't worked out. What I find harder to accept is that there doesn't > exist *any* definition of purity that would be superior to nothing at > all. C++ derives some benefit from constexpr. Haskell derives a lot of > benefit from enforced purity. Surely there is some point in the design > space which would be beneficial for Rust. Perhaps a wiki page collecting > the various options with their applications, benefits, and drawbacks > would be helpful? C++ derives the ability to evaluate at compile time from constexpr. Haskell you're saying doesn't do that (aside from template haskell, which you're excluding) so I assume the benefits you're pointing to are in the more-narrow space of "increasing your confidence that code has no IO effects", yes? And you mean this in a way that _isn't_ already covered by rust's system for control over mutability. That's certainly beneficial. I'm just pointing out that the previous times we tried to encode that benefit, we found that the costs of it outweighed the benefits. Users soured on the mechanism, felt it was too wordy, awkward and confusing. > (FWIW I sorta suspect the presence of mutability and lifetimes in the > type system might make an observable notion of purity a la Haskell > easier to define, but I haven't thought it all the way through.) It's possible. I won't stop you from making a wiki page wherein you try to find a very lightweight way of re-encoding the concept of IO effects. I know we've all been sympathetic to the desire. It's just .. it seems that the cognitive budget available for it is very slim, and there are significant interaction costs from most approaches we've tried. -Graydon From danielmicay at gmail.com Mon May 6 12:37:26 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 6 May 2013 15:37:26 -0400 Subject: [rust-dev] Having zip() fail when the two iterators are not the same length In-Reply-To: <5187EA30.8050306@mozilla.com> References: <5187EA30.8050306@mozilla.com> Message-ID: On Mon, May 6, 2013 at 1:36 PM, Graydon Hoare wrote: > On 13-05-06 09:46 AM, Matthieu Monrocq wrote: > >> I would therefore propose: >> >> - zip: only on collections of equal length >> - zipcut: stop iteration as soon as the shortest collection is exhausted >> - zipfill: fill the "void" (somehow: default value, Option, ...) >> >> This way we have all 3 variants, with descriptive names for those 2 who >> introduce specific behavior. > > This seems to me exactly the sort of "customize how you continue in the > face of a rare event that has multiple reasonable forms of recovery" > that conditions are made for. Do you think they'd be appropriate? > > -Graydon I like the idea of using conditions for a situation like this, but I'm worried about it being too much of a performance hit in this case. The next() method is a fragment of the loop body, so they really need to be as tiny as possible for LLVM to be able to inline them all and merge the code into one loop. The current zip implementation is a single branch based on whether two enum discriminants are zeroed. From graydon at mozilla.com Mon May 6 12:42:01 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 12:42:01 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> Message-ID: <51880789.6080408@mozilla.com> On 13-05-04 12:31 AM, Mikhail Zabaluev wrote: > If you are talking about gettext-like functionality, usually this and > format strings are thought of as independent processing layers: format > strings are translated as such and then fed to the formatting function. > This brings some ramifications, as the order of parameters in the > translated template can change, so the format syntax has to support > positional parameters. But this also allows to account for data-derived > context such as numeral cases, without complicating the printf-like > functions too much. Yes, this is the sort of thing I was thinking of: that there are some pressures that a gettext() layer feed back to the selection of formatting strings that might be worth considering. Also that it might be nice to make fmt!() default-to, or very easily be adapted-to (without too much extra noise, say with ifmt!() or such) invoking the message-catalogue system. The _() macro is used in C I think due to trying to reduce the noise-effect i18n efforts have on code. We should keep that in mind. > There are other difficulties with localizing formatted messages that are > never systematically solved, for example, accounting for gender. In all, > it looks like an interesting area for library research, beyond the basic > "stick this value pretty-printed into a string" problem. There are a few of those, yes. They get quite complex. Though there is some ... "reasonably lightweight" prior art in the ICU format library that I think might be worth pursuing: http://userguide.icu-project.org/formatparse/messages https://ssl.icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html -Graydon From simon.sapin at exyr.org Mon May 6 13:06:19 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Mon, 06 May 2013 22:06:19 +0200 Subject: [rust-dev] Nightly builds of incoming for Arch Linux In-Reply-To: References: Message-ID: <51880D3B.80409@exyr.org> Le 06/05/2013 21:19, Daniel Micay a ?crit : > If you're an Arch user you may have noticed the rust package I already > put in the repositories[1], and I now have a cronjob set up on Arch's > build server to generate a daily build of incoming, originally for the > rusti bot in #rust to use. This is great to have, thanks. -- Simon Sapin From graydon at mozilla.com Mon May 6 13:20:04 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 06 May 2013 13:20:04 -0700 Subject: [rust-dev] lib: regular expressions in std In-Reply-To: References: Message-ID: <51881074.7060902@mozilla.com> On 13-05-04 06:54 AM, Devin Jeanpierre wrote: > I've also added this library page to the wiki: > https://github.com/mozilla/rust/wiki/Lib-re This is great! Thanks. I should also point out that you might want to include / depend on another bug-in-process concerning "raw strings". It looks like I haven't actually filed a bug on it yet after the comment-un-balancing change, but I mean to. There's mention of it on the roadmap: https://github.com/mozilla/rust/wiki/Note-development-roadmap#raw-strings-rather-than-balanced-character-custom-lexemes Really this is just an r"..." lexeme (alternative suggestions welcome) that does the minimum possible escape-processing, for encoding stuff like regexps and windows paths and "other things that have a lot of backslashes in them naturally". (also possibly related to https://github.com/mozilla/rust/issues/4334) -Graydon From makoto.nksm at gmail.com Sun May 5 19:21:16 2013 From: makoto.nksm at gmail.com (NAKASHIMA, Makoto) Date: Mon, 06 May 2013 11:21:16 +0900 Subject: [rust-dev] enum base type Message-ID: <5187139C.3050604@gmail.com> Hello, I'm new to this list and I enjoy programming in Rust. I have a question. Does rust's enum type support specifying base type? C++11 and D support it as below. // C++11 and D enum Color: uint { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff } // D only enum Foo: string { AAA = "aaa", BBB = "bbb", CCC = "ccc" } I tried using this in rust, but it seems not supported (Code 1 and Code 2). * Code 1 enum Color: uint { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff } enum.rs:1:10: 1:11 error: expected `{` but found `:` enum.rs:1 enum Color: uint { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff } * Code 2 enum Color { RED = 0xff0000u, GREEN = 0x00ff00u, BLUE = 0x0000ffu } enum.rs:1:19: 1:28 error: mismatched types: expected `int` but found `uint` (expected int but found uint) enum.rs:1 enum Color { RED = 0xff0000u, GREEN = 0x00ff00u, BLUE = 0x0000ffu } I think enum with base type is very usable for bit field flags or masks. Thank you. gifnksm From danielmicay at gmail.com Mon May 6 13:47:06 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 6 May 2013 16:47:06 -0400 Subject: [rust-dev] enum base type In-Reply-To: <5187139C.3050604@gmail.com> References: <5187139C.3050604@gmail.com> Message-ID: On Sun, May 5, 2013 at 10:21 PM, NAKASHIMA, Makoto wrote: > Hello, > > I'm new to this list and I enjoy programming in Rust. > > I have a question. > Does rust's enum type support specifying base type? > > C++11 and D support it as below. > > // C++11 and D > enum Color: uint { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff } > > // D only > enum Foo: string { AAA = "aaa", BBB = "bbb", CCC = "ccc" } > > > I tried using this in rust, but it seems not supported (Code 1 and Code 2). > > * Code 1 > enum Color: uint { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff } > > enum.rs:1:10: 1:11 error: expected `{` but found `:` > enum.rs:1 enum Color: uint { RED = 0xff0000, GREEN = 0x00ff00, BLUE = > 0x0000ff } > > * Code 2 > enum Color { RED = 0xff0000u, GREEN = 0x00ff00u, BLUE = 0x0000ffu } > > enum.rs:1:19: 1:28 error: mismatched types: expected `int` but found > `uint` (expected int but found uint) > enum.rs:1 enum Color { RED = 0xff0000u, GREEN = 0x00ff00u, BLUE = > 0x0000ffu } > > > I think enum with base type is very usable for bit field flags or masks. > > Thank you. > > gifnksm Rust's enums aren't usable for bit fields or masks because they're guaranteed to only contain the variants you specify. It would be better to make a type with the | operator overloaded and pre-defined statics. They're a tagged union rather than what C/C++/D call an enum. I think the naming is unfortunate. Probably too late to call them "variant" though :P. From lindsey at composition.al Mon May 6 13:56:49 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Mon, 6 May 2013 16:56:49 -0400 Subject: [rust-dev] enum base type In-Reply-To: <5187139C.3050604@gmail.com> References: <5187139C.3050604@gmail.com> Message-ID: On Sun, May 5, 2013 at 10:21 PM, NAKASHIMA, Makoto wrote: > Hello, > > I'm new to this list and I enjoy programming in Rust. > > I have a question. > Does rust's enum type support specifying base type? > enum Color { RED = 0xff0000u, GREEN = 0x00ff00u, BLUE = 0x0000ffu } > > enum.rs:1:19: 1:28 error: mismatched types: expected `int` but found > `uint` (expected int but found uint) > enum.rs:1 enum Color { RED = 0xff0000u, GREEN = 0x00ff00u, BLUE = > 0x0000ffu } Quoting from the section of the tutorial on enums (http://static.rust-lang.org/doc/tutorial.html#enums): "When an enum is C-like (that is, when none of the variants have parameters), it is possible to explicitly set the discriminator values to a constant value: enum Color { Red = 0xff0000, Green = 0x00ff00, Blue = 0x0000ff }" So, in other words, what you did almost works, but you should leave the `u` suffixes off of the base values because they should be ints, not uints -- which is why you got the error message you got. Here's a little example program: fn main() { enum Color { RED = 0xff0000, GREEN = 0x00ff00, BLUE = 0x0000ff } print(fmt!("%d\n", BLUE as int)); // prints 255 } Lindsey From banderson at mozilla.com Mon May 6 14:03:03 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 06 May 2013 14:03:03 -0700 Subject: [rust-dev] MinGW and Rust for Windows Users In-Reply-To: References: Message-ID: <51881A87.2000403@mozilla.com> On 05/04/2013 10:13 PM, Thad Guidry wrote: > > So, I went back to MinGW and managed to get a compiler chain for > Windows 7 64bit working with mingw64 and using MingGW / Msys and > additionally I was able to get the Wget gui to actually work > correctly... so in essence, Windows users will have a nice gui like > interface to install the Unix tools they need for the compiler chain. > In the Msys terminal window, you just type "mingw-get" and it > launches the gui. > > The only thing that is not packaged up in the gui as a mouse click > away is the actual headers and CRT for Mingw64 for gcc to use. The > headers/CRT is currently a separate download and has to be unzipped > into the C:\MinGW folder. > > LLVM seemed to get built just fine under Release+Asserts it says. > > Libuv is a different matter... it can't find uv.h for whatever > dasterdly reason, even though it is sitting right there under its foot > > C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv-private (folder) > C:/MinGW/msys/1.0/home/Thad/rust/src/libuv/include/uv.h (file) > > Here's the paste and asking the community for help on what next ? .. > > http://pastebin.mozilla.org/2375997 > I can reproduce this build error and filed an issue https://github.com/mozilla/rust/issues/6279 From niko at alum.mit.edu Mon May 6 19:14:20 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Mon, 6 May 2013 22:14:20 -0400 Subject: [rust-dev] RFC: Pattern matching binding operator In-Reply-To: <2110252982.14377134.1367657272044.JavaMail.root@mozilla.com> References: <20130503183216.GD18950@Mr-Bennet> <2110252982.14377134.1367657272044.JavaMail.root@mozilla.com> Message-ID: <20130507021420.GD19365@Mr-Bennet> > But you might see more value than I do in keeping the scope of `s` > strictly contained to the single match-clause, versus overloading a > (non-`=`) operator/keyword to denote binding. I have no > counter-argument for that. I tend to prefer just using scoping because it falls out for free without adding any new concepts to the language. > As another variant on my proposal: we could just disallow top-level > =-binding for `let` alone, but leave top-level =-binding for > `match`. That's a little ugly, but still preferable to me over > abusing other keywords. Would that suit you, as a language user? I can't think of any harm in *that*. Niko From jeaye at arrownext.com Mon May 6 20:27:51 2013 From: jeaye at arrownext.com (Jeaye) Date: Mon, 06 May 2013 20:27:51 -0700 Subject: [rust-dev] enum base type In-Reply-To: References: <5187139C.3050604@gmail.com> Message-ID: <518874B7.9040203@arrownext.com> On 05/06/2013 01:47 PM, Daniel Micay wrote: > They're a tagged union rather than what C/C++/D call an enum. I think > the naming is unfortunate. Probably too late to call them "variant" > though :P. It's definitely not too late! Let's call them "variants"! :D Cheers, Jeaye From jeaye at arrownext.com Mon May 6 20:30:40 2013 From: jeaye at arrownext.com (Jeaye) Date: Mon, 06 May 2013 20:30:40 -0700 Subject: [rust-dev] Nightly builds of incoming for Arch Linux In-Reply-To: References: Message-ID: <51887560.1050101@arrownext.com> On 05/06/2013 12:19 PM, Daniel Micay wrote: > If you're an Arch user you may have noticed the rust package I already > put in the repositories[1], and I now have a cronjob set up on Arch's > build server to generate a daily build of incoming, originally for the > rusti bot in #rust to use. > > You can add it with the following snippet: > > [thestinger] > SigLevel = Optional > Server = http://pkgbuild.com/~thestinger/repo/$arch > > In theory it generates deltas every day to make the upgrades small, > but they're turning out to be pretty huge :). > > [1] https://www.archlinux.org/packages/community/x86_64/rust/ > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev This is very awesome and puts the pain of keeping up to date into pacman's capable hands. Thanks, Daniel! Cheers, Jeaye From james at openhorizonlabs.com Mon May 6 21:01:34 2013 From: james at openhorizonlabs.com (James Tranovich) Date: Mon, 6 May 2013 21:01:34 -0700 Subject: [rust-dev] rusti: a call to action In-Reply-To: References: Message-ID: Hello all, What can I do to help make rusti "halfway tolerable"? Not to belabor the point, but rusti definitely needs some love -- my git version of rusti as of one or two days ago always crashes with "memory_region::~memory_region(): Assertion `false' failed." It will return the evaluated expression correctly before that, though, most of the time. I stopped before diving into that particular rabbit hole, because it seems that rusti might need a more invasive and "proper" fix. On IRC, Walton suggested flatpipes for sending the AST (which, he said, was "generally Encodable") through channels. Just wondering what the general plan of attack was and if there was anything I could do to help. Thanks, James On Wed, May 1, 2013 at 4:12 PM, Lindsey Kuper wrote: > Hi everyone, > > I'd like to give rusti more attention and make it actually useful and > usable. As I'm sure we're all aware, a good REPL is especially > valuable for a new and not-yet-well-documented language. Various open > bugs [0, 1, 2] illustrate some of the current problems with rusti, and > astrieanna recently volunteered to work on rusti, so I've been > thinking about what it needs. > > To start with, there are no rusti tests [3]. This means that even > when it's working, it doesn't stay that way for long; for instance, as > strcat pointed out on IRC today, rusti is more broken now than it was > in the 0.6 release, due to the last LLVM version bump. A `make > check-stage[N]-rusti` build target does exist (and since there are no > tests, it passes with flying colors, with 0 of 0 tests failing). > We'll work on ameliorating this situation. > > Another problem seems to be social and circular: rusti doesn't work > very well, so people don't use it, so bugs don't surface as fast as > they would otherwise, so rusti doesn't work very well, so ... . I > want to try to break that circularity by doing what we can to > encourage a culture of rusti use, once we've made the initial effort > to make it halfway tolerable. So, this is mostly just a call to > action: please file rusti bugs, or comment on the existing bugs tagged > with 'A-rusti' (a tag I just created) if you can shed any light on the > issues therein. Thanks! > > Lindsey > > [0]: https://github.com/mozilla/rust/issues/5675 > [1]: https://github.com/mozilla/rust/issues/5774 > [2]: https://github.com/mozilla/rust/issues/5803 > [3]: https://github.com/mozilla/rust/issues/5469 > _______________________________________________ > 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 jeanpierreda at gmail.com Mon May 6 22:15:38 2013 From: jeanpierreda at gmail.com (Devin Jeanpierre) Date: Tue, 7 May 2013 01:15:38 -0400 Subject: [rust-dev] rusti: a call to action In-Reply-To: References: Message-ID: On Wed, May 1, 2013 at 7:12 PM, Lindsey Kuper wrote: > To start with, there are no rusti tests [3]. This means that even > when it's working, it doesn't stay that way for long; for instance, as > strcat pointed out on IRC today, rusti is more broken now than it was > in the 0.6 release, due to the last LLVM version bump. A `make > check-stage[N]-rusti` build target does exist (and since there are no > tests, it passes with flying colors, with 0 of 0 tests failing). > We'll work on ameliorating this situation. I wonder if writing something like doctest [1] and using it pervasively in the documentation for examples would be a reasonable approach. .. [1] http://docs.python.org/2/library/doctest.html -- Devin From sh4.seo at samsung.com Tue May 7 08:09:11 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Tue, 07 May 2013 15:09:11 +0000 (GMT) Subject: [rust-dev] bors feature requests Message-ID: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> Here are some feature requests to bors queue status page at http://buildbot.rust-lang.org/bors/bors.html 1. It seems to show no more than 30 pull requests. It used to be enough, but these days we often have more than 30 pull requests in the queue. 2. The page has last-updated timestamp. It would be useful to get timestamp from the browser and warn when the queue is not updating. (Say, when the gap is more than 10 minutes.) 3. OUTDATED state, for pull requests that need to be rebased. GitHub API provides "mergeable" attribute for this. Thanks for bors! It has been great so far. From sh4.seo at samsung.com Tue May 7 09:12:01 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Tue, 07 May 2013 16:12:01 +0000 (GMT) Subject: [rust-dev] Download statistics Message-ID: <9992436.291761367943121161.JavaMail.weblogic@epv6ml01> I asked about this in January https://mail.mozilla.org/pipermail/rust-dev/2013-January/002879.html and was told 1) request logging was disabled 2) it will probably not be interesting before the next release. It has been a month since 0.6 release, so I would like to know how it turned out. Thanks! From mikhail.zabaluev at gmail.com Tue May 7 09:49:52 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Tue, 7 May 2013 19:49:52 +0300 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <51880789.6080408@mozilla.com> References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> Message-ID: Hi Graydon, 2013/5/6 Graydon Hoare > > Yes, this is the sort of thing I was thinking of: that there are some > pressures that a gettext() layer feed back to the selection of > formatting strings that might be worth considering. > > Also that it might be nice to make fmt!() default-to, or very easily be > adapted-to (without too much extra noise, say with ifmt!() or such) > invoking the message-catalogue system. The _() macro is used in C I > think due to trying to reduce the noise-effect i18n efforts have on > code. We should keep that in mind. > > > There are other difficulties with localizing formatted messages that are > > never systematically solved, for example, accounting for gender. In all, > > it looks like an interesting area for library research, beyond the basic > > "stick this value pretty-printed into a string" problem. > > There are a few of those, yes. They get quite complex. What do you think of using Rust lambdas for context-sensitive translations? That could easily accommodate any sort of variance, and would not complicate the fmt! syntax (though it would require another fmt-like macro to substitute, as well as mark, translated messages). Creating message catalogs may be more challenging this way, but they should be automatically collected and type-bracketed from the source by a translation tool, and most of the messages would be plain strings or have stock code patterns to fill. Best regards, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From heri16 at gmail.com Tue May 7 10:27:17 2013 From: heri16 at gmail.com (heri16 at gmail.com) Date: Tue, 07 May 2013 10:27:17 -0700 (PDT) Subject: [rust-dev] Mobile Platforms programming Message-ID: <51893975.a6fe440a.3b6f.5e51@mx.google.com> An HTML attachment was scrubbed... URL: From sh4.seo at samsung.com Tue May 7 10:41:33 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Tue, 07 May 2013 17:41:33 +0000 (GMT) Subject: [rust-dev] Mobile Platforms programming Message-ID: <16933684.291871367948493619.JavaMail.weblogic@epv6ml01> > Any idea whether Rust could be used for iOS programming? Not yet, but see #6170 for an issue. > Is there an Objective-C interoperability layer? No. > Rust works well with ARM MMU? I am not sure what you mean by MMU. Rust now works well on the ARM architecture. From catamorphism at gmail.com Tue May 7 15:40:46 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Tue, 7 May 2013 23:40:46 +0100 Subject: [rust-dev] bors feature requests In-Reply-To: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> References: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> Message-ID: On Tue, May 7, 2013 at 4:09 PM, Sanghyeon Seo wrote: > Here are some feature requests to bors queue status page at > http://buildbot.rust-lang.org/bors/bors.html > > 1. It seems to show no more than 30 pull requests. It used to be enough, > but these days we often have more than 30 pull requests in the queue. > > 2. The page has last-updated timestamp. It would be useful to get > timestamp from the browser and warn when the queue is not updating. > (Say, when the gap is more than 10 minutes.) > > 3. OUTDATED state, for pull requests that need to be rebased. GitHub > API provides "mergeable" attribute for this. Thanks! I filed these enhancements in the bors issue tracker (which is private right now for security reasons). Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Too much to carry, too much to let go Time goes fast, learning goes slow." -- Bruce Cockburn From corey at octayn.net Tue May 7 20:05:03 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 7 May 2013 23:05:03 -0400 Subject: [rust-dev] Refactoring namespace code Message-ID: Currently, TypeNS and ValueNS are handled very similarly in rustc::middle::resolve, differing in only a few places, but having a fair bit of duplication. It seems merging them somehow would clean things up a lot. From sh4.seo at samsung.com Tue May 7 23:02:08 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Wed, 08 May 2013 06:02:08 +0000 (GMT) Subject: [rust-dev] Dataflow and bit vector Message-ID: <20739114.318671367992927986.JavaMail.weblogic@epv6ml07> dataflow.rs in rustc seems to re-implement much of bit vector implemented in std::bitv. Is there any particular reason? Would it be a good idea to rewrite using std::bitv? From niko at alum.mit.edu Wed May 8 05:50:44 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 8 May 2013 08:50:44 -0400 Subject: [rust-dev] Dataflow and bit vector In-Reply-To: <20739114.318671367992927986.JavaMail.weblogic@epv6ml07> References: <20739114.318671367992927986.JavaMail.weblogic@epv6ml07> Message-ID: <20130508125044.GD9096@Mr-Bennet> The main reason that I did not use the bitv logic was because I wanted to allocate the entire set of bit vectors in one allocation. Also: I am in the process of rewriting dataflow to make use of a graph and be more reusable, so please do not modify it without discussing with me first. Niko On Wed, May 08, 2013 at 06:02:08AM +0000, Sanghyeon Seo wrote: > dataflow.rs in rustc seems to re-implement much of bit vector implemented in std::bitv. > Is there any particular reason? Would it be a good idea to rewrite using std::bitv? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From info at bnoordhuis.nl Wed May 8 09:25:20 2013 From: info at bnoordhuis.nl (Ben Noordhuis) Date: Wed, 8 May 2013 18:25:20 +0200 Subject: [rust-dev] What parts of libuv are used ? why ? In-Reply-To: <5185A4CF.3030409@mozilla.com> References: <5185A4CF.3030409@mozilla.com> Message-ID: On Sun, May 5, 2013 at 2:16 AM, Brian Anderson wrote: > On 05/03/2013 09:24 PM, Thad Guidry wrote: >> >> Looks like libuv is a showstopper currently for me on Windows Cygwin >> building. >> >> Why is it used ? Should it be ? Will it be in the future ? >> >> Can someone throw up a quick paragraph or 2 about this on the wiki and let >> me know ? > > > libuv is Rust's I/O abstraction layer. It provides efficient asynchronous > I/O that works on all platforms, including windows (but apparently excluding > cygwin). > > The I/O layer is somewhat tightly integrated with the new scheduler, but the > scheduler is being designed with the intent that the I/O implementation be > dynamically pluggable, allowing for alternatives to libuv. Making libuv > truly optional requires fixing a few blockers, ripping out and refactoring a > lot of code. If you are someone else is interested I can point in the > direction necessary, but it is a significant amount of work. > > Under the *current* runtime libuv is not strictly necessary, so it may be > possible to carve out everything that depends on libuv and still get it to > compile, but it would be very ugly. > > The path of least resistance here is probably to port libuv to cygwin. > > Some details here: https://github.com/mozilla/rust/issues/4419 Libuv used to support cygwin but I recently removed it[1]. It was broken (as in: wouldn't build) for a long time with no bug reports; strong indication that no one uses it. I'll happily take pull requests that resurrect it but, if you can get away with it, I would suggest that Rust uses the native windows back-end instead: it's much more battle-tested, performs way better and should mostly Just Work(TM) in a cygwin environment. [1] https://github.com/joyent/libuv/commit/7f8130a From graydon at mozilla.com Wed May 8 15:11:08 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 08 May 2013 15:11:08 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> Message-ID: <518ACD7C.9000306@mozilla.com> On 13-05-07 09:49 AM, Mikhail Zabaluev wrote: > What do you think of using Rust lambdas for context-sensitive > translations? That could easily accommodate any sort of variance, and > would not complicate the fmt! syntax (though it would require another > fmt-like macro to substitute, as well as mark, translated messages). > Creating message catalogs may be more challenging this way, but they > should be automatically collected and type-bracketed from the source by > a translation tool, and most of the messages would be plain strings or > have stock code patterns to fill. I think it's relatively important that translations (in message catalog technology) be just string -> string maps. The delayed / conditional evaluation part happens dynamically, at runtime. That is: the problem isn't one of "what gets expressed in the source", it's "what gets expressed in the message catalog". If you look at the examples here: http://userguide.icu-project.org/formatparse/messages#TOC-Complex-Argument-Types and here: https://ssl.icu-project.org/apiref/icu4c/classicu_1_1SelectFormat.html the purpose is to permit a programmer to write something (say, in English) like: fmt!("{0} went to {2}") in their code, and have the _translator_ look at that and (say, if they're doing a French translation) decide it maps to a little miniature case-statement depending on the arguments: "{0} est {1, select, female {all?e} other {all?}} ? {2}." That is a single translation-string. It gets interpreted on the fly by the formatter, given the current locale. As such, I think it's not correct to think of this as something done "in rust code". (Note: in that example, the condition is based on argument 1, which is _not even written_ into the target string. It's just used to convey additional context-information to the format-string evaluator, by agreement between programmers and translators.) -Graydon From blerner at cs.brown.edu Wed May 8 15:33:14 2013 From: blerner at cs.brown.edu (Ben Lerner) Date: Wed, 08 May 2013 18:33:14 -0400 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> <517850A6.7080409@mozilla.com> <517AAA18.3070200@mozilla.com> <517ED03E.9060101@mozilla.com> Message-ID: <518AD2AA.50900@cs.brown.edu> Timely bug: today's explanation of the Diablo3 gold-duping market crash. http://pastebin.com/YYPM4uQK On 4/29/2013 10:43 PM, Jack Moffitt wrote: >>> For the most part, nobody checks. They weighed the cost of those errors >>> against the potential performance loss and decided they would prefer to >>> go fast. >> In C the checking is just too ugly without operator overloading. In C++ you >> can make it look nice, but it's a lot more expensive than it could be if you >> had compiler support, I expect. Even so, in the browser we write a lot of >> checking code. Other browsers do too. > I came across Tim Sweeny's POPL presentation[1] again today and > spotted page 30 where he claims 50% of the bugs in AAA games come > from: > > - array bounds > - deref of null pointers > - integer overflow > - accessing unintialized vars > > http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf > > jack. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From jack at metajack.im Wed May 8 16:07:56 2013 From: jack at metajack.im (Jack Moffitt) Date: Wed, 8 May 2013 17:07:56 -0600 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <518AD2AA.50900@cs.brown.edu> References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> <517850A6.7080409@mozilla.com> <517AAA18.3070200@mozilla.com> <517ED03E.9060101@mozilla.com> <518AD2AA.50900@cs.brown.edu> Message-ID: I was just going to post that as well. This is also exactly the kind of thing that checked arithmetic performance would not be an issue for. jack. On Wed, May 8, 2013 at 4:33 PM, Ben Lerner wrote: > Timely bug: today's explanation of the Diablo3 gold-duping market crash. > http://pastebin.com/YYPM4uQK > > > On 4/29/2013 10:43 PM, Jack Moffitt wrote: >>>> >>>> For the most part, nobody checks. They weighed the cost of those errors >>>> against the potential performance loss and decided they would prefer to >>>> go fast. >>> >>> In C the checking is just too ugly without operator overloading. In C++ >>> you >>> can make it look nice, but it's a lot more expensive than it could be if >>> you >>> had compiler support, I expect. Even so, in the browser we write a lot of >>> checking code. Other browsers do too. >> >> I came across Tim Sweeny's POPL presentation[1] again today and >> spotted page 30 where he claims 50% of the bugs in AAA games come >> from: >> >> - array bounds >> - deref of null pointers >> - integer overflow >> - accessing unintialized vars >> >> >> http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/sweeny.pdf >> >> jack. >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > From graydon at mozilla.com Wed May 8 19:18:38 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 08 May 2013 19:18:38 -0700 Subject: [rust-dev] Download statistics In-Reply-To: <9992436.291761367943121161.JavaMail.weblogic@epv6ml01> References: <9992436.291761367943121161.JavaMail.weblogic@epv6ml01> Message-ID: <518B077E.50809@mozilla.com> On 13-05-07 09:12 AM, Sanghyeon Seo wrote: > I asked about this in January > https://mail.mozilla.org/pipermail/rust-dev/2013-January/002879.html > and was told 1) request logging was disabled 2) it will probably not be > interesting before the next release. > > It has been a month since 0.6 release, so I would like to know how it > turned out. The amazon access logs have been collecting for some time. I spent some of the afternoon with different tools and have convinced analog, at least, to digest them. Here's a snapshot anyway: http://static.rust-lang.org/logs/analog.html It's not continuously-updating or anything but I'm happy to re-run it periodically. It's not the most amazing analysis but it makes a few things quite plain. Releases get traffic spikes. The tutorial is very important. Windows is very important. Nothing really surprising (to me). (I guess it's amazing that someone visited from a RISC OS browser?) -Graydon From lindsey at composition.al Wed May 8 19:22:21 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Wed, 8 May 2013 22:22:21 -0400 Subject: [rust-dev] rusti: a call to action In-Reply-To: References: Message-ID: On Tue, May 7, 2013 at 12:01 AM, James Tranovich wrote: > Hello all, > > What can I do to help make rusti "halfway tolerable"? > > Not to belabor the point, but rusti definitely needs some love -- my git > version of rusti as of one or two days ago always crashes with > "memory_region::~memory_region(): Assertion `false' failed." It will return > the evaluated expression correctly before that, though, most of the time. That's one I haven't seen yet. Can you file a bug tagged with A-rusti? > I stopped before diving into that particular rabbit hole, because it seems > that rusti might need a more invasive and "proper" fix. I think you're right that we may need to rethink the whole approach to rusti. Right now, it literally just takes the user's input, wraps it in a main function that it gins up, and JITs that. For example, "let x = 3;" will produce a "warning: unused variable: `x`" error, which would be great if you were compiling `fn main() { let x = 3; }` but hardly the right behavior for a REPL. > Just wondering what the general plan of attack was and if there was anything > I could do to help. We have a plan to make a plan, but no plan yet. But an obvious problem that we can do something about at the moment is that there are no tests for rusti (https://github.com/mozilla/rust/issues/5469), which astrieanna and I are (slowly) working on fixing. Lindsey From matthieu.monrocq at gmail.com Thu May 9 04:26:26 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Thu, 9 May 2013 13:26:26 +0200 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <518ACD7C.9000306@mozilla.com> References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> <518ACD7C.9000306@mozilla.com> Message-ID: On Thu, May 9, 2013 at 12:11 AM, Graydon Hoare wrote: > On 13-05-07 09:49 AM, Mikhail Zabaluev wrote: > > > What do you think of using Rust lambdas for context-sensitive > > translations? That could easily accommodate any sort of variance, and > > would not complicate the fmt! syntax (though it would require another > > fmt-like macro to substitute, as well as mark, translated messages). > > Creating message catalogs may be more challenging this way, but they > > should be automatically collected and type-bracketed from the source by > > a translation tool, and most of the messages would be plain strings or > > have stock code patterns to fill. > > I think it's relatively important that translations (in message catalog > technology) be just string -> string maps. The delayed / conditional > evaluation part happens dynamically, at runtime. > > That is: the problem isn't one of "what gets expressed in the source", > it's "what gets expressed in the message catalog". If you look at the > examples here: > > > http://userguide.icu-project.org/formatparse/messages#TOC-Complex-Argument-Types > > and here: > > https://ssl.icu-project.org/apiref/icu4c/classicu_1_1SelectFormat.html > > the purpose is to permit a programmer to write something (say, in > English) like: > > fmt!("{0} went to {2}") > > in their code, and have the _translator_ look at that and (say, if > they're doing a French translation) decide it maps to a little miniature > case-statement depending on the arguments: > > "{0} est {1, select, female {all?e} other {all?}} ? {2}." > > That is a single translation-string. It gets interpreted on the fly by > the formatter, given the current locale. As such, I think it's not > correct to think of this as something done "in rust code". > > (Note: in that example, the condition is based on argument 1, which is > _not even written_ into the target string. It's just used to convey > additional context-information to the format-string evaluator, by > agreement between programmers and translators.) > > -Graydon > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > I agree that their is a need for meta-information that may (or may not) end up being used. Number (for plural terms) and gender probably being the most common here, I've also seen it being used in Clang's diagnostics to fold several "similar" looking messages into a single one with a "variant". However, I am not too sure about the idea of string -> string mapping. The example you give here is actually slightly more complicated because there are several orthogonal axes: - singular/plural of the subject (we're lucky it's simpler in French than Polish) - gender of the subject - singular/plural of the destination: "to the supermarket" = "au supermarch?", "to the halles" = "aux halles" - gender of the destination: "to the sea" = "? la mer", "to the supermarket" = "au supermarch?", "to the hairdresser" = "chez le coiffeur"/"chez la coiffeuse" [1] => I'll leave this last one aside [1] We could actually express it "au salon de coiffure" but it feels awkward and is rarely used. Still, it fits here. My point is, therefore, that even a seemingly innocent looking sentence like this one actually turns into a monster: "{0} {1, select, singular {{2, select, female {est all?e} other {est all?}}}, other {{2, select, female {sont all?es} other {sont all?s}}}} {3, select, singular {{4, female {? la} other {au}}} other {aux}} {5}" (note: I apologize if the { and } are mismatched... I gave up) And, as mentioned, this is French and not Polish, because in Polish the plural form is declined with special cases depending on the remainder of the number modulo 10 quite similar to ordinals in English (st, nd, rd vs th). However, even that example is a bit... too simple. Gender is not universal, English people talk about "a table" (neutral) whilst French people talk about "une table" (feminine) and German talk about "der Tisch" (masculin)... so the programmer cannot indicate whether the word is feminine or not: it depends on the target language! Therefore, a more realistic example would imply that the select is done by looking up the English word in a dictionary for its equivalent in another language and from there adjust the translation depending on the gender of the word in the target language! And of course, the same issue occurs with singular/plural formal, the English "a piece of information" is in French "une information" (singular), whilst the English "information" (non-countable) is in French "les informations" (plural). It seems to me that given the extraordinary complexity that is lurking here: - either you end up with a complicated micro-syntax that you'll have to keep buffing up as you discover corner cases in various languages and translators keep complaining they cannot do their job. - or you just decouple formatting from translation, and provide a separate library for translation (outside of core, most probably) As for that library, I heavily suggest letting translators manipulate Rust code directly. I see it as no more difficult than asking them to learn a special micro-language that keeps evolving and pattern-matching is really adapted for the task at hand. My 2c. -- Matthieu -------------- next part -------------- An HTML attachment was scrubbed... URL: From o.renaud at gmx.fr Thu May 9 13:40:58 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Thu, 09 May 2013 22:40:58 +0200 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks Message-ID: <20130509204058.217770@gmx.com> As for that library, I heavily suggest letting translators manipulate Rust code directly. I see it as no more difficult than asking them to learn a special micro-language that keeps evolving and pattern-matching is really adapted for the task at hand. I'd like to react to this. If the translators have to write Rust code instead of interpretable strings, it most likely means that they now have to set up a full development environment. This alone can be blocking. Ok, let's say that they don't have to do so, because the i18n system is smart enough to dynamically compile and load the rust code written by the translators. There is still another, bigger problem : the code can be wrong. It can be invalid Rust code, or it can contain a bug that will blow the whole application at runtime, or more likely it will be out of sync with the application. With a good i18n system, an ill-formatted or "buggy" translation cannot break the program. The resulting string would be either the raw translation (without interpretation), or it will fall back to the english (original) string. Knowing that a translation cannot break the program is a really nice guarantee ! And knowing that it cannot introduce security risks is great, too ! I said that the translation will likely be out of sync, because this is how translations work. The programmer and the translators must be able to work at their own pace. Let's say a program is translated in 10 languages, and a programmer updates a translated string in the code by adding a new parameter. Now, with a "translations using rust code" system, he has to update the 10 translations correctly, just for the application to compile happily. This is plain impossible. He can also add the parameter and intentionally break the build, and wait for all 10 translators to fix this update in their transaltions. There is clearly a problem, with this solution... The manual of Gettext explains quite well the "continuous" nature of the i18n process : http://www.gnu.org/software/gettext/manual/gettext.html#Overview -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Thu May 9 17:41:55 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 09 May 2013 17:41:55 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> <518ACD7C.9000306@mozilla.com> Message-ID: <518C4253.7000301@mozilla.com> On 13-05-09 04:26 AM, Matthieu Monrocq wrote: > However, I am not too sure about the idea of string -> string mapping. > The example you give here is actually slightly more complicated because > there are several orthogonal axes: Hm. I think you're missing what I mean. I mean that the interface -- literally the localization-library-interface we're going to be talking to on a given OS -- takes a string and returns a string. And translations are stored in string->string maps. And edited on websites and with tools that store a translated string as another string. I'm not a translation expert by any means, I'm just trying to reverse-engineer their requirements. And I think you're misunderstanding them. The "translation produces a single string" model is, I think, wired into all the tooling. And more importantly (see below...) > My point is, therefore, that even a seemingly innocent looking sentence > like this one actually turns into a monster: > > "{0} {1, select, singular {{2, select, female {est all?e} other {est > all?}}}, other {{2, select, female {sont all?es} other {sont all?s}}}} > {3, select, singular {{4, female {? la} other {au}}} other {aux}} {5}" > > (note: I apologize if the { and } are mismatched... I gave up) Ok, three things to note here: - Any expression of that conditional logic is going to be ugly, but it is actually required for the translator to give an accurate translation. - The odds are that not all those values will be runtime-variable; the parts that aren't can be directly translated. The switching is _just_ to defer a decision to runtime based on the provided substitution value. - The important part: you can't ask a translator to express this "as rust code" because the _locale_ is also a runtime setting; that is, the translation string is evaluated at runtime based on whatever-gettext()-returns. The programmer cannot accommodate the translator's switch-logic because it is neither static (locale varies at runtime) nor will be it be the same between locales (logical structure varies with locale). I am not trying to be obtuse, just figure out why translators have come up with this system and what we need to preserve about it. As far as I can tell, the "balance" between runtime and compile-time variability is the key factor. So any example has to be very careful to reason about which things vary and which are constant. > However, even that example is a bit... too simple. Gender is not > universal, English people talk about "a table" (neutral) whilst French > people talk about "une table" (feminine) and German talk about "der > Tisch" (masculin)... so the programmer cannot indicate whether the word > is feminine or not: it depends on the target language! That assumes you're talking about a runtime-provided noun being slotted into a runtime-provided format string. It's of course possible this could happen, but it's a bit of a corner case within corner cases. The case I think the gender-selectors are designed for are those where you're presenting a runtime-variable _person_ in a message (eg. an email program or such). And you can pass their gender (assuming they want to use one of the gender-binary words for it) as a value directly to the formatter. A seemingly-good and short-ish slide deck on this is available here. I recommend reading it: https://docs.google.com/presentation/d/1ZyN8-0VXmod5hbHveq-M1AeQ61Ga3BmVuahZjbmbBxo/pub?start=false&loop=false&delayms=3000#slide=id.g1bc43a82_2_14 Especially the "non-goals". There's a limit. They just want to hit the majority of cases. "Handle gender - at least for people". > It seems to me that given the extraordinary complexity that is lurking here: > > - either you end up with a complicated micro-syntax that you'll have to > keep buffing up as you discover corner cases in various languages and > translators keep complaining they cannot do their job. I think you're overstating it. This is a problem people have been struggling with for a long time, but have worked their way towards a _reasonable_ solution that isn't impossibly complex. There's a simplified implementation of it here: https://github.com/SlexAxton/messageformat.js > - or you just decouple formatting from translation, and provide a > separate library for translation (outside of core, most probably) Layering it might work. I'm not opposed to that. I just thought it worth looking over the problem space and considering whether it's "too hard" to support localization from the get-go, and/or whether there'd be any advantage to combining the design of the two parts. It's pretty important. We're going to want to localize rustc, and most other things we write in rust. -Graydon From graydon at mozilla.com Thu May 9 17:45:33 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 09 May 2013 17:45:33 -0700 Subject: [rust-dev] bors feature requests In-Reply-To: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> References: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> Message-ID: <518C432D.1040005@mozilla.com> On 13-05-07 08:09 AM, Sanghyeon Seo wrote: > Here are some feature requests to bors queue status page at > http://buildbot.rust-lang.org/bors/bors.html > > 1. It seems to show no more than 30 pull requests. It used to be enough, > but these days we often have more than 30 pull requests in the queue. > > 2. The page has last-updated timestamp. It would be useful to get > timestamp from the browser and warn when the queue is not updating. > (Say, when the gap is more than 10 minutes.) > > 3. OUTDATED state, for pull requests that need to be rebased. GitHub > API provides "mergeable" attribute for this. I've fixed #1 and #3 today (as well as adding last-comments and a DISCUSSING state). I'll look into #2 soon. Thanks for the feedback. -Graydon From mikhail.zabaluev at gmail.com Thu May 9 22:49:54 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Fri, 10 May 2013 08:49:54 +0300 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: <518C4253.7000301@mozilla.com> References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> <518ACD7C.9000306@mozilla.com> <518C4253.7000301@mozilla.com> Message-ID: Hi, 2013/5/10 Graydon Hoare > > - Any expression of that conditional logic is going to be ugly, > but it is actually required for the translator to give an > accurate translation. > I agree. And if expressions are in Rust, you get the benefit of a Rust compiler validating them. A lambda must produce _some_ string to be valid; match clauses will be checked for correct type and coverage. Dynamically interpreted syntax engines do not usually give this benefit and may in fact let the translator unwittingly and quietly introduce runtime errors, which are less likely to be caught the farther off the beaten track the language is (I may be bitter at my EU-market Samsung TV, that has the Russian language option for the UI, but starts crashing randomly if you switch to it; no grudge against the Samsung folks on this list). - The odds are that not all those values will be runtime-variable; > the parts that aren't can be directly translated. The switching > is _just_ to defer a decision to runtime based on the provided > substitution value. > > - The important part: you can't ask a translator to express this > "as rust code" because the _locale_ is also a runtime setting; > that is, the translation string is evaluated at runtime > based on whatever-gettext()-returns. The programmer cannot > accommodate the translator's switch-logic because it is neither > static (locale varies at runtime) nor will be it be the same > between locales (logical structure varies with locale). > A translation catalog for a particular locale is supposed to be invoked in that locale, isn't it? But there is a thing, indeed: a translator can get "adventurous" and use more Rust than they are supposed to, up to tweaking with the locale settings (which, if the Rust runtime is any good, should only affect the internal task invoking the translation lambda). This could be solved by compiling the translation catalogs without the prelude and warning on any unusual use statements (e.g. anything outside tr:: utilities, which provide all the selector utilities a translator might need), or auto-providing a "translation prelude" and banning use altogether. That assumes you're talking about a runtime-provided noun being slotted > into a runtime-provided format string. It's of course possible this > could happen, but it's a bit of a corner case within corner cases. The > case I think the gender-selectors are designed for are those where > you're presenting a runtime-variable _person_ in a message (eg. an email > program or such). And you can pass their gender (assuming they want to > use one of the gender-binary words for it) as a value directly to the > formatter. > > A seemingly-good and short-ish slide deck on this is available here. I > recommend reading it: > > > https://docs.google.com/presentation/d/1ZyN8-0VXmod5hbHveq-M1AeQ61Ga3BmVuahZjbmbBxo/pub?start=false&loop=false&delayms=3000#slide=id.g1bc43a82_2_14 > > Especially the "non-goals". There's a limit. They just want to hit the > majority of cases. "Handle gender - at least for people". > My favorite real world example is "%s has joined the chat room." The gender may be unknown (they didn't say in their user profile), female, male, and if you are really thorough and provide for non-human chat participants, neutral. > It seems to me that given the extraordinary complexity that is lurking > here: > > > > - either you end up with a complicated micro-syntax that you'll have to > > keep buffing up as you discover corner cases in various languages and > > translators keep complaining they cannot do their job. > > I think you're overstating it. This is a problem people have been > struggling with for a long time, but have worked their way towards a > _reasonable_ solution that isn't impossibly complex. There's a > simplified implementation of it here: > > https://github.com/SlexAxton/messageformat.js > This syntax do not appear to me more "translator-friendly" than a restricted and macro-assisted use of Rust. > > - or you just decouple formatting from translation, and provide a > > separate library for translation (outside of core, most probably) > > Layering it might work. I'm not opposed to that. I just thought it worth > looking over the problem space and considering whether it's "too hard" > to support localization from the get-go, and/or whether there'd be any > advantage to combining the design of the two parts. It's pretty > important. We're going to want to localize rustc, and most other things > we write in rust. > I support a separate layer and a macro distinct from fmt!() to invoke it. Plain formatting is used for non-user-visible purposes such as logging or constructing protocol messages, and no translator should have to deal with those format strings picked up by the extractor tool to clutter the catalog. Also, for plain strings, a tr!("foo") looks more logical than a fmt! with no formatting parameters. Best regards, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Thu May 9 22:56:33 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Thu, 9 May 2013 22:56:33 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> <518ACD7C.9000306@mozilla.com> <518C4253.7000301@mozilla.com> Message-ID: On Thu, May 9, 2013 at 10:49 PM, Mikhail Zabaluev wrote: > My favorite real world example is "%s has joined the chat room." The gender > may be unknown (they didn't say in their user profile), female, male, and if > you are really thorough and provide for non-human chat participants, > neutral. At the risk of being off-topic, many human beings affirm their gender as neutral or as another gender that isn't male or female. I'm not interested in starting a lengthy thread on this topic; mainly, I just want to make sure that a comment that potentially implies that some people who read this mailing list and/or participate in this project aren't human doesn't go by unremarked-on. Everyone is welcome to work on Rust, whether or not they identify within the gender binary. (Recommended reading: http://www.sarahmei.com/blog/2010/11/26/disalienation/ and http://genderqueerid.com/what-is-gq ). If anyone wants to discuss this point further, please *reply sender* and email me privately, rather than replying to the list. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Too much to carry, too much to let go Time goes fast, learning goes slow." -- Bruce Cockburn From mikhail.zabaluev at gmail.com Fri May 10 02:50:59 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Fri, 10 May 2013 12:50:59 +0300 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> <518ACD7C.9000306@mozilla.com> <518C4253.7000301@mozilla.com> Message-ID: Hi, 2013/5/10 Tim Chevalier > On Thu, May 9, 2013 at 10:49 PM, Mikhail Zabaluev > wrote: > > My favorite real world example is "%s has joined the chat room." The > gender > > may be unknown (they didn't say in their user profile), female, male, > and if > > you are really thorough and provide for non-human chat participants, > > neutral. > > At the risk of being off-topic, many human beings affirm their gender > as neutral or as another gender that isn't male or female. I'm not > interested in starting a lengthy thread on this topic; mainly, I just > want to make sure that a comment that potentially implies that some > people who read this mailing list and/or participate in this project > aren't human doesn't go by unremarked-on. Everyone is welcome to work > on Rust, whether or not they identify within the gender binary. > (Recommended reading: > http://www.sarahmei.com/blog/2010/11/26/disalienation/ and > http://genderqueerid.com/what-is-gq ). > > If anyone wants to discuss this point further, please *reply sender* > and email me privately, rather than replying to the list. > Replying on-list as potentially guilty... Sorry if my comment has caused any offense. In my example, the gender information is intended to be used for grammatical purposes, if provided. For people with more complicated gender than male/female, "neutral" would not be a proper option in this context, as the resulting phrase may sound degrading (like referring to people with the non-personal pronoun "it" in English). So for such cases I suppose it's down to the default "other/unknown", at the disadvantage of translated messages looking form-letterish. Respect, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucian.branescu at gmail.com Fri May 10 03:07:29 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Fri, 10 May 2013 11:07:29 +0100 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> <518ACD7C.9000306@mozilla.com> Message-ID: On 9 May 2013 12:26, Matthieu Monrocq wrote: > My point is, therefore, that even a seemingly innocent looking sentence > like this one actually turns into a monster: > > "{0} {1, select, singular {{2, select, female {est all?e} other {est > all?}}}, other {{2, select, female {sont all?es} other {sont all?s}}}} {3, > select, singular {{4, female {? la} other {au}}} other {aux}} {5}" > > (note: I apologize if the { and } are mismatched... I gave up) > > And, as mentioned, this is French and not Polish, because in Polish the > plural form is declined with special cases depending on the remainder of > the number modulo 10 quite similar to ordinals in English (st, nd, rd vs > th). > In practice, that almost never happens. Most strings have quite specific context and require no conditionals. Rarely, there are conditions for things like "one" vs "1" and so on. Some use-case require extreme flexibility, but at that point they're more likely to be split off into groups, which may differ greatly and have separate source-language (English) strings: in an RPG game there might be a player character 'female' and 'male' version for each string, then perhaps another for each emotion that may be applicable in that case. ICU is in fact one of the more programable translation libraries. Anything more must be handled in cooperation between engineers and translators, so out of scope of a gettext-alike. -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Fri May 10 07:48:01 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sat, 11 May 2013 00:48:01 +1000 Subject: [rust-dev] Random number generation, continued. Message-ID: <518D08A1.4090503@gmail.com> Hi all, After a brief discussion here a while ago and doing some research[1], I've started actually implementing a new random number generation framework. The code I've got so far is on GitHub[2], it's fairly poorly architectured/organised at the moment (especially the number of submodules), but it's something. Comments/pull requests welcome! While doing this, I was testing performance, and Rust can be very fast[3], faster than both GCC and Clang! Huon [1]: https://github.com/mozilla/rust/wiki/Lib-rand (still in progress) [2]: https://github.com/huonw/rust-rand [3]: https://gist.github.com/huonw/5553335 and http://www.reddit.com/r/rust/comments/1e262v/rust_can_be_faster_than_c_for_random_number/ for some discussion From graydon at mozilla.com Fri May 10 10:44:31 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 10 May 2013 10:44:31 -0700 Subject: [rust-dev] RFC: User-implementable format specifiers w/ compile-time checks In-Reply-To: References: <5183D7AB.4050707@gmail.com> <51841A13.6050103@mozilla.com> <51841C61.705@mozilla.com> <51841D08.7090303@mozilla.com> <51880789.6080408@mozilla.com> <518ACD7C.9000306@mozilla.com> <518C4253.7000301@mozilla.com> Message-ID: <518D31FF.10603@mozilla.com> On 13-05-09 10:49 PM, Mikhail Zabaluev wrote: > I agree. And if expressions are in Rust, you get the benefit of a Rust > compiler validating them. A lambda must produce _some_ string to be > valid; match clauses will be checked for correct type and coverage. > Dynamically interpreted syntax engines do not usually give this benefit > and may in fact let the translator unwittingly and quietly introduce > runtime errors, which are less likely to be caught the farther off the > beaten track the language is (I may be bitter at my EU-market Samsung > TV, that has the Russian language option for the UI, but starts crashing > randomly if you switch to it; no grudge against the Samsung folks on > this list). The sublanguage is non-effectful, non-stateful, non-turing-complete, and has no functions. Evaluation time is linear and harmless if it fails: it can just use the default (non-translated -- wrong language) format if interpretation goes wrong. I will reiterate why I keep objecting to "using rust code" as both the wrong answer and an answer to the wrong question: - Dynamic loading of translations currently happens in the deployment environment. If you require rust code, you're requiring a dynamic load of a .so or .dll rather than reading a .po file for a string. - There are extensive existing toolchains, processes and communities who have no interest in learning to program in rust to (eg.) translate a web browser or consumer product. http://www.poedit.net/screenshots.php https://en.wikipedia.org/wiki/Virtaal http://mozilla.locamotion.org/ http://weblate.org/en/ http://sourceforge.net/projects/translate/ etc. etc. - The whole point of this thread is to _design_ a formatting mini-language. If "plain rust code" was sufficient for this, people would write: let x = do fmt::with_sfmt_writer |f| { f.putstr("there are "); a.fmtD(f); f.putstr(" files in the folder"); }; rather than: let x = fmt!("there are %d files in the folder", a); Yet here we are discussing that format-string mini-language. So all I'm saying is: given that we _are_ discussing the design of a held-in-a-format-string mini-language, why not make sure that design scales nicely to cases when a translator has to express the little bits of logic they often do, such as: "there {num_files, plural, one {is one file} other {are {num_files} files}} in the folder" This is relatively easy to adopt as an extension to {}-based format strings, whereas it's tricker with %s-based. I think this thread keeps going repeatedly off into discussion of problems we are not facing. We're not trying to eliminate format-string mini-languages from rust: we're trying to design one. We're not trying to solve all hypothetical turing-complete translation tasks: we're trying to accommodate the level of translation-variability that normal translators (even people writing non-translated format strings in their home language) run into all the time when composing format strings. -Graydon From ben.striegel at gmail.com Fri May 10 13:57:33 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Fri, 10 May 2013 16:57:33 -0400 Subject: [rust-dev] Random number generation, continued. In-Reply-To: <518D08A1.4090503@gmail.com> References: <518D08A1.4090503@gmail.com> Message-ID: A commenter on Reddit seems to think that the state values are twice as large in the C version, which explains the slower benchmark result: http://www.reddit.com/r/rust/comments/1e262v/rust_can_be_faster_than_c_for_random_number/c9wd8qb Still, the revised numbers are very competitive! On Fri, May 10, 2013 at 10:48 AM, Huon Wilson wrote: > Hi all, > > After a brief discussion here a while ago and doing some research[1], I've > started actually implementing a new random number generation framework. The > code I've got so far is on GitHub[2], it's fairly poorly > architectured/organised at the moment (especially the number of > submodules), but it's something. Comments/pull requests welcome! > > While doing this, I was testing performance, and Rust can be very fast[3], > faster than both GCC and Clang! > > Huon > > > [1]: https://github.com/mozilla/**rust/wiki/Lib-rand(still in progress) > [2]: https://github.com/huonw/rust-**rand > [3]: https://gist.github.com/huonw/**5553335and > http://www.reddit.com/r/rust/**comments/1e262v/rust_can_be_** > faster_than_c_for_random_**number/for some discussion > ______________________________**_________________ > 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 Fri May 10 18:37:35 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sat, 11 May 2013 11:37:35 +1000 Subject: [rust-dev] Random number generation, continued. In-Reply-To: References: <518D08A1.4090503@gmail.com> Message-ID: <518DA0DF.4030601@gmail.com> On 11/05/13 06:57, Benjamin Striegel wrote: > A commenter on Reddit seems to think that the state values are twice > as large in the C version, which explains the slower benchmark result: > > http://www.reddit.com/r/rust/comments/1e262v/rust_can_be_faster_than_c_for_random_number/c9wd8qb > > Still, the revised numbers are very competitive! > > On Fri, May 10, 2013 at 10:48 AM, Huon Wilson > wrote: > > Hi all, > > After a brief discussion here a while ago and doing some > research[1], I've started actually implementing a new random > number generation framework. The code I've got so far is on > GitHub[2], it's fairly poorly architectured/organised at the > moment (especially the number of submodules), but it's something. > Comments/pull requests welcome! > > While doing this, I was testing performance, and Rust can be very > fast[3], faster than both GCC and Clang! > > Huon > > > [1]: https://github.com/mozilla/rust/wiki/Lib-rand (still in progress) > [2]: https://github.com/huonw/rust-rand > [3]: https://gist.github.com/huonw/5553335 and > http://www.reddit.com/r/rust/comments/1e262v/rust_can_be_faster_than_c_for_random_number/ > for some discussion > _______________________________________________ > 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 Hm, they are correct... that was embarrassing. But, even on the revised test[1], Rust still seems to be faster than Clang (v3.2-2) on my system, so we're using LLVM better! [1]: http://www.reddit.com/r/rust/comments/1e262v/rust_can_be_faster_than_c_for_random_number/c9wggp0 -------------- next part -------------- An HTML attachment was scrubbed... URL: From skirmantas.kligys at gmail.com Fri May 10 18:04:00 2013 From: skirmantas.kligys at gmail.com (Skirmantas Kligys) Date: Fri, 10 May 2013 18:04:00 -0700 Subject: [rust-dev] Calling back into Rust from C code Message-ID: I am trying to write a native wrapper for https://github.com/pascalj/rust-expat (BTW, if there is a native Rust XML parser, I am interested to hear about it, did not find it). I have trouble calling back into Rust from C code: fn set_element_handlers(parser: expat::XML_Parser, start_handler: &fn(tag: &str, attrs: &[@str]), end_handler: &fn(tag: &str)) { let start_cb = |_user_data: *c_void, c_name: *c_char, _c_attrs: **c_char| { unsafe { let name = str::raw::from_c_str(c_name); start_handler(name, []); } }; let end_cb = |_user_data: *c_void, c_name: *c_char| { unsafe { let name = str::raw::from_c_str(c_name); end_handler(name); } }; expat::XML_SetElementHandler(parser, start_cb, end_cb); } This says that it saw &fn... instead of expected extern fn for the second and third parameter. Any ideas how to do this? Thanks. From matthieu.monrocq at gmail.com Sun May 12 01:01:52 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sun, 12 May 2013 10:01:52 +0200 Subject: [rust-dev] Calling back into Rust from C code In-Reply-To: References: Message-ID: As the error implies, the function type that you try to pass as a callback is incorrect. The problem is that because the callback is called from C it ought to be "compatible" with C, thus the "extern" bit. Rather than defining an anonymous function, you need to write an "extern fn" function (with a name), so that the function (at low-level) have a compatible ABI with C. -- Matthieu On Sat, May 11, 2013 at 3:04 AM, Skirmantas Kligys < skirmantas.kligys at gmail.com> wrote: > I am trying to write a native wrapper for > > https://github.com/pascalj/rust-expat > > (BTW, if there is a native Rust XML parser, I am interested to hear > about it, did not find it). I have trouble calling back into Rust > from C code: > > fn set_element_handlers(parser: expat::XML_Parser, start_handler: > &fn(tag: &str, attrs: &[@str]), end_handler: &fn(tag: &str)) { > let start_cb = |_user_data: *c_void, c_name: *c_char, _c_attrs: > **c_char| { > unsafe { > let name = str::raw::from_c_str(c_name); > start_handler(name, []); > } > }; > > let end_cb = |_user_data: *c_void, c_name: *c_char| { > unsafe { > let name = str::raw::from_c_str(c_name); > end_handler(name); > } > }; > > expat::XML_SetElementHandler(parser, start_cb, end_cb); > } > > This says that it saw &fn... instead of expected extern fn for the > second and third parameter. Any ideas how to do this? > > Thanks. > _______________________________________________ > 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 fw at deneb.enyo.de Sun May 12 03:23:32 2013 From: fw at deneb.enyo.de (Florian Weimer) Date: Sun, 12 May 2013 12:23:32 +0200 Subject: [rust-dev] Calling back into Rust from C code In-Reply-To: (Skirmantas Kligys's message of "Fri, 10 May 2013 18:04:00 -0700") References: Message-ID: <877gj433a3.fsf@mid.deneb.enyo.de> * Skirmantas Kligys: > I am trying to write a native wrapper for > > https://github.com/pascalj/rust-expat > > (BTW, if there is a native Rust XML parser, I am interested to hear > about it, did not find it). I have trouble calling back into Rust > from C code: It's probably better to avoid calling back into Rust, storing events in a buffer in C callbacks. From bill_myers at outlook.com Sun May 12 20:00:35 2013 From: bill_myers at outlook.com (Bill Myers) Date: Mon, 13 May 2013 03:00:35 +0000 Subject: [rust-dev] Adding exception handling as syntax sugar with declared exceptions Message-ID: This is a suggestion for adding an exception system to Rust that satisfies these requirements: 1. Unwinding does NOT pass through code that is not either in a function that declares throwing exceptions or in a try block (instead, that triggers task failure) 2. Callers can ignore the fact that a function throws an exception, resulting in task failure 3. Callers can handle exceptions if desired, with the same syntax of C++, Java and C# (1) avoids the issue with C++ exception handling forcing to think about exception safety everywhere (2) avoids the issue with Java's checked exceptions forcing to explicitly handle or redeclare them (3) provides an easy-to-use exception mechanism The specification is based on adding some syntax sugar, which is then transformed by the compiler into the current Rust syntax, and thus does not really alter runtime behavior (but it is also possible to implement this with traditional unwinding if desired). Functions can be declared to throw exceptions, and if the conceptual unwinding process would have to pass through a function call that does not declare throwing an exception of that type, task failure is invoked instead. To integrate with the condition system, one can raise a condition instead of throwing, and declare the condition type and handlers with "throws", allowing them to throw exceptions if desired (note that of course this will just result in task failure unless the function raising the condition is declared to throw). It is of course possible to code using this style "by hand", but the syntax sugar allows to do it in a much terser way, and allows to convert functions that use task failure to functions that throw exceptions without changing the source code of callers that don't want to handle them. * New syntax added: - "throws E1, E2, ..." modifier on functions and closures - try/catch block - try() expression - throw e statement * New type declarations added: enum Result1 { Ok(T), Fail(E1) } enum Result2 { Ok(T), Fail1(E1), Fail2(E2) } ... and so on... * Transformations to implement the system: Everywhere: fn foo() -> T throws E1 [similar with closures] => fn foo() -> Result1 fn foo() -> T throws E1, E2 [similar with closures] => fn foo() -> Result2 try(f(args)) [if f declared with throws] => f(args) f(args) [if f returns T and is declared with throws, not inside try()] => match f(args) {Ok(x) => x, Fail1(e) => throw e, Fail2(e) => throw e, ...} In functions declared throws: return v => return Ok(v) try {try_body} catch(e1: E1) {catch_body} catch(e2: E2) {catch_body} => let mut e1_: Option = None; let mut e2_: Option = None; 'try_: loop {try_body; break;} if e1_.is_some() { let e1 = e1_.unwrap(); catch1_body } else if e2_.is_some() { let e2 = e2_.unwrap(); catch2_body } throw e, if there is any containing try block that has a catch block with argument eK with type EK such that e is convertible to EK (taking the innermost suitable try block and the first suitable catch block) => eK_ = Some(e); break 'try_ throw e, if there are no suitable try blocks but the function is declared throws and e is convertible to throws type EK => return FailK(e) throw e, otherwise, if e implements ToStr: => fail!(e.to_str()) throw e, otherwise: => fail!() -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Mon May 13 11:47:55 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 13 May 2013 11:47:55 -0700 Subject: [rust-dev] Calling back into Rust from C code In-Reply-To: References: Message-ID: <5191355B.3040309@mozilla.com> On 05/10/2013 06:04 PM, Skirmantas Kligys wrote: > I am trying to write a native wrapper for > > https://github.com/pascalj/rust-expat > > (BTW, if there is a native Rust XML parser, I am interested to hear > about it, did not find it). I have trouble calling back into Rust > from C code: > > fn set_element_handlers(parser: expat::XML_Parser, start_handler: > &fn(tag: &str, attrs: &[@str]), end_handler: &fn(tag: &str)) { > let start_cb = |_user_data: *c_void, c_name: *c_char, _c_attrs: **c_char| { > unsafe { > let name = str::raw::from_c_str(c_name); > start_handler(name, []); > } > }; > > let end_cb = |_user_data: *c_void, c_name: *c_char| { > unsafe { > let name = str::raw::from_c_str(c_name); > end_handler(name); > } > }; > > expat::XML_SetElementHandler(parser, start_cb, end_cb); > } > > This says that it saw &fn... instead of expected extern fn for the > second and third parameter. Any ideas how to do this? > You need a function type that is compatible with C. Here `start_cb` is a Rust closure, using the Rust ABI, but you need it to be a C function pointer. It should be defined more like extern fn start_cb(user_data: *c_void, c_name: *c_char, c_attrs: **c_char) { ... } The `extern` says that it uses a foreign ABI, C by default. You can take a value to it like let start: *u8 = start_cb; Note that the extern fn has type *u8. This is a temporary hack. Eventually it will have type `extern "C" fn(...)`. Then your XML_SetElementHandler can be defined like `fn XML_SetELementHandler(parser: Parser, start_cb: *u8, end_cb: *u8)`. Good luck. -Brian From skirmantas.kligys at gmail.com Sun May 12 21:49:30 2013 From: skirmantas.kligys at gmail.com (Skirmantas Kligys) Date: Sun, 12 May 2013 21:49:30 -0700 Subject: [rust-dev] Calling back into Rust from C code In-Reply-To: <877gj433a3.fsf@mid.deneb.enyo.de> References: <877gj433a3.fsf@mid.deneb.enyo.de> Message-ID: On Sun, May 12, 2013 at 3:23 AM, Florian Weimer wrote: > * Skirmantas Kligys: > >> I am trying to write a native wrapper for >> >> https://github.com/pascalj/rust-expat >> >> (BTW, if there is a native Rust XML parser, I am interested to hear >> about it, did not find it). I have trouble calling back into Rust >> from C code: > > It's probably better to avoid calling back into Rust, storing events > in a buffer in C callbacks. Florian, Any reasons why? Stack overflows? I now have two working approaches: 1. Store Rust callbacks in a struct, pass it through expat as user_data: *c_void, cast it back into a struct in a C callback, call the Rust callback. 2. Create a port/chan pair, pass the chan through expat as user_data: *c_void, cast it back into chan in a C callback, use it to send XmlEvent enum variants; a child task listens on the port and does the processing. The second approach seems more "rusty" and probably will load two cores unlike the first. Both approaches pass data around as *c_void, which makes me a bit nervous, but I just don't see any other way to pass typed pointers into a C callback. Let me know if I am missing something. Thanks. Skirmantas Kligys From hatahet at gmail.com Wed May 15 12:12:21 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 15 May 2013 12:12:21 -0700 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: References: <517790B4.3070700@mozilla.com> Message-ID: I tried the above, but I got the following errors: $ rustc -v rustc 0.6 host: x86_64-unknown-linux-gnu $ cat static_type.rs trait Newable { fn new() -> Self; } struct Foo(int); impl Newable for Foo { fn new() -> Foo { Foo(1) } } fn getOneOfThese() -> T { let x:T = Newable::new(); x } fn main() { let test : Foo = getOneOfThese(); } $ rustc static_type.rs static_type.rs:19:19: 19:36 error: binary operation < cannot be applied to type `extern "Rust" fn() -> ` static_type.rs:19 let test : Foo = getOneOfThese(); ^~~~~~~~~~~~~~~~~ static_type.rs:19:19: 19:32 error: cannot determine a type for this bounded type parameter: unconstrained type static_type.rs:19 let test : Foo = getOneOfThese(); ^~~~~~~~~~~~~ -- Ziad On Sun, Apr 28, 2013 at 10:02 PM, Ashish Myles wrote: > Ha! I asked the same question when I first started. I wouldn't be > surprised if this is a common cause of confusion for people coming > from C++ and that name resolution family. > Perhaps notes regarding this could be added to > https://github.com/mozilla/rust/wiki/Rust-for-CXX-programmers > ? > > Ashish > > On Wed, Apr 24, 2013 at 3:58 AM, Patrick Walton > wrote: > > On 4/23/13 10:22 PM, Dylan Knutson wrote: > >> > >> Hello everyone, > >> I've been pretty enamored with Rust the past few weeks, and I'm loving > >> the language so far. However, there is one feature of generics that > >> doesn't seem to exist in the language, which is being able to call > >> static methods on type parameters (provided that the type parameter can > >> be guaranteed to implement it). I'm not all that familiar with > >> the technical details of the language, so I'm not sure if this is > >> impossible, or just decided against for some reason. I'm not even sure > >> if I'm using the terminology correctly, so let me illustrate with some > >> code: > >> > >> trait Newable { > >> fn new() -> Self; > >> } > >> > >> struct Foo(int); > >> impl Newable for Foo { > >> fn new() -> Foo { > >> return Foo(1); > >> } > >> } > >> > >> fn getOneOfThese() -> T { > >> T::new() > >> } > >> > >> fn main() { > >> let test = getOneOfThese(); > >> } > > > > > > Inside `getOneOfThese`, try this: > > > > let x: T = Newable::new(); > > > > 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 hatahet at gmail.com Wed May 15 12:24:31 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 15 May 2013 12:24:31 -0700 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: References: <517790B4.3070700@mozilla.com> Message-ID: The following works though: let test: Foo = getOneOfThese(); hmm.... -- Ziad On Wed, May 15, 2013 at 12:12 PM, Ziad Hatahet wrote: > I tried the above, but I got the following errors: > > $ rustc -v > rustc 0.6 > host: x86_64-unknown-linux-gnu > > $ cat static_type.rs > trait Newable { > fn new() -> Self; > } > > struct Foo(int); > > impl Newable for Foo { > fn new() -> Foo { > Foo(1) > } > } > > fn getOneOfThese() -> T { > let x:T = Newable::new(); > x > } > > fn main() { > let test : Foo = getOneOfThese(); > } > > $ rustc static_type.rs > static_type.rs:19:19: 19:36 error: binary operation < cannot be applied > to type `extern "Rust" fn() -> ` > static_type.rs:19 let test : Foo = getOneOfThese(); > ^~~~~~~~~~~~~~~~~ > static_type.rs:19:19: 19:32 error: cannot determine a type for this > bounded type parameter: unconstrained type > static_type.rs:19 let test : Foo = getOneOfThese(); > ^~~~~~~~~~~~~ > > > > > -- > Ziad > > > On Sun, Apr 28, 2013 at 10:02 PM, Ashish Myles wrote: > >> Ha! I asked the same question when I first started. I wouldn't be >> surprised if this is a common cause of confusion for people coming >> from C++ and that name resolution family. >> Perhaps notes regarding this could be added to >> https://github.com/mozilla/rust/wiki/Rust-for-CXX-programmers >> ? >> >> Ashish >> >> On Wed, Apr 24, 2013 at 3:58 AM, Patrick Walton >> wrote: >> > On 4/23/13 10:22 PM, Dylan Knutson wrote: >> >> >> >> Hello everyone, >> >> I've been pretty enamored with Rust the past few weeks, and I'm loving >> >> the language so far. However, there is one feature of generics that >> >> doesn't seem to exist in the language, which is being able to call >> >> static methods on type parameters (provided that the type parameter can >> >> be guaranteed to implement it). I'm not all that familiar with >> >> the technical details of the language, so I'm not sure if this is >> >> impossible, or just decided against for some reason. I'm not even sure >> >> if I'm using the terminology correctly, so let me illustrate with some >> >> code: >> >> >> >> trait Newable { >> >> fn new() -> Self; >> >> } >> >> >> >> struct Foo(int); >> >> impl Newable for Foo { >> >> fn new() -> Foo { >> >> return Foo(1); >> >> } >> >> } >> >> >> >> fn getOneOfThese() -> T { >> >> T::new() >> >> } >> >> >> >> fn main() { >> >> let test = getOneOfThese(); >> >> } >> > >> > >> > Inside `getOneOfThese`, try this: >> > >> > let x: T = Newable::new(); >> > >> > 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 pwalton at mozilla.com Wed May 15 12:29:02 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 15 May 2013 12:29:02 -0700 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: References: <517790B4.3070700@mozilla.com> Message-ID: <5193E1FE.4070509@mozilla.com> On 5/15/13 12:12 PM, Ziad Hatahet wrote: > >> fn main() { > >> let test = getOneOfThese(); > >> } You can't specify type parameters explicitly here; instead you need to use `let test: Foo = ...`. In the future you'll be able to write something like: impl F = Newable for Foo; let test = F::getOneOfThese(); This isn't implemented yet, however (nor is it likely to appear before Rust 1.0). Patrick From hatahet at gmail.com Wed May 15 12:30:44 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 15 May 2013 12:30:44 -0700 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: <5193E1FE.4070509@mozilla.com> References: <517790B4.3070700@mozilla.com> <5193E1FE.4070509@mozilla.com> Message-ID: Thanks Patrick! -- Ziad On Wed, May 15, 2013 at 12:29 PM, Patrick Walton wrote: > On 5/15/13 12:12 PM, Ziad Hatahet wrote: > >> >> fn main() { >> >> let test = getOneOfThese(); >> >> } >> > > You can't specify type parameters explicitly here; instead you need to use > `let test: Foo = ...`. > > In the future you'll be able to write something like: > > impl F = Newable for Foo; > let test = F::getOneOfThese(); > > This isn't implemented yet, however (nor is it likely to appear before > Rust 1.0). > > Patrick > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jld at panix.com Wed May 15 16:30:20 2013 From: jld at panix.com (Jed Davis) Date: Wed, 15 May 2013 16:30:20 -0700 Subject: [rust-dev] lib: regular expressions in std In-Reply-To: References: <51854EA3.5040209@mozilla.com> Message-ID: <20130515233020.GA26147@panix.com> On Sat, May 04, 2013 at 08:49:48PM -0400, Devin Jeanpierre wrote: > - It is possible in general to remove the overhead of NFA, by > compiling to DFA instead of emulating the NFA. > > Caveats: > > * The algorithm for doing this for tagged NFA (NFA that keep track > of submatch extraction) is not well studied. Ville Laurikari wrote a > paper on it, but the paper has some errors, and there is no public > implementation of this algorithm. (I meant to implement it before, > but haven't gotten around to it yet.) Possibly also of interest: ocamllex. I believe it works by generating some kind of DFA, and it supports submatches. I don't know if there's a good description of its algorithm. I've also wondered about trying to apply Brzozowski derivatives to regular expressions with captures (or markers more generally, maybe); I didn't get very far, but there might be something interesting there. The other thing about ocamllex is that some of its expressiveness comes from lexers being able to call each other recursively, including tail-recursively, passing arbitrary arguments. This is more powerful than a "run this code then go to state X" feature in that the state can contain arbitrary values, and seems hard to do as elegantly in Rust in the absence of tail calls. > - There are approaches that attempt to get "most of the time" > performance like DFA, but without the huge memory cost. These are > pretty cutting edge though, and therefore also not well studied. > > * http://link.springer.com/chapter/10.1007%2F978-3-642-15512-3_4 > (without submatch extraction) > * http://www.hpl.hp.com/techreports/2012/HPL-2012-215.pdf > (with) So... they use BDDs to represent the state set and the transition relation, and step the machine with existentials. > I don't know how it /really/ compares performance wise with NFA and > backtracking implementations (the paper authors cannot be trusted to give > reliable performance data ;). What I can do is implement this and some > benchmarks, and then decide based on that how significant a technique > it is. My entirely uninformed guess is that BDDs will work best (compared to other approaches) when the NFA state set would be large -- e.g., for an IDS, where the application is matching a lot of (probably somewhat overlapping) patterns at once. For a more focused search, or for something like a programming language lexer (potentially lots of patterns, but many of them small and trivially disjoint), the results might be different. > I am slightly skeptical of this technique compared to Thompson NFA, > because OBDDs don't have great worst-case performance (although > it still beats exponential time). Yes, this seemed to be a conspicuous absence from the paper -- if the NFA has reachable state sets that aren't efficiently representable as BDDs, it may be possible to craft input strings that reach them. It's still linear in the input size, but if it changes the coefficient enough to exhaust the IDS's CPU capacity (or RAM), then that's a problem. --Jed From dbau.pp at gmail.com Wed May 15 20:37:07 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Thu, 16 May 2013 13:37:07 +1000 Subject: [rust-dev] Buildbot performance monitoring Message-ID: <51945463.4000504@gmail.com> Hi, I spent a few hours hacking together a performance graph thing[1] that takes the compile and test times from the auto buildbot and plots it, ala arewefastyet.com. It's not great, but it's something. (It apparently shows that #6417[2] cut the compile times on the linux buildbot in half.) Huon Wilson [1]: http://huonw.github.io/isrustfastyet/ [2]: https://github.com/mozilla/rust/pull/6417 From pwalton at mozilla.com Wed May 15 21:14:09 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 15 May 2013 21:14:09 -0700 Subject: [rust-dev] Buildbot performance monitoring In-Reply-To: <51945463.4000504@gmail.com> References: <51945463.4000504@gmail.com> Message-ID: <51945D11.2020503@mozilla.com> On 5/15/13 8:37 PM, Huon Wilson wrote: > Hi, > > I spent a few hours hacking together a performance graph thing[1] that > takes the compile and test times from the auto buildbot and plots it, > ala arewefastyet.com. > > It's not great, but it's something. (It apparently shows that #6417[2] > cut the compile times on the linux buildbot in half.) This is excellent, thank you! Patrick From graydon at mozilla.com Thu May 16 08:48:48 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 16 May 2013 08:48:48 -0700 Subject: [rust-dev] Buildbot performance monitoring In-Reply-To: <51945463.4000504@gmail.com> References: <51945463.4000504@gmail.com> Message-ID: <5194FFE0.2020201@mozilla.com> On 15/05/2013 8:37 PM, Huon Wilson wrote: > Hi, > > I spent a few hours hacking together a performance graph thing[1] that > takes the compile and test times from the auto buildbot and plots it, > ala arewefastyet.com. *applause* that's excellent, thanks! I wonder what on earth changed in #6417 that mattered so much on linux (only). Mysterious. It looks like a pretty innocuous change. -Graydon From graydon at mozilla.com Thu May 16 10:58:28 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 16 May 2013 10:58:28 -0700 Subject: [rust-dev] Adding exception handling as syntax sugar with declared exceptions In-Reply-To: References: Message-ID: <51951E44.2090306@mozilla.com> On 12/05/2013 8:00 PM, Bill Myers wrote: > This is a suggestion for adding an exception system to Rust that > satisfies these requirements: > 1. Unwinding does NOT pass through code that is not either in a function > that declares throwing exceptions or in a try block (instead, that > triggers task failure) > 2. Callers can ignore the fact that a function throws an exception, > resulting in task failure > 3. Callers can handle exceptions if desired, with the same syntax of > C++, Java and C# > > (1) avoids the issue with C++ exception handling forcing to think about > exception safety everywhere > (2) avoids the issue with Java's checked exceptions forcing to > explicitly handle or redeclare them > (3) provides an easy-to-use exception mechanism Hi, sorry, I did mean to get back to this. I think this is ... unlikely to work out, or be something we incorporate into our repo. For a few reasons: - It's very late in the design cycle to be making changes of this scope. We're trying to stabilize. - It'll be a big performance hit on code paths that want to use such exceptions. Things that look like "just function calls" turn into quite extensive operations. We're already struggling with the costs of a return-bool solution for unwinding on platforms that have difficult "normal" EH (#4342). - Most seriously: it doesn't actually resolve (1) or (2), imo. (1) You'd still have to declare checked exceptions everywhere. But worse than in java, if you failed to declare them _anywhere_ you wouldn't get a compilation error, but a runtime failure. This is like making C++ default to 'throw ()', which tends to surprise everyone. (2) You still have to write in "worry about exceptions everywhere" style inside a try-block or function-that-rethrows. Only get to avoid it when you're insulating yourself by the implicit "throw ()" declaration. I'm sympathetic to the desire here, as with all attempts to "get exceptions right". Sadly I've never really seen it; I don't think anyone has really worked out the "right" way to work with catchable-exceptions in a language. -Graydon From vadimcn at gmail.com Thu May 16 12:04:31 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 16 May 2013 12:04:31 -0700 Subject: [rust-dev] Co-routines Message-ID: Tasks can be used as co-routines, but they impose restrictions on data types that can be exchanged (as well as add some scheduler overhead, I presume). Are there any plans for separating stack switching and concurrency? (Or maybe there's already a module for this in the library, that I missed?) -------------- next part -------------- An HTML attachment was scrubbed... URL: From hatahet at gmail.com Thu May 16 12:22:03 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Thu, 16 May 2013 12:22:03 -0700 Subject: [rust-dev] Parallelism and concurrency need different tools Message-ID: Good article I came by via Hacker News: http://www.yosefk.com/blog/parallelism-and-concurrency-need-different-tools.html I figured people here would be interested. -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at steveklabnik.com Thu May 16 12:30:10 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Thu, 16 May 2013 12:30:10 -0700 Subject: [rust-dev] Parallelism and concurrency need different tools In-Reply-To: References: Message-ID: Patrick's first comment is pretty good, as well: https://news.ycombinator.com/item?id=5712758 From banderson at mozilla.com Thu May 16 14:20:04 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 16 May 2013 14:20:04 -0700 Subject: [rust-dev] Co-routines In-Reply-To: References: Message-ID: <51954D84.80806@mozilla.com> On 05/16/2013 12:04 PM, Vadim wrote: > Tasks can be used as co-routines, but they impose restrictions on data > types that can be exchanged (as well as add some scheduler overhead, I > presume). > > Are there any plans for separating stack switching and concurrency? > (Or maybe there's already a module for this in the library, that I > missed?) I haven't put much thought into it yet, but the new scheduler has the coroutine context and the task state factored in a way that task-local coroutines that can capture @-boxes should be possible eventually. -Brian From illissius at gmail.com Sat May 18 05:24:54 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sat, 18 May 2013 14:24:54 +0200 Subject: [rust-dev] Adding exception handling as syntax sugar with declared exceptions In-Reply-To: <51951E44.2090306@mozilla.com> References: <51951E44.2090306@mozilla.com> Message-ID: On Thu, May 16, 2013 at 7:58 PM, Graydon Hoare wrote: > > I'm sympathetic to the desire here, as with all attempts to "get > exceptions right". Sadly I've never really seen it; I don't think anyone > has really worked out the "right" way to work with catchable-exceptions in > a language. > > -Graydon > What's problematic about exceptions in C++, and what forces you to "worry about exceptions everywhere", is that code inside a try-block and code outside of it may share state, which the code in the try block may be in various stages of modifying (along with allocating resources) when the exception is thrown, potentially leaving an inconsistent state and/or leaked resources at the point where the exception is caught. Therefore all functions have to be very careful that any mutable state accessible to the function is in (or reverts to) a consistent state at any point where an exception might be thrown, and that resources aren't left dangling, because who knows whether that mutable state might not be on the outside of a try-block and the function on the inside of it. What if instead of that, the language enforced that code in try blocks could not share any state with code outside, only allowing for data to be transferred in at the beginning and out (whether a result or an exception) at the end, and ensured that all resources acquired inside the try block were destroyed after it exited, no matter how it did? That would free the authors of individual functions from having to care about any of it, because if an exception is passing through their code, that means that from their perspective "the world is ending", everything they have access to will be destroyed, so they can do whatever they want and it won't matter a bit. If that sounds familiar at all, it's because I just described the semantics of Rust's existing try()*. I still suspect that the best of all worlds would be something with the semantics of try(), or close, and the implementation and performance of traditional EH. Is that unrealistic? * Along with the ability to actually observe the thrown exception, but IINM that's planned. And I guess you could have multiple variations on how to handle catching-and-or-rethrowing. If the plan is to use dynamic typing for the exception object you could have something like: impl Result { fn catch(self, hndlr: &fn(ex: ~E) -> T) -> T { match self { Ok(res) => res, Err(ex) => { match ex.cast::() { Ok(casted_ex) => hndlr(casted_ex), Err(uncasted_ex) => fail!(uncasted_ex) } } } } } That doesn't really do "catch block" chaining well and I probably made 10 type errors, but oh well. -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From rexlen at gmail.com Sat May 18 08:46:18 2013 From: rexlen at gmail.com (Renato Lenzi) Date: Sat, 18 May 2013 17:46:18 +0200 Subject: [rust-dev] Integer from string Message-ID: I don't understand why this code is bad: let n1 = int::from_str(line); if n1 == 0 compiler complains: 00003.rs:7:12: 7:13 error: mismatched types: expected `core::option::Option ` but found `` (expected enum core::option::Option but found integral varia ble) 00003.rs:7 if n1 == 0 wht's wrong? Thx. -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Sat May 18 08:57:52 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 18 May 2013 11:57:52 -0400 Subject: [rust-dev] Integer from string In-Reply-To: References: Message-ID: On Sat, May 18, 2013 at 11:46 AM, Renato Lenzi wrote: > I don't understand why this code is bad: > > let n1 = int::from_str(line); > if n1 == 0 > > compiler complains: > > 00003.rs:7:12: 7:13 error: mismatched types: expected > `core::option::Option > ` but found `` (expected enum core::option::Option but found integral > varia > ble) > 00003.rs:7 if n1 == 0 > from_str returns an Option, see http://static.rust-lang.org/doc/core/option.html. If you don't care about the case where line is not a valid integer, you can use the unwrap method. Else, use: ``` match int::from_str(line) { Some(x) => n1 = x, None => { /* handle error... */} } if n1 == 0 { ... ``` From corey at octayn.net Sat May 18 09:00:21 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 18 May 2013 12:00:21 -0400 Subject: [rust-dev] Integer from string In-Reply-To: References: Message-ID: On Sat, May 18, 2013 at 11:57 AM, Corey Richardson wrote: > ``` > match int::from_str(line) { > Some(x) => n1 = x, > None => { /* handle error... */} > } > if n1 == 0 { > ... > ``` Amend that to: let n1; match int::from_str(line) { Some(x) => n1 = x, None => { /* handle error... */} } if n1 == 0 { ... From masklinn at masklinn.net Sat May 18 09:37:38 2013 From: masklinn at masklinn.net (Masklinn) Date: Sat, 18 May 2013 18:37:38 +0200 Subject: [rust-dev] Integer from string In-Reply-To: References: Message-ID: On 2013-05-18, at 17:46 , Renato Lenzi wrote: > I don't understand why this code is bad: > > let n1 = int::from_str(line); > if n1 == 0 > > compiler complains: > > 00003.rs:7:12: 7:13 error: mismatched types: expected > `core::option::Option > ` but found `` (expected enum core::option::Option but found integral > varia > ble) > 00003.rs:7 if n1 == 0 > > wht's wrong? from_str can fail (if your line is "frubnutz" for instance, there's no integer making sense) so as the compiler's message explains it returns an Option (which means "there may or may not be an int here") rather than an int. You have to handle this case, Corey Richardson showed how to match[0], there are a few other options: * You can use option::map to transform the integer if one parsed and ignore a failure (option::map will let a None pass through) * You can use option::get_or_default to either get the parsed integer or get a default value of some sort if the parsing failed (there's a special option::get_or_zero which will return `0` in that case) * For testing things/screwing around, you can also use option::get which will blow up (error out and terminate the program[1]) if the parsing failed and you got a None. see below for demonstration of these (except for map) [0] depending on the situation you could also do something like: match int::from_str(line) { Some(0) => // parsed integer 0 Some(n) => // parsed non-0 integer None => // not an integer at all } if you want to handle an enumerated set of values specially [1] unless you catch the error of course fn main() { let ok = int::from_str("42"); let nok = int::from_str("foo"); // invoke check with a valid parse, Some(42) check(ok); // invoke check with an invalid parse, None check(nok); } fn check(val: Option) { match val { Some(0) => println("zero"), Some(x) => println(int::to_str(x)), None => println("nothing") } println(int::to_str(val.get_or_default(-1))); println(int::to_str(val.get_or_zero())); println(int::to_str(val.get())); } result: 42 42 42 42 nothing -1 0 rust: task failed at 'option::get none', rust-0.6/src/libcore/option.rs:324 rust: domain main @0x100826810 root task failed From banderson at mozilla.com Sat May 18 15:27:31 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 18 May 2013 15:27:31 -0700 Subject: [rust-dev] Performance of task switching using the new Rust scheduler Message-ID: <51980053.5050209@mozilla.com> The new scheduler is still far from complete, but there is enough in place that we can start to get a sense for its performance characteristics. I've done a simulation of making message-passing calls into a layout task and have some preliminary numbers. The new scheduler is a work-stealing scheduler. It generally executes tasks greedily, so when it sends a message and sees that the other task is already waiting to receive, it will context switch directly to the other task and process the message, deferring the running task to a work-stealing deque (where it may be stolen by other threads). The scheduler does not actually do multithreading yet, but it does have the parallel work queue in place. What I've tested is the single-threaded scenario where the script task can context switch directly to layout. This won't be a perfect test because in the full scheduler you might have other threads that can steal the dormant script task and e.g. run the GC, but I think we're in the ballpark of the overall cost model. This test makes 50000 calls to a no-op layout function, either through a task or as a direct function call, then calculates the average time. The cross-task call amounts to two send/recv pairs. The source is here: https://github.com/brson/rust-sched-bench/blob/master/coroutine-call.rs. Requires my 'io' branch of Rust. # The numbers function call ns per call: 2 new scheduler cross-task call ns per call: 2217 old scheduler cross-task call ns per call: 14737 The [profile] is encouraging in that most of the hottest functions are not the synchronization and context switching functions that I expect to be our limiting factors, but this performance is still probably on the order we might ultimately expect. [profile]: https://gist.github.com/brson/5605807 Various observations: * The accounting we do on the global heap, just atomic atomic inc/dec pairs, has a huge cost. This is the only thing that the Rust global_heap::mallac/free functions do before deferring to libc via fast_ffi and these are the two functions at the profile. We're going to have to turn this off eventually. * A large amount of time is spent in malloc/free. There are two main offenders here: one is the uv idle callback used in the scheduler, which is trivially optimizable, and the other is the pipes allocation (they allocate on send). I suspect that the protocol between script and layout is bounded so we can use non-allocating message abstraction here (this could be an argument for keeping the pipes compiler but we'll have to think about it more). * The time hitting thread-local-storage will be minimized once we add split stacks and can avoid the pthread_getspecific FFI call by using the TCB directly. There are some other hotspots relating to FFI calls around TLS, like `rust_get_tls_key` which doesn't need to exist. * The `run_cleanup_job` function is one I've been worried about and it shows up high in the profile. This function executes a single command after every context switch on behalf of the previous context and contains a virtual call. * The `shim` functions will go away with pending FFI changes. * `try_recv` is not fully optimized and currently always costs 2 context switches and an atomic swap with full fence. This can be optimized in a way that would remove two context switches from one of the receives here. * `send` and `try_recv::anon` are both dominated by atomic swaps. * The work queue here is implemented with a lock, which in this test is never contested. The final work queue will be a Chase/Lev lock free deque. The costs will be different. * The scheduler doesn't yet have any facility for waking sleeping schedulers. This will have some performance impact on the receive path. Finally, for the curious I've listed here the exact sequence of events that happens in a single call to layout. I've left out the calls to thread-local storage because I don't think they are particularly illuminating. # The request * script task allocates a new 'oneshot' pipe that layout will use to send the response. * script task allocates a new buffer as part of the 'stream' send. * script task places the message payload into the pipe buffer. * script task does an atomic swap with full fence to take the ~Task pointer of the blocked layout task from the 'stream'. * script task context switches to the layout task. * layout task (on behalf of the scheduler) pushes script task onto the work queue, here taking and dropping an uncontested mutex. * layout task (on behalf of the scheduler) schedules an event loop idle callback to check up on the work queue later. * layout task takes the message payload. * layout task performs layout. # The response * layout task places the response message payload into the 'oneshot' buffer send by script. * layout does an atomic swap with full fence to check the status of the script task and sees that it is not waiting for the response message (it's in the work queue). * layout goes to wait for the next message from script... * layout context switches to the scheduler to recv the next request. * layout (in scheduler context) does an atomic swap with full fence to place it's ~Task pointer into the pipe buffer and discover that no message is available. Layout is now blocked. * the scheduler drops back into the uv event loop. * the scheduler wakes up later in response to the idle callback. * the scheduler takes the work queue lock. * the scheduler takes the script task out of the work queue. * the scheduler drops the work queue lock. * the scheduler context switches to the script task. * the script task (as part of the unoptimized try_recv) context switches *back* to scheduler context to recv. * the script task (in scheduler context) does an atomic swap with full fence and sees that the response payload is available * the script task context switches back to its own context and takes the response payload. From pwalton at mozilla.com Sat May 18 15:29:26 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 18 May 2013 15:29:26 -0700 Subject: [rust-dev] Performance of task switching using the new Rust scheduler In-Reply-To: <51980053.5050209@mozilla.com> References: <51980053.5050209@mozilla.com> Message-ID: <519800C6.6060803@mozilla.com> On 5/18/13 3:27 PM, Brian Anderson wrote: > The new scheduler is still far from complete, but there is enough in > place that we can start to get a sense for its performance > characteristics. I've done a simulation of making message-passing calls > into a layout task and have some preliminary numbers. Thanks a lot for doing this work. This is very important work for Servo. Patrick From pwalton at mozilla.com Sat May 18 16:05:55 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 18 May 2013 16:05:55 -0700 Subject: [rust-dev] Performance of task switching using the new Rust scheduler In-Reply-To: <51980053.5050209@mozilla.com> References: <51980053.5050209@mozilla.com> Message-ID: <51980953.2050307@mozilla.com> On 5/18/13 3:27 PM, Brian Anderson wrote: > * layout task places the response message payload into the 'oneshot' > buffer send by script. > * layout does an atomic swap with full fence to check the status of the > script task and sees that it is not waiting for the response message > (it's in the work queue). > * layout goes to wait for the next message from script... > * layout context switches to the scheduler to recv the next request. > * layout (in scheduler context) does an atomic swap with full fence to > place it's ~Task pointer into the pipe buffer and discover that no > message is available. Layout is now blocked. > * the scheduler drops back into the uv event loop. > * the scheduler wakes up later in response to the idle callback. > * the scheduler takes the work queue lock. > * the scheduler takes the script task out of the work queue. > * the scheduler drops the work queue lock. > * the scheduler context switches to the script task. > * the script task (as part of the unoptimized try_recv) context switches > *back* to scheduler context to recv. > * the script task (in scheduler context) does an atomic swap with full > fence and sees that the response payload is available > * the script task context switches back to its own context and takes the > response payload. Is it possible to optimize this path by introducing a dual atomic send/recv primitive that allows the script task to place its ~Task directly into the port it's going to receive on instead of placing it back into the work queue? This would save the trip through the idle callback. It would prevent the script task from doing anything useful while layout is running, such as GC, but maybe it's worth it for layouts that are predicted to be short. (In Servo today the script task does have an idea of how much damage it's going to cause, so this could be tuned.) Patrick From banderson at mozilla.com Sat May 18 16:15:30 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 18 May 2013 16:15:30 -0700 Subject: [rust-dev] Performance of task switching using the new Rust scheduler In-Reply-To: <51980953.2050307@mozilla.com> References: <51980053.5050209@mozilla.com> <51980953.2050307@mozilla.com> Message-ID: <51980B92.90604@mozilla.com> On 05/18/2013 04:05 PM, Patrick Walton wrote: > On 5/18/13 3:27 PM, Brian Anderson wrote: >> * layout task places the response message payload into the 'oneshot' >> buffer send by script. >> * layout does an atomic swap with full fence to check the status of the >> script task and sees that it is not waiting for the response message >> (it's in the work queue). >> * layout goes to wait for the next message from script... >> * layout context switches to the scheduler to recv the next request. >> * layout (in scheduler context) does an atomic swap with full fence to >> place it's ~Task pointer into the pipe buffer and discover that no >> message is available. Layout is now blocked. >> * the scheduler drops back into the uv event loop. >> * the scheduler wakes up later in response to the idle callback. >> * the scheduler takes the work queue lock. >> * the scheduler takes the script task out of the work queue. >> * the scheduler drops the work queue lock. >> * the scheduler context switches to the script task. >> * the script task (as part of the unoptimized try_recv) context switches >> *back* to scheduler context to recv. >> * the script task (in scheduler context) does an atomic swap with full >> fence and sees that the response payload is available >> * the script task context switches back to its own context and takes the >> response payload. > > Is it possible to optimize this path by introducing a dual atomic > send/recv primitive that allows the script task to place its ~Task > directly into the port it's going to receive on instead of placing it > back into the work queue? This would save the trip through the idle > callback. > > It would prevent the script task from doing anything useful while > layout is running, such as GC, but maybe it's worth it for layouts > that are predicted to be short. (In Servo today the script task does > have an idea of how much damage it's going to cause, so this could be > tuned.) Yes, I think this is possible. From banderson at mozilla.com Sat May 18 18:58:24 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 18 May 2013 18:58:24 -0700 Subject: [rust-dev] Performance of task switching using the new Rust scheduler In-Reply-To: <51980053.5050209@mozilla.com> References: <51980053.5050209@mozilla.com> Message-ID: <519831C0.1010204@mozilla.com> On 05/18/2013 03:27 PM, Brian Anderson wrote: > The new scheduler is still far from complete, but there is enough in > place that we can start to get a sense for its performance > characteristics. I've done a simulation of making message-passing > calls into a layout task and have some preliminary numbers. > Some additional notes that may be worth mentioning: * Both the PortOne and ChanOne implementations contain an extra allocation to work around a bug in Rust by-value self paramaters. That's 4 extra allocations per iteration in this test. * The variance with the old scheduler was very high, and I saw times from 10000 ns to 30000 ns. The new scheduler's time was always ~2200 ns. From ted.horst at earthlink.net Sat May 18 20:31:45 2013 From: ted.horst at earthlink.net (Ted Horst) Date: Sat, 18 May 2013 22:31:45 -0500 Subject: [rust-dev] Performance of task switching using the new Rust scheduler In-Reply-To: <51980053.5050209@mozilla.com> References: <51980053.5050209@mozilla.com> Message-ID: Is there a design document for the new scheduler? Ted On 2013-05-18, at 17:27, Brian Anderson wrote: > The new scheduler is still far from complete, but there is enough in place that we can start to get a sense for its performance characteristics. I've done a simulation of making message-passing calls into a layout task and have some preliminary numbers. From banderson at mozilla.com Sat May 18 23:28:17 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sat, 18 May 2013 23:28:17 -0700 Subject: [rust-dev] Performance of task switching using the new Rust scheduler In-Reply-To: References: <51980053.5050209@mozilla.com> Message-ID: <51987101.6000201@mozilla.com> On 05/18/2013 08:31 PM, Ted Horst wrote: > Is there a design document for the new scheduler? > Not a complete one, but the issue tracker covers some things: https://github.com/mozilla/rust/issues/4419 From masklinn at masklinn.net Sun May 19 07:05:19 2013 From: masklinn at masklinn.net (Masklinn) Date: Sun, 19 May 2013 16:05:19 +0200 Subject: [rust-dev] Documentation, completeness & cross-reference hyperlinks? In-Reply-To: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> References: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> Message-ID: On 2013-05-19, at 15:59 , Masklinn wrote: > > [8] that would give the documentation code-coloration for free as well, > since there is already a Rust lexer in Pygments: > http://pygments.org/demo/81135/, though of course Rust support > can also be added to Pandoc. And apparently it's already been added[0] but is not on the bots yet, I should have checked harder. Sorry about that one. [0] https://github.com/mozilla/rust/issues/5259 From banderson at mozilla.com Sun May 19 14:03:58 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sun, 19 May 2013 14:03:58 -0700 Subject: [rust-dev] Documentation, completeness & cross-reference hyperlinks? In-Reply-To: References: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> Message-ID: <51993E3E.2090303@mozilla.com> On 05/19/2013 07:05 AM, Masklinn wrote: > On 2013-05-19, at 15:59 , Masklinn wrote: >> [8] that would give the documentation code-coloration for free as well, >> since there is already a Rust lexer in Pygments: >> http://pygments.org/demo/81135/, though of course Rust support >> can also be added to Pandoc. > And apparently it's already been added[0] but is not on the bots yet, I > should have checked harder. Sorry about that one. > > [0] https://github.com/mozilla/rust/issues/5259 This thread sounds topical and relevant to my interests but I don't see the parent email in my inbox nor in the rust-dev archives. Did it not send or am I missing something? From lucian.branescu at gmail.com Sun May 19 14:09:19 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Sun, 19 May 2013 22:09:19 +0100 Subject: [rust-dev] Documentation, completeness & cross-reference hyperlinks? In-Reply-To: <51993E3E.2090303@mozilla.com> References: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> <51993E3E.2090303@mozilla.com> Message-ID: I don't see it either, fwiw. On Sunday, 19 May 2013, Brian Anderson wrote: > On 05/19/2013 07:05 AM, Masklinn wrote: > >> On 2013-05-19, at 15:59 , Masklinn wrote: >> >>> [8] that would give the documentation code-coloration for free as well, >>> since there is already a Rust lexer in Pygments: >>> http://pygments.org/demo/**81135/ , >>> though of course Rust support >>> can also be added to Pandoc. >>> >> And apparently it's already been added[0] but is not on the bots yet, I >> should have checked harder. Sorry about that one. >> >> [0] https://github.com/mozilla/**rust/issues/5259 >> > > This thread sounds topical and relevant to my interests but I don't see > the parent email in my inbox nor in the rust-dev archives. Did it not send > or am I missing something? > ______________________________**_________________ > 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 jeaye at arrownext.com Sun May 19 22:52:03 2013 From: jeaye at arrownext.com (Jeaye) Date: Sun, 19 May 2013 22:52:03 -0700 Subject: [rust-dev] Documentation, completeness & cross-reference hyperlinks? In-Reply-To: References: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> <51993E3E.2090303@mozilla.com> Message-ID: <5199BA03.2090209@arrownext.com> On 05/19/2013 02:09 PM, Lucian Branescu wrote: > I don't see it either, fwiw. > Ok, so I'm not crazy. I was wondering the exact same thing. Can we get the original message sent to the list, Masklinn? J From masklinn at masklinn.net Sun May 19 23:51:21 2013 From: masklinn at masklinn.net (Masklinn) Date: Mon, 20 May 2013 08:51:21 +0200 Subject: [rust-dev] Documentation, completeness & cross-reference hyperlinks? In-Reply-To: <5199BA03.2090209@arrownext.com> References: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> <51993E3E.2090303@mozilla.com> <5199BA03.2090209@arrownext.com> Message-ID: <4CF270DE-7CC6-4C16-B010-31A92DE7EDDC@masklinn.net> On 2013-05-20, at 07:52 , Jeaye wrote: > On 05/19/2013 02:09 PM, Lucian Branescu wrote: >> I don't see it either, fwiw. >> > Ok, so I'm not crazy. I was wondering the exact same thing. Can we get the original message sent to the list, Masklinn? It has been but it's apparently got caught in some sort of filter I assumed a list admin would let it go through, either none's been online or I assumed wrong. Let me try again. From masklinn at masklinn.net Sun May 19 23:51:49 2013 From: masklinn at masklinn.net (Masklinn) Date: Mon, 20 May 2013 08:51:49 +0200 Subject: [rust-dev] Documentation, completeness & cross-reference hyperlinks? In-Reply-To: <5199BA03.2090209@arrownext.com> References: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> <51993E3E.2090303@mozilla.com> <5199BA03.2090209@arrownext.com> Message-ID: <3E9E14E5-C2C0-409C-9A6C-17DAF5AF9F1F@masklinn.net> On 2013-05-20, at 07:52 , Jeaye wrote: > On 05/19/2013 02:09 PM, Lucian Branescu wrote: >> I don't see it either, fwiw. >> > Ok, so I'm not crazy. I was wondering the exact same thing. Can we get the original message sent to the list, Masklinn? Yesterday as I was trying to provide more info/background for an answer to the list, I encountered an issue which I think is going to hinder lots of people trying out rust: using the documentation is an exercise in frustration. To expand, I hit 2 main pain points: 1. I wanted to see all the built-in ways to use Option (aside from simply pattern-matching on None and Some), for this I went to the corresponding doc page http://static.rust-lang.org/doc/0.6/core/option.html. Although probably not the worst by a long shot, this page still demonstrates a number of issues: - None of the methods provides examples showing off their purpose and how they can improve code. For some of them, it makes understanding their power and purpose much harder (e.g. Option.each) especially for people coming from languages without these facilities and thus not actively looking for them - The only examples could actually be simpler if replaced by using one of Option's methods, e.g. I believe the second example let unwrapped_msg = match msg { Some(m) => m, None => ~"default message" }; could have been written: let unwrapped_msg = msg.get_or_default(~"default message"); and would demonstrate the value of the corresponding method (this could of also be used as a teaching device by first showing "raw" examples then showing how the code can be simplified/improved using the module's toolbox, but it's not the case here) (and the example is incorrect in the first place, the compiler rejects `Some(ref m) => io::println(m)`, this should be `Some(ref m) => io::println(*m)`) - The uniform color scheme, font and indentation make it hard to notice e.g. admonitions (several methods will fail on a None, have a note indicating it, but the node melds into the rest of the document) - None of the method is hyperlinked from the module's top (or some sort of sidebar) and it's impossible to get a link to them short of inspecting the page's HTML source Now part of these issues are tooling and parts are copywriting, most are easily fixable per-documentation the issue is that they're exist across all of the documentation. But there's a bigger issue: 2. Missing cross-section hyperlinks and references. There I was looking for the various formats available in fmt!. fmt! is mentioned and used extensively in the Rust tutorial[0] and is also listed as an example macro in the reference manual[1]. Yet *not one* of the mentions is hyperlinked to any specification or documentation for it. The core library[2] nor the standard library[3] indexes don't list anything having to do with fmt! either. And to add insult to injury, the first mention of fmt! in the tutorial is linked to the documentation for C++'s printf[4] but *not* to any fmt! related documentation. I ended up finding extfmt[5] (after quite a bit of googling), but looking for it wasn't exactly fun. As I mentioned part of it is basic copywriting (and putting the effort in), but I think part of it is also tooling: nobody is going to bother looking up the exact url to the spec/documentation of fmt! (if it even exists, does it?). Having "short syntaxes" for object-aware hyperlinks (e.g. being able to easily link to the definition/documentation of a macro, module, function, type or method) in the way of Sphinx domains[6] and extensively using these would solve the issue at least in part, but I don't know if Pandoc can be extended in such a way, or if the Rust team would be willing to switch to Sphinx[8]. [0] http://static.rust-lang.org/doc/tutorial.html [1] http://static.rust-lang.org/doc/rust.html#syntax-extensions [2] http://static.rust-lang.org/doc/core/index.html [3] http://static.rust-lang.org/doc/std/index.html [4] http://static.rust-lang.org/doc/tutorial.html#syntax-extensions [5] http://static.rust-lang.org/doc/core/extfmt.html [6] http://sphinx-doc.org/latest/domains.html there is no Rust domain at the moment, but a custom one can be written[7] [7] http://sphinx-doc.org/latest/ext/appapi.html#domain-api https://bitbucket.org/birkenfeld/sphinx-contrib [8] that would give the documentation code-coloration for free as well, since there is already a Rust lexer in Pygments: http://pygments.org/demo/81135/, though of course Rust support can also be added to Pandoc. From sh4.seo at samsung.com Tue May 21 01:03:42 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Tue, 21 May 2013 08:03:42 +0000 (GMT) Subject: [rust-dev] Coding style for struct expression Message-ID: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> What is the preferred coding style for the struct expression? Given: struct Point { x: float, y: float } Point { x: 1.0, y: 1.0 } // (1) Point{x: 1.0, y: 1.0} // (2) Tutorial uses 1, pretty printer does 2. It seems to me that when an expression is on multiple lines, spaces are common, but for a single line it is mixed. core::path uses 1, but core::iterator uses 2. From kimhyunkang at gmail.com Tue May 21 01:16:02 2013 From: kimhyunkang at gmail.com (Kim HyunKang) Date: Tue, 21 May 2013 17:16:02 +0900 Subject: [rust-dev] Questions about task and thread local storage Message-ID: <9037C628-F0A1-4A57-93E0-45E3999EE8DD@gmail.com> Hello list. I'm a Rust newbie and I'm really excited about this language As a process of knowing each other, I'm implementing a libgit2 bindings for Rust. (You can look at the code at here: https://github.com/kimhyunkang/git2-rs though it has virtually no features for now.) libgit2 uses thread local storage to store and retrieve error info from last library call. But the Rust tutorial states that tasks are considered green threads. As far as I can understand, that means tasks are not mapped 1:1 to OS thread, thus making thread-local storage unsafe for direct use. Then I rememberd errno, another thread local storage that I know of, and checked the source code to find out how core::os handles errno. But core::os::errno seems to just call __errno without locking or blocking anything. So, the question is: How does the runtime makes sure that errno is not overwritten by another syscall failure? Is it safe to ignore the possibility of another task scheduled into the same OS thread? - kimhyunkang From vincent.ocquet at gmail.com Tue May 21 04:50:21 2013 From: vincent.ocquet at gmail.com (Vincent O.) Date: Tue, 21 May 2013 13:50:21 +0200 Subject: [rust-dev] Boxed traits and generics. Message-ID: Hi, I tried to use core::managed::ptr_eq for boxed traits but it compile-fails with a mismatched type error. Here's a code example that reproduces my problem : use core::ToStr; fn main() { let a = @S; foo::(a as @ToStr); } struct S; impl S for ToStr { fn to-str(&self) -> ~str {~""} } fn foo(value: @T) {} // similar to ptr_eq with the error message : test.rs:5:15: 5:26 error: mismatched types: expected `@core::to_str::ToStr` but found `@core::to_str::ToStr` (expected @-ptr but found trait core::to_str::ToStr) test.rs:5 test::(a as @ToStr); The issue is the same with owned boxes. Is it the intended behavior ? in this case, is there any workaround ? -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucian.branescu at gmail.com Tue May 21 05:03:50 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Tue, 21 May 2013 13:03:50 +0100 Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: <9037C628-F0A1-4A57-93E0-45E3999EE8DD@gmail.com> References: <9037C628-F0A1-4A57-93E0-45E3999EE8DD@gmail.com> Message-ID: Rust has task-local storage, which sounds like what you're looking for. This example (http://bubblingbeebles.livejournal.com/111016.html) is a bit old, I'm not sure it would still work. On 21 May 2013 09:16, Kim HyunKang wrote: > Hello list. > > I'm a Rust newbie and I'm really excited about this language > > As a process of knowing each other, I'm implementing a libgit2 bindings > for Rust. (You can look at the code at here: > https://github.com/kimhyunkang/git2-rs though it has virtually no > features for now.) > > libgit2 uses thread local storage to store and retrieve error info from > last library call. But the Rust tutorial states that tasks are considered > green threads. As far as I can understand, that means tasks are not mapped > 1:1 to OS thread, thus making thread-local storage unsafe for direct use. > > Then I rememberd errno, another thread local storage that I know of, and > checked the source code to find out how core::os handles errno. But > core::os::errno seems to just call __errno without locking or blocking > anything. > > So, the question is: > > How does the runtime makes sure that errno is not overwritten by another > syscall failure? Is it safe to ignore the possibility of another task > scheduled into the same OS thread? > > - kimhyunkang > _______________________________________________ > 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 Tue May 21 05:53:53 2013 From: corey at octayn.net (Corey Richardson) Date: Tue, 21 May 2013 08:53:53 -0400 Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: References: <9037C628-F0A1-4A57-93E0-45E3999EE8DD@gmail.com> Message-ID: On Tue, May 21, 2013 at 8:03 AM, Lucian Branescu wrote: > Rust has task-local storage, which sounds like what you're looking for. This > example (http://bubblingbeebles.livejournal.com/111016.html) is a bit old, > I'm not sure it would still work. > > > On 21 May 2013 09:16, Kim HyunKang wrote: >> >> Hello list. >> >> I'm a Rust newbie and I'm really excited about this language >> >> As a process of knowing each other, I'm implementing a libgit2 bindings >> for Rust. (You can look at the code at here: >> https://github.com/kimhyunkang/git2-rs though it has virtually no features >> for now.) >> >> libgit2 uses thread local storage to store and retrieve error info from >> last library call. But the Rust tutorial states that tasks are considered >> green threads. As far as I can understand, that means tasks are not mapped >> 1:1 to OS thread, thus making thread-local storage unsafe for direct use. >> >> Then I rememberd errno, another thread local storage that I know of, and >> checked the source code to find out how core::os handles errno. But >> core::os::errno seems to just call __errno without locking or blocking >> anything. >> >> So, the question is: >> >> How does the runtime makes sure that errno is not overwritten by another >> syscall failure? Is it safe to ignore the possibility of another task >> scheduled into the same OS thread? >> >> - kimhyunkang It's http://static.rust-lang.org/doc/core/local_data.html now. From fedor at indutny.com Tue May 21 05:54:23 2013 From: fedor at indutny.com (Fedor Indutny) Date: Tue, 21 May 2013 16:54:23 +0400 Subject: [rust-dev] Boxed traits and generics. In-Reply-To: References: Message-ID: Hi! You can't cast structs to traits, traits is just a behaviour for structs. What you probably wanted to do was: fn foo(value: @T) -> ~str { value.to_str() } Cheers, Fedor. On Tue, May 21, 2013 at 3:50 PM, Vincent O. wrote: > Hi, > > I tried to use core::managed::ptr_eq for boxed traits but it compile-fails > with a mismatched type error. > > Here's a code example that reproduces my problem : > > use core::ToStr; > > fn main() { > let a = @S; > foo::(a as @ToStr); > } > > struct S; > impl S for ToStr { fn to-str(&self) -> ~str {~""} } > fn foo(value: @T) {} // similar to ptr_eq > > with the error message : > test.rs:5:15: 5:26 error: mismatched types: expected > `@core::to_str::ToStr` but found `@core::to_str::ToStr` (expected @-ptr but > found trait core::to_str::ToStr) > test.rs:5 test::(a as @ToStr); > > The issue is the same with owned boxes. Is it the intended behavior ? in > this case, is there any workaround ? > > _______________________________________________ > 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 hatahet at gmail.com Tue May 21 06:04:27 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Tue, 21 May 2013 06:04:27 -0700 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: <5193E1FE.4070509@mozilla.com> References: <517790B4.3070700@mozilla.com> <5193E1FE.4070509@mozilla.com> Message-ID: On Wed, May 15, 2013 at 12:29 PM, Patrick Walton wrote: > > You can't specify type parameters explicitly here; instead you need to use > `let test: Foo = ...`. > > I just found out that the following also works: let test = getOneOfThese::(); Is one style preferred over the other / considered more idiomatic? Thanks -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From kimhyunkang at gmail.com Tue May 21 06:09:41 2013 From: kimhyunkang at gmail.com (=?UTF-8?Q?=EA=B9=80=ED=98=84=EA=B0=95?=) Date: Tue, 21 May 2013 06:09:41 -0700 (PDT) Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: References: Message-ID: <1369141781102.1a443509@Nodemailer> Thank you for the info, but I'm not sure it's what I was looking for. giterr_last uses pthread_key_create which does knows nothing about rust runtime or rust task. How can I use task local storage to safely call giterr_last, which uses pthread local storage? Maybe I'm asking a wrong question. If then, please tell me what I'm wrong about. ? Sent from Mailbox for iPhone On Tue, May 21, 2013 at 9:53 PM, Corey Richardson wrote: > On Tue, May 21, 2013 at 8:03 AM, Lucian Branescu > wrote: >> Rust has task-local storage, which sounds like what you're looking for. This >> example (http://bubblingbeebles.livejournal.com/111016.html) is a bit old, >> I'm not sure it would still work. >> >> >> On 21 May 2013 09:16, Kim HyunKang wrote: >>> >>> Hello list. >>> >>> I'm a Rust newbie and I'm really excited about this language >>> >>> As a process of knowing each other, I'm implementing a libgit2 bindings >>> for Rust. (You can look at the code at here: >>> https://github.com/kimhyunkang/git2-rs though it has virtually no features >>> for now.) >>> >>> libgit2 uses thread local storage to store and retrieve error info from >>> last library call. But the Rust tutorial states that tasks are considered >>> green threads. As far as I can understand, that means tasks are not mapped >>> 1:1 to OS thread, thus making thread-local storage unsafe for direct use. >>> >>> Then I rememberd errno, another thread local storage that I know of, and >>> checked the source code to find out how core::os handles errno. But >>> core::os::errno seems to just call __errno without locking or blocking >>> anything. >>> >>> So, the question is: >>> >>> How does the runtime makes sure that errno is not overwritten by another >>> syscall failure? Is it safe to ignore the possibility of another task >>> scheduled into the same OS thread? >>> >>> - kimhyunkang > It's http://static.rust-lang.org/doc/core/local_data.html now. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kimhyunkang at gmail.com Tue May 21 06:35:06 2013 From: kimhyunkang at gmail.com (kimhyunkang at gmail.com) Date: Tue, 21 May 2013 22:35:06 +0900 Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: <1369141781102.1a443509@Nodemailer> References: <1369141781102.1a443509@Nodemailer> Message-ID: Sorry to disturb the thread with many messages. I feel I have to provide details to my question In POSIX programming, calling errno is thread-safe in the following sense 1. Thread A makes some system call X, and the call fails 2. Meanwhile, Thread B makes some system call Y. This call also fails 3. Thread A checks its errno. The errno indicates the reason of failure of call X 4. Thread B also checks its errno. The errno indicates the failure of call Y The above is guaranteed, because errno is stored in thread-local storage But Rust uses green thread, which means it's possible that multiple tasks may run on a thread. 1. Task A calls function core::os::X. The system call fails and sets errno 2. Meanwhile (on the same thread) Task B is switched in and calls core::os::Y. The system call fails and replaces the errno set from task A. 3. Task A is switched in again, and checks errno. It expects errno returns the reason of failure of core::os::X, but what A sees is the failure of core::os::Y Is above case possible in Rust? If not, how does Rust prevents this? 2013/5/21 ??? > Thank you for the info, but I'm not sure it's what I was looking for. > > giterr_last uses pthread_key_create which does knows nothing about rust > runtime or rust task. How can I use task local storage to safely call > giterr_last, which uses pthread local storage? > > Maybe I'm asking a wrong question. If then, please tell me what I'm wrong > about. > -- > Sent from Mailbox for iPhone > > > On Tue, May 21, 2013 at 9:53 PM, Corey Richardson wrote: > >> On Tue, May 21, 2013 at 8:03 AM, Lucian Branescu >> wrote: >> > Rust has task-local storage, which sounds like what you're looking for. >> This >> > example (http://bubblingbeebles.livejournal.com/111016.html) is a bit >> old, >> > I'm not sure it would still work. >> > >> > >> > On 21 May 2013 09:16, Kim HyunKang wrote: >> >> >> >> Hello list. >> >> >> >> I'm a Rust newbie and I'm really excited about this language >> >> >> >> As a process of knowing each other, I'm implementing a libgit2 >> bindings >> >> for Rust. (You can look at the code at here: >> >> https://github.com/kimhyunkang/git2-rs though it has virtually no >> features >> >> for now.) >> >> >> >> libgit2 uses thread local storage to store and retrieve error info >> from >> >> last library call. But the Rust tutorial states that tasks are >> considered >> >> green threads. As far as I can understand, that means tasks are not >> mapped >> >> 1:1 to OS thread, thus making thread-local storage unsafe for direct >> use. >> >> >> >> Then I rememberd errno, another thread local storage that I know of, >> and >> >> checked the source code to find out how core::os handles errno. But >> >> core::os::errno seems to just call __errno without locking or blocking >> >> anything. >> >> >> >> So, the question is: >> >> >> >> How does the runtime makes sure that errno is not overwritten by >> another >> >> syscall failure? Is it safe to ignore the possibility of another task >> >> scheduled into the same OS thread? >> >> >> >> - kimhyunkang >> >> It's http://static.rust-lang.org/doc/core/local_data.html now. >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mikhail.zabaluev at gmail.com Tue May 21 08:08:44 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Tue, 21 May 2013 18:08:44 +0300 Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: References: <1369141781102.1a443509@Nodemailer> Message-ID: Hi, 2013/5/21 > But Rust uses green thread, which means it's possible that multiple tasks > may run on a thread. > > 1. Task A calls function core::os::X. The system call fails and sets errno > 2. Meanwhile (on the same thread) Task B is switched in and calls > core::os::Y. The system call fails and replaces the errno set from task A. > AFAIK that's not supposed to happen if task A checks errno (or other thread-local value) immediately after returning from the failed call. Tasks are switched cooperatively within the scheduler thread. Hope this helps, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From jack at metajack.im Tue May 21 10:22:03 2013 From: jack at metajack.im (Jack Moffitt) Date: Tue, 21 May 2013 11:22:03 -0600 Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: References: <1369141781102.1a443509@Nodemailer> Message-ID: > AFAIK that's not supposed to happen if task A checks errno (or other > thread-local value) immediately after returning from the failed call. Tasks > are switched cooperatively within the scheduler thread. Those semantics are true I think, and I believe will remain true, but they are not obvious. Hopefully this will get documented. The docs for the core::os calls should probably mention that you have to check errno without doing any intermediate I/O. What are the task switch boundaries? Is it just I/O? Or can non-inlined function calls also cause switches (this is for example where Erlang code replacement is allowed to happen). There's no way to know if some function does I/O transitively, so predicting task switches is not necessarily trivial. How often is this pattern used in C code? Are there other examples where thread-local storage is used for library state? jack. From niko at alum.mit.edu Tue May 21 10:58:04 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 21 May 2013 13:58:04 -0400 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: References: <517790B4.3070700@mozilla.com> <5193E1FE.4070509@mozilla.com> Message-ID: <20130521175804.GJ22687@Mr-Bennet> > I just found out that the following also works: > > let test = getOneOfThese::(); This form is unlikely to continue working in the future. Instead, a new syntax will be introduced. See this blog post for more details: http://blog.pnkfx.org/blog/2013/04/22/designing-syntax-for-associated-items-in-rust/ Niko From vincent.ocquet at gmail.com Tue May 21 11:15:52 2013 From: vincent.ocquet at gmail.com (Vincent Ocquet) Date: Tue, 21 May 2013 20:15:52 +0200 Subject: [rust-dev] Boxed traits and generics. In-Reply-To: References: Message-ID: <519BB9D8.8090109@gmail.com> Hi, The thing is, I want to use function ptr_eq(@T, @T) from core::managed and I can't change it in the way you describe. Actually, I'd like to make sure that I can't add twice the same object to a vector like below : use core::vec::position; use core::managed::ptr_eq; struct DummyListener; trait Listener { fn fire_event(&self); } impl Listener for DummyListener { fn fire_event(&self) { /* stuff */ } } fn main() { let mut vec: ~[@Listener] = ~[]; let a = @DummyListener; let b = @DummyListener; vec = add(vec, a as @Listener); vec = add(vec, b as @Listener); vec = add(vec, b as @Listener); for vec.each |listener| {listener.fire_event();} } fn add(mut vec: ~[@Listener], toAdd: @Listener) -> ~[@Listener] { if ( position(vec, |listener| { ptr_eq::(toAdd, *listener) }) == None) { vec.push(toAdd); } vec } What do you mean by you can't cast to Traits, isn't it what 'as' is for ? On 21/05/2013 14:54, Fedor Indutny wrote: > Hi! > > You can't cast structs to traits, traits is just a behaviour for > structs. What you probably wanted to do was: > > fn foo(value: @T) -> ~str { value.to_str() } > > Cheers, > Fedor. > > > On Tue, May 21, 2013 at 3:50 PM, Vincent O. > wrote: > > Hi, > > I tried to use core::managed::ptr_eq for boxed traits but it > compile-fails with a mismatched type error. > > Here's a code example that reproduces my problem : > > use core::ToStr; > > fn main() { > let a = @S; > foo::(a as @ToStr); > } > > struct S; > impl S for ToStr { fn to-str(&self) -> ~str {~""} } > fn foo(value: @T) {} // similar to ptr_eq > > with the error message : > test.rs:5:15: 5:26 error: mismatched types: expected > `@core::to_str::ToStr` but found `@core::to_str::ToStr` (expected > @-ptr but found trait core::to_str::ToStr) > test.rs:5 test::(a as @ToStr); > > The issue is the same with owned boxes. Is it the intended > behavior ? in this case, is there any workaround ? > > _______________________________________________ > 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 banderson at mozilla.com Tue May 21 14:27:19 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 21 May 2013 14:27:19 -0700 Subject: [rust-dev] Coding style for struct expression In-Reply-To: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> References: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> Message-ID: <519BE6B7.9040209@mozilla.com> On 05/21/2013 01:03 AM, Sanghyeon Seo wrote: > What is the preferred coding style for the struct expression? > > Given: > > struct Point { > x: float, > y: float > } > > Point { x: 1.0, y: 1.0 } // (1) > Point{x: 1.0, y: 1.0} // (2) > > Tutorial uses 1, pretty printer does 2. It seems to me that when an expression is on > multiple lines, spaces are common, but for a single line it is mixed. core::path uses 1, > but core::iterator uses 2. I use 2. From pwalton at mozilla.com Tue May 21 14:27:52 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 21 May 2013 14:27:52 -0700 Subject: [rust-dev] Coding style for struct expression In-Reply-To: <519BE6B7.9040209@mozilla.com> References: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> <519BE6B7.9040209@mozilla.com> Message-ID: <519BE6D8.2040701@mozilla.com> On 5/21/13 2:27 PM, Brian Anderson wrote: > On 05/21/2013 01:03 AM, Sanghyeon Seo wrote: >> What is the preferred coding style for the struct expression? >> >> Given: >> >> struct Point { >> x: float, >> y: float >> } >> >> Point { x: 1.0, y: 1.0 } // (1) >> Point{x: 1.0, y: 1.0} // (2) I prefer neither: Point { x: 1.0, y: 2.0, } Patrick From banderson at mozilla.com Tue May 21 14:32:16 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 21 May 2013 14:32:16 -0700 Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: References: <1369141781102.1a443509@Nodemailer> Message-ID: <519BE7E0.5030205@mozilla.com> On 05/21/2013 06:35 AM, kimhyunkang at gmail.com wrote: > Sorry to disturb the thread with many messages. I feel I have to > provide details to my question > > In POSIX programming, calling errno is thread-safe in the following sense > > 1. Thread A makes some system call X, and the call fails > 2. Meanwhile, Thread B makes some system call Y. This call also fails > 3. Thread A checks its errno. The errno indicates the reason of > failure of call X > 4. Thread B also checks its errno. The errno indicates the failure of > call Y > > The above is guaranteed, because errno is stored in thread-local storage > > But Rust uses green thread, which means it's possible that multiple > tasks may run on a thread. > > 1. Task A calls function core::os::X. The system call fails and sets errno > 2. Meanwhile (on the same thread) Task B is switched in and calls > core::os::Y. The system call fails and replaces the errno set from task A. > 3. Task A is switched in again, and checks errno. It expects errno > returns the reason of failure of core::os::X, but what A sees is the > failure of core::os::Y > > Is above case possible in Rust? If not, how does Rust prevents this? > Rust currently context switches in relatively few places, so it is generally safe to make a system call then call errno - you won't get descheduled between the two. Pipe sends and receives, as well as other task-blocking concurrency types will cause you to be descheduled and could cause errno to be invalidated. From banderson at mozilla.com Tue May 21 14:33:55 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 21 May 2013 14:33:55 -0700 Subject: [rust-dev] Questions about task and thread local storage In-Reply-To: References: <1369141781102.1a443509@Nodemailer> Message-ID: <519BE843.4050805@mozilla.com> On 05/21/2013 10:22 AM, Jack Moffitt wrote: >> AFAIK that's not supposed to happen if task A checks errno (or other >> thread-local value) immediately after returning from the failed call. Tasks >> are switched cooperatively within the scheduler thread. > Those semantics are true I think, and I believe will remain true, but > they are not obvious. Hopefully this will get documented. The docs for > the core::os calls should probably mention that you have to check > errno without doing any intermediate I/O. Oh, yeah I/O is a good one to point out. It's not currently the case that I/O will deschedule your task, but it will be in the future. > > What are the task switch boundaries? Is it just I/O? Or can > non-inlined function calls also cause switches (this is for example > where Erlang code replacement is allowed to happen). There's no way to > know if some function does I/O transitively, so predicting task > switches is not necessarily trivial. Currently tasks yield primarily on pipe sends and receives, but there are also a some other synchronization types in std that yield. > > How often is this pattern used in C code? Are there other examples > where thread-local storage is used for library state? > > jack. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From banderson at mozilla.com Tue May 21 14:34:40 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 21 May 2013 14:34:40 -0700 Subject: [rust-dev] Coding style for struct expression In-Reply-To: <519BE6B7.9040209@mozilla.com> References: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> <519BE6B7.9040209@mozilla.com> Message-ID: <519BE870.9030903@mozilla.com> On 05/21/2013 02:27 PM, Brian Anderson wrote: > On 05/21/2013 01:03 AM, Sanghyeon Seo wrote: >> What is the preferred coding style for the struct expression? >> >> Given: >> >> struct Point { >> x: float, >> y: float >> } >> >> Point { x: 1.0, y: 1.0 } // (1) >> Point{x: 1.0, y: 1.0} // (2) >> >> Tutorial uses 1, pretty printer does 2. It seems to me that when an >> expression is on >> multiple lines, spaces are common, but for a single line it is mixed. >> core::path uses 1, >> but core::iterator uses 2. > > I use 2. He's lying. Brian actually uses 1. From erick.tryzelaar at gmail.com Tue May 21 16:26:26 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Tue, 21 May 2013 16:26:26 -0700 Subject: [rust-dev] Coding style for struct expression In-Reply-To: <519BE870.9030903@mozilla.com> References: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> <519BE6B7.9040209@mozilla.com> <519BE870.9030903@mozilla.com> Message-ID: I use 1 as well. If there's no other opposition, can we add this to the style guide? On Tue, May 21, 2013 at 2:34 PM, Brian Anderson wrote: > On 05/21/2013 02:27 PM, Brian Anderson wrote: > >> On 05/21/2013 01:03 AM, Sanghyeon Seo wrote: >> >>> What is the preferred coding style for the struct expression? >>> >>> Given: >>> >>> struct Point { >>> x: float, >>> y: float >>> } >>> >>> Point { x: 1.0, y: 1.0 } // (1) >>> Point{x: 1.0, y: 1.0} // (2) >>> >>> Tutorial uses 1, pretty printer does 2. It seems to me that when an >>> expression is on >>> multiple lines, spaces are common, but for a single line it is mixed. >>> core::path uses 1, >>> but core::iterator uses 2. >>> >> >> I use 2. >> > > He's lying. Brian actually uses 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 banderson at mozilla.com Tue May 21 16:30:49 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 21 May 2013 16:30:49 -0700 Subject: [rust-dev] Coding style for struct expression In-Reply-To: References: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> <519BE6B7.9040209@mozilla.com> <519BE870.9030903@mozilla.com> Message-ID: <519C03A9.106@mozilla.com> On 05/21/2013 04:26 PM, Erick Tryzelaar wrote: > I use 1 as well. If there's no other opposition, can we add this to > the style guide? > I'm in favor, maybe emphasizing to only do this for small structs. From jack at metajack.im Tue May 21 16:31:44 2013 From: jack at metajack.im (Jack Moffitt) Date: Tue, 21 May 2013 17:31:44 -0600 Subject: [rust-dev] Coding style for struct expression In-Reply-To: <519C03A9.106@mozilla.com> References: <25311862.537351369123421802.JavaMail.weblogic@epv6ml02> <519BE6B7.9040209@mozilla.com> <519BE870.9030903@mozilla.com> <519C03A9.106@mozilla.com> Message-ID: >> I use 1 as well. If there's no other opposition, can we add this to the >> style guide? >> > > I'm in favor, maybe emphasizing to only do this for small structs. +1 jack. From hatahet at gmail.com Tue May 21 17:38:55 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Tue, 21 May 2013 17:38:55 -0700 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: <20130521175804.GJ22687@Mr-Bennet> References: <517790B4.3070700@mozilla.com> <5193E1FE.4070509@mozilla.com> <20130521175804.GJ22687@Mr-Bennet> Message-ID: On Tue, May 21, 2013 at 10:58 AM, Niko Matsakis wrote: > This form is unlikely to continue working in the future. Instead, a > new syntax will be introduced. See this blog post for more details: > > > http://blog.pnkfx.org/blog/2013/04/22/designing-syntax-for-associated-items-in-rust/ > > Niko > Interesting. I went through the link above, and both of your blog posts on associated types. Though honestly I can't say I grasped everything :) We will still retain the ability to do have polymorphism on the return type though, correct? (ala let x: Int = parse("123")) Thanks -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Wed May 22 03:52:04 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 22 May 2013 06:52:04 -0400 Subject: [rust-dev] Best name for Const trait Message-ID: <20130522105204.GA2245@Mr-Bennet> After our meeting yesterday I was thinking that perhaps `Freeze` is not the best name for what is now `Const`. Given that we wound up disliking `Owned` because it described a property of the type, and not what you could do with it, perhaps the best name for `Const`/`Freeze` would be something related to sharing between threads. Therefore I nominate `Share` (or some similar name). `Share` seems more analogous to `Send` and, I think, makes it easier to reason about when the type is appropriate: - ARC: Mutated privately atomically, still shareable - RC: Mutated privately but non-atomically, not shareable - Cell: Mutated privately but non-atomically, not shareable - `@`, `&`: Immutable, shareable, see below. - `@mut`, `&mut`: Inherently mutable, not shareable - Joe random struct: No interior mutability, shareable One complication is `@` and `&`. These types are `Const` but cannot (today) be shared between threads. However, I hope to change this by adding fork-join style parallelism. The idea would be to build on the type `fn:Share()` (meaning: a closure that cannot mutate its environment) and offer methods like `pmap` on vectors that execute their iterations in parallel. In this context, the name `Share` is perfect, because it distinguishes between values that can be shared between threads but cannot be *sent* between threads (meaning: no transfer of ownership). Granted, this forkjoin parallelism design is speculative and may not come to pass. Another complication is that we have sometimes called `@T` a "shared box". But that name is deprecated in favor of managed. Or maybe someone else can come up with another word that conveys "shared between parallel tasks" more precisely. Anyway, I wanted to toss that out there. Niko From zo1980 at gmail.com Wed May 22 04:39:26 2013 From: zo1980 at gmail.com (=?UTF-8?B?Wm9sdMOhbiBUw7N0aA==?=) Date: Wed, 22 May 2013 13:39:26 +0200 Subject: [rust-dev] Rust Documentation - incomplete Message-ID: Hi Folks! I am new on this list. I am a regular C++ algorithm programmer, who is very interested in Rust. First of all - congratulation for this project. After reading the tutorial (which btw I found very good quality (it is both concise and explanatory in the same time)), I still have questions about the project. I also quickly went throught the manual, but neither it did answer my questions. I hope you will and I ask you too extend the documentation with the answers. 1) The implementation details of the garbage collector. I understand that implementation details may sound a bit boring topic for a languge designer, but for anyone considering using the language in practice it may be a decisive factor. Abou the GC: Is it precise? It is moving? Is it based on clang? When is gc triggered? Does it call the destructors of objects detected as garbage? About the exchange heap: Is it compacted? The importance of these questions is from the fact that Rust denies explicit memory management for the programmer and instead forces its own solutions, the GC heap and the exchange heap. 2) Rust does not provide exception handling, but in the same time still does stack unwind. I can understand choices either for or against EH in a new language, but this mixture seems weird. I missed a design rational about this decision. Why is the task fail ability so important that it is worth the inclusion of stack unwinding into a semantics that does not support EH anyway? Or do you consider stack unwind a cheap, non-problematic addition? If you omitted stack unwind, then the user programmer could always easily argue about the execution flow of its code easily, which is a big advantage. Now the user does not have EH, but still has its disadvantage, that is - has to worry about exception safety (RAII takes care of only the majority of exception safety issues, not all, right?). How is unsuccessful memory allocation handled? -------------- next part -------------- An HTML attachment was scrubbed... URL: From corey at octayn.net Wed May 22 04:48:08 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 22 May 2013 07:48:08 -0400 Subject: [rust-dev] Rust Documentation - incomplete In-Reply-To: References: Message-ID: I'm still a newbie too, so I can't answer all of your questions, but: On Wed, May 22, 2013 at 7:39 AM, Zolt?n T?th wrote: > 1) The implementation details of the garbage collector. I understand that > implementation details may sound a bit boring topic for a languge designer, > but for anyone considering using the language in practice it may be a > decisive factor. > The garbage collector for managed boxes (@-ptrs) is currently reference counting with a broken cycle collector. It leaks a lot, not good at all. Graydon has a real GC in https://github.com/graydon/rust/tree/gc. It's conservative and not very sophisticated yet. Someone else will have to elaborate on the details, I don't know them. > The importance of these questions is from the fact that Rust denies explicit > memory management for the programmer and instead forces its own solutions, > the GC heap and the exchange heap. > This actually isn't true. You can still use raw pointers (same syntax as C, *foo) and custom allocation code, but you need to use unsafe code and write your own safe wrappers. From danielmicay at gmail.com Wed May 22 04:58:25 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 22 May 2013 07:58:25 -0400 Subject: [rust-dev] Rust Documentation - incomplete In-Reply-To: References: Message-ID: On Wed, May 22, 2013 at 7:48 AM, Corey Richardson wrote: > I'm still a newbie too, so I can't answer all of your questions, but: > > On Wed, May 22, 2013 at 7:39 AM, Zolt?n T?th wrote: >> 1) The implementation details of the garbage collector. I understand that >> implementation details may sound a bit boring topic for a languge designer, >> but for anyone considering using the language in practice it may be a >> decisive factor. >> > > The garbage collector for managed boxes (@-ptrs) is currently > reference counting with a broken cycle collector. It leaks a lot, not > good at all. Graydon has a real GC in There isn't actually a cycle collector anymore, they're just destroyed at the end of the task. It doesn't really leak, and a proper garbage collector doesn't give you a better worst-case collection time. From corey at octayn.net Wed May 22 05:14:28 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 22 May 2013 08:14:28 -0400 Subject: [rust-dev] Rust Documentation - incomplete In-Reply-To: References: Message-ID: Specific details would be useful to add to https://github.com/mozilla/rust/wiki/Doc-lowlevel-details, as they're revealed, btw. From niko at alum.mit.edu Wed May 22 05:34:28 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 22 May 2013 08:34:28 -0400 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: References: <517790B4.3070700@mozilla.com> <5193E1FE.4070509@mozilla.com> <20130521175804.GJ22687@Mr-Bennet> Message-ID: <20130522123428.GC2245@Mr-Bennet> > We will still retain the ability to do have polymorphism on the return type > though, correct? (ala let x: Int = parse("123")) Correct. Niko From danielmicay at gmail.com Wed May 22 05:41:02 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 22 May 2013 08:41:02 -0400 Subject: [rust-dev] Rust Documentation - incomplete In-Reply-To: References: Message-ID: On Wed, May 22, 2013 at 7:39 AM, Zolt?n T?th wrote: > Hi Folks! > > I am new on this list. I am a regular C++ algorithm programmer, who is very > interested in Rust. > > First of all - congratulation for this project. > > > After reading the tutorial (which btw I found very good quality (it is both > concise and explanatory in the same time)), I still have questions about the > project. I also quickly went throught the manual, but neither it did answer > my questions. I hope you will and I ask you too extend the documentation > with the answers. > > > 1) The implementation details of the garbage collector. I understand that > implementation details may sound a bit boring topic for a languge designer, > but for anyone considering using the language in practice it may be a > decisive factor. > > Abou the GC: > Is it precise? It is moving? Is it based on clang? When is gc triggered? > Does it call the destructors of objects detected as garbage? There's not currently a working garbage collection implementation beyond reference counting and an annihilator to destroy cycles at the end of a task. The garbage collector will be task-local since managed boxes are task-local, and it can eventually be a nice precise, generational, compacting collector. Mutable managed boxes already have to keep of whether they are borrowed from, so the data needed for a moving collector is already there for @mut. > About the exchange heap: > Is it compacted? It uses the allocator from the system's C standard library. In the future, Rust will probably ship with an allocator like jemalloc/tcmalloc for consistent performance across platforms but they aren't much different than glibc's standard allocator. Small allocations are allocated in groups by size, so the heap is already compact. Large allocations don't go through the thread-local caches. > The importance of these questions is from the fact that Rust denies explicit > memory management for the programmer and instead forces its own solutions, > the GC heap and the exchange heap. It doesn't deny anything, there are examples of alternate memory management solutions in the standard library (std::rc, std::arc, std::arena). Unique pointers/vectors are a thin wrapper around malloc/free. > 2) Rust does not provide exception handling, but in the same time still does > stack unwind. I can understand choices either for or against EH in a new > language, but this mixture seems weird. I missed a design rational about > this decision. Why is the task fail ability so important that it is worth > the inclusion of stack unwinding into a semantics that does not support EH > anyway? Or do you consider stack unwind a cheap, non-problematic addition? > If you omitted stack unwind, then the user programmer could always easily > argue about the execution flow of its code easily, which is a big advantage. > Now the user does not have EH, but still has its disadvantage, that is - has > to worry about exception safety (RAII takes care of only the majority of > exception safety issues, not all, right?). Task failure is exception handling with the restriction that you can only catch them at task boundaries. Since tasks don't share memory, there are few of the usual exception-safety concerns like implementing any series of mutations in a transaction. > How is unsuccessful memory allocation handled? It's handled by exiting. Handling it by unwinding like C++ isn't possible because growable stacks result in almost anything being a potential allocation. Although, unsuccessful memory allocation doesn't actually occur on a system using overcommit. Resource exhaustion happens during a page fault. From steve at steveklabnik.com Wed May 22 07:00:31 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Wed, 22 May 2013 07:00:31 -0700 Subject: [rust-dev] Rust Documentation - incomplete In-Reply-To: References: Message-ID: > Unique pointers/vectors are a thin wrapper around > malloc/free. Whoah. Now that you say it this way, I think this is a waaaaaay better way to explain unique pointers than we currently do. I don't know why I didn't think of it before. From ben.striegel at gmail.com Wed May 22 08:08:17 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 22 May 2013 11:08:17 -0400 Subject: [rust-dev] Rust Documentation - incomplete In-Reply-To: References: Message-ID: > I don't know why I didn't think of it before. pcwalton also alludes to it in http://pcwalton.github.io/blog/2013/03/18/an-overview-of-memory-management-in-rust/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Wed May 22 08:16:30 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 22 May 2013 08:16:30 -0700 Subject: [rust-dev] Best name for Const trait In-Reply-To: <20130522105204.GA2245@Mr-Bennet> References: <20130522105204.GA2245@Mr-Bennet> Message-ID: <519CE14E.7020209@mozilla.com> On 5/22/13 3:52 AM, Niko Matsakis wrote: > After our meeting yesterday I was thinking that perhaps `Freeze` is > not the best name for what is now `Const`. Given that we wound up > disliking `Owned` because it described a property of the type, and not > what you could do with it, perhaps the best name for `Const`/`Freeze` > would be something related to sharing between threads. Therefore I > nominate `Share` (or some similar name). I like this idea. Patrick From danielmicay at gmail.com Wed May 22 08:16:42 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 22 May 2013 11:16:42 -0400 Subject: [rust-dev] Rust Documentation - incomplete In-Reply-To: References: Message-ID: On Wed, May 22, 2013 at 10:00 AM, Steve Klabnik wrote: >> Unique pointers/vectors are a thin wrapper around >> malloc/free. > > Whoah. Now that you say it this way, I think this is a waaaaaay better > way to explain unique pointers than we currently do. I don't know why > I didn't think of it before. I added a section to the tutorial showing how ~ maps to malloc/free, but it seemed like a lot of people *really* disliked having the comparison so that's removed now. From banderson at mozilla.com Wed May 22 11:05:28 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 22 May 2013 11:05:28 -0700 Subject: [rust-dev] Best name for Const trait In-Reply-To: <20130522105204.GA2245@Mr-Bennet> References: <20130522105204.GA2245@Mr-Bennet> Message-ID: <519D08E8.4050506@mozilla.com> On 05/22/2013 03:52 AM, Niko Matsakis wrote: > After our meeting yesterday I was thinking that perhaps `Freeze` is > not the best name for what is now `Const`. Given that we wound up > disliking `Owned` because it described a property of the type, and not > what you could do with it, perhaps the best name for `Const`/`Freeze` > would be something related to sharing between threads. Therefore I > nominate `Share` (or some similar name). I was thinking of this too, but I dislike the name shared for two reasons: * we've also used it to mean 'shared locally' - 'shared pointers' e.g. managed pointers. * there are plenty of types that are shared memory but not immutable From niko at alum.mit.edu Wed May 22 12:03:33 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 22 May 2013 15:03:33 -0400 Subject: [rust-dev] Best name for Const trait In-Reply-To: <519D08E8.4050506@mozilla.com> References: <20130522105204.GA2245@Mr-Bennet> <519D08E8.4050506@mozilla.com> Message-ID: <20130522190333.GE2245@Mr-Bennet> On Wed, May 22, 2013 at 11:05:28AM -0700, Brian Anderson wrote: > * we've also used it to mean 'shared locally' - 'shared pointers' > e.g. managed pointers. > * there are plenty of types that are shared memory but not immutable e.g., RWARC? Niko From banderson at mozilla.com Wed May 22 14:05:30 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 22 May 2013 14:05:30 -0700 Subject: [rust-dev] Best name for Const trait In-Reply-To: <20130522190333.GE2245@Mr-Bennet> References: <20130522105204.GA2245@Mr-Bennet> <519D08E8.4050506@mozilla.com> <20130522190333.GE2245@Mr-Bennet> Message-ID: <519D331A.7080103@mozilla.com> On 05/22/2013 12:03 PM, Niko Matsakis wrote: > On Wed, May 22, 2013 at 11:05:28AM -0700, Brian Anderson wrote: >> * we've also used it to mean 'shared locally' - 'shared pointers' >> e.g. managed pointers. >> * there are plenty of types that are shared memory but not immutable > e.g., RWARC? Yeah, and most things built on UnsafeAtomicRcBox, like Exclusive and Mutex, MutexARC. Port and Chan use shared memory as will abstractions we haven't imagined yet. From hatahet at gmail.com Wed May 22 23:13:29 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 22 May 2013 23:13:29 -0700 Subject: [rust-dev] Do-notation? Message-ID: Say we want to implement the following function: fn add(x: Option, y: Option) -> Option { ... } Some functional languages, like Haskell and Scala offer some sort of a "do" notation to make unwrapping multiple Option type values easier. add :: Maybe Int -> Maybe Int -> Maybe Int add mx my = do x <- mx y <- my return (x + y) Is there an equivalent construct in Rust? -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From o.renaud at gmx.fr Thu May 23 02:24:33 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Thu, 23 May 2013 11:24:33 +0200 Subject: [rust-dev] Boxed traits and generics. Message-ID: <20130523092433.277010@gmx.com> Hi, I am not the OP, but this question made me curious. If I understand the problem correctly, the type system makes a strong distinction between an @Struct and an @Trait. And ptr_eq seems to accept @Struct only. How can this restriction be inferred from the signature of ptr_eq ? Is this because it's ptr_eq instead of ptr_eq<@T> ? Does the fact that this function is marked as inlined has an influence on that behavior ? I would be interrested in the answer of the original question, too (how to compare 2 @Trait pointers). Thanks. ----- Message d'origine ----- De : Vincent Ocquet Envoy?s : 21.05.13 20:15 ? : Fedor Indutny Objet : Re: [rust-dev] Boxed traits and generics. Hi, The thing is, I want to use function ptr_eq(@T, @T) from core::managed and I can't change it in the way you describe. Actually, I'd like to make sure that I can't add twice the same object to a vector like below : use core::vec::position; use core::managed::ptr_eq; struct DummyListener; trait Listener { fn fire_event(&self); } impl Listener for DummyListener { fn fire_event(&self) { /* stuff */ } } fn main() { let mut vec: ~[@Listener] = ~[]; let a = @DummyListener; let b = @DummyListener; vec = add(vec, a as @Listener); vec = add(vec, b as @Listener); vec = add(vec, b as @Listener); for vec.each |listener| {listener.fire_event();} } fn add(mut vec: ~[@Listener], toAdd: @Listener) -> ~[@Listener] { if ( position(vec, |listener| { ptr_eq::(toAdd, *listener) }) == None) { vec.push(toAdd); } vec } What do you mean by you can't cast to Traits, isn't it what 'as' is for ? On 21/05/2013 14:54, Fedor Indutny wrote: Hi! You can't cast structs to traits, traits is just a behaviour for structs. What you probably wanted to do was: fn foo(value: @T) -> ~str { value.to_str() } Cheers, Fedor. On Tue, May 21, 2013 at 3:50 PM, Vincent O. < vincent.ocquet at gmail.com > wrote:Hi, I tried to use core::managed::ptr_eq for boxed traits but it compile-fails with a mismatched type error. Here's a code example that reproduces my problem : use core::ToStr; fn main() { let a = @S; foo::(a as @ToStr); } struct S; impl S for ToStr { fn to-str(&self) -> ~str {~""} } fn foo(value: @T) {} // similar to ptr_eq with the error message : test.rs:5:15: 5:26 error: mismatched types: expected `@core::to_str::ToStr` but found `@core::to_str::ToStr` (expected @-ptr but found trait core::to_str::ToStr) http://test.rs:5 test::(a as @ToStr); The issue is the same with owned boxes. Is it the intended behavior ? in this case, is there any workaround ? _______________________________________________ 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 May 23 02:34:50 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 23 May 2013 05:34:50 -0400 Subject: [rust-dev] Do-notation? In-Reply-To: References: Message-ID: <20130523093450.GG2245@Mr-Bennet> No, just the chain method, though in some parts of the code we have adapted macros to this purpose. Niko > Say we want to implement the following function: > > fn add(x: Option, y: Option) -> Option { ... } > > Some functional languages, like Haskell and Scala offer some sort of a "do" > notation to make unwrapping multiple Option type values easier. > > add :: Maybe Int -> Maybe Int -> Maybe Int > add mx my = do > x <- mx > y <- my > return (x + y) > > Is there an equivalent construct in Rust? > > -- > Ziad > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From rust-dev at tomlee.co Thu May 23 03:33:24 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Thu, 23 May 2013 03:33:24 -0700 Subject: [rust-dev] glue_fns, shims & tydescs Message-ID: Hey Rustlers, I'm fighting with issue #6575 which involves the removal of a useless function parameter emitted during the trans phase. I've got a WIP available hereif anybody's interested, though it does right now is segfault. :) I *think *the segfault is the result of me getting something silly wrong & somehow the stack is getting messed up in the process (and/or something is getting prematurely collected). In any case, all this digging around is leaving me with some questions that may or may not be useful to getting this thing to stop segfaulting & start doing something useful. Can anybody out there offer some clarification about the following? - What are glue_fns and why are they necessary? How/why do they differ from shim_fns (used to invoke foreign functions)? - What's the purpose of *visit_glue* in the type_desc struct? The others seem largely obvious (take/drop doing some sort of refcounting, free to clean up, but visit ... ?) - Where are type_descs/tydescs written? The stack? The heap(s)? (i.e. anything that can be a GC root?) Where in the source code does this happen? - What exactly is a "safe point" wrt the garbage collector? Appreciate any insight! Thanks, Tom -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Thu May 23 05:28:20 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 23 May 2013 08:28:20 -0400 Subject: [rust-dev] Do-notation? In-Reply-To: References: Message-ID: There's no generalized notation, but a while ago I overloaded the + operator on Option such that it automatically unwraps them, adds the contained elements together (for any two types that implement Add), and returns a wrapped result. let foo = Some(1) + Some(4); error!(foo); // Some(5) This behavior seems mostly innocuous, but there's some question as to whether the behavior is correct (and also whether we want to support this sort of overloading at all): https://github.com/mozilla/rust/issues/6002 If this sort of thing is useful, it's feasible that we could overload the other operators as well. But obviously it's not quite the same as having a generalized solution (and I do think that Options needs to be as nice to use as possible in order for anyone to bother adopting them). On Thu, May 23, 2013 at 2:13 AM, Ziad Hatahet wrote: > Say we want to implement the following function: > > fn add(x: Option, y: Option) -> Option { ... } > > Some functional languages, like Haskell and Scala offer some sort of a > "do" notation to make unwrapping multiple Option type values easier. > > add :: Maybe Int -> Maybe Int -> Maybe Int > add mx my = do > x <- mx > y <- my > return (x + y) > > Is there an equivalent construct in Rust? > > -- > Ziad > > _______________________________________________ > 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 masklinn at masklinn.net Thu May 23 07:18:38 2013 From: masklinn at masklinn.net (Masklinn) Date: Thu, 23 May 2013 16:18:38 +0200 Subject: [rust-dev] Do-notation? In-Reply-To: References: Message-ID: On 2013-05-23, at 14:28 , Benjamin Striegel wrote: > There's no generalized notation, but a while ago I overloaded the + > operator on Option such that it automatically unwraps them, adds the > contained elements together (for any two types that implement Add), and > returns a wrapped result. > > let foo = Some(1) + Some(4); > error!(foo); // Some(5) > > > This behavior seems mostly innocuous, but there's some question as to > whether the behavior is correct (and also whether we want to support this > sort of overloading at all): https://github.com/mozilla/rust/issues/6002 > > If this sort of thing is useful, it's feasible that we could overload the > other operators as well. I think that's way too specialized and repetitive for the general case. A form of zip/map_zip for option would be better as it'd allow applying arbitrary operations cleanly, something along the lines of fn zip(t: Option, u: Option) -> Option<(T, U)> And thus you would write something along the lines of: let foo = option::zip(Some(1), Some(2)).map(|&(a, b)| { a + b }) zip would be something along the lines of: match (t, u) { (Some t1, Some v1) => Some (t1, v1), _ => None } (well it would require pointer and lifetime powder thing, but you get the idea) From dbau.pp at gmail.com Thu May 23 07:27:05 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Fri, 24 May 2013 00:27:05 +1000 Subject: [rust-dev] Do-notation? In-Reply-To: References: Message-ID: <519E2739.9030708@gmail.com> On 23/05/13 16:13, Ziad Hatahet wrote: > Say we want to implement the following function: > > fn add(x: Option, y: Option) -> Option { ... } > > Some functional languages, like Haskell and Scala offer some sort of a > "do" notation to make unwrapping multiple Option type values easier. > > add :: Maybe Int -> Maybe Int -> Maybe Int > add mx my = do > x <- mx > y <- my > return (x + y) > > Is there an equivalent construct in Rust? > > -- > Ziad > I just whipped up a very basic do-notation syntax extension[1] (it can't be called "do!" unfortunately), it was much easier than I was expecting. The following compiles fine: fn main () { let x = do_!(bind a = Some(1); bind b = None; let res = a + b; Some(res)); println(fmt!("%?", x)) } and prints None (or Some(3), if you change the None to Some(2)). It works for anything that defines a method called "chain" (e.g. Result), but there's no generic return equivalent yet, so that has to be changed for each type. (I chose to use bind rather than <- (or similar) for parsing ease.) Huon [1]: https://github.com/huonw/rust/tree/do-notation -------------- next part -------------- An HTML attachment was scrubbed... URL: From hatahet at gmail.com Thu May 23 09:48:28 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Thu, 23 May 2013 09:48:28 -0700 Subject: [rust-dev] Do-notation? In-Reply-To: <519E2739.9030708@gmail.com> References: <519E2739.9030708@gmail.com> Message-ID: Thanks all for the replies. Niko, could you point out where in the code you defined the macro you mention? Thanks -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From hatahet at gmail.com Thu May 23 10:09:12 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Thu, 23 May 2013 10:09:12 -0700 Subject: [rust-dev] Do-notation? In-Reply-To: <519E2739.9030708@gmail.com> References: <519E2739.9030708@gmail.com> Message-ID: On Thu, May 23, 2013 at 7:27 AM, Huon Wilson wrote: > I just whipped up a very basic do-notation syntax extension[1] (it can't > be called "do!" unfortunately), it was much easier than I was expecting. > > > Huon > That's great! I haven't messed around with macros yet, but I presume there is nothing preventing from having a generic version of what you wrote? That could be helpful once Rust has the ability to export macros. -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Thu May 23 11:14:34 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 23 May 2013 11:14:34 -0700 Subject: [rust-dev] glue_fns, shims & tydescs In-Reply-To: References: Message-ID: <519E5C8A.2020709@mozilla.com> On 23/05/2013 3:33 AM, Tom Lee wrote: > Can anybody out there offer some clarification about the following? > > * What are glue_fns and why are they necessary? How/why do they differ > from shim_fns (used to invoke foreign functions)? Glue functions are invoked by the compiler when types are dropped or copied. They manage the lifecycle of the type, and are ubiquitous and compiler-generated. They have nothing to do with shim functions aside from them both being compiler-generated (and too-numerous for our taste!) > * What's the purpose of /visit_glue/ in the type_desc struct? The > others seem largely obvious (take/drop doing some sort of > refcounting, free to clean up, but visit ... ?) Visit is for reflection. See core::reflect (renamed last night to std::reflect). > * Where are type_descs/tydescs written? The stack? The heap(s)? (i.e. > anything that can be a GC root?) Where in the source code does this > happen? They're global constant static data. Compiler-generated. > * What exactly is a "safe point" wrt the garbage collector? The name refers to the idea (in many GCs) of a place in a code-sequence at which the compiler has to spill references back to stack locations or otherwise arrive at a state properly described by metadata / frame maps, such that it can find all roots. It's only relevant in a precise GC. Since the current strategy for GC is conservative (presently _everywhere_, though this will eventually be limited to just-the-stack) there's on such need: the GC just spills all registers on entry and treats them as possible-roots like very other word on the stack. If you see the term in our code, it's residue from the most recent experiment with precise GC, which has been (for the time being) abandoned. -Graydon From graydon at mozilla.com Thu May 23 11:35:11 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 23 May 2013 11:35:11 -0700 Subject: [rust-dev] Boxed traits and generics. In-Reply-To: References: Message-ID: <519E615F.5000302@mozilla.com> On 21/05/2013 4:50 AM, Vincent O. wrote: > The issue is the same with owned boxes. Is it the intended behavior ? in > this case, is there any workaround ? You're running into one of the motivations for Niko's work on trying to unify our treatment of unknown-sized types: http://smallcultfollowing.com/babysteps/blog/2013/04/30/dynamically-sized-types/ Essentially: at the moment, a trait-name used as a type is of unknown size -- each implementation has a different size -- so we disallow referring to it as a type _at all_ in "type context" such as the T in ptr_eq, requiring you to write a known-size type there, such as @Trait or ~Trait or &Trait. This also comes up with 'str' and '[]' not being types, only @str, &str and ~str (or @[], ~[] and &[]). The more-complete solution will involve a reorganization of how unknown-size types are classified. It's planned work, just not done yet. In the meantime, I suspect your best workaround for what you're trying to do is ... somewhat awful, as it relies on the fact (that I happen to know!) that a @Trait is a 2-word "fat pointer": unsafe { let a : (*u8,*u8) = cast::transmute(x); let b : (*u8,*u8) = cast::transmute(y); x == y } This is obviously an awful "solution", but if you're blocked on it, it should work for now. -Graydon From corey at octayn.net Thu May 23 18:11:31 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 23 May 2013 21:11:31 -0400 Subject: [rust-dev] The Great Renaming Message-ID: In case you haven't been paying attention, the great libcore renaming landed on incoming today. So, libcore is now libstd libstd is now libextra From niko at alum.mit.edu Thu May 23 18:33:46 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 23 May 2013 21:33:46 -0400 Subject: [rust-dev] glue_fns, shims & tydescs In-Reply-To: References: Message-ID: <20130524001133.GI2245@Mr-Bennet> Shim functions are an artifact of how we compiled foreign functions. They are explained a comment in . They are not long for this world, though: https://github.com/mozilla/rust/pull/6661 Niko On Thu, May 23, 2013 at 03:33:24AM -0700, Tom Lee wrote: > Hey Rustlers, > > I'm fighting with issue #6575 > which > involves the removal of a useless function parameter emitted during the > trans phase. I've got a WIP available > hereif anybody's > interested, though it does right now is segfault. :) I > *think *the segfault is the result of me getting something silly wrong & > somehow the stack is getting messed up in the process (and/or something is > getting prematurely collected). > > In any case, all this digging around is leaving me with some questions that > may or may not be useful to getting this thing to stop segfaulting & start > doing something useful. > > Can anybody out there offer some clarification about the following? > > - What are glue_fns and why are they necessary? How/why do they differ > from shim_fns (used to invoke foreign functions)? > > - What's the purpose of *visit_glue* in the type_desc struct? The others > seem largely obvious (take/drop doing some sort of refcounting, free to > clean up, but visit ... ?) > > - Where are type_descs/tydescs written? The stack? The heap(s)? (i.e. > anything that can be a GC root?) Where in the source code does this happen? > > - What exactly is a "safe point" wrt the garbage collector? > > Appreciate any insight! > > Thanks, > Tom > > > -- > *Tom Lee */ http://tomlee.co / @tglee > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Thu May 23 18:36:57 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 23 May 2013 21:36:57 -0400 Subject: [rust-dev] Do-notation? In-Reply-To: References: <519E2739.9030708@gmail.com> Message-ID: <20130524013657.GJ2245@Mr-Bennet> I was thinking of the if_ok! macro, which is intended for use with the Result type: ``` macro_rules! if_ok( ($inp: expr) => ( match $inp { Ok(v) => { v } Err(e) => { return Err(e); } } ) ) ``` It is used like: ``` let foo = if_ok!(something_that_yields_a_result()); ``` Niko On Thu, May 23, 2013 at 09:48:28AM -0700, Ziad Hatahet wrote: > Thanks all for the replies. > > Niko, could you point out where in the code you defined the macro you > mention? > > Thanks > > -- > Ziad From vincent.ocquet at gmail.com Thu May 23 23:44:12 2013 From: vincent.ocquet at gmail.com (Vincent Ocquet) Date: Fri, 24 May 2013 08:44:12 +0200 Subject: [rust-dev] Boxed traits and generics. In-Reply-To: <519E615F.5000302@mozilla.com> References: <519E615F.5000302@mozilla.com> Message-ID: <519F0C3C.7080409@gmail.com> This solution works well ! I think that's a nice enough workaround for now as I won't spread it that much in my code. Now I understand why there's a restriction on trait types (though I thought at the beginning it was an argument type mismatch), I'm looking forward for a cleaner solution :) Thanks a lot for your answer. On 23/05/2013 20:35, Graydon Hoare wrote: > On 21/05/2013 4:50 AM, Vincent O. wrote: > >> The issue is the same with owned boxes. Is it the intended behavior ? in >> this case, is there any workaround ? > > You're running into one of the motivations for Niko's work on trying > to unify our treatment of unknown-sized types: > > http://smallcultfollowing.com/babysteps/blog/2013/04/30/dynamically-sized-types/ > > > Essentially: at the moment, a trait-name used as a type is of unknown > size -- each implementation has a different size -- so we disallow > referring to it as a type _at all_ in "type context" such as the T in > ptr_eq, requiring you to write a known-size type there, such as > @Trait or ~Trait or &Trait. This also comes up with 'str' and '[]' not > being types, only @str, &str and ~str (or @[], ~[] and &[]). > > The more-complete solution will involve a reorganization of how > unknown-size types are classified. It's planned work, just not done yet. > > In the meantime, I suspect your best workaround for what you're trying > to do is ... somewhat awful, as it relies on the fact (that I happen > to know!) that a @Trait is a 2-word "fat pointer": > > unsafe { > let a : (*u8,*u8) = cast::transmute(x); > let b : (*u8,*u8) = cast::transmute(y); > x == y > } > > This is obviously an awful "solution", but if you're blocked on it, it > should work for now. > > -Graydon > From rust-dev at tomlee.co Fri May 24 01:38:30 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Fri, 24 May 2013 01:38:30 -0700 Subject: [rust-dev] glue_fns, shims & tydescs In-Reply-To: <519E5C8A.2020709@mozilla.com> References: <519E5C8A.2020709@mozilla.com> Message-ID: Thanks for the info guys, very helpful. Folks following along at home may be interested in seeing where & how compiler writes out the set of tydescs: https://github.com/mozilla/rust/blob/1393c3a3f438c896083405dca501c8cf05767c65/src/librustc/middle/trans/glue.rs#L766 I had assumed for some reason that they were local to some unit of execution -- didn't realize that they were global (although that should have been obvious, thinking about it). Cheers, Tom On Thu, May 23, 2013 at 11:14 AM, Graydon Hoare wrote: > On 23/05/2013 3:33 AM, Tom Lee wrote: > > Can anybody out there offer some clarification about the following? >> >> * What are glue_fns and why are they necessary? How/why do they differ >> >> from shim_fns (used to invoke foreign functions)? >> > > Glue functions are invoked by the compiler when types are dropped or > copied. They manage the lifecycle of the type, and are ubiquitous and > compiler-generated. They have nothing to do with shim functions aside from > them both being compiler-generated (and too-numerous for our taste!) > > * What's the purpose of /visit_glue/ in the type_desc struct? The >> >> others seem largely obvious (take/drop doing some sort of >> refcounting, free to clean up, but visit ... ?) >> > > Visit is for reflection. See core::reflect (renamed last night to > std::reflect). > > * Where are type_descs/tydescs written? The stack? The heap(s)? (i.e. >> >> anything that can be a GC root?) Where in the source code does this >> happen? >> > > They're global constant static data. Compiler-generated. > > * What exactly is a "safe point" wrt the garbage collector? >> > > The name refers to the idea (in many GCs) of a place in a code-sequence at > which the compiler has to spill references back to stack locations or > otherwise arrive at a state properly described by metadata / frame maps, > such that it can find all roots. It's only relevant in a precise GC. Since > the current strategy for GC is conservative (presently _everywhere_, though > this will eventually be limited to just-the-stack) there's on such need: > the GC just spills all registers on entry and treats them as possible-roots > like very other word on the stack. > > If you see the term in our code, it's residue from the most recent > experiment with precise GC, which has been (for the time being) abandoned. > > -Graydon > > -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From rust-dev at tomlee.co Fri May 24 01:44:12 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Fri, 24 May 2013 01:44:12 -0700 Subject: [rust-dev] glue_fns, shims & tydescs In-Reply-To: <20130524001133.GI2245@Mr-Bennet> References: <20130524001133.GI2245@Mr-Bennet> Message-ID: Oh & I'm glad to see that stuff go, Niko. I've been in & around that code recently. In fact, it seems your changes here may be headed for a bunch of conflicts with my work on https://github.com/mozilla/rust/issues/6575 -- perhaps I should defer doing more work until these changes land. Any ETA on that? Cheers, Tom On Thu, May 23, 2013 at 6:33 PM, Niko Matsakis wrote: > Shim functions are an artifact of how we compiled foreign functions. > They are explained a comment in . They are not long > for this world, though: https://github.com/mozilla/rust/pull/6661 > > > Niko > > On Thu, May 23, 2013 at 03:33:24AM -0700, Tom Lee wrote: > > Hey Rustlers, > > > > I'm fighting with issue #6575 > > which > > involves the removal of a useless function parameter emitted during the > > trans phase. I've got a WIP available > > hereif anybody's > > interested, though it does right now is segfault. :) I > > *think *the segfault is the result of me getting something silly wrong & > > somehow the stack is getting messed up in the process (and/or something > is > > getting prematurely collected). > > > > In any case, all this digging around is leaving me with some questions > that > > may or may not be useful to getting this thing to stop segfaulting & > start > > doing something useful. > > > > Can anybody out there offer some clarification about the following? > > > > - What are glue_fns and why are they necessary? How/why do they differ > > from shim_fns (used to invoke foreign functions)? > > > > - What's the purpose of *visit_glue* in the type_desc struct? The > others > > seem largely obvious (take/drop doing some sort of refcounting, free > to > > clean up, but visit ... ?) > > > > - Where are type_descs/tydescs written? The stack? The heap(s)? (i.e. > > anything that can be a GC root?) Where in the source code does this > happen? > > > > - What exactly is a "safe point" wrt the garbage collector? > > > > Appreciate any insight! > > > > Thanks, > > Tom > > > > > > -- > > *Tom Lee */ http://tomlee.co / @tglee > > > _______________________________________________ > > 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 erick.tryzelaar at gmail.com Fri May 24 10:59:45 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Fri, 24 May 2013 10:59:45 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? Message-ID: Good morning everyone, I know there are a couple of us in the San Francisco Bay Area that are working on Rust. Would any of you have interest in a meetup or hackathon sometime? I'm trying to gauge interest so I know how to size the event. If it's just a few of us, I'd be happy to do something informal at a coffee shop/bar/etc, but if there's a lot of interest I'll see if I can find a place we could do presentations. Please email me directly or ping me (erickt) on IRC so we don't spam everyone. Thanks, Erick -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian at linuxfood.net Fri May 24 11:30:46 2013 From: brian at linuxfood.net (Brian Smith) Date: Fri, 24 May 2013 11:30:46 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? In-Reply-To: References: Message-ID: I think that could be pretty fun! On Fri, May 24, 2013 at 10:59 AM, Erick Tryzelaar wrote: > Good morning everyone, > > I know there are a couple of us in the San Francisco Bay Area that are > working on Rust. Would any of you have interest in a meetup or hackathon > sometime? I'm trying to gauge interest so I know how to size the event. If > it's just a few of us, I'd be happy to do something informal at a coffee > shop/bar/etc, but if there's a lot of interest I'll see if I can find a > place we could do presentations. Please email me directly or ping me > (erickt) on IRC so we don't spam everyone. > > Thanks, > Erick > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From banderson at mozilla.com Fri May 24 14:22:50 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 24 May 2013 14:22:50 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? In-Reply-To: References: Message-ID: <519FDA2A.70007@mozilla.com> On 05/24/2013 10:59 AM, Erick Tryzelaar wrote: > Good morning everyone, > > I know there are a couple of us in the San Francisco Bay Area that are > working on Rust. Would any of you have interest in a meetup or > hackathon sometime? I'm trying to gauge interest so I know how to size > the event. If it's just a few of us, I'd be happy to do something > informal at a coffee shop/bar/etc, but if there's a lot of interest > I'll see if I can find a place we could do presentations. Please email > me directly or ping me (erickt) on IRC so we don't spam everyone. > Thanks for taking this initiative. Spamming everyone might be ok since it lets others see that there's interest. For my part I'll attend Rust-related events in the bay area. Summer is a probably a good time for them too since there will be a number of interns in Mountain View who might want to participate. From i at cantor.mx Fri May 24 14:31:18 2013 From: i at cantor.mx (Max Cantor) Date: Fri, 24 May 2013 14:31:18 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? In-Reply-To: <519FDA2A.70007@mozilla.com> References: <519FDA2A.70007@mozilla.com> Message-ID: Oops, didn't reply to all, but +1 for me too. On Fri, May 24, 2013 at 2:22 PM, Brian Anderson wrote: > On 05/24/2013 10:59 AM, Erick Tryzelaar wrote: > >> Good morning everyone, >> >> I know there are a couple of us in the San Francisco Bay Area that are >> working on Rust. Would any of you have interest in a meetup or hackathon >> sometime? I'm trying to gauge interest so I know how to size the event. If >> it's just a few of us, I'd be happy to do something informal at a coffee >> shop/bar/etc, but if there's a lot of interest I'll see if I can find a >> place we could do presentations. Please email me directly or ping me >> (erickt) on IRC so we don't spam everyone. >> >> > Thanks for taking this initiative. > > Spamming everyone might be ok since it lets others see that there's > interest. For my part I'll attend Rust-related events in the bay area. > Summer is a probably a good time for them too since there will be a number > of interns in Mountain View who might want to participate. > > ______________________________**_________________ > 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 hatahet at gmail.com Fri May 24 15:27:02 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Fri, 24 May 2013 15:27:02 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? In-Reply-To: References: <519FDA2A.70007@mozilla.com> Message-ID: I replied in private at the beginning. Too :) +1 -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From erick.tryzelaar at gmail.com Fri May 24 15:31:48 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Fri, 24 May 2013 15:31:48 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? In-Reply-To: <519FDA2A.70007@mozilla.com> References: <519FDA2A.70007@mozilla.com> Message-ID: Glad to help. So far I've heard from 10 others so far, which I think is pretty good for our first one in the bay area. When do the interns start? This could be a good way to introduce them into the community / convince them work on my feature requests :) On Fri, May 24, 2013 at 2:22 PM, Brian Anderson wrote: > On 05/24/2013 10:59 AM, Erick Tryzelaar wrote: > >> Good morning everyone, >> >> I know there are a couple of us in the San Francisco Bay Area that are >> working on Rust. Would any of you have interest in a meetup or hackathon >> sometime? I'm trying to gauge interest so I know how to size the event. If >> it's just a few of us, I'd be happy to do something informal at a coffee >> shop/bar/etc, but if there's a lot of interest I'll see if I can find a >> place we could do presentations. Please email me directly or ping me >> (erickt) on IRC so we don't spam everyone. >> >> > Thanks for taking this initiative. > > Spamming everyone might be ok since it lets others see that there's > interest. For my part I'll attend Rust-related events in the bay area. > Summer is a probably a good time for them too since there will be a number > of interns in Mountain View who might want to participate. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri May 24 15:48:42 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 24 May 2013 15:48:42 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? In-Reply-To: References: <519FDA2A.70007@mozilla.com> Message-ID: <519FEE4A.8040104@mozilla.com> On 05/24/2013 03:31 PM, Erick Tryzelaar wrote: > Glad to help. > > So far I've heard from 10 others so far, which I think is pretty good > for our first one in the bay area. When do the interns start? This > could be a good way to introduce them into the community / convince > them work on my feature requests :) > All the rust interns will be here by 6/10. From rust-dev at tomlee.co Fri May 24 22:06:19 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Fri, 24 May 2013 22:06:19 -0700 Subject: [rust-dev] Anybody in PDX for some Rust-ing? Message-ID: Hey folks, Since the folks in San Francisco seem to be trying to arrange some sort of meetup, I can't help but wonder if there's any similar interest in good ol' Portland, OR? Meetup, hackathon, whatever. My employer's tends to be pretty generous wrt hosting tech events, but if I can get some sort of indication of interest it'd help me make my case. :) Cheers, Tom -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Fri May 24 22:10:49 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Fri, 24 May 2013 22:10:49 -0700 Subject: [rust-dev] Anybody in PDX for some Rust-ing? In-Reply-To: References: Message-ID: On Fri, May 24, 2013 at 10:06 PM, Tom Lee wrote: > Hey folks, > > Since the folks in San Francisco seem to be trying to arrange some sort of > meetup, I can't help but wonder if there's any similar interest in good ol' > Portland, OR? Meetup, hackathon, whatever. > > My employer's tends to be pretty generous wrt hosting tech events, but if I > can get some sort of indication of interest it'd help me make my case. :) > FYI, I'm giving a talk at Open Source Bridge in Portland on (I think) June 19, and I'll be around for a few days before/after. Other Rust team members (but not me) will be at OSCON in July. If a meetup happened to be when I was in town, I'd be happy to show up! Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Not a riot, it's a rebellion." -- Boots Riley "Attention Bros and Trolls: When I call out your spew, I'm not angry, I'm defiant." -- Reg Braithwaite From talex5 at gmail.com Sat May 25 03:09:33 2013 From: talex5 at gmail.com (Thomas Leonard) Date: Sat, 25 May 2013 11:09:33 +0100 Subject: [rust-dev] Owned pointers vs raw pointers (newbie question) Message-ID: Hi, I'm trying to interface to some C code which uses a lot of structs. I can declare these using raw pointers, but then I lose the benefits of Rust's compile-time pointer checking. So I tried replacing the raw pointers with owned pointers, which more accurately captures the meaning of the C interface. But when I do this, the pointers get offset by 32 bytes. Here's my test-case: use core::libc::c_void; struct WithRaw { p: *c_void } struct WithOwned { p: ~c_void } fn main() { let p = unsafe { cast::transmute(100) }; let raw_s = &WithRaw{p: p}; let raw_p = raw_s.p; io::println(fmt!("raw_s.p = %?", raw_p)); let owned_s :&WithOwned = unsafe { cast::transmute(raw_s) }; let owned_p = ptr::to_unsafe_ptr(owned_s.p); io::println(fmt!("owned_s.p = %?", owned_p)); } This prints (rust 0.6): raw_s.p = 100 owned_s.p = 132 This makes me think that owned structures perhaps each have an extra 32 byte header, but I can't imagine why that would be. I thought all the checking of owned pointers happened at compile time? For example, I'd like to replace this: struct xmlNode { name: *i8, ... } with: struct CString; struct xmlNode { name: ~CString, ... } Then I could (I assume) define safe functions on my CString type (len, eq, etc) and not have to worry about memory leaks, etc when using them from safe code. Is this possible? Thanks, -- Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA From ben at 0x539.de Sat May 25 04:03:37 2013 From: ben at 0x539.de (Benjamin Herr) Date: Sat, 25 May 2013 13:03:37 +0200 Subject: [rust-dev] Owned pointers vs raw pointers (newbie question) In-Reply-To: References: Message-ID: <1369479817.2353.21.camel@vigil> On Sat, 2013-05-25 at 11:09 +0100, Thomas Leonard wrote: > Hi, Hi! > I'm trying to interface to some C code which uses a lot of structs. I > can declare these using raw pointers, but then I lose the benefits of > Rust's compile-time pointer checking. So I tried replacing the raw > pointers with owned pointers, which more accurately captures the > meaning of the C interface. But when I do this, the pointers get > offset by 32 bytes. > > [...] Yeah, there's currently some overhead for owned boxes. From what I understand, they share the structure of the refcounted managed boxes with most of the fields nulled out (there's a struct to that effect in https://github.com/mozilla/rust/blob/incoming/src/libstd/managed.rs#L17 I believe). I figure this is because managed boxes were there first, and owned boxes kind of grew out of them, and this is going to change eventually when someone gets around to it... > For example, I'd like to replace this: > > struct xmlNode { > name: *i8, > ... > } > > with: > > struct CString; > > struct xmlNode { > name: ~CString, > ... > } > > Then I could (I assume) define safe functions on my CString type (len, > eq, etc) and not have to worry about memory leaks, etc when using them > from safe code. > > Is this possible? I don't believe this is possible in general even accounting for the box headers somehow because rust isn't promising what malloc/free implementation it is using for owned pointers. Maybe someone else has a better idea, but you could wrap the unsafe pointer into a struct with a safe interface and an impl for the Drop trait that calls libc's free() for much the same semantics, if a bit more awkward syntax. I think a type like this ought to be in libextra at some point, but I don't think there is yet. https://github.com/mozilla/rust/blob/incoming/src/libextra/rc.rs does something similar with refcounting instead of unique ownership semantics, maybe that's a starting point. Good luck, Benjamin Herr From talex5 at gmail.com Sat May 25 05:04:09 2013 From: talex5 at gmail.com (Thomas Leonard) Date: Sat, 25 May 2013 13:04:09 +0100 Subject: [rust-dev] Owned pointers vs raw pointers (newbie question) In-Reply-To: <1369479817.2353.21.camel@vigil> References: <1369479817.2353.21.camel@vigil> Message-ID: On 25 May 2013 12:03, Benjamin Herr wrote: > On Sat, 2013-05-25 at 11:09 +0100, Thomas Leonard wrote: >> Hi, > > Hi! > >> I'm trying to interface to some C code which uses a lot of structs. I >> can declare these using raw pointers, but then I lose the benefits of >> Rust's compile-time pointer checking. So I tried replacing the raw >> pointers with owned pointers, which more accurately captures the >> meaning of the C interface. But when I do this, the pointers get >> offset by 32 bytes. >> >> [...] > > Yeah, there's currently some overhead for owned boxes. From what I > understand, they share the structure of the refcounted managed boxes > with most of the fields nulled out (there's a struct to that effect in > https://github.com/mozilla/rust/blob/incoming/src/libstd/managed.rs#L17 > I believe). > > I figure this is because managed boxes were there first, and owned boxes > kind of grew out of them, and this is going to change eventually when > someone gets around to it... Oh, OK. >> For example, I'd like to replace this: >> >> struct xmlNode { >> name: *i8, >> ... >> } >> >> with: >> >> struct CString; >> >> struct xmlNode { >> name: ~CString, >> ... >> } >> >> Then I could (I assume) define safe functions on my CString type (len, >> eq, etc) and not have to worry about memory leaks, etc when using them >> from safe code. >> >> Is this possible? > > I don't believe this is possible in general even accounting for the box > headers somehow because rust isn't promising what malloc/free > implementation it is using for owned pointers. Wouldn't that be up to the constructor/finalizer for CString (if any)? But in this case, the way you use the API is: let doc: ~XmlDoc = xmlParseFile("test.xml"); let cur: &xmlNode = xmlDocGetRootElement(doc); XmlDoc is a Rust struct which wraps the C one, freeing the whole document when done. xmlNode is the actual C struct. So you never get a ~xmlNode, just a borrowed &xmlNode, and therefore Rust should never try to free any items that were allocated by the C library. Code using the library should be able to explore the tree freely within the lifetime of the borrowed root node, I think. On the other hand, providing mutable access might require a different API. If CString had constructors and destructors then they could ensure that they used malloc/free, and maybe then allow direct access to the C struct. Or maybe all mutations should go via wrapper functions. > Maybe someone else has a better idea, but you could wrap the unsafe > pointer into a struct with a safe interface and an impl for the Drop > trait that calls libc's free() for much the same semantics, if a bit > more awkward syntax. I think a type like this ought to be in libextra at > some point, but I don't think there is yet. > > https://github.com/mozilla/rust/blob/incoming/src/libextra/rc.rs does > something similar with refcounting instead of unique ownership > semantics, maybe that's a starting point. Thanks, -- Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA From erick.tryzelaar at gmail.com Sat May 25 05:29:37 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Sat, 25 May 2013 05:29:37 -0700 Subject: [rust-dev] Owned pointers vs raw pointers (newbie question) In-Reply-To: References: <1369479817.2353.21.camel@vigil> Message-ID: In cases like this the normal thing to do is to make the C structures private and expose an abstract interface. Check out my zeromq binding, it might be helpful: https://github.com/erickt/rust-zmq/blob/master/zmq.rc In your case with xmlParseFile, I would suggest not returning a pointer at all, but return an value with the C structure hidden inside of it with a destructor to free any memory associated with it. That will allow someone to mutate it or store it into various boxes: let mut doc1 = xmlParseFile("text.xml"); let doc2 = ~xmlParseFile("text.xml"); let doc3 = @mut xmlParseFile("text.xml"); On Sat, May 25, 2013 at 5:04 AM, Thomas Leonard wrote: > On 25 May 2013 12:03, Benjamin Herr wrote: > > On Sat, 2013-05-25 at 11:09 +0100, Thomas Leonard wrote: > >> Hi, > > > > Hi! > > > >> I'm trying to interface to some C code which uses a lot of structs. I > >> can declare these using raw pointers, but then I lose the benefits of > >> Rust's compile-time pointer checking. So I tried replacing the raw > >> pointers with owned pointers, which more accurately captures the > >> meaning of the C interface. But when I do this, the pointers get > >> offset by 32 bytes. > >> > >> [...] > > > > Yeah, there's currently some overhead for owned boxes. From what I > > understand, they share the structure of the refcounted managed boxes > > with most of the fields nulled out (there's a struct to that effect in > > https://github.com/mozilla/rust/blob/incoming/src/libstd/managed.rs#L17 > > I believe). > > > > I figure this is because managed boxes were there first, and owned boxes > > kind of grew out of them, and this is going to change eventually when > > someone gets around to it... > > Oh, OK. > > >> For example, I'd like to replace this: > >> > >> struct xmlNode { > >> name: *i8, > >> ... > >> } > >> > >> with: > >> > >> struct CString; > >> > >> struct xmlNode { > >> name: ~CString, > >> ... > >> } > >> > >> Then I could (I assume) define safe functions on my CString type (len, > >> eq, etc) and not have to worry about memory leaks, etc when using them > >> from safe code. > >> > >> Is this possible? > > > > I don't believe this is possible in general even accounting for the box > > headers somehow because rust isn't promising what malloc/free > > implementation it is using for owned pointers. > > Wouldn't that be up to the constructor/finalizer for CString (if any)? > > But in this case, the way you use the API is: > > let doc: ~XmlDoc = xmlParseFile("test.xml"); > let cur: &xmlNode = xmlDocGetRootElement(doc); > > XmlDoc is a Rust struct which wraps the C one, freeing the whole > document when done. xmlNode is the actual C struct. > > So you never get a ~xmlNode, just a borrowed &xmlNode, and therefore > Rust should never try to free any items that were allocated by the C > library. Code using the library should be able to explore the tree > freely within the lifetime of the borrowed root node, I think. > > On the other hand, providing mutable access might require a different > API. If CString had constructors and destructors then they could > ensure that they used malloc/free, and maybe then allow direct access > to the C struct. Or maybe all mutations should go via wrapper > functions. > > > Maybe someone else has a better idea, but you could wrap the unsafe > > pointer into a struct with a safe interface and an impl for the Drop > > trait that calls libc's free() for much the same semantics, if a bit > > more awkward syntax. I think a type like this ought to be in libextra at > > some point, but I don't think there is yet. > > > > https://github.com/mozilla/rust/blob/incoming/src/libextra/rc.rs does > > something similar with refcounting instead of unique ownership > > semantics, maybe that's a starting point. > > > Thanks, > > -- > Dr Thomas Leonard http://0install.net/ > GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 > GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA > _______________________________________________ > 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 garethdanielsmith at gmail.com Sat May 25 11:36:19 2013 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Sat, 25 May 2013 19:36:19 +0100 Subject: [rust-dev] bors feature requests In-Reply-To: <518C432D.1040005@mozilla.com> References: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> <518C432D.1040005@mozilla.com> Message-ID: <51A104A3.5000405@gmail.com> On 10/05/13 01:45, Graydon Hoare wrote: > On 13-05-07 08:09 AM, Sanghyeon Seo wrote: >> Here are some feature requests to bors queue status page at >> http://buildbot.rust-lang.org/bors/bors.html >> >> 3. OUTDATED state, for pull requests that need to be rebased. GitHub >> API provides "mergeable" attribute for this. > I've fixed #1 and #3 today (as well as adding last-comments and a > DISCUSSING state). I'll look into #2 soon. Thanks for the feedback. I am guessing that STALE on http://buildbot.rust-lang.org/bors/bors.html means "needs rebase" - right? How does a pull request leave the STALE state? Does it have to be reviewed again or will the status update automatically at some point after rebasing? I have rebased https://github.com/mozilla/rust/pull/6433 but it still shows as STALE. Thanks Gareth From corey at octayn.net Sat May 25 12:02:27 2013 From: corey at octayn.net (Corey Richardson) Date: Sat, 25 May 2013 15:02:27 -0400 Subject: [rust-dev] bors feature requests In-Reply-To: <51A104A3.5000405@gmail.com> References: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> <518C432D.1040005@mozilla.com> <51A104A3.5000405@gmail.com> Message-ID: On Sat, May 25, 2013 at 2:36 PM, Gareth Smith wrote: > I am guessing that STALE on http://buildbot.rust-lang.org/bors/bors.html > means "needs rebase" - right? > Yes > How does a pull request leave the STALE state? Does it have to be reviewed > again or will the status update automatically at some point after rebasing? > I have rebased https://github.com/mozilla/rust/pull/6433 but it still shows > as STALE. > It needs to be r+'d again. From isaac.aggrey at gmail.com Sat May 25 18:37:48 2013 From: isaac.aggrey at gmail.com (Isaac Aggrey) Date: Sat, 25 May 2013 20:37:48 -0500 Subject: [rust-dev] Development Policy re: bug assignment Message-ID: Hi rust-dev, I thought we should have a brief discussion on the development policy, specifically about bug assignment (from the perspective of a new contributor to the Rust codebase). # Motivation I had a working patch for fixing a small Rust issue (my first Rust bug) at one point before some major compiler changes stalled my patch as I was waiting it out, but I did my best to continue to express my intent to finish the bug fix. However, another contributor (not core team but GitHub collaborator privileges) recently decided to submit their request and bors happily ran off to integrate it. Of course, working code beats non-pull requested code any day, but I did leave disappointed nonetheless. # The Problem Unfortunately, GitHub does not allow bug assignment to non-collaborators, but I do not believe I could have been clearer that I was working on the bug (first comment, referenced the bug in another issue). For what it's worth, they acknowledged they still did not realize the bug was taken, so we did a bit of yo-yoing on who exactly was going to work on it since their code wasn't quite there yet until the next snapshot either, but we seemed to agree that I would wrap up the bug AFAICT. Moreover, the bug was a very simple one and not on the block for 0.7, so that is all the more reason for it to not have been pressing to work on. To avoid sounding like I'm crying over spilled milk, I am entirely on board if someone has code that already works and encourage more frequent contributions to Rust, but this is all to say I believe the situation could have been avoided if we could adopt more formal bug assignment. tl;dr The current development policy [1] is if a bug is unassigned, then it is fair game so long as you comment on the bug (for non-collaborators). From my experience, I feel this system is insufficient in identifying bug owners. # Potential Solutions * Transfer Mozilla to an organization account [2] (may already be the case) then add the potential bug fixer as a read-only collaborator in order to gain the ability to officially assign them to the bug - Downsides: with a busy core team, this could get unwieldy very quickly to add read-only contributors who may not even finish fixing their bug * Stick with commenting on bugs, but do what some projects have adopted: Assigned to @foouser so at least foouser can filter issues according to "mentioning you". - Downsides: this "solution" is the same policy with a bit more formality and all of the same flaws # Conclusion I doubt this is a pervasive issue in the community and it's most likely my little exposure to OSS development that leaves me a bit sensitive, especially as I've only contributed some code cleanups to Firefox so far. However, Bugzilla (and all its faults) at least makes it clear if someone is working on a bug/issue, and I think it would be valuable if we adopt a solution that will prevent future contributors from feeling as if they are in a race to pull request first. [1]: https://github.com/mozilla/rust/wiki/Note-development-policy#getting-involved-how-to-pick-your-first-bug [2]: https://github.com/blog/674-introducing-organizations Sincerely, Isaac Aggrey From catamorphism at gmail.com Sat May 25 19:11:58 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Sat, 25 May 2013 19:11:58 -0700 Subject: [rust-dev] Development Policy re: bug assignment In-Reply-To: References: Message-ID: I agree that this is a real concern. It may not be happening very often so far, but it's a seriously bad feeling to find that someone else has gone ahead and done the same work you were making headway on (regardless of intent). I think if it's possible on github, we should have a way for any contributor to assign a bug to themself. We should also have guidelines about what happens if someone assigned to a bug goes missing for several months and doesn't respond to communication. We should probably also write down what expectations go along with assignment (for example, I've used assigning-to-myself as a way of signaling "I intend to work on this", but more recently people have implied that you should only take a bug when actively working on it. Either is ok as long as it's made explicit). Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Not a riot, it's a rebellion." -- Boots Riley "Attention Bros and Trolls: When I call out your spew, I'm not angry, I'm defiant." -- Reg Braithwaite From rust-dev at tomlee.co Sat May 25 23:48:32 2013 From: rust-dev at tomlee.co (Tom Lee) Date: Sat, 25 May 2013 23:48:32 -0700 Subject: [rust-dev] Anybody in PDX for some Rust-ing? In-Reply-To: References: Message-ID: Sounds awesome Tim. Either way, let me know when you're in town -- I'm not attending OSBridge, but it'd be good to put a face to the name. If there's interest in a PDX Rust meetup for either June or July, all the better. Cheers, Tom On Fri, May 24, 2013 at 10:10 PM, Tim Chevalier wrote: > On Fri, May 24, 2013 at 10:06 PM, Tom Lee wrote: > > Hey folks, > > > > Since the folks in San Francisco seem to be trying to arrange some sort > of > > meetup, I can't help but wonder if there's any similar interest in good > ol' > > Portland, OR? Meetup, hackathon, whatever. > > > > My employer's tends to be pretty generous wrt hosting tech events, but > if I > > can get some sort of indication of interest it'd help me make my case. :) > > > > FYI, I'm giving a talk at Open Source Bridge in Portland on (I think) > June 19, and I'll be around for a few days before/after. Other Rust > team members (but not me) will be at OSCON in July. If a meetup > happened to be when I was in town, I'd be happy to show up! > > Cheers, > Tim > > -- > Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt > "Not a riot, it's a rebellion." -- Boots Riley > "Attention Bros and Trolls: When I call out your spew, I'm not angry, > I'm defiant." -- Reg Braithwaite > -- *Tom Lee */ http://tomlee.co / @tglee -------------- next part -------------- An HTML attachment was scrubbed... URL: From garethdanielsmith at gmail.com Sun May 26 01:48:50 2013 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Sun, 26 May 2013 09:48:50 +0100 Subject: [rust-dev] bors feature requests In-Reply-To: References: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> <518C432D.1040005@mozilla.com> <51A104A3.5000405@gmail.com> Message-ID: <51A1CC72.5020609@gmail.com> On 25/05/13 20:02, Corey Richardson wrote: > On Sat, May 25, 2013 at 2:36 PM, Gareth Smith > wrote: >> I am guessing that STALE on http://buildbot.rust-lang.org/bors/bors.html >> means "needs rebase" - right? >> > Yes > >> How does a pull request leave the STALE state? Does it have to be reviewed >> again or will the status update automatically at some point after rebasing? >> I have rebased https://github.com/mozilla/rust/pull/6433 but it still shows >> as STALE. >> > It needs to be r+'d again. I see. Thanks. By the time it gets reviewed, though, it will probably already need a rebase... which will require another review, by which time it may need another rebase... There is probably no easy solution to this, but maybe bors can help? Gareth From corey at octayn.net Sun May 26 03:57:09 2013 From: corey at octayn.net (Corey Richardson) Date: Sun, 26 May 2013 06:57:09 -0400 Subject: [rust-dev] bors feature requests In-Reply-To: <51A1CC72.5020609@gmail.com> References: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> <518C432D.1040005@mozilla.com> <51A104A3.5000405@gmail.com> <51A1CC72.5020609@gmail.com> Message-ID: On Sun, May 26, 2013 at 4:48 AM, Gareth Smith wrote: > > By the time it gets reviewed, though, it will probably already need a > rebase... which will require another review, by which time it may need > another rebase... There is probably no easy solution to this, but maybe bors > can help? > Ask "r? " in IRC during daytime PST, usually you get a review real fast that way :) From lindsey at composition.al Sun May 26 22:23:54 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Mon, 27 May 2013 01:23:54 -0400 Subject: [rust-dev] Documentation, completeness & cross-reference hyperlinks? In-Reply-To: <3E9E14E5-C2C0-409C-9A6C-17DAF5AF9F1F@masklinn.net> References: <83BC5FF7-7A87-45D2-94EA-A4DA0608BDA5@masklinn.net> <51993E3E.2090303@mozilla.com> <5199BA03.2090209@arrownext.com> <3E9E14E5-C2C0-409C-9A6C-17DAF5AF9F1F@masklinn.net> Message-ID: On Mon, May 20, 2013 at 2:51 AM, Masklinn wrote: > Yesterday as I was trying to provide more info/background for an > answer to the list, I encountered an issue which I think is going > to hinder lots of people trying out rust: using the documentation > is an exercise in frustration. Yes, I think most people on this list will agree with you that the docs need a lot of work. I filed issues (linked below) for some of the specific problems you described. > 1. I wanted to see all the built-in ways to use Option (aside > from simply pattern-matching on None and Some), for this I > went to the corresponding doc page > http://static.rust-lang.org/doc/0.6/core/option.html. Although > probably not the worst by a long shot, this page still > demonstrates a number of issues: > > - None of the methods provides examples showing off their > purpose and how they can improve code. [...] I didn't file an issue for this because it isn't something that I expect will ever be "done". It is, however, something people can start to fix right away. Adding more examples to the docs is also a low-barrier-to-entry way for someone new to start contributing to Rust. > - The only examples could actually be simpler if replaced by > using one of Option's methods, e.g. I believe the second > example > > let unwrapped_msg = match msg { > Some(m) => m, > None => ~"default message" > }; > > could have been written: > > let unwrapped_msg = msg.get_or_default(~"default message"); This, among other things, can go into a patch I'm working on to update and expand the option.rs docs. Thanks. > (and the example is incorrect in the first place, the > compiler rejects `Some(ref m) => io::println(m)`, this > should be `Some(ref m) => io::println(*m)`) It seems like the thing to do here is to extract and run code examples in the library docs, as we do already for the tutorial and manual. There's an open bug for this: https://github.com/mozilla/rust/issues/2925 This would at least make sure that the code examples compile and run without error. (Checking that the running code has the behavior we expect it to is another question, but we don't even do that now for the rest of the test suite.) > - The uniform color scheme, font and indentation make it hard > to notice e.g. admonitions (several methods will fail on a > None, have a note indicating it, but the node melds into the > rest of the document) Issue filed: https://github.com/mozilla/rust/issues/6759 > - None of the method is hyperlinked from the module's top (or > some sort of sidebar) and it's impossible to get a link to > them short of inspecting the page's HTML source Issue filed: https://github.com/mozilla/rust/issues/6760 > 2. Missing cross-section hyperlinks and references. There I was > looking for the various formats available in fmt!. fmt! is > mentioned and used extensively in the Rust tutorial[0] and is > also listed as an example macro in the reference manual[1]. > > Yet *not one* of the mentions is hyperlinked to any > specification or documentation for it. > > [...] > > Having "short syntaxes" for object-aware hyperlinks (e.g. being > able to easily link to the definition/documentation of a macro, > module, function, type or method) Issue filed: https://github.com/mozilla/rust/issues/6758 Lindsey From graydon at mozilla.com Mon May 27 12:04:04 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 27 May 2013 12:04:04 -0700 Subject: [rust-dev] bors feature requests In-Reply-To: <51A104A3.5000405@gmail.com> References: <29910398.291621367939351105.JavaMail.weblogic@epv6ml01> <518C432D.1040005@mozilla.com> <51A104A3.5000405@gmail.com> Message-ID: <51A3AE24.9060100@mozilla.com> On 13-05-25 11:36 AM, Gareth Smith wrote: > On 10/05/13 01:45, Graydon Hoare wrote: >> On 13-05-07 08:09 AM, Sanghyeon Seo wrote: >>> Here are some feature requests to bors queue status page at >>> http://buildbot.rust-lang.org/bors/bors.html >>> >>> 3. OUTDATED state, for pull requests that need to be rebased. GitHub >>> API provides "mergeable" attribute for this. >> I've fixed #1 and #3 today (as well as adding last-comments and a >> DISCUSSING state). I'll look into #2 soon. Thanks for the feedback. > > I am guessing that STALE on http://buildbot.rust-lang.org/bors/bors.html > means "needs rebase" - right? > > How does a pull request leave the STALE state? Does it have to be > reviewed again or will the status update automatically at some point > after rebasing? I have rebased https://github.com/mozilla/rust/pull/6433 > but it still shows as STALE. Interesting. That pull req is closed but ... it should not be happening. It should only say STALE if it's in the state where github says it can't be merged (i.e. "We can?t automatically merge this pull request. to resolve conflicts before continuing."). That's the API we're asking, anyways! Once un-STALE, it should go back to UNREVIEWED or DISCUSSING. I now see what while _most_ of the current STALE requests are like that, one in particular (https://github.com/mozilla/rust/pull/6703) is not. So this is either a github API problem or a bug in bors. I'll look into it shortly. Thanks for reporting it. -Graydon From me at kevincantu.org Mon May 27 16:27:24 2013 From: me at kevincantu.org (Kevin Cantu) Date: Mon, 27 May 2013 16:27:24 -0700 Subject: [rust-dev] Any interest in a San Francisco Bay Area Rust meetup and/or hackathon? In-Reply-To: <519FEE4A.8040104@mozilla.com> References: <519FDA2A.70007@mozilla.com> <519FEE4A.8040104@mozilla.com> Message-ID: Count me in. :) Kevin -- Kevin Cantu On Fri, May 24, 2013 at 3:48 PM, Brian Anderson wrote: > On 05/24/2013 03:31 PM, Erick Tryzelaar wrote: > >> Glad to help. >> >> So far I've heard from 10 others so far, which I think is pretty good for >> our first one in the bay area. When do the interns start? This could be a >> good way to introduce them into the community / convince them work on my >> feature requests :) >> >> > All the rust interns will be here by 6/10. > > ______________________________**_________________ > 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 a.stavonin at gmail.com Tue May 28 02:45:24 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Tue, 28 May 2013 13:45:24 +0400 Subject: [rust-dev] Do we have shared ports? Message-ID: Hi! As I know, As I know, we have SharedChan mechanism which can be used for "many clients -> server" communications. But how can I send response from server to many clients? This is not commonly used case, and looks like there is no such mechanism or I've missed something? Best regards, Alexander. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Tue May 28 09:24:55 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Tue, 28 May 2013 18:24:55 +0200 Subject: [rust-dev] Do we have shared ports? In-Reply-To: References: Message-ID: Hi, I am not quite sure whether you are asking for a multi-cast feature (all clients receive a copy of the message) or for a send-to-one-among feature (in which one of the available client would pick up the message). Could you elaborate ? -- Matthieu On Tue, May 28, 2013 at 11:45 AM, Alexander Stavonin wrote: > Hi! > > As I know, As I know, we have SharedChan mechanism which can be used for > "many clients -> server" communications. But how can I send response from > server to many clients? This is not commonly used case, and looks like > there is no such mechanism or I've missed something? > > Best regards, > Alexander. > > _______________________________________________ > 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 a.stavonin at gmail.com Tue May 28 11:36:15 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Tue, 28 May 2013 22:36:15 +0400 Subject: [rust-dev] Do we have shared ports? In-Reply-To: References: Message-ID: Yes, I'm interesting in multi-cast feature. Best regards, Alexander. On May 28, 2013, at 20:24, Matthieu Monrocq wrote: > Hi, > > I am not quite sure whether you are asking for a multi-cast feature (all clients receive a copy of the message) or for a send-to-one-among feature (in which one of the available client would pick up the message). > > Could you elaborate ? > > -- Matthieu > > > On Tue, May 28, 2013 at 11:45 AM, Alexander Stavonin wrote: >> Hi! >> >> As I know, As I know, we have SharedChan mechanism which can be used for "many clients -> server" communications. But how can I send response from server to many clients? This is not commonly used case, and looks like there is no such mechanism or I've missed something? >> >> Best regards, >> Alexander. >> >> _______________________________________________ >> 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 banderson at mozilla.com Tue May 28 11:44:38 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 28 May 2013 11:44:38 -0700 Subject: [rust-dev] Do we have shared ports? In-Reply-To: References: Message-ID: <51A4FB16.1070101@mozilla.com> On 05/28/2013 02:45 AM, Alexander Stavonin wrote: > Hi! > > As I know, As I know, we have SharedChan mechanism which can be used > for "many clients -> server" communications. But how can I send > response from server to many clients? This is not commonly used case, > and looks like there is no such mechanism or I've missed something? There isn't a type defined for this currently. From mcguire at crsr.net Tue May 28 11:48:55 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Tue, 28 May 2013 13:48:55 -0500 Subject: [rust-dev] Question about lifetimes in type parameters Message-ID: <51A4FC17.6090803@crsr.net> I have a largeish buffer containing bytes that I would like to avoid copying. The first thing I have to do with this buffer is parse it into a hashmap structure. To that end, I have the following function: fn line_map<'b>(buffer : &'b [u8]) -> ~LinearMap<&'b [u8],&'b [u8]> {...} The problem I am running into is that the type of the LinearMap's find() method (Yes, this is 0.6.) is: fn find(&self, k: &&'b [u8]) -> Option<&'self &'b [u8]> In other words, the key argument is a borrowed pointer to a borrowed pointer to a vector with the same lifetime as the buffer. That argument is kind of difficult to provide. What am I doing wrong? Is there a better way? -- Tommy M. McGuire mcguire at crsr.net From daniel at fdr.io Tue May 28 12:09:21 2013 From: daniel at fdr.io (Daniel Farina) Date: Tue, 28 May 2013 12:09:21 -0700 Subject: [rust-dev] zero.rs compilation problems, involving pthreads Message-ID: I don't understand rust's compilation model very well, but I am left confused as to how to compile the example program (hello) included with zero.rs using a recent 'incoming' commit (05735a934a807333f9cbeadd9ef4dc 431240bec2). For some reason it seems like the object file is referencing pthreads et al: $ rust build hello.rs error: linking with `cc` failed with code 1 note: cc arguments: -L/home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib -m64 -o hello hello.o -lrt -ldl -lm -lmorestack -lrustrt -Wl,-rpath,$ORIGIN/../../home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib -Wl,-rpath,/home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib note: /home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so: undefined reference to `sem_init' /home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so: undefined reference to `pthread_mutex_trylock' /home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so: undefined reference to `pthread_rwlock_trywrlock' etcetera etcetera error: aborting due to previous error Is that expected, or am I in error? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Tue May 28 13:53:50 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 28 May 2013 16:53:50 -0400 Subject: [rust-dev] Null-terminated strings and str::as_c_str() Message-ID: A few days ago I submitted a pull request to convert str::as_c_str() from a function into a method on strings: https://github.com/mozilla/rust/pull/6729 And today in IRC there was a discussion regarding the fact that Rust's strings are null-terminated: https://botbot.me/mozilla/rust/msg/3466672/ The impression that I'm getting from each is that this aspect of Rust's C interop appears to have no concrete design, so I figured I'd bring this up on the mailing list. Some questions I'd like to definitively answer: 1) What should the API look like for providing strings to C code? 2) Should Rust continue to null-terminate all strings for the sake of C compatibility? -------------- next part -------------- An HTML attachment was scrubbed... URL: From fedor at indutny.com Tue May 28 14:15:55 2013 From: fedor at indutny.com (Fedor Indutny) Date: Wed, 29 May 2013 01:15:55 +0400 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: On what platform are you trying to compile it? Is it a linux? Cheers, Fedor. On Tue, May 28, 2013 at 11:09 PM, Daniel Farina wrote: > I don't understand rust's compilation model very well, but I am left > confused as to how to compile the example program (hello) included with > zero.rs using a recent 'incoming' commit (05735a934a807333f9cbeadd9ef4dc > 431240bec2). > > For some reason it seems like the object file is referencing pthreads et > al: > > $ rust build hello.rs > error: linking with `cc` failed with code 1 > note: cc arguments: > -L/home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib -m64 -o hello > hello.o -lrt -ldl -lm -lmorestack -lrustrt > -Wl,-rpath,$ORIGIN/../../home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib > -Wl,-rpath,/home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib > note: /home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so: > undefined reference to `sem_init' > /home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so: > undefined reference to `pthread_mutex_trylock' > /home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so: > undefined reference to `pthread_rwlock_trywrlock' > > etcetera etcetera > > error: aborting due to previous error > > Is that expected, or am I in 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 daniel at fdr.io Tue May 28 14:17:52 2013 From: daniel at fdr.io (Daniel Farina) Date: Tue, 28 May 2013 14:17:52 -0700 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: On Tue, May 28, 2013 at 2:15 PM, Fedor Indutny wrote: > On what platform are you trying to compile it? Is it a linux? > Yes. -------------- next part -------------- An HTML attachment was scrubbed... URL: From fedor at indutny.com Tue May 28 14:19:50 2013 From: fedor at indutny.com (Fedor Indutny) Date: Wed, 29 May 2013 01:19:50 +0400 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: Ok, which one and what version? Cheers, Fedor. On Wed, May 29, 2013 at 1:17 AM, Daniel Farina wrote: > On Tue, May 28, 2013 at 2:15 PM, Fedor Indutny wrote: > >> On what platform are you trying to compile it? Is it a linux? >> > > Yes. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel at fdr.io Tue May 28 14:23:23 2013 From: daniel at fdr.io (Daniel Farina) Date: Tue, 28 May 2013 14:23:23 -0700 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: On Tue, May 28, 2013 at 2:19 PM, Fedor Indutny wrote: > Ok, which one and what version? Ubuntu Raring, a.k.a. 13.04 From fedor at indutny.com Tue May 28 14:32:15 2013 From: fedor at indutny.com (Fedor Indutny) Date: Wed, 29 May 2013 01:32:15 +0400 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: It seems that linker flag `-lphtread` is missing... Can you try building it using following line: `rustc --link-args -lpthread`? Cheers, Fedor. On Wed, May 29, 2013 at 1:23 AM, Daniel Farina wrote: > On Tue, May 28, 2013 at 2:19 PM, Fedor Indutny wrote: > > Ok, which one and what version? > > Ubuntu Raring, a.k.a. 13.04 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel at fdr.io Tue May 28 14:40:55 2013 From: daniel at fdr.io (Daniel Farina) Date: Tue, 28 May 2013 14:40:55 -0700 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: On Tue, May 28, 2013 at 2:32 PM, Fedor Indutny wrote: > It seems that linker flag `-lphtread` is missing... Can you try building it > using following line: `rustc --link-args -lpthread`? That helps, but it now complains about missing references to the dynamic linker. I threw in -ldl to make that work, too: $ rustc --link-args '-lpthread -ldl' hello.rs $ ./hello Hello world! However: $ ldd ./hello linux-vdso.so.1 => (0x00007fffb5fce000) librustrt.so => /tmp/zero.rs/./../../home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so (0x00007fd93be33000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd93bbf3000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd93b9ef000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd93b627000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd93b323000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd93b10d000) /lib64/ld-linux-x86-64.so.2 (0x00007fd93c084000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd93ae08000) Are some of these loaded objects at least in part defeating the point of zero.rs? For example, if I try to start hello after removing the runtime (librustrt.so), I get the predictable: ./hello: error while loading shared libraries: librustrt.so: cannot open shared object file: No such file or directory From fedor at indutny.com Tue May 28 14:46:09 2013 From: fedor at indutny.com (Fedor Indutny) Date: Wed, 29 May 2013 01:46:09 +0400 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: Can you post contents of your hello.rs file? Cheers, Fedor. On Wed, May 29, 2013 at 1:40 AM, Daniel Farina wrote: > On Tue, May 28, 2013 at 2:32 PM, Fedor Indutny wrote: > > It seems that linker flag `-lphtread` is missing... Can you try building > it > > using following line: `rustc --link-args -lpthread`? > > That helps, but it now complains about missing references to the > dynamic linker. I threw in -ldl to make that work, too: > > $ rustc --link-args '-lpthread -ldl' hello.rs > $ ./hello > Hello world! > > However: > > $ ldd ./hello > linux-vdso.so.1 => (0x00007fffb5fce000) > librustrt.so => > /tmp/ > zero.rs/./../../home/fdr/rust/lib/rustc/x86_64-unknown-linux-gnu/lib/librustrt.so > (0x00007fd93be33000) > libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 > (0x00007fd93bbf3000) > libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd93b9ef000) > libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd93b627000) > libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 > (0x00007fd93b323000) > libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd93b10d000) > /lib64/ld-linux-x86-64.so.2 (0x00007fd93c084000) > libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd93ae08000) > > Are some of these loaded objects at least in part defeating the point > of zero.rs? For example, if I try to start hello after removing the > runtime (librustrt.so), I get the predictable: > > ./hello: error while loading shared libraries: librustrt.so: cannot > open shared object file: No such file or directory > -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel at fdr.io Tue May 28 14:51:28 2013 From: daniel at fdr.io (Daniel Farina) Date: Tue, 28 May 2013 14:51:28 -0700 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: On Tue, May 28, 2013 at 2:46 PM, Fedor Indutny wrote: > Can you post contents of your hello.rs file? I'm trying to compile https://github.com/pcwalton/zero.rs, which I am using verbatim. From fedor at indutny.com Tue May 28 14:53:30 2013 From: fedor at indutny.com (Fedor Indutny) Date: Wed, 29 May 2013 01:53:30 +0400 Subject: [rust-dev] zero.rs compilation problems, involving pthreads In-Reply-To: References: Message-ID: Ah, sorry. Unfortunately, I've no idea :) Cheers, Fedor. On Wed, May 29, 2013 at 1:51 AM, Daniel Farina wrote: > On Tue, May 28, 2013 at 2:46 PM, Fedor Indutny wrote: > > Can you post contents of your hello.rs file? > > I'm trying to compile https://github.com/pcwalton/zero.rs, which I am > using verbatim. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue May 28 15:06:31 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 28 May 2013 15:06:31 -0700 Subject: [rust-dev] Null-terminated strings and str::as_c_str() In-Reply-To: References: Message-ID: <51A52A67.8060504@mozilla.com> On 28/05/2013 1:53 PM, Benjamin Striegel wrote: > A few days ago I submitted a pull request to convert str::as_c_str() > from a function into a method on strings: > > https://github.com/mozilla/rust/pull/6729 > > And today in IRC there was a discussion regarding the fact that Rust's > strings are null-terminated: > > https://botbot.me/mozilla/rust/msg/3466672/ > > The impression that I'm getting from each is that this aspect of Rust's > C interop appears to have no concrete design, so I figured I'd bring > this up on the mailing list. It has a concrete design, it's just (like many things) underdocumented. My own fault, apologies. Rust ~strs and static strings are null terminated, and &strs are defined as (ptr,len+1) such that they reach one-past-the-end of the data you wish the slice to cover. When they are taken from a null-terminated "full string", the final null is detectable. When they are taken as a sub-slice of some other slice, the final null is missing. When making an as_c_str() sort of call, we check the final null and only strdup if it's missing. This is all intended to minimize the number of strdups we have to do during calls to C. Most &strs originate in full strings and most of the time we want our APIs to pass &str down to the last point, then convert to a C string to pass into an OS or library function. Many C APIs take null-terminated strings. That's just a fact. You can criticize them all you like; they won't spontaneously change. I made this choice a long time ago, around when I was doing the in-place-append optimization for [] and "". Long time. It's fine to be revisiting and questioning it. The main problems with the design are: - It's asymmetric with ~[] and &[] - You don't always _have_ len+1 addressable bytes in a string - It makes performance less predictable - It's easy to forget since it appears to be redundant to hold both null and len I believe Brian has wanted to remove this choice for a long time. I won't fight it either way, though it will take quite a lot of fiddling library code and debugging crashes to get it fixed up. You'll want to use valgrind. It _will_ also cost new strdups on many C boundaries, if we fix it. Maybe that's ok. Potential performance traps are worth measuring rather than speculating about. One possibility to mitigate a performance problem, if it arises, is to make a small-but-fixed size buffer on the as_c_str() path so that for < N byte strings you can copy to the stack. Another would be to keep an arena around for the purpose; we should probably have TLS-based arena for non-escaping dynamic allocations anyways, it keeps coming up. -Graydon From alex at crichton.co Tue May 28 21:03:09 2013 From: alex at crichton.co (Alex Crichton) Date: Tue, 28 May 2013 23:03:09 -0500 Subject: [rust-dev] A case for removing rusti Message-ID: I've been tinkering with rusti recently, and I'm reaching the conclusion that it should be removed entirely from the compiler. As many people are probably aware, rusti hasn't been working fantastically for awhile now, but that's only partially why I think that it should be removed. - What I think a REPL should be In my opinion, the point of rusti is to be a REPL for rust. I type in valid rust code and it spits out the results. This all works today, except for the fact that it's not a REPL in the sense of what other languages have. I'm most familiar with ruby's irb, so these opinions will be derived from that. When using a REPL, I imagine that there's a flow of execution that's just pausing for a very long time between lines (waiting for input). What this means is that if I've defined any variables or functions previously, they're still available to me at the current line. Not only that, but nothing is "re-run" in the sense that if the previous line calculated fib(50), I don't want each line I enter into the repl to calculate again fib(50) for some reason. - What rusti is The way that rusti works today in my opinion is a bit hacky once you look inside. It will take your line of input, fmt! it into a template, and then compile the whole template (via rustc using LLVM). After compilation is successful, it walks down the ast to figure out what you just input, and it then records that line of input in its history *as a string*. What this means is that for the second line of input to rusti, it will put both the history and the input into the template, and re-run all the code again. Now this doesn't sound that bad in theory. Normally rusti is for quick computations. There's not much of a history and nothing really takes a long time. This quickly becomes a problem though for anything which uses resources. Let's say that you call io::println. Do you really want that statement executed every time you enter a line into rusti? What if you opened a file or a network connection? In my opinion, re-running code is unacceptable. This actually glosses over the fact that rusti currently doesn't even save all input. It only saves declarations and definitions right now. I made a patch to save assignments as well, but that still doesn't work in all situations. I don't believe that there's a good way to "filter the code" such that you "only get what you want" (which is what rusti currently attempts). - Can rusti be my version of a REPL? Basically what all that means is that rusti has to save the world's state between your lines of input to be my version of a REPL. To the best of my knowledge (which could very well be wrong), this is not possible to do in Rust. This leads me to the conclusion that rusti cannot be a true REPL (at least the way I see a REPL). In my opinion, this also means that rusti should be discarded. If someone new comes to rust and tries out the fancy 'rusti' command, they'll start to play around but very quickly run into some odd scenario that doesn't match what they think. After playing around for awhile, they may realize that the "REPL" is behaving oddly, or they'll just leave entirely. Regardless, no one is going to get what they're expecting when they run rusti. If no one gets what they want when they run it, and I don't believe that anyone can ever actually get what they want, I don't think that there's a reason to keep it around as a tool that is built into rust. I believe that the 'rust run' command is an excellent alternative. No, it's not as fast as rusti, but it's correct and you know exactly what's happening. I don't necessarily think that this warrants the removal of the "-Z jit" flag either, but it makes me seriously question whether it's worth maintaining that code. So that's all just my own personal opinion. I was wondering what other people thought about this course of action? If anyone has questions about how rusti currently works, I can also do my best to answer those as well. From zack at z0w0.me Tue May 28 21:44:58 2013 From: zack at z0w0.me (Zack Corr) Date: Wed, 29 May 2013 14:44:58 +1000 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: Message-ID: Disclaimer: I may be slightly biased because I originally committed the rusti code. I think the general conclusion you've come to here is that a tool that is explicitly marked as experimental is in fact, experimental. Good language tools, especially REPLs, don't pop up into existence out of nowhere. They need to be polished over time with the language itself. rusti is certainly unstable, but this is not the fault of the tool but the way the compiler works. I knew that pretty printing history into a big list of strings was a bad way for it to work, but there was no other way to make it work at the time. Each compiler instance (i.e. every time a line was inputted) had to be run on a separate task every time, so the history had to be sendable. A better alternative would have been to store the history as AST (so it didn't need to be parsed each time, only compiled), but that wasn't sendable. As far as I know, each compiler instance no longer needs to be on a separate task so this could probably be used instead now. In my opinion, rusti gets the job done. Yes, having in-memory compiled state would work a lot better. But I don't know how viable that is. I know for a fact that a big feature plan is to have the compiler only partially compile when applicable, i.e. only compile things are actually important. That would help drastically here. And no-no-no, I think removing the JIT backend is a really bad idea. That sort of thing is really useful and removing it now is not going to be productive. There has been much work from the community recently to improve rusti and the JIT compiler. I think once Mozilla setup automated testing of the JIT compiler it could easily be polished and have all tests green under it, which would be great. On Wed, May 29, 2013 at 2:03 PM, Alex Crichton wrote: > I've been tinkering with rusti recently, and I'm reaching the > conclusion that it should be removed entirely from the compiler. As > many people are probably aware, rusti hasn't been working > fantastically for awhile now, but that's only partially why I think > that it should be removed. > > - What I think a REPL should be > > In my opinion, the point of rusti is to be a REPL for rust. I type in > valid rust code and it spits out the results. This all works today, > except for the fact that it's not a REPL in the sense of what other > languages have. I'm most familiar with ruby's irb, so these opinions > will be derived from that. > > When using a REPL, I imagine that there's a flow of execution that's > just pausing for a very long time between lines (waiting for input). > What this means is that if I've defined any variables or functions > previously, they're still available to me at the current line. Not > only that, but nothing is "re-run" in the sense that if the previous > line calculated fib(50), I don't want each line I enter into the repl > to calculate again fib(50) for some reason. > > - What rusti is > > The way that rusti works today in my opinion is a bit hacky once you > look inside. It will take your line of input, fmt! it into a template, > and then compile the whole template (via rustc using LLVM). After > compilation is successful, it walks down the ast to figure out what > you just input, and it then records that line of input in its history > *as a string*. What this means is that for the second line of input to > rusti, it will put both the history and the input into the template, > and re-run all the code again. > > Now this doesn't sound that bad in theory. Normally rusti is for quick > computations. There's not much of a history and nothing really takes a > long time. This quickly becomes a problem though for anything which > uses resources. Let's say that you call io::println. Do you really > want that statement executed every time you enter a line into rusti? > What if you opened a file or a network connection? In my opinion, > re-running code is unacceptable. > > This actually glosses over the fact that rusti currently doesn't even > save all input. It only saves declarations and definitions right now. > I made a patch to save assignments as well, but that still doesn't > work in all situations. I don't believe that there's a good way to > "filter the code" such that you "only get what you want" (which is > what rusti currently attempts). > > - Can rusti be my version of a REPL? > > Basically what all that means is that rusti has to save the world's > state between your lines of input to be my version of a REPL. To the > best of my knowledge (which could very well be wrong), this is not > possible to do in Rust. > > This leads me to the conclusion that rusti cannot be a true REPL (at > least the way I see a REPL). In my opinion, this also means that rusti > should be discarded. If someone new comes to rust and tries out the > fancy 'rusti' command, they'll start to play around but very quickly > run into some odd scenario that doesn't match what they think. After > playing around for awhile, they may realize that the "REPL" is > behaving oddly, or they'll just leave entirely. Regardless, no one is > going to get what they're expecting when they run rusti. > > If no one gets what they want when they run it, and I don't believe > that anyone can ever actually get what they want, I don't think that > there's a reason to keep it around as a tool that is built into rust. > I believe that the 'rust run' command is an excellent alternative. No, > it's not as fast as rusti, but it's correct and you know exactly > what's happening. I don't necessarily think that this warrants the > removal of the "-Z jit" flag either, but it makes me seriously > question whether it's worth maintaining that code. > > > > So that's all just my own personal opinion. I was wondering what other > people thought about this course of action? If anyone has questions > about how rusti currently works, I can also do my best to answer those > as well. > _______________________________________________ > 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 lindsey at composition.al Tue May 28 21:45:14 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Wed, 29 May 2013 00:45:14 -0400 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: Message-ID: On Wed, May 29, 2013 at 12:03 AM, Alex Crichton wrote: > In my opinion, the point of rusti is to be a REPL for rust. Is this a matter of opinion? I thought it was a fact! :) > - What rusti is > > The way that rusti works today in my opinion is a bit hacky once you > look inside. It will take your line of input, fmt! it into a template, > and then compile the whole template (via rustc using LLVM). After > compilation is successful, it walks down the ast to figure out what > you just input, and it then records that line of input in its history > *as a string*. What this means is that for the second line of input to > rusti, it will put both the history and the input into the template, > and re-run all the code again. Yep, it's a hack. > - Can rusti be my version of a REPL? > > Basically what all that means is that rusti has to save the world's > state between your lines of input to be my version of a REPL. To the > best of my knowledge (which could very well be wrong), this is not > possible to do in Rust. Why would this not be possible? > If someone new comes to rust and tries out the > fancy 'rusti' command, they'll start to play around but very quickly > run into some odd scenario that doesn't match what they think. I agree, and I think this is a reason to try to improve rusti. Lindsey P.S. It might be interesting to look at the approach taken by Cling (http://root.cern.ch/drupal/content/cling), an LLVM-based REPL for C++. There's an overview video at http://www.youtube.com/watch?v=f9Xfh8pv3Fs. I don't know a lot about it, but I think the basic approach is: still JIT, but drastically change the notion of "compilation unit". From alex at crichton.co Tue May 28 22:17:52 2013 From: alex at crichton.co (Alex Crichton) Date: Wed, 29 May 2013 00:17:52 -0500 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: Message-ID: Thanks for your input! It sounds like one thing we can definitely agree that rustc isn't ready for a rusti-like tool to work 100% today. > I knew that pretty printing history into a big list of strings was a bad way > for it to work, but there was no other way to make it work at the time. Each > compiler instance (i.e. every time a line was inputted) had to be run on a > separate task every time, so the history had to be sendable. A better > alternative would have been to store the history as AST (so it didn't need > to be parsed each time, only compiled), but that wasn't sendable. As far as > I know, each compiler instance no longer needs to be on a separate task so > this could probably be used instead now. I'll respond to Lindsey here as well. I think that this is one main reason that rusti can't work in today's model. There's no way getting around running rustc in a separate task from rusti, which implies that everything has to be sendable. This means that you can't have any "local variables" in rusti which are @ (assuming that there's some saved local state between lines of input). > In my opinion, rusti gets the job done. Yes, having in-memory compiled state > would work a lot better. But I don't know how viable that is. I know for a > fact that a big feature plan is to have the compiler only partially compile > when applicable, i.e. only compile things are actually important. That would > help drastically here. For me, if I use rusti I expect to get all of rust and everything that entails. Sadly, rusti only gives you certain portions right now, and to me that doesn't cut it for being a core tool that rust provides. That being said, if the compiler did partially compile and have a lot of extra options, I can see how a true rusti would be much more plausible. For now though, I think that a reasonable course of action would be to remove rusti, leverage rustpkg to install rusti once rustpkg is working, and then continue to update it with the compiler. In theory it could be re-integrated back into the tree once the compiler supports it, but I think the idea of it being a separate installable package would also be a good idea long term. To me this is a much more preferable solution than "half a rusti waiting for the compiler to change." > And no-no-no, I think removing the JIT backend is a really bad idea. That > sort of thing is really useful and removing it now is not going to be > productive. There has been much work from the community recently to improve > rusti and the JIT compiler. I think once Mozilla setup automated testing of > the JIT compiler it could easily be polished and have all tests green under > it, which would be great. I definitely don't mind leaving it in, it's not too much extra code to maintain. It's just something that I'd want to be sure was kept around for a good reason. Currently the way that it's used, it's not clear to my why it doesn't just write the binary somewhere and run it externally instead of running it in-process (although that only applies to current use-cases). That being said though, there is automated testing for the JIT right now (I added it), and I've also been fixing it for various platforms (x86 mainly). I think the JIT is much more robust than rusti because right now the only bug is that task failures in JIT code are completely broken, but probably has to do with LLVM anyway. Regardless, I still think that rusti should be removed: * It's a fair amount of code to maintain and keep up with all the giant language changes * It's not the tool that you would expect it to be. Under a minute of interaction with it will convince you of that. Not only that, but even if you include all my un-landed patches to help rusti, I can still think of many examples which run different in rusti than rustc. If a tool is distributed by the main rust distribution, I would expect it to be of the same quality as the rest of the tools distributed (in terms of what it does when I throw input at it). This is my major reason for thinking that rusti should be dropped for now, and I think that if it were dropped rusti shouldn't be a part of the tree until these issues are mitigated. Again though, these issues may be able to be mitigated right now and I'm just unaware! * If it's just "waiting for rustc to evolve", it can do that outside the main rust tree (this shouldn't affect how rustc evolves, it should have the same goals). It doesn't sound like this is really happening in the near future at all. The changes necessary to make rusti only perhaps plausible sound like major architectural changes to the compiler (I could be wrong), so waiting in tree seems a bit infeasible. All that being said, I'll definitely take a look at cling (thanks Lindsey!). I would imagine that there are many similar problems in a JIT for C++ as there is for Rust. From masklinn at masklinn.net Wed May 29 00:54:53 2013 From: masklinn at masklinn.net (Masklinn) Date: Wed, 29 May 2013 09:54:53 +0200 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: Message-ID: <92371A60-DDAC-4749-9DD3-2F93D3CA425D@masklinn.net> On 2013-05-29, at 07:17 , Alex Crichton wrote: > >> In my opinion, rusti gets the job done. Yes, having in-memory compiled state >> would work a lot better. But I don't know how viable that is. I know for a >> fact that a big feature plan is to have the compiler only partially compile >> when applicable, i.e. only compile things are actually important. That would >> help drastically here. > > For me, if I use rusti I expect to get all of rust and everything that > entails. Although I don't think rusti works well enough now (I don't think many would disagree), I think this expectation is essentially crazy, Rust not being a language where everything happens at runtime, it seems only logical that there will be limitations on what an interpreter can do, just as there are limitations on what ghci[0] does compared to ghc, or the erlang shell compared to an actual erlang module[1]. That said, I'd also expect additional features (not available in a normal program) for observing and investigating the current available environment as Rust doesn't (as far as I know) provide these in the core language/library (for obvious reasons already mentioned): where one can use standard ruby or python objects and methods to introspect the interpreter's namespace[2], ghci has to provide a number of dedicated command[5] to introspect the interpreter's state and interact with the external environment sensibly. [0] Talking about ghci, how does it work? Haskell is also a "compile-heavy" language but ghci has very little issues, could rusti work the same way? [1] Part of these limitations stem from eshell being a console, a shell, an interface for interacting with a running erlang node before being a REPL. Which makes me wonder if Rust will provide a basis for such things, providing arguments to the runtime itself ? la GHC[3] and allowing external tools to connect to a running Rust program and inspect/interact with it ? la Erlang[4]? [2] And even then, "augmented REPLs" such as ipython or bpython have added REPL commands separate from Python's own. [3] http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/runtime-control.html#rts-opts-cmdline [4] http://www.erlang.org/doc/apps/webtool/webtool_chapter.html http://www.erlang.org/doc/apps/appmon/appmon_chapter.html http://www.erlang.org/doc/apps/observer/observer_ug.html http://www.metabrew.com/article/bigwig-erlang-webtool-spawnfest [5] http://www.haskell.org/ghc/docs/7.6.2/html/users_guide/ghci-commands.html From niko at alum.mit.edu Wed May 29 02:55:03 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 29 May 2013 05:55:03 -0400 Subject: [rust-dev] Question about lifetimes in type parameters In-Reply-To: <51A4FC17.6090803@crsr.net> References: <51A4FC17.6090803@crsr.net> Message-ID: <20130529095503.GA22384@Mr-Bennet> On Tue, May 28, 2013 at 01:48:55PM -0500, Tommy M. McGuire wrote: > The problem I am running into is that the type of the LinearMap's find() > method (Yes, this is 0.6.) is: > > fn find(&self, k: &&'b [u8]) -> Option<&'self &'b [u8]> > > In other words, the key argument is a borrowed pointer to a borrowed > pointer to a vector with the same lifetime as the buffer. That argument > is kind of difficult to provide. First, I'm sure you've heard this before, but you'll probably be happier if you bite the bullet and upgrade to incoming. There are a lot of bugs fixed around the treatment of lifetimes, and more to come. That said, why is a `&&[u8]` so difficult to provide? You can do something like this: let my_slice: &[u8] = my_vec.slice(from, to); match map.find(&my_slice) { ... } Or even: match map.find(&my_vec.slice(from, to)) { ... } > What am I doing wrong? Is there a better way? I think you are doing it right. You may find it easier to just put indices into the map rather than slices, but slices should work too. Niko From corey at octayn.net Wed May 29 07:27:53 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 29 May 2013 10:27:53 -0400 Subject: [rust-dev] A case for removing rusti In-Reply-To: <92371A60-DDAC-4749-9DD3-2F93D3CA425D@masklinn.net> References: <92371A60-DDAC-4749-9DD3-2F93D3CA425D@masklinn.net> Message-ID: On Wed, May 29, 2013 at 3:54 AM, Masklinn wrote: > On 2013-05-29, at 07:17 , Alex Crichton wrote: >> >>> In my opinion, rusti gets the job done. Yes, having in-memory compiled state >>> would work a lot better. But I don't know how viable that is. I know for a >>> fact that a big feature plan is to have the compiler only partially compile >>> when applicable, i.e. only compile things are actually important. That would >>> help drastically here. >> >> For me, if I use rusti I expect to get all of rust and everything that >> entails. > > Although I don't think rusti works well enough now (I don't think many > would disagree), I think this expectation is essentially crazy, Rust > not being a language where everything happens at runtime, it seems > only logical that there will be limitations on what an interpreter > can do > When I was getting started with rust I was excited to see a repl: "rapid prototyping, yay!" But identical one-liners ran very differently (and brokenly) in rusti, and it was very misleading. I think rusti should stick around, but I don't think it should be marketed as a REPL, it should just act like the irc bot until it actually has identical semantics as real rust. From michaelwoerister at gmail.com Wed May 29 08:01:21 2013 From: michaelwoerister at gmail.com (=?ISO-8859-1?Q?Michael_W=F6rister?=) Date: Wed, 29 May 2013 17:01:21 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation Message-ID: Hi everyone, I wanted to quickly introduce myself here. My name is Michael Woerister and I was accepted for Rust's Google Summer of Code project this year, regarding debug symbol generation for rustc. I've been following the Rust project for a while now and I'm really proud that I can be a part of it. Rust already is a beautiful language and I hope to be able to use it a lot in the future. It's great to get this opportunity of contributing some to its progress! A bit about the project: Debugger support for Rust is very rudimentary at the moment. LLVM allows for producing debug symbols during code generation but for this to work the LLVM IR has to be annotated correctly with metadata. Some of this is already implemented in "librustc/middle/trans/debuginfo.rs" but quite a few things are still missing. At the same time the language is still evolving and like other parts of the compiler the debug symbol code has to keep up. Also new LLVM versions come with their needs for adaption. My task over the summer will be to extend the code in debuginfo.rs to also handle things like enums, traits, and closures, and just as important, write more unit tests so the 5 lonely files in test/debug-info get some company. The goal is that at the end of summer we will be able to debug rustc itself with gdb. I will post my weekly project updates to my github page: http://michaelwoerister.github.io (nothing there yet) I am grateful for any advice or comments. Also, I want to thank my 'GSoC mentor' Josh Matthews who has been nothing but helpful so far :-) Cheers, Michael -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Wed May 29 08:23:52 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 29 May 2013 10:23:52 -0500 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: Best of luck Michael and thanks for tackling this objective ! The only quick advice I have is too let you know that Eclipse can be a nice frontend for GDB itself, in case your not aware... http://dpc.ucore.info/blog/2013/02/06/eclipse-as-an-excellent-gdb-frontend/ On Wed, May 29, 2013 at 10:01 AM, Michael W?rister < michaelwoerister at gmail.com> wrote: > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael Woerister > and I was accepted for Rust's Google Summer of Code project this year, > regarding debug symbol generation for rustc. > > I've been following the Rust project for a while now and I'm really proud > that I can be a part of it. Rust already is a beautiful language and I hope > to be able to use it a lot in the future. It's great to get this > opportunity of contributing some to its progress! > > A bit about the project: > Debugger support for Rust is very rudimentary at the moment. LLVM allows > for producing debug symbols during code generation but for this to work the > LLVM IR has to be annotated correctly with metadata. Some of this is > already implemented in "librustc/middle/trans/debuginfo.rs" but quite a > few things are still missing. At the same time the language is still > evolving and like other parts of the compiler the debug symbol code has to > keep up. Also new LLVM versions come with their needs for adaption. > > My task over the summer will be to extend the code in debuginfo.rs to > also handle things like enums, traits, and closures, and just as important, > write more unit tests so the 5 lonely files in test/debug-info get some > company. The goal is that at the end of summer we will be able to debug > rustc itself with gdb. > > I will post my weekly project updates to my github page: > http://michaelwoerister.github.io (nothing there yet) > > I am grateful for any advice or comments. Also, I want to thank my 'GSoC > mentor' Josh Matthews who has been nothing but helpful so far :-) > > Cheers, > Michael > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Wed May 29 10:32:44 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 29 May 2013 10:32:44 -0700 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: Message-ID: <51A63BBC.9080701@mozilla.com> On 13-05-28 09:03 PM, Alex Crichton wrote: > Now this doesn't sound that bad in theory. Normally rusti is for quick > computations. There's not much of a history and nothing really takes a > long time. This quickly becomes a problem though for anything which > uses resources. Let's say that you call io::println. Do you really > want that statement executed every time you enter a line into rusti? > What if you opened a file or a network connection? In my opinion, > re-running code is unacceptable. Yeah. Probably what it should do is save any item decl statments (by name, allowing you to redefine them), discard any plain expr statements, and note the local var decl statements. Then compile a wrapper that reloads, evaluates exprs, and sends-back all those local var decls via serialization. Might require prepending #[deriving(auto_serialize)] to any local struct definition, but otherwise I think it ought to work. > This actually glosses over the fact that rusti currently doesn't even > save all input. It only saves declarations and definitions right now. > I made a patch to save assignments as well, but that still doesn't > work in all situations. I don't believe that there's a good way to > "filter the code" such that you "only get what you want" (which is > what rusti currently attempts). Huh. Would the scheme I outline above not work? Every variable does have to be introduced at some point, which means we can enumerate them and ask to have them loaded from serial form and sent-back to the REPL on subprocess completion. > Basically what all that means is that rusti has to save the world's > state between your lines of input to be my version of a REPL. To the > best of my knowledge (which could very well be wrong), this is not > possible to do in Rust. "The world", no. Just the local variables. And we can probably reject any local decl that fails the "we can save this" test. I mean, it'll be a little delicate, and not a perfect emulation, but I think it can _mostly_ work. > If no one gets what they want when they run it, and I don't believe > that anyone can ever actually get what they want, I don't think that > there's a reason to keep it around as a tool that is built into rust. > I believe that the 'rust run' command is an excellent alternative. No, > it's not as fast as rusti, but it's correct and you know exactly > what's happening. I don't necessarily think that this warrants the > removal of the "-Z jit" flag either, but it makes me seriously > question whether it's worth maintaining that code. I agree that a 'rust run' command, or indeed exploiting our support for shebang comments[1], should be sufficient for most users. But I'm not convinced the repl serves no purpose, yet (though it's true, I don't use seem to ever use it; I also write surprisingly little rust code these days). People ask for it, and it doesn't really bend the language any to support it. It _is_ a code-maintenance cost, of course, so I'm also curious what others think in terms of the balance of costs/benefits. -Graydon [1] https://github.com/mozilla/rust/issues/1772 From corey at octayn.net Wed May 29 10:33:59 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 29 May 2013 13:33:59 -0400 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: On Wed, May 29, 2013 at 11:01 AM, Michael W?rister wrote: > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael Woerister and > I was accepted for Rust's Google Summer of Code project this year, regarding > debug symbol generation for rustc. > This will be extremely useful just to have working again, let alone extended to more features. I hope to see you in IRC :) From lindsey at composition.al Wed May 29 10:40:03 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Wed, 29 May 2013 13:40:03 -0400 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: On Wed, May 29, 2013 at 11:01 AM, Michael W?rister wrote: > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael Woerister and > I was accepted for Rust's Google Summer of Code project this year, regarding > debug symbol generation for rustc. Welcome, Michael. That will be a much-appreciated project! Lindsey From hatahet at gmail.com Wed May 29 10:53:41 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 29 May 2013 10:53:41 -0700 Subject: [rust-dev] Runtime cost of Option Message-ID: Hi all, Does using Option incur a runtime cost (like increased memory usage) compared to a hypothetical case if Rust had a NULL type in the language? Or does it get optimized away, such that it is akin to using NULL in the first place (albeit safer of course)? I have not looked at any assemblies, ut my intuition says that a comparison with None is a single-word check, so it should be pretty fast. Thanks -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From erick.tryzelaar at gmail.com Wed May 29 11:01:36 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Wed, 29 May 2013 11:01:36 -0700 Subject: [rust-dev] Runtime cost of Option In-Reply-To: References: Message-ID: Q patch just recently landed to do that optimization for Option types containing a pointer. Options wrapping a value type still need an extra word however in order to distinguish between the Some/None cases though. On Wednesday, May 29, 2013, Ziad Hatahet wrote: > Hi all, > > Does using Option incur a runtime cost (like increased memory usage) > compared to a hypothetical case if Rust had a NULL type in the language? Or > does it get optimized away, such that it is akin to using NULL in the first > place (albeit safer of course)? > > I have not looked at any assemblies, ut my intuition says that a > comparison with None is a single-word check, so it should be pretty fast. > > Thanks > > -- > Ziad > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed May 29 11:52:50 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 29 May 2013 14:52:50 -0400 Subject: [rust-dev] Runtime cost of Option In-Reply-To: References: Message-ID: On Wed, May 29, 2013 at 1:53 PM, Ziad Hatahet wrote: > Hi all, > > Does using Option incur a runtime cost (like increased memory usage) > compared to a hypothetical case if Rust had a NULL type in the language? Or > does it get optimized away, such that it is akin to using NULL in the first > place (albeit safer of course)? > > I have not looked at any assemblies, ut my intuition says that a comparison > with None is a single-word check, so it should be pretty fast. > > Thanks > > -- > Ziad Any enum with a non-nullable pointer type (~T, @T, &T, ~[T], @[T], ~str, @str) and second zero-size variant is optimized to a nullable pointer now. The optimization still needs to be extended to slices though (they're two words, but the enum could also be 2 words, not 3). From o.renaud at gmx.fr Wed May 29 11:59:24 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Wed, 29 May 2013 20:59:24 +0200 Subject: [rust-dev] Runtime cost of Option In-Reply-To: References: Message-ID: <3519640.C6GgxSHQRo@bureau-linux> You will find some more informations in this recent Stackoverflow question : http://stackoverflow.com/q/16504643/112053 Le mercredi 29 mai 2013 10:53:41 Ziad Hatahet a ?crit : > Hi all, > > Does using Option incur a runtime cost (like increased memory usage) > compared to a hypothetical case if Rust had a NULL type in the language? Or > does it get optimized away, such that it is akin to using NULL in the first > place (albeit safer of course)? > > I have not looked at any assemblies, ut my intuition says that a comparison > with None is a single-word check, so it should be pretty fast. > > Thanks > > -- > Ziad From vadimcn at gmail.com Wed May 29 12:27:58 2013 From: vadimcn at gmail.com (Vadim) Date: Wed, 29 May 2013 12:27:58 -0700 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: Hi Michael, Just last week I've embarked on a project to fix Rust's debug info emitter (it's been broken ever since last LLVM version update because of change in debug metadata format). I've made some progress, but new code still doesn't have all the features that old code used to have. I was going to look into adding support for traits, enums etc after that, but since you can work on this full time, I'd love to hand this part over to you. When are you starting? Vadim On Wed, May 29, 2013 at 8:01 AM, Michael W?rister < michaelwoerister at gmail.com> wrote: > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael Woerister > and I was accepted for Rust's Google Summer of Code project this year, > regarding debug symbol generation for rustc. > > I've been following the Rust project for a while now and I'm really proud > that I can be a part of it. Rust already is a beautiful language and I hope > to be able to use it a lot in the future. It's great to get this > opportunity of contributing some to its progress! > > A bit about the project: > Debugger support for Rust is very rudimentary at the moment. LLVM allows > for producing debug symbols during code generation but for this to work the > LLVM IR has to be annotated correctly with metadata. Some of this is > already implemented in "librustc/middle/trans/debuginfo.rs" but quite a > few things are still missing. At the same time the language is still > evolving and like other parts of the compiler the debug symbol code has to > keep up. Also new LLVM versions come with their needs for adaption. > > My task over the summer will be to extend the code in debuginfo.rs to > also handle things like enums, traits, and closures, and just as important, > write more unit tests so the 5 lonely files in test/debug-info get some > company. The goal is that at the end of summer we will be able to debug > rustc itself with gdb. > > I will post my weekly project updates to my github page: > http://michaelwoerister.github.io (nothing there yet) > > I am grateful for any advice or comments. Also, I want to thank my 'GSoC > mentor' Josh Matthews who has been nothing but helpful so far :-) > > Cheers, > 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 jon.mb at proinbox.com Wed May 29 12:51:36 2013 From: jon.mb at proinbox.com (John Mija) Date: Wed, 29 May 2013 20:51:36 +0100 Subject: [rust-dev] Rust and Go Message-ID: <51A65C48.90006@proinbox.com> How could be integrated the Go language in Rust? If somebody were to write a Go compiler to be integrated in Rust[1], which path would be the best one? To create bindings to commands [568][acgl] [2] or write the SSA library/interpreter [3] in Rust? [1] "to be integrated in other language": I refer to can compile Go code without to use an OS call to execute the command, just like a browser built in C++ has integrated JavaScript or like Lua can be integrated with C. [2]: http://golang.org/src/cmd/ [3]: http://godoc.org/code.google.com/p/go.tools/ssa http://godoc.org/code.google.com/p/go.tools/ssa/interp * * * What reasons could want somebody to use Go from Rust? + It could be used in programs where you want give power to users to run some tasks, i.e. into a database; today, it's being added JS to some DBMSs + To Run web scripts in Go --into a fork of Servo-- which will allow create powerful applications easily with a great performance and easily of debugging. From fedor at indutny.com Wed May 29 13:06:24 2013 From: fedor at indutny.com (Fedor Indutny) Date: Thu, 30 May 2013 00:06:24 +0400 Subject: [rust-dev] Rust and Go In-Reply-To: <51A65C48.90006@proinbox.com> References: <51A65C48.90006@proinbox.com> Message-ID: If you'll ever wish to choose SSA interpretation way - feel free to use my library to allocate registers for this stuff https://github.com/indutny/linearscan.rs . Cheers, Fedor. On Wed, May 29, 2013 at 11:51 PM, John Mija wrote: > How could be integrated the Go language in Rust? > > If somebody were to write a Go compiler to be integrated in Rust[1], which > path would be the best one? To create bindings to commands [568][acgl] [2] > or write the SSA library/interpreter [3] in Rust? > > [1] "to be integrated in other language": I refer to can compile Go code > without to use an OS call to execute the command, just like a browser built > in C++ has integrated JavaScript or like Lua can be integrated with C. > > [2]: http://golang.org/src/cmd/ > [3]: http://godoc.org/code.google.**com/p/go.tools/ssa > http://godoc.org/code.google.**com/p/go.tools/ssa/interp > > * * * > > What reasons could want somebody to use Go from Rust? > > + It could be used in programs where you want give power to users to run > some tasks, i.e. into a database; today, it's being added JS to some DBMSs > > + To Run web scripts in Go --into a fork of Servo-- which will allow > create powerful applications easily with a great performance and easily of > debugging. > ______________________________**_________________ > 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 Wed May 29 13:24:13 2013 From: corey at octayn.net (Corey Richardson) Date: Wed, 29 May 2013 16:24:13 -0400 Subject: [rust-dev] Rust and Go In-Reply-To: <51A65C48.90006@proinbox.com> References: <51A65C48.90006@proinbox.com> Message-ID: On Wed, May 29, 2013 at 3:51 PM, John Mija wrote: > How could be integrated the Go language in Rust? > [...] > + It could be used in programs where you want give power to users to run > some tasks, i.e. into a database; today, it's being added JS to some DBMSs > > + To Run web scripts in Go --into a fork of Servo-- which will allow create > powerful applications easily with a great performance and easily of > debugging. > If you don't call precompile or at the very least JIT, performance is going to be very lackluster, and I'm unconvinced any existing debuggers would be usable. I think this effort is misguided. Go's semantics aren't well suited to embedding like Lua or even JS or Python are. But you can call Go code from Rust if it exports a C-compatible ABI From graydon at mozilla.com Wed May 29 13:40:59 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 29 May 2013 13:40:59 -0700 Subject: [rust-dev] Rust and Go In-Reply-To: <51A65C48.90006@proinbox.com> References: <51A65C48.90006@proinbox.com> Message-ID: <51A667DB.7030705@mozilla.com> On 13-05-29 12:51 PM, John Mija wrote: > How could be integrated the Go language in Rust? To embed a language, it generally needs to present a cdecl callable interface (= accept C callbacks), and be willing to schedule its coroutines and IO operations as steps within someone else's event loop. It will also need some form of marshaling of data values and/or mapping between types in the embedded and embedding languages; but that part is often the easiest part. Rust has been shifting[1] to a structure that permits embedding _Rust_ programs in others[2]; but embedding Go in Rust would be a different direction and probably requires work on Go's side. It seems someone is working on it[3] but I doubt it would be very easy today. > If somebody were to write a Go compiler to be integrated in Rust[1], > which path would be the best one? To create bindings to commands > [568][acgl] [2] or write the SSA library/interpreter [3] in Rust? That would be another option. I have no idea how mature those semantics are or the associated tooling. That route would probably run much more slowly; I suspect you'll have better luck trying to get the two runtimes to cooperate via linking. > What reasons could want somebody to use Go from Rust? > > + It could be used in programs where you want give power to users to run > some tasks, i.e. into a database; today, it's being added JS to some DBMSs Those contexts usually embed very lightweight / dynamic languages expressly for user convenience. Typical programs are one line, or even one expression long. They also tend to support runtime evaluation from strings, very loose typing, extending the type and value dictionaries at runtime, etc. Go, like Rust, was not developed with these pressures in mind, and I suspect it's not an ideal language in that sense. Though of course here we are on universal Turing machines, you're always free to use unusual tools for any given job. With enough effort you might be able to get it working. > + To Run web scripts in Go --into a fork of Servo-- which will allow > create powerful applications easily with a great performance and easily > of debugging. Similarly here, I think the "in a web page" environment is not terribly fertile soil for the Go semantics. Even setting aside the same argument above (most js programs, by volume, are probably onclick="" handlers and only a few expressions long) I think the backward compatibility issues -- your program now only runs in GoScript-aware browsers -- would limit applicability. It has been tried with quite a number of other languages, even nice small terse ones. In any case, this is getting far afield; this is rust-dev, not golang-nuts. If you want to try, I suspect your difficulties will emerge mostly on the "embeddable Go runtime" side, which we can't help you with. -Graydon [1] https://github.com/mozilla/rust/pull/5022 [2] http://brson.github.io/2013/03/10/embedding-rust-in-ruby/ [3] https://code.google.com/p/go/issues/detail?id=2790 From banderson at mozilla.com Wed May 29 13:56:27 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 29 May 2013 13:56:27 -0700 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: <51A66B7B.5000508@mozilla.com> On 05/29/2013 08:01 AM, Michael W?rister wrote: > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael > Woerister and I was accepted for Rust's Google Summer of Code project > this year, regarding debug symbol generation for rustc. Welcome, and good luck. From wmatyjewicz at fastmail.fm Wed May 29 14:00:31 2013 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Wed, 29 May 2013 23:00:31 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: <51A66C6F.9010607@fastmail.fm> On 29.05.2013 17:01, Michael W?rister wrote: > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael Woerister > and I was accepted for Rust's Google Summer of Code project this year, > regarding debug symbol generation for rustc. Congratulations and good luck! As for comments (please, excuse me if I am writing something obvious): I have noticed that the current implementation in debuginfo.rs emits debug information by directly building proper LLVM metadata nodes using the low-level functions. An alternative approach could be taken by using LLVM's DIBuilder [1] class that abstracts these low-level functions and the debugging metadata format into a higher-level interface. Taking this approach would involve creating bindings for DIBuilder. However, this effort might pay off in the longer term, because all the (undocumented) changes that may happen to the LLVM's low-level debug information format would be hidden behind DIBuilder. The other benefit is that DIBuilder keeps track of what metadata nodes it has generated and reuses the existing nodes instead of generating identical ones --- similar functionality from debuginfo.rs could be removed then. Cheers, Wojtek From wmatyjewicz at fastmail.fm Wed May 29 14:15:38 2013 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Wed, 29 May 2013 23:15:38 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: <51A66C6F.9010607@fastmail.fm> References: <51A66C6F.9010607@fastmail.fm> Message-ID: <51A66FFA.2010704@fastmail.fm> > An alternative approach could be taken by using > LLVM's DIBuilder [1] class [...] Forgotten to add the reference: [1] http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DIBuilder.h?view=markup From illissius at gmail.com Wed May 29 14:18:17 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Wed, 29 May 2013 23:18:17 +0200 Subject: [rust-dev] Modest proposal: Make `pub` the default everywhere, possibly remove it Message-ID: Hello list, Currently Rust has different default visibilities in different places: - `mod` items are private - `struct` fields and `enum` variants are public - `trait` methods are public - `impl` methods are private - `impls for` are public (by necessity) I propose to change this to: - Everything not `priv` is public Points in favor: - It's much easier to explain, grok, and remember. - Most definitions are written to be public. Writing `public` in front of every dang thing was annoying in Java and C#, and it's no less annoying in Rust. Maybe especially so for those coming from C/C++, who haven't already resigned themselves to it. - Currently `impls for` are always public, while other items including `impl`s are private. This would make it consistent and remove a potential source of confusion. And instead of a deep-seated semantic rule for users to remember, there would be a simple syntactic one: you can't put `priv` on an `impl for`. - I get the reason for the `priv` default and requiring `pub` explicitly, and initially agreed with it: that module authors should think about what they export, therefore the burden should be on those cases where you want to make something public. But in my experience, module authors are very conscientious about their public interfaces, and put special importance on what should be kept hidden. Having this be explicit with `priv` isn't necessarily a disadvantage. - Reading a module for its interface won't be any worse: instead of looking for `pub`s and skipping things without it unless if they're `impls for`, you would read everything and skip the `priv`s. - The `pub` keyword could potentially be removed from the language. Issues: - Public by default clearly can't extend to `use`, which should remain private. That means `pub use` is left as an orphan. Either it could remain `pub`'s only use, or it could be expressed some other way. Thanks for considering, G?bor -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Wed May 29 14:29:16 2013 From: clements at brinckerhoff.org (John Clements) Date: Wed, 29 May 2013 14:29:16 -0700 Subject: [rust-dev] A case for removing rusti In-Reply-To: <51A63BBC.9080701@mozilla.com> References: <51A63BBC.9080701@mozilla.com> Message-ID: On May 29, 2013, at 10:32 AM, Graydon Hoare wrote: ... > > I agree that a 'rust run' command, or indeed exploiting our support for > shebang comments[1], should be sufficient for most users. But I'm not > convinced the repl serves no purpose, yet (though it's true, I don't use > seem to ever use it; I also write surprisingly little rust code these > days). People ask for it, and it doesn't really bend the language any to > support it. It _is_ a code-maintenance cost, of course, so I'm also > curious what others think in terms of the balance of costs/benefits. My vote: dump it. This might sound surprising from a Schemer, but probably not from a Racketeer. Making the top-level work correctly soaked up far too much time in the Racket environment. There's nothing more infuriating than getting something to work in the REPL and then discovering that it doesn't work in compiled code? unless it's struggling for weeks to get something to work in the REPL, only to discover that it works just fine in compiled code. I think that the principal use case for a REPL is interactive exploration of what rust programs mean, and I think that the best way to support this is to have a nice clean "rust run", and possibly some sugar that makes evaluating and printing the result of a single expression more convenient. My opinion only. John From jon.mb at proinbox.com Wed May 29 14:32:21 2013 From: jon.mb at proinbox.com (John Mija) Date: Wed, 29 May 2013 22:32:21 +0100 Subject: [rust-dev] Rust and Go In-Reply-To: <51A667DB.7030705@mozilla.com> References: <51A65C48.90006@proinbox.com> <51A667DB.7030705@mozilla.com> Message-ID: <51A673E5.9090809@proinbox.com> Thanks for your answer, El 29/05/13 21:40, Graydon Hoare escribi?: > On 13-05-29 12:51 PM, John Mija wrote: > >> How could be integrated the Go language in Rust? > > To embed a language, it generally needs to present a cdecl callable > interface (= accept C callbacks), and be willing to schedule its > coroutines and IO operations as steps within someone else's event loop. > It will also need some form of marshaling of data values and/or mapping > between types in the embedded and embedding languages; but that part is > often the easiest part. > > Rust has been shifting[1] to a structure that permits embedding _Rust_ > programs in others[2]; but embedding Go in Rust would be a different > direction and probably requires work on Go's side. It seems someone is > working on it[3] but I doubt it would be very easy today. > >> If somebody were to write a Go compiler to be integrated in Rust[1], >> which path would be the best one? To create bindings to commands >> [568][acgl] [2] or write the SSA library/interpreter [3] in Rust? > > That would be another option. I have no idea how mature those semantics > are or the associated tooling. That route would probably run much more > slowly; I suspect you'll have better luck trying to get the two runtimes > to cooperate via linking. And what do you think about this one? (a) The Go programs must use a function for that the output been to a socket in Unix systems or to a pipe in Windows systems. (b) The Go program is compiled from Rust using bindings to the Go's C compilers). (c) Now, Rust can read the output through a socket. So, we get fast compilation and easy access to the Go's output. >> + To Run web scripts in Go --into a fork of Servo-- which will allow >> create powerful applications easily with a great performance and easily >> of debugging. > > Similarly here, I think the "in a web page" environment is not terribly > fertile soil for the Go semantics. Even setting aside the same argument > above (most js programs, by volume, are probably onclick="" handlers and > only a few expressions long) I think the backward compatibility issues > -- your program now only runs in GoScript-aware browsers -- would limit > applicability. It has been tried with quite a number of other languages, > even nice small terse ones. Well, the usage of Go like web language would be mainly useful for large web applications like games. Go has integer and float types of 64 bits. From pwalton at mozilla.com Wed May 29 14:34:24 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 29 May 2013 14:34:24 -0700 Subject: [rust-dev] Modest proposal: Make `pub` the default everywhere, possibly remove it In-Reply-To: References: Message-ID: <51A67460.6000703@mozilla.com> On 5/29/13 2:18 PM, G?bor Lehel wrote: > Hello list, > > Currently Rust has different default visibilities in different places: > - `mod` items are private > - `struct` fields and `enum` variants are public > - `trait` methods are public > - `impl` methods are private > - `impls for` are public (by necessity) This isn't quite accurate. Actually, struct fields, enum variants, and trait methods are public if and only if the struct/enum/trait they're contained within are public. This is basically equivalent to the above, but is a more consistent formulation of the rule. > - Most definitions are written to be public. Writing `public` in front > of every dang thing was annoying in Java and C#, and it's no less > annoying in Rust. Maybe especially so for those coming from C/C++, who > haven't already resigned themselves to it. I have a lot of sympathy for this, mainly because I personally don't like the look of the word `pub` and don't like seeing it everywhere :) Also your points about it being easier to remember are valid and well-taken. But I worry about people making too many symbols public for this reason. Also it would be a large change at this stage. Overall I think I'm neutral/conflicted on this proposal. Patrick From mikhail.zabaluev at gmail.com Wed May 29 14:34:36 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Thu, 30 May 2013 00:34:36 +0300 Subject: [rust-dev] Modest proposal: Make `pub` the default everywhere, possibly remove it In-Reply-To: References: Message-ID: Hi, I have a strong point against it: your crates are going to be christmas trees of exposed APIs unless you are careful. This has a runtime cost, increases the risk of breaking the ABI more often than you should, and often results in unintentional APIs that you may be later beholden to maintain. Look at the tragedy of failing to use -fvisibility=hidden when building shared libraries with gcc. Best regards, Mikhail 2013/5/30 G?bor Lehel Currently Rust has different default visibilities in different places: > - `mod` items are private > - `struct` fields and `enum` variants are public > - `trait` methods are public > - `impl` methods are private > - `impls for` are public (by necessity) > > I propose to change this to: > - Everything not `priv` is public > -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Wed May 29 14:40:24 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Wed, 29 May 2013 23:40:24 +0200 Subject: [rust-dev] Modest proposal: Make `pub` the default everywhere, possibly remove it In-Reply-To: References: Message-ID: Maybe I'm unusual. But in C++ I'm always super-careful (one might say anal retentive) about keeping my headers as clean of implementation details as humanly possible. I don't think forgetting a `priv` would ever be an issue. But I'm not everyone. On Wed, May 29, 2013 at 11:34 PM, Mikhail Zabaluev < mikhail.zabaluev at gmail.com> wrote: > Hi, > > I have a strong point against it: your crates are going to be christmas > trees of exposed APIs unless you are careful. This has a runtime cost, > increases the risk of breaking the ABI more often than you should, and > often results in unintentional APIs that you may be later beholden to > maintain. > > Look at the tragedy of failing to use -fvisibility=hidden when building > shared libraries with gcc. > > Best regards, > Mikhail > > > 2013/5/30 G?bor Lehel > > Currently Rust has different default visibilities in different places: >> - `mod` items are private >> - `struct` fields and `enum` variants are public >> - `trait` methods are public >> - `impl` methods are private >> - `impls for` are public (by necessity) >> >> I propose to change this to: >> - Everything not `priv` is public >> > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From vadimcn at gmail.com Wed May 29 14:46:04 2013 From: vadimcn at gmail.com (Vadim) Date: Wed, 29 May 2013 14:46:04 -0700 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: <51A66C6F.9010607@fastmail.fm> References: <51A66C6F.9010607@fastmail.fm> Message-ID: BTW, that's the exact approach I took for fixing Rust's debug info emitter. On Wed, May 29, 2013 at 2:00 PM, Wojciech Matyjewicz < wmatyjewicz at fastmail.fm> wrote: > On 29.05.2013 17:01, Michael W?rister wrote: > >> Hi everyone, >> I wanted to quickly introduce myself here. My name is Michael Woerister >> and I was accepted for Rust's Google Summer of Code project this year, >> regarding debug symbol generation for rustc. >> > > Congratulations and good luck! > > As for comments (please, excuse me if I am writing something obvious): I > have noticed that the current implementation in debuginfo.rs emits debug > information by directly building proper LLVM metadata nodes using the > low-level functions. An alternative approach could be taken by using LLVM's > DIBuilder [1] class that abstracts these low-level functions and the > debugging metadata format into a higher-level interface. Taking this > approach would involve creating bindings for DIBuilder. However, this > effort might pay off in the longer term, because all the (undocumented) > changes that may happen to the LLVM's low-level debug information format > would be hidden behind DIBuilder. The other benefit is that DIBuilder keeps > track of what metadata nodes it has generated and reuses the existing nodes > instead of generating identical ones --- similar functionality from > debuginfo.rs could be removed then. > > Cheers, > Wojtek > ______________________________**_________________ > 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 Wed May 29 14:48:23 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 29 May 2013 14:48:23 -0700 Subject: [rust-dev] Rust and Go In-Reply-To: <51A673E5.9090809@proinbox.com> References: <51A65C48.90006@proinbox.com> <51A667DB.7030705@mozilla.com> <51A673E5.9090809@proinbox.com> Message-ID: <51A677A7.1080105@mozilla.com> On 13-05-29 02:32 PM, John Mija wrote: > And what do you think about this one? > > (a) The Go programs must use a function for that the output been to a > socket in Unix systems or to a pipe in Windows systems. > (b) The Go program is compiled from Rust using bindings to the Go's C > compilers). > (c) Now, Rust can read the output through a socket. > > So, we get fast compilation and easy access to the Go's output. Yes, this is a way to interoperate between any two languages that have I/O facilities. > Well, the usage of Go like web language would be mainly useful for large > web applications like games. > Go has integer and float types of 64 bits. So do many languages (including Rust). But as I said, this is not the right topic for this list. -Graydon From graydon at mozilla.com Wed May 29 14:53:49 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 29 May 2013 14:53:49 -0700 Subject: [rust-dev] Modest proposal: Make `pub` the default everywhere, possibly remove it In-Reply-To: References: Message-ID: <51A678ED.7060006@mozilla.com> On 13-05-29 02:40 PM, G?bor Lehel wrote: > Maybe I'm unusual. But in C++ I'm always super-careful (one might say > anal retentive) about keeping my headers as clean of implementation > details as humanly possible. I don't think forgetting a `priv` would > ever be an issue. But I'm not everyone. Because Rust does not differentiate between "header" and "implementation" -- the signatures and metadata are extracted from the program and compiled-in to the resulting binary -- our experience when "everything was public" (as it once was, briefly) was that everything got exported. People just didn't notice all the things they were exporting, or deferred having to think about it. At a different time, we had explicit export lists, and a sort of "phase transition" when developing a library: everything was exported when you mentioned nothing and were just doing sketches; but as soon as you mentioned exports, _only_ those things were exported. This facility was removed when we switched to pub and priv, on the basis that people complained about having to scroll up and down the screen looking for the export list. I think there is no perfect answer here. I'm sympathetic to your concerns ('pub' was chosen as small as possible, to minimize these costs) but I think that making everything public by default is a major hazard for growing private-API dependencies, and would not want us to go there. -Graydon From mikhail.zabaluev at gmail.com Wed May 29 14:54:26 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Thu, 30 May 2013 00:54:26 +0300 Subject: [rust-dev] Modest proposal: Make `pub` the default everywhere, possibly remove it In-Reply-To: References: Message-ID: Hi, 2013/5/30 G?bor Lehel > Maybe I'm unusual. But in C++ I'm always super-careful (one might say anal > retentive) about keeping my headers as clean of implementation details as > humanly possible. I don't think forgetting a `priv` would ever be an issue. > But I'm not everyone. Unfortunately, it's not always enough: traditionally in Unix, any functions and other symbols that are not explicitly private to the compilation unit are emitted as PLT symbols by default when building a shared library. This is not only near-useless symbol table pollution and extra grind material for the dynamic linker, it's also an API leak: anyone could define their own prototype and call your implementation function. Best regards, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From josh at joshmatthews.net Wed May 29 14:54:26 2013 From: josh at joshmatthews.net (Josh Matthews) Date: Wed, 29 May 2013 17:54:26 -0400 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: <51A66C6F.9010607@fastmail.fm> References: <51A66C6F.9010607@fastmail.fm> Message-ID: On 29 May 2013 17:00, Wojciech Matyjewicz wrote: > The other benefit is that DIBuilder keeps track of what metadata nodes it > has generated and reuses the existing nodes instead of generating identical > ones --- similar functionality from debuginfo.rs could be removed then. > I don't think this is quite correct. LLVM merges identical metadata nodes without any outside intervention. The metadata cache in debuginfo.rs is strictly a performance optimization. Cheers, Josh -------------- next part -------------- An HTML attachment was scrubbed... URL: From mcguire at crsr.net Wed May 29 14:55:31 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Wed, 29 May 2013 16:55:31 -0500 Subject: [rust-dev] Question about lifetimes in type parameters In-Reply-To: <20130529095503.GA22384@Mr-Bennet> References: <51A4FC17.6090803@crsr.net> <20130529095503.GA22384@Mr-Bennet> Message-ID: <51A67953.7010308@crsr.net> On 05/29/2013 04:55 AM, Niko Matsakis wrote: > On Tue, May 28, 2013 at 01:48:55PM -0500, Tommy M. McGuire wrote: >> The problem I am running into is that the type of the LinearMap's find() >> method (Yes, this is 0.6.) is: >> >> fn find(&self, k: &&'b [u8]) -> Option<&'self &'b [u8]> >> >> In other words, the key argument is a borrowed pointer to a borrowed >> pointer to a vector with the same lifetime as the buffer. That argument >> is kind of difficult to provide. > > First, I'm sure you've heard this before, but you'll probably be > happier if you bite the bullet and upgrade to incoming. There are a > lot of bugs fixed around the treatment of lifetimes, and more to come. Yes, yes. I know. :-) I'm in the process of doing that, now. > That said, why is a `&&[u8]` so difficult to provide? You can do > something like this: > > let my_slice: &[u8] = my_vec.slice(from, to); > match map.find(&my_slice) { ... } > > Or even: > > match map.find(&my_vec.slice(from, to)) { ... } > >> What am I doing wrong? Is there a better way? > > I think you are doing it right. You may find it easier to just put > indices into the map rather than slices, but slices should work too. The problem is that I want to use a completely unrelated vector as the argument to find() instead of an alias for part of the buffer or a pair of indices into the buffer. Currently, with my quick change to incoming, the code let kkey : &[u8] = key; // key : ~[u8] match dictionary.find(&kkey) { produces: 55:38 error: borrowed value does not live long enough let kkey : &[u8] = key; ^~~ 67:1 note: borrowed pointer must be valid for the lifetime &br_named({repr: 83, ctxt: 0}) as defined on the block at 48:0... ... 65:5 note: ...but borrowed value is only valid for the block at 50:46 The lifetime '&br_named(...)' stuff should be "'b", the lifetime parameter of the function (the block at 48:0) that is associated with the keys and values from the HashMap (was LinearMap) and the buffer. Here's the complete file: https://gist.github.com/tmmcguire/5674103#file-gistfile1-rs -- Tommy M. McGuire mcguire at crsr.net From jon.mb at proinbox.com Wed May 29 15:34:30 2013 From: jon.mb at proinbox.com (John Mija) Date: Wed, 29 May 2013 23:34:30 +0100 Subject: [rust-dev] Rust and Go In-Reply-To: <51A677A7.1080105@mozilla.com> References: <51A65C48.90006@proinbox.com> <51A667DB.7030705@mozilla.com> <51A673E5.9090809@proinbox.com> <51A677A7.1080105@mozilla.com> Message-ID: <51A68276.1010405@proinbox.com> El 29/05/13 22:48, Graydon Hoare escribi?: > On 13-05-29 02:32 PM, John Mija wrote: > >> Well, the usage of Go like web language would be mainly useful for large >> web applications like games. >> Go has integer and float types of 64 bits. > > So do many languages (including Rust). But as I said, this is not the > right topic for this list. My sentence was not against Rust else against JavaScript which is being used in games having only floats with 54 bits of precision. I love Rust since it is closer to metal than Go, getting more control over memory. But Go can be a great replacement to script languages due to a simple syntax; that's my reason to be used instead of JS. However Rust is a great language to build AAA games so it could be used too in web games. From illissius at gmail.com Wed May 29 16:05:44 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Thu, 30 May 2013 01:05:44 +0200 Subject: [rust-dev] Modest proposal: Make `pub` the default everywhere, possibly remove it In-Reply-To: <51A678ED.7060006@mozilla.com> References: <51A678ED.7060006@mozilla.com> Message-ID: On Wed, May 29, 2013 at 11:53 PM, Graydon Hoare wrote: > On 13-05-29 02:40 PM, G?bor Lehel wrote: > > Maybe I'm unusual. But in C++ I'm always super-careful (one might say > > anal retentive) about keeping my headers as clean of implementation > > details as humanly possible. I don't think forgetting a `priv` would > > ever be an issue. But I'm not everyone. > > Because Rust does not differentiate between "header" and > "implementation" -- the signatures and metadata are extracted from the > program and compiled-in to the resulting binary -- our experience when > "everything was public" (as it once was, briefly) was that everything > got exported. People just didn't notice all the things they were > exporting, or deferred having to think about it. > > At a different time, we had explicit export lists, and a sort of "phase > transition" when developing a library: everything was exported when you > mentioned nothing and were just doing sketches; but as soon as you > mentioned exports, _only_ those things were exported. > > This facility was removed when we switched to pub and priv, on the basis > that people complained about having to scroll up and down the screen > looking for the export list. > > I think there is no perfect answer here. I'm sympathetic to your > concerns ('pub' was chosen as small as possible, to minimize these > costs) but I think that making everything public by default is a major > hazard for growing private-API dependencies, and would not want us to go > there. > > -Graydon > > My proposal does rest on the assumption that module authors know what they're doing and wouldn't leave things exported accidentally (won't the exported items showing up in the generated docs dissuade them, at least?), but if that's not true then I agree the proposal is much less attractive. -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Wed May 29 17:50:21 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 29 May 2013 19:50:21 -0500 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: <51A63BBC.9080701@mozilla.com> Message-ID: RUST RUN. FTW. :-) On Wed, May 29, 2013 at 4:29 PM, John Clements wrote: > > On May 29, 2013, at 10:32 AM, Graydon Hoare wrote: > > ... > > > > I agree that a 'rust run' command, or indeed exploiting our support for > > shebang comments[1], should be sufficient for most users. But I'm not > > convinced the repl serves no purpose, yet (though it's true, I don't use > > seem to ever use it; I also write surprisingly little rust code these > > days). People ask for it, and it doesn't really bend the language any to > > support it. It _is_ a code-maintenance cost, of course, so I'm also > > curious what others think in terms of the balance of costs/benefits. > > My vote: dump it. This might sound surprising from a Schemer, but probably > not from a Racketeer. Making the top-level work correctly soaked up far too > much time in the Racket environment. There's nothing more infuriating than > getting something to work in the REPL and then discovering that it doesn't > work in compiled code? unless it's struggling for weeks to get something to > work in the REPL, only to discover that it works just fine in compiled code. > > I think that the principal use case for a REPL is interactive exploration > of what rust programs mean, and I think that the best way to support this > is to have a nice clean "rust run", and possibly some sugar that makes > evaluating and printing the result of a single expression more convenient. > > My opinion only. > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From aatch at aatch.net Wed May 29 20:15:48 2013 From: aatch at aatch.net (James Miller) Date: Thu, 30 May 2013 15:15:48 +1200 Subject: [rust-dev] PSA: use #[inline(always)] with care Message-ID: <20130530031545.GA31088@freya.fritz.box> Hello Everyone, I've been doing work around optimizations recently, and noticed that libextra was taking an inordinate amount of time to build. My investigations led me to find that well over half the time spent was on Loop Invariant Code motion, i.e. moving expressions that don't change out of the loop. One of the more common cases turns this: while i < n { data.field[i] = something(i); i += 1; } into this: let tmp = data.field; while i < n { tmp[i] = something(i); } since, the field access is invariant. Anyway, the BigInt module uses this pattern a lot. It also has 112 functions marked with #[inline(always)]. This does two things: causes massive code bloat, 2 orders of magnitude worth of code bloat, and makes later passes work much, much harder. Many of the functions in BigInt would have been inlined multiple times into one function, and in some cases, those functions would be further inlined into other functions, despite blowing past the normal inline cost limit. This meant that a fairly simple, standard pass, was being called on over 100x more code than it needed to be. If you want to know why a full build takes so long, there is why. Inlining is a pretty standard optimization, and is potentially done for every function that isn't marked with `#[inline(never)]`, but the compiler is smart enough to know when it's not worth it. `#[inline(always)]` is a very strong statement, and should be reserved for cases where you are certain that the function absolutely needs to be inlined, no exceptions. Remember that "always" means it, so every single function that uses it will get a copy. Inlining is not a magic bullet for performance and the compiler passes are far smarter at knowing what is more efficient than you are. Thank you for your time, James Miller From ben.striegel at gmail.com Wed May 29 20:32:23 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 29 May 2013 23:32:23 -0400 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: <20130530031545.GA31088@freya.fritz.box> References: <20130530031545.GA31088@freya.fritz.box> Message-ID: Indeed, I think it might be useful to embark on a project to review *all* the uses of #[inline(always)] that currently exist and determine their necessity. I too have been guilty of using it where #[inline] alone would suffice. On Wed, May 29, 2013 at 11:15 PM, James Miller wrote: > Hello Everyone, > > I've been doing work around optimizations recently, and noticed that > libextra was taking an > inordinate amount of time to build. My investigations led me to find that > well over half the time > spent was on Loop Invariant Code motion, i.e. moving expressions that > don't change out of the loop. > > One of the more common cases turns this: > > while i < n { > data.field[i] = something(i); > i += 1; > } > > into this: > > let tmp = data.field; > while i < n { > tmp[i] = something(i); > } > > since, the field access is invariant. > > Anyway, the BigInt module uses this pattern a lot. It also has 112 > functions marked with > #[inline(always)]. This does two things: causes massive code bloat, 2 > orders of magnitude worth of > code bloat, and makes later passes work much, much harder. Many of the > functions in BigInt would > have been inlined multiple times into one function, and in some cases, > those functions would be > further inlined into other functions, despite blowing past the normal > inline cost limit. > > This meant that a fairly simple, standard pass, was being called on over > 100x more code than it > needed to be. If you want to know why a full build takes so long, there is > why. > > Inlining is a pretty standard optimization, and is potentially done for > every function that isn't > marked with `#[inline(never)]`, but the compiler is smart enough to know > when it's not worth it. > `#[inline(always)]` is a very strong statement, and should be reserved for > cases where you are > certain that the function absolutely needs to be inlined, no exceptions. > Remember that "always" > means it, so every single function that uses it will get a copy. > > Inlining is not a magic bullet for performance and the compiler passes are > far smarter at knowing > what is more efficient than you are. > > Thank you for your time, > James Miller > _______________________________________________ > 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 mikhail.zabaluev at gmail.com Wed May 29 23:39:17 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Thu, 30 May 2013 09:39:17 +0300 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: <20130530031545.GA31088@freya.fritz.box> References: <20130530031545.GA31088@freya.fritz.box> Message-ID: Hi, 2013/5/30 James Miller > > Inlining is a pretty standard optimization, and is potentially done for > every function that isn't > marked with `#[inline(never)]`, but the compiler is smart enough to know > when it's not worth it. > `#[inline(always)]` is a very strong statement, and should be reserved for > cases where you are > certain that the function absolutely needs to be inlined, no exceptions. > Remember that "always" > means it, so every single function that uses it will get a copy. > > Inlining is not a magic bullet for performance and the compiler passes are > far smarter at knowing > what is more efficient than you are. > Why even have the option? The programmer almost never has better information than the compiler to decide whether a function could be beneficially inlined at each particular call site. And as we see with the Rust code base itself, this has a great potential of being unwittingly abused. Look, a "make my function run fast" directive! Plain #[inline] has a declarative value, though. I haven't looked into what the compiler does, but I guess #[inline] can instruct it to emit metadata for inlining a public function at the call site, rather than just shipping a symbol in the crate. Best regards, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Wed May 29 23:48:52 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Thu, 30 May 2013 16:48:52 +1000 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: References: <20130530031545.GA31088@freya.fritz.box> Message-ID: <51A6F654.30400@gmail.com> On 30/05/13 16:39, Mikhail Zabaluev wrote: > > Why even have the option? The programmer almost never has better > information than the compiler to decide whether a function could be > beneficially inlined at each particular call site. And as we see with > the Rust code base itself, this has a great potential of being > unwittingly abused. Look, a "make my function run fast" directive! Apparently it's required to guarantee that LLVM inlines the closure in for loops (e.g. uint::range). > > Plain #[inline] has a declarative value, though. I haven't looked into > what the compiler does, but I guess #[inline] can instruct it to emit > metadata for inlining a public function at the call site, rather than > just shipping a symbol in the crate. > This is correct, as far as I understand; the AST of a function has to be written to the crate for cross-crate inlining (so that it is accessible to Rust/LLVM on the next compilations), and this is only written for #[inline(always)] and #[inline]. However, #[inline] isn't just doing this, it also sets the inline hint for LLVM, which makes it inline more eagerly than the default. (I've got an old PR[1] that adds #[inline(maybe)], which is the same as #[inline] but doesn't set the hint, i.e. it allows cross-crate inlining by writing the AST to the crate, but gives LLVM full control of when and where to do it. However, it seems that people aren't super keen on it.) Huon [1]: https://github.com/mozilla/rust/pull/6616 From mikhail.zabaluev at gmail.com Thu May 30 00:01:32 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Thu, 30 May 2013 10:01:32 +0300 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: <51A6F654.30400@gmail.com> References: <20130530031545.GA31088@freya.fritz.box> <51A6F654.30400@gmail.com> Message-ID: Hi, 2013/5/30 Huon Wilson > > Plain #[inline] has a declarative value, though. I haven't looked into >> what the compiler does, but I guess #[inline] can instruct it to emit >> metadata for inlining a public function at the call site, rather than just >> shipping a symbol in the crate. >> >> This is correct, as far as I understand; the AST of a function has to be > written to the crate for cross-crate inlining (so that it is accessible to > Rust/LLVM on the next compilations), and this is only written for > #[inline(always)] and #[inline]. I think the API impact of this should be documented. If you have a public #[inline] function, changing its body effectively changes the public API of your crate. Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From michaelwoerister at gmail.com Thu May 30 01:13:59 2013 From: michaelwoerister at gmail.com (=?ISO-8859-1?Q?Michael_W=F6rister?=) Date: Thu, 30 May 2013 10:13:59 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: <51A70A47.90207@gmail.com> Thanks Thad! I'll definitely look into that. On 29.05.2013 17:23, Thad Guidry wrote: > Best of luck Michael and thanks for tackling this objective ! > > The only quick advice I have is too let you know that Eclipse can be a > nice frontend for GDB itself, in case your not aware... > http://dpc.ucore.info/blog/2013/02/06/eclipse-as-an-excellent-gdb-frontend/ > > > > On Wed, May 29, 2013 at 10:01 AM, Michael W?rister > > wrote: > > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael > Woerister and I was accepted for Rust's Google Summer of Code > project this year, regarding debug symbol generation for rustc. > > I've been following the Rust project for a while now and I'm > really proud that I can be a part of it. Rust already is a > beautiful language and I hope to be able to use it a lot in the > future. It's great to get this opportunity of contributing some to > its progress! > > A bit about the project: > Debugger support for Rust is very rudimentary at the moment. LLVM > allows for producing debug symbols during code generation but for > this to work the LLVM IR has to be annotated correctly with > metadata. Some of this is already implemented in > "librustc/middle/trans/debuginfo.rs " but quite a > few things are still missing. At the same time the language is > still evolving and like other parts of the compiler the debug > symbol code has to keep up. Also new LLVM versions come with their > needs for adaption. > > My task over the summer will be to extend the code in debuginfo.rs > to also handle things like enums, traits, > and closures, and just as important, write more unit tests so the > 5 lonely files in test/debug-info get some company. The goal is > that at the end of summer we will be able to debug rustc itself > with gdb. > > I will post my weekly project updates to my github page: > http://michaelwoerister.github.io (nothing there yet) > > I am grateful for any advice or comments. Also, I want to thank my > 'GSoC mentor' Josh Matthews who has been nothing but helpful so > far :-) > > Cheers, > Michael > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From michaelwoerister at gmail.com Thu May 30 01:17:08 2013 From: michaelwoerister at gmail.com (=?ISO-8859-1?Q?Michael_W=F6rister?=) Date: Thu, 30 May 2013 10:17:08 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: <51A70B04.8070804@gmail.com> On 29.05.2013 19:33, Corey Richardson wrote: > On Wed, May 29, 2013 at 11:01 AM, Michael W?rister > wrote: >> Hi everyone, >> I wanted to quickly introduce myself here. My name is Michael Woerister and >> I was accepted for Rust's Google Summer of Code project this year, regarding >> debug symbol generation for rustc. >> > This will be extremely useful just to have working again, let alone > extended to more features. I hope to see you in IRC :) My IRC nick is 'mw', see you there :) From michaelwoerister at gmail.com Thu May 30 01:22:15 2013 From: michaelwoerister at gmail.com (=?ISO-8859-1?Q?Michael_W=F6rister?=) Date: Thu, 30 May 2013 10:22:15 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: Message-ID: <51A70C37.90304@gmail.com> Hi Vadim, I'll be starting full time on June 17. Until then my time budget is still limited. -Michael On 29.05.2013 21:27, Vadim wrote: > Hi Michael, > Just last week I've embarked on a project to fix Rust's debug info > emitter (it's been broken ever since last LLVM version update because > of change in debug metadata format). I've made some progress, but > new code still doesn't have all the features that old code used to have. > > I was going to look into adding support for traits, enums etc after > that, but since you can work on this full time, I'd love to hand this > part over to you. > > When are you starting? > > Vadim > > > On Wed, May 29, 2013 at 8:01 AM, Michael W?rister > > wrote: > > Hi everyone, > I wanted to quickly introduce myself here. My name is Michael > Woerister and I was accepted for Rust's Google Summer of Code > project this year, regarding debug symbol generation for rustc. > > I've been following the Rust project for a while now and I'm > really proud that I can be a part of it. Rust already is a > beautiful language and I hope to be able to use it a lot in the > future. It's great to get this opportunity of contributing some to > its progress! > > A bit about the project: > Debugger support for Rust is very rudimentary at the moment. LLVM > allows for producing debug symbols during code generation but for > this to work the LLVM IR has to be annotated correctly with > metadata. Some of this is already implemented in > "librustc/middle/trans/debuginfo.rs " but quite a > few things are still missing. At the same time the language is > still evolving and like other parts of the compiler the debug > symbol code has to keep up. Also new LLVM versions come with their > needs for adaption. > > My task over the summer will be to extend the code in debuginfo.rs > to also handle things like enums, traits, > and closures, and just as important, write more unit tests so the > 5 lonely files in test/debug-info get some company. The goal is > that at the end of summer we will be able to debug rustc itself > with gdb. > > I will post my weekly project updates to my github page: > http://michaelwoerister.github.io (nothing there yet) > > I am grateful for any advice or comments. Also, I want to thank my > 'GSoC mentor' Josh Matthews who has been nothing but helpful so > far :-) > > Cheers, > 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 michaelwoerister at gmail.com Thu May 30 01:46:39 2013 From: michaelwoerister at gmail.com (=?ISO-8859-1?Q?Michael_W=F6rister?=) Date: Thu, 30 May 2013 10:46:39 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: <51A66C6F.9010607@fastmail.fm> Message-ID: <51A711EF.8080605@gmail.com> On 29.05.2013 23:54, Josh Matthews wrote: > On 29 May 2013 17:00, Wojciech Matyjewicz > wrote: > > The other benefit is that DIBuilder keeps track of what metadata > nodes it has generated and reuses the existing nodes instead of > generating identical ones --- similar functionality from > debuginfo.rs could be removed then. > > > I don't think this is quite correct. LLVM merges identical metadata > nodes without any outside intervention. The metadata cache in > debuginfo.rs is strictly a performance optimization. > > Cheers, > Josh Thanks Wojtek and Vadim! Josh has already mentioned that wrapping DIBuilder might be a good idea in the future, and I'm starting to think that we should do so better sooner than later. -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Thu May 30 02:56:37 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 30 May 2013 05:56:37 -0400 Subject: [rust-dev] RFC: conventions for default arguments Message-ID: <20130530095637.GH3607@Mr-Bennet> I have a proposal about library conventions and I'm not sure where is the right place to pose it. I think that anytime there is a "default" argument of generic type that may or may not get used, we should offer two variants, one of which requires the Zero trait, and one of which takes a closure. This follows precedent from many languages, including Smalltalk, Scala, and to some extent Haskell, since in Haskell all evaluation is lazy. Right now, we typically either (1) only offer a version that takes the default "by value", as with `option::get_or_default`: fn get_or_default(self, def: T) -> T; But I often find in practice I cannot use this because it always evaluates `def`. Even something as simple as: let vec = opt_vec.get_or_default(~[]); allocates unconditionally. I would prefer: fn get_or_default(self: def: &fn() -> T) -> T; The only case where I think this pattern is really useful is something like: let is_true = opt_bool.get_or_default(false); let count = opt_counter.get_or_default(0); Under my proposal, we would have: fn get_or_default(self, def: &fn() -> T) -> T; fn get_or_zero(self) -> T; // where T:Zero Then you could write: let vec = opt_vec.get_or_default(|| ~[]); let is_true = opt_bool.get_or_zero(); let count = opt_counter.get_or_zero(); At worst, if the Zero default isn't what you want, you might to write something like: let foo = opt_bool.get_or_default(|| true); But I think our closure syntax is lightweight enough that this is not a big deal. Another example is in Hashmaps, where we offer two variants on the "find-or-insert" pattern: fn find_or_insert(&mut self, K, V) -> Option<&V> fn find_or_insert_with(&mut self, K, &fn(&K) -> V) -> Option<&V> Under my proposal there would just be: fn find_or_insert(&mut self, K, &fn(&K) -> V) -> Option<&mut V> fn find_or_insert_zero(&mut self, K) -> Option<&mut V> // where V:Zero Thoughts? Niko From niko at alum.mit.edu Thu May 30 03:05:50 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 30 May 2013 06:05:50 -0400 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: <20130530031545.GA31088@freya.fritz.box> References: <20130530031545.GA31088@freya.fritz.box> Message-ID: <20130530100550.GI3607@Mr-Bennet> This is definitely good advice. One of the problems we had in "the early days" was that LLVM heuristics didn't seem to quite be tuned for our case, so we wound up tossing around `always`, and I think we have seen far overdone it (and probably already overdid it in the beginning). It'd be interesting to see whether the LLVM heuristics can be tuned at all to better estimate the benefts of inlining in Rust specifically. And no, I don't have any examples right now :) Niko On Thu, May 30, 2013 at 03:15:48PM +1200, James Miller wrote: > Hello Everyone, > > I've been doing work around optimizations recently, and noticed that libextra was taking an > inordinate amount of time to build. My investigations led me to find that well over half the time > spent was on Loop Invariant Code motion, i.e. moving expressions that don't change out of the loop. > > One of the more common cases turns this: > > while i < n { > data.field[i] = something(i); > i += 1; > } > > into this: > > let tmp = data.field; > while i < n { > tmp[i] = something(i); > } > > since, the field access is invariant. > > Anyway, the BigInt module uses this pattern a lot. It also has 112 functions marked with > #[inline(always)]. This does two things: causes massive code bloat, 2 orders of magnitude worth of > code bloat, and makes later passes work much, much harder. Many of the functions in BigInt would > have been inlined multiple times into one function, and in some cases, those functions would be > further inlined into other functions, despite blowing past the normal inline cost limit. > > This meant that a fairly simple, standard pass, was being called on over 100x more code than it > needed to be. If you want to know why a full build takes so long, there is why. > > Inlining is a pretty standard optimization, and is potentially done for every function that isn't > marked with `#[inline(never)]`, but the compiler is smart enough to know when it's not worth it. > `#[inline(always)]` is a very strong statement, and should be reserved for cases where you are > certain that the function absolutely needs to be inlined, no exceptions. Remember that "always" > means it, so every single function that uses it will get a copy. > > Inlining is not a magic bullet for performance and the compiler passes are far smarter at knowing > what is more efficient than you are. > > Thank you for your time, > James Miller > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From niko at alum.mit.edu Thu May 30 03:09:47 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 30 May 2013 06:09:47 -0400 Subject: [rust-dev] Question about lifetimes in type parameters In-Reply-To: <51A67953.7010308@crsr.net> References: <51A4FC17.6090803@crsr.net> <20130529095503.GA22384@Mr-Bennet> <51A67953.7010308@crsr.net> Message-ID: <20130530100947.GJ3607@Mr-Bennet> On Wed, May 29, 2013 at 04:55:31PM -0500, Tommy M. McGuire wrote: > The problem is that I want to use a completely unrelated vector as the > argument to find() instead of an alias for part of the buffer or a pair > of indices into the buffer. > > Currently, with my quick change to incoming, the code > > let kkey : &[u8] = key; // key : ~[u8] > match dictionary.find(&kkey) { > > produces: > > 55:38 error: borrowed value does not live long enough > let kkey : &[u8] = key; > ^~~ > 67:1 note: borrowed pointer must be valid for the lifetime > &br_named({repr: 83, ctxt: 0}) as defined on the block at 48:0... > ... > 65:5 note: ...but borrowed value is only valid for the block at 50:46 > > The lifetime '&br_named(...)' stuff should be "'b", the lifetime > parameter of the function (the block at 48:0) that is associated with > the keys and values from the HashMap (was LinearMap) and the buffer. This seems like a bug (also, what a lousy error message! sorry.), I will further investigate. Niko From wmatyjewicz at fastmail.fm Thu May 30 04:12:34 2013 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Thu, 30 May 2013 13:12:34 +0200 Subject: [rust-dev] Summer of Code 2013: Rust Debug Symbol Generation In-Reply-To: References: <51A66C6F.9010607@fastmail.fm> Message-ID: <51A73422.3080305@fastmail.fm> > The other benefit is that DIBuilder keeps track of what metadata > nodes it has generated and reuses the existing nodes instead of > generating identical ones --- similar functionality from > debuginfo.rs could be removed then. > > > I don't think this is quite correct. LLVM merges identical metadata > nodes without any outside intervention. The metadata cache in > debuginfo.rs is strictly a performance optimization. You are right: identical metadata nodes are always merged at the LLVM side. Cheers, Wojtek From danielmicay at gmail.com Thu May 30 05:14:39 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 30 May 2013 08:14:39 -0400 Subject: [rust-dev] RFC: conventions for default arguments In-Reply-To: <20130530095637.GH3607@Mr-Bennet> References: <20130530095637.GH3607@Mr-Bennet> Message-ID: On Thu, May 30, 2013 at 5:56 AM, Niko Matsakis wrote: > I have a proposal about library conventions and I'm not sure where is > the right place to pose it. I think that anytime there is a "default" > argument of generic type that may or may not get used, we should offer > two variants, one of which requires the Zero trait, and one of which > takes a closure. This follows precedent from many languages, including > Smalltalk, Scala, and to some extent Haskell, since in Haskell all > evaluation is lazy. > > Right now, we typically either (1) only offer a version that takes > the default "by value", as with `option::get_or_default`: > > fn get_or_default(self, def: T) -> T; > > But I often find in practice I cannot use this because it always > evaluates `def`. Even something as simple as: > > let vec = opt_vec.get_or_default(~[]); > > allocates unconditionally. I would prefer: > > fn get_or_default(self: def: &fn() -> T) -> T; > > The only case where I think this pattern is really useful is > something like: > > let is_true = opt_bool.get_or_default(false); > let count = opt_counter.get_or_default(0); > > Under my proposal, we would have: > > fn get_or_default(self, def: &fn() -> T) -> T; > fn get_or_zero(self) -> T; // where T:Zero > > Then you could write: > > let vec = opt_vec.get_or_default(|| ~[]); > let is_true = opt_bool.get_or_zero(); > let count = opt_counter.get_or_zero(); > > At worst, if the Zero default isn't what you want, > you might to write something like: > > let foo = opt_bool.get_or_default(|| true); > > But I think our closure syntax is lightweight enough that this > is not a big deal. > > Another example is in Hashmaps, where we offer two variants on the > "find-or-insert" pattern: > > fn find_or_insert(&mut self, K, V) -> Option<&V> > fn find_or_insert_with(&mut self, K, &fn(&K) -> V) -> Option<&V> > > Under my proposal there would just be: > > fn find_or_insert(&mut self, K, &fn(&K) -> V) -> Option<&mut V> > fn find_or_insert_zero(&mut self, K) -> Option<&mut V> // where V:Zero > > Thoughts? > > > Niko We could have a more generic trait than `Zero` for this. For example, Haskell has a third party data-default package[1] that's fairly widely used (pandoc is one of the users) and there's a similar concept in C++ with default constructors. We could just standardize the parameter-free `new` method this way. [1] http://hackage.haskell.org/package/data-default-0.5.3 From mcguire at crsr.net Thu May 30 07:00:32 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Thu, 30 May 2013 09:00:32 -0500 Subject: [rust-dev] Question about lifetimes in type parameters In-Reply-To: <20130530100947.GJ3607@Mr-Bennet> References: <51A4FC17.6090803@crsr.net> <20130529095503.GA22384@Mr-Bennet> <51A67953.7010308@crsr.net> <20130530100947.GJ3607@Mr-Bennet> Message-ID: <51A75B80.9080400@crsr.net> On 05/30/2013 05:09 AM, Niko Matsakis wrote: > On Wed, May 29, 2013 at 04:55:31PM -0500, Tommy M. McGuire wrote: >> The problem is that I want to use a completely unrelated vector as the >> argument to find() instead of an alias for part of the buffer or a pair >> of indices into the buffer. >> >> Currently, with my quick change to incoming, the code >> >> let kkey : &[u8] = key; // key : ~[u8] >> match dictionary.find(&kkey) { >> >> produces: >> >> 55:38 error: borrowed value does not live long enough >> let kkey : &[u8] = key; >> ^~~ >> 67:1 note: borrowed pointer must be valid for the lifetime >> &br_named({repr: 83, ctxt: 0}) as defined on the block at 48:0... >> ... >> 65:5 note: ...but borrowed value is only valid for the block at 50:46 >> >> The lifetime '&br_named(...)' stuff should be "'b", the lifetime >> parameter of the function (the block at 48:0) that is associated with >> the keys and values from the HashMap (was LinearMap) and the buffer. > > This seems like a bug (also, what a lousy error message! sorry.), I > will further investigate. Thanks! (The error message changed when I updated incoming, so it's something recent.) I'm not sure it is a bug, though. I may not be understanding lifetimes well enough, but I think the interaction between that and generics is problematic. In this case, there doesn't seem to be enough information to tell the difference between find(), for which the lifetime argument is not terribly useful, and insert(), where it would be. -- Tommy M. McGuire mcguire at crsr.net From niko at alum.mit.edu Thu May 30 08:17:07 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 30 May 2013 11:17:07 -0400 Subject: [rust-dev] RFC: conventions for default arguments In-Reply-To: References: <20130530095637.GH3607@Mr-Bennet> Message-ID: <20130530151707.GA3002@Mr-Bennet> On Thu, May 30, 2013 at 08:14:39AM -0400, Daniel Micay wrote: > We could have a more generic trait than `Zero` for this. For example, > Haskell has a third party data-default package[1] that's fairly widely > used (pandoc is one of the users) and there's a similar concept in C++ > with default constructors. We could just standardize the > parameter-free `new` method this way. That's fine too, though I kind of thought this is what Zero was. Still, a `Default` trait that defines `new()` seems clearer and less math-geeky than using `Zero`. I'm fine with either. Mainly I just don't want to take random default values that may or may not be used, since that's only convenient if the type happens to be a scalar, basically. Niko From pwalton at mozilla.com Thu May 30 08:18:52 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 30 May 2013 08:18:52 -0700 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: References: <20130530031545.GA31088@freya.fritz.box> Message-ID: <51A76DDC.8090908@mozilla.com> On 5/29/13 11:39 PM, Mikhail Zabaluev wrote: > Why even have the option? The programmer almost never has better > information than the compiler to decide whether a function could be > beneficially inlined at each particular call site. And as we see with > the Rust code base itself, this has a great potential of being > unwittingly abused. Look, a "make my function run fast" directive! uint::range and vec::each weren't always being inlined. (It's very important to inline them.) Unfortunately it seems it was taken too far. Patrick From mcguire at crsr.net Thu May 30 08:40:46 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Thu, 30 May 2013 10:40:46 -0500 Subject: [rust-dev] RFC: conventions for default arguments In-Reply-To: <20130530095637.GH3607@Mr-Bennet> References: <20130530095637.GH3607@Mr-Bennet> Message-ID: <51A772FE.4020709@crsr.net> On 05/30/2013 04:56 AM, Niko Matsakis wrote: > Another example is in Hashmaps, where we offer two variants on the > "find-or-insert" pattern: > > fn find_or_insert(&mut self, K, V) -> Option<&V> > fn find_or_insert_with(&mut self, K, &fn(&K) -> V) -> Option<&V> > > Under my proposal there would just be: > > fn find_or_insert(&mut self, K, &fn(&K) -> V) -> Option<&mut V> > fn find_or_insert_zero(&mut self, K) -> Option<&mut V> // where V:Zero > > Thoughts? I like the idea of the closure, but (as a relative newcomer), how would the Zero trait be specified? Wouldn't it require all HashMap's V's implement Zero? -- Tommy M. McGuire mcguire at crsr.net From pwalton at mozilla.com Thu May 30 08:44:37 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 30 May 2013 08:44:37 -0700 Subject: [rust-dev] RFC: conventions for default arguments In-Reply-To: <51A772FE.4020709@crsr.net> References: <20130530095637.GH3607@Mr-Bennet> <51A772FE.4020709@crsr.net> Message-ID: <51A773E5.6080902@mozilla.com> On 5/30/13 8:40 AM, Tommy M. McGuire wrote: > On 05/30/2013 04:56 AM, Niko Matsakis wrote: >> Another example is in Hashmaps, where we offer two variants on the >> "find-or-insert" pattern: >> >> fn find_or_insert(&mut self, K, V) -> Option<&V> >> fn find_or_insert_with(&mut self, K, &fn(&K) -> V) -> Option<&V> >> >> Under my proposal there would just be: >> >> fn find_or_insert(&mut self, K, &fn(&K) -> V) -> Option<&mut V> >> fn find_or_insert_zero(&mut self, K) -> Option<&mut V> // where V:Zero >> >> Thoughts? > > I like the idea of the closure, but (as a relative newcomer), how would > the Zero trait be specified? Wouldn't it require all HashMap's V's > implement Zero? You can add additional bounds to type arguments for a subset of the methods. Use a different impl block: impl HashMap { ... find_or_insert goes here ... } impl HashMap { ... find_or_insert_zero goes here ... } Patrick From pnkfelix at mozilla.com Thu May 30 09:05:37 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Thu, 30 May 2013 18:05:37 +0200 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: <20130530031545.GA31088@freya.fritz.box> References: <20130530031545.GA31088@freya.fritz.box> Message-ID: <51A778D1.6010109@mozilla.com> On 30/05/2013 05:15, James Miller wrote: > This meant that a fairly simple, standard pass, was being called on over 100x more code than it > needed to be. If you want to know why a full build takes so long, there is why. Since I've been curious about the build times this week, I thought I'd experiment with this assertion in a brute force way: compare the times between a baseline build and a build with every occurrence of #[inline(always)] replaced with #[inline]. The above is not ideal, especially if uint::range and vec::each are not being inlined without an inline(always) directive, as pcwalton mentioned. But it was something easy to try. This is on a system that's making use of a ccache for the C/C++ portions of the runtime (and I checked it was getting used as the builds ran, via ccache --show-stat), so hopefully its just rustc invocations that are taking the bulk of the time below; but I have not carefully verified that claim. % cd % time make > ../../rust-baseline-build-log 2>&1 real 23m38.869s user 22m50.757s sys 0m55.156s % cd % time make > ../../rust-reinline-build-log 2>&1 real 20m52.833s user 20m1.642s sys 0m56.104s It's just two data points, but I thought I would share. Two and a half minutes may not seem like a lot, but its quite possible that better tuning would reap more gains here. Cheers, -Felix -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.org From asb at asbradbury.org Thu May 30 09:08:04 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Thu, 30 May 2013 17:08:04 +0100 Subject: [rust-dev] PSA: use #[inline(always)] with care In-Reply-To: <51A778D1.6010109@mozilla.com> References: <20130530031545.GA31088@freya.fritz.box> <51A778D1.6010109@mozilla.com> Message-ID: On 30 May 2013 17:05, Felix S. Klock II wrote: > On 30/05/2013 05:15, James Miller wrote: >> >> This meant that a fairly simple, standard pass, was being called on over >> 100x more code than it >> needed to be. If you want to know why a full build takes so long, there is >> why. > > Since I've been curious about the build times this week, I thought I'd > experiment with this assertion in a brute force way: compare the times > between a baseline build and a build with every occurrence of > #[inline(always)] replaced with #[inline]. Excellent, I was going to suggest exactly this would make a good automated test for checking whether #[inline(always)] has been applied too liberally in the codebase (perhaps also with the addition of statistics on generated code size). Alex From xazax.hun at gmail.com Wed May 29 06:48:55 2013 From: xazax.hun at gmail.com (=?ISO-8859-1?Q?G=E1bor_Horv=E1th?=) Date: Wed, 29 May 2013 15:48:55 +0200 Subject: [rust-dev] Variables with the same name in the same scope Message-ID: Hi! The following code snippet is well formed and prints 6: fn main() { let x = 5; let x = 6; println(fmt!("%?",x)); } I was told this behavior is intentional. However I consider this pattern as a potential source of errors. Consider a larger function which one wants to modify. One declares a new variable in the middle of the function, and if there was a name collosion the whole meaning of the function is changed and the compiler does not even provide us with a warning about it. I'm curious what was the reason of allowing multiple variables with the same name in the same scope? Thanks, G?bor Horv?th -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Thu May 30 11:06:27 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 30 May 2013 11:06:27 -0700 Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: References: Message-ID: <5FFCCF7B-174D-4D11-98DF-1CD5F152A2B5@brinckerhoff.org> On May 29, 2013, at 6:48 AM, G?bor Horv?th wrote: > Hi! > > The following code snippet is well formed and prints 6: > > fn main() { > let x = 5; > let x = 6; > println(fmt!("%?",x)); > } > > I was told this behavior is intentional. However I consider this pattern as a potential source of errors. > Consider a larger function which one wants to modify. One declares a new variable in the middle of the function, and if there was a name collosion the whole meaning of the function is changed and the compiler does not even provide us with a warning about it. > > I'm curious what was the reason of allowing multiple variables with the same name in the same scope? I think this idiom is quite common. In at least one set of cases, it can help *avoid* errors: let x = compute_some_value(); // uh oh, clean up value of x: let x = clean_up(x); use_of(x); use_of(x); In this case, you may want to ensure that the earlier binding of 'x' is no longer visible. So, it's a tradeoff: disallowing re-use of names ensures that you can easily spot the binding site; allowing re-use of names allows you to limit the possible uses of the binding. Naturally, I speak only for myself. Best, John Clements From mcguire at crsr.net Thu May 30 11:07:41 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Thu, 30 May 2013 13:07:41 -0500 Subject: [rust-dev] RFC: conventions for default arguments In-Reply-To: <51A773E5.6080902@mozilla.com> References: <20130530095637.GH3607@Mr-Bennet> <51A772FE.4020709@crsr.net> <51A773E5.6080902@mozilla.com> Message-ID: <51A7956D.60701@crsr.net> On 05/30/2013 10:44 AM, Patrick Walton wrote: > You can add additional bounds to type arguments for a subset of the > methods. Use a different impl block: Cool! I didn't realize that. -- Tommy M. McGuire mcguire at crsr.net From corey at octayn.net Thu May 30 11:09:57 2013 From: corey at octayn.net (Corey Richardson) Date: Thu, 30 May 2013 14:09:57 -0400 Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: <5FFCCF7B-174D-4D11-98DF-1CD5F152A2B5@brinckerhoff.org> References: <5FFCCF7B-174D-4D11-98DF-1CD5F152A2B5@brinckerhoff.org> Message-ID: I think there should be a lint pass to check for it, I guess defaulting to warn, John brings up a good point. But it seems weird to me, since you can't just do "x = clean_up(x)". From tkuehn at mozilla.com Thu May 30 11:14:51 2013 From: tkuehn at mozilla.com (Timothy Kuehn) Date: Thu, 30 May 2013 11:14:51 -0700 (PDT) Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: Message-ID: <1178935509.880306.1369937691937.JavaMail.root@mozilla.com> You can do "x = clean_up(x)" if the type isn't changing. But consider the common case of getting a port into a closure by wrapping it in a Cell. Then, what you really want is the port, not the cell. Here's a line from Servo's script_task: let (script_chan_copy, script_port) = (script_chan.clone(), Cell(script_port)); Cheers, Tim ----- Original Message ----- From: "Corey Richardson" To: "John Clements" Cc: rust-dev at mozilla.org, "G?bor Horv?th" Sent: Thursday, May 30, 2013 11:09:57 AM Subject: Re: [rust-dev] Variables with the same name in the same scope I think there should be a lint pass to check for it, I guess defaulting to warn, John brings up a good point. But it seems weird to me, since you can't just do "x = clean_up(x)". _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From graydon at mozilla.com Thu May 30 11:20:27 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 30 May 2013 11:20:27 -0700 Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: References: Message-ID: <51A7986B.1000708@mozilla.com> On 29/05/2013 6:48 AM, G?bor Horv?th wrote: > Hi! > > The following code snippet is well formed and prints 6: > > fn main() { > let x = 5; > let x = 6; > println(fmt!("%?",x)); > } > > I was told this behavior is intentional. However I consider this pattern > as a potential source of errors. It is intentional. It falls out automatically from supporting shadowing-in-general (idents in enclosing scopes) and the ability to declare new variables mid-block. Each new decl opens a new implicit scope from its point-of-decl to the end of its lexical block. > Consider a larger function which one wants to modify. One declares a new > variable in the middle of the function, and if there was a name > collosion the whole meaning of the function is changed and the compiler > does not even provide us with a warning about it. Yeah, a lint for this -- or for shadowing in general -- might be worthwhile. Though some of us write this way ... somewhat regularly. It's most common when you do something like: let foo = complex_expression_returning_option(); let foo = foo.get_or_default(|| 10); ... Where you're just repeatedly unwrapping and digging-in to a value, changing type with each binding; making up throwaway names for the intermediates that only last one line is tedious. But even when you're not changing the type from one binding to the next, it can be a nice way of doing a few "mutations" (rebindings) and then leaving the value immutable through the rest of the block: let foo = something(); let foo = something_else(foo) + bar; // from here on in, foo is not mutated // ... "let" stands out in syntax-highlighting much more readily than a casual assignment to a mutable variable. It's a style issue. -Graydon From lists at arctur.us Thu May 30 13:49:47 2013 From: lists at arctur.us (Mitch Skinner) Date: Thu, 30 May 2013 13:49:47 -0700 Subject: [rust-dev] RFC: conventions for default arguments In-Reply-To: <20130530095637.GH3607@Mr-Bennet> References: <20130530095637.GH3607@Mr-Bennet> Message-ID: I'm not sure how much this overlaps with what you're proposing, but regarding hashmaps: I'm hoping to see overloadable IndexAddAssign and IndexMulAssign and friends someday, and the notion of neutral element differs between them, e.g.: impl HashMap { ... IndexAddAssign ... } impl HashMap { ... IndexMulAssign ... } So I guess the question I'm asking is, is Zero universal enough to make it a library convention? Mitch On Thu, May 30, 2013 at 2:56 AM, Niko Matsakis wrote: > Another example is in Hashmaps, where we offer two variants on the > "find-or-insert" pattern: > > fn find_or_insert(&mut self, K, V) -> Option<&V> > fn find_or_insert_with(&mut self, K, &fn(&K) -> V) -> Option<&V> > > Under my proposal there would just be: > > fn find_or_insert(&mut self, K, &fn(&K) -> V) -> Option<&mut V> > fn find_or_insert_zero(&mut self, K) -> Option<&mut V> // where V:Zero > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Thu May 30 13:52:46 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 30 May 2013 16:52:46 -0400 Subject: [rust-dev] RFC: conventions for default arguments In-Reply-To: References: <20130530095637.GH3607@Mr-Bennet> Message-ID: On Thu, May 30, 2013 at 4:49 PM, Mitch Skinner wrote: > I'm not sure how much this overlaps with what you're proposing, but > regarding hashmaps: > > I'm hoping to see overloadable IndexAddAssign and IndexMulAssign and friends > someday, and the notion of neutral element differs between them, e.g.: > > > impl HashMap { > ... IndexAddAssign ... > } > impl HashMap { > ... IndexMulAssign ... > } > > So I guess the question I'm asking is, is Zero universal enough to make it a > library convention? > > Mitch I don't think Zero/One are needed for Index methods, since it's already defined as failing if the element isn't present for vectors. It would be odd to implement it differently for other types. From rexlen at gmail.com Thu May 30 15:26:16 2013 From: rexlen at gmail.com (Renato Lenzi) Date: Fri, 31 May 2013 00:26:16 +0200 Subject: [rust-dev] for loop Message-ID: with fot int::range(low,hi) i can loop from low to h1-1 with for int::range_step(low, hi, step) i can loop for low to hi-1 with step "step" with for int::range_rev(hi, low) i can loop from hi to low, reverse mode but... how can loop from hi to low with step other than 1? range_rev_step is obviously undefined.... thx. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lindsey at composition.al Thu May 30 15:42:48 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Thu, 30 May 2013 18:42:48 -0400 Subject: [rust-dev] for loop In-Reply-To: References: Message-ID: On Thu, May 30, 2013 at 6:26 PM, Renato Lenzi wrote: > with > fot int::range(low,hi) > i can loop from low to h1-1 > > with > for int::range_step(low, hi, step) > i can loop for low to hi-1 with step "step" > > with > for int::range_rev(hi, low) > i can loop from hi to low, reverse mode > > but... how can loop from hi to low with step other than 1? range_rev_step is > obviously undefined.... range_step works fine for this, too: fn main() { for int::range_step(10, 1, -2) |i| { io::print(fmt!("%d ", i)); } } prints "10 8 6 4 2". The first and second arguments are "start" and "stop" rather than "lo" and "hi". Lindsey From jeaye at arrownext.com Thu May 30 15:44:43 2013 From: jeaye at arrownext.com (jeaye at arrownext.com) Date: Thu, 30 May 2013 16:44:43 -0600 Subject: [rust-dev] for loop In-Reply-To: References: Message-ID: <308805e79ab2cd517d96b34c616fe971@arrownext.com> Perhaps with the following (not tested) for int::range_step(hi, low, step) or for int::range_step(hi, low, -step) J On 2013-05-30 16:26, Renato Lenzi wrote: > with > fot int::range(low,hi)? > i can loop from low to h1-1 > > with > for int::range_step(low, hi, step)? > i can loop for low to hi-1 with step "step" > > with > for int::range_rev(hi, low) > i can loop from hi to low, reverse mode > > but... how can loop from hi to low with step other than 1? > range_rev_step is obviously undefined.... > > thx. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From steve at steveklabnik.com Thu May 30 15:49:38 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Thu, 30 May 2013 15:49:38 -0700 Subject: [rust-dev] for loop In-Reply-To: <308805e79ab2cd517d96b34c616fe971@arrownext.com> References: <308805e79ab2cd517d96b34c616fe971@arrownext.com> Message-ID: I literally committed an example of using this just today: https://github.com/mozilla/rust/pull/6841/files From banderson at mozilla.com Thu May 30 19:42:00 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 30 May 2013 19:42:00 -0700 Subject: [rust-dev] Scheduler and I/O work items for the summer Message-ID: <51A80DF8.3000608@mozilla.com> Hi Rusties, Allow me to present the status of our ongoing quest to rewrite the task scheduler, along with the major work items remaining. The results so far are encouraging but there is a very large amount of work left, particularly regarding I/O. In addition to myself we'll have two interns working on these areas this summer, but we could use more help still. This is an especially good opportunity to influence the way I/O works in Rust. I'm hoping that we will cut over to the new scheduler in June, but expect that crucial I/O-related work will continue for most of the year. At the moment we have a multithreaded task scheduler that integrates non-blocking TCP built on top of libuv. So far it uses a very basic scheduling strategy that employs several contended locks, but most of the components of the full algorithm are in place, just waiting to be filled in. It is expected that once we're done the entire scheduler will be lock-free. Besides the aforementioned locking it also allocates far too much at the moment but that's not a limitation of the design. As far as the scheduler goes I have not run into any major surprises and still expect it to be significantly more efficient than the current one. The biggest concern about scheduling is that our requirements force our scheduler to do more synchronization than specified by the work stealing algorithm alone. Whereas the literature describes work stealing as only synchronizing on the work stealing deque, we also have message passing between schedulers and a mechanism to put individual schedulers that can't find work to sleep and wake them later, both of which require further synchronization. This expense can be mitigated in some cases, but not all. As I've been working on the scheduler I have begun separating the task and its services from the coroutine task scheduler with the intent that we can have Rust tasks that are not green threads but instead regular threads with no userspace scheduling overhead at all. This has ripple effects throughout the standard library, particularly with the concurrency primitives, and I don't expect this to reach feature parity with green thread tasks for a long time, but removing the green thread requirement allows us to make a stronger case still for being a true 'systems language'. Most of my work on the I/O stack has been in specifying the main I/O traits and building up the multi-layer interface between the public-facing I/O library and libuv. I think I've sufficiently proven the strategy of using the scheduler to convert async I/O to sync I/O, but there's a whole lot more to implement and there are a number of outstanding design problems to solve. We've previously discussed here how I/O should do [error handling]. The feedback in that thread was great, but it is not yet reflected in the current implementation. I have though introduced a `read_error` condition specifically for the `read` method and all extensions that build upon it, but it is not fleshed out. What worries me the most about the entire endeavour is 'select'. We have great need for some facility to wait on multiple types of events (particularly I/O and ports) simultaneously, but the requirements can be rather complex (detailed later). I am not sure that the old unix 'select' function (as we used in pipes) is the best abstraction for this and feel we need to do further research on this topic. I would like to start prototyping something here soon. I've previously done two experiments with microbenchmarks of TCP [read performance] and single-threaded [scheduling performance] and claimed that the results were encouraging. Of course things will change a lot as we implement multi-threading and move on to better benchmarks. I'm maintaining a selection of comparative [benchmarks] in an external repo that are currently a bit out of date. I don't know that I recommend using the new scheduler yet for purposes other than scheduler development, but it can be turned on by setting the RUST_NEWRT environment variable. At the moment this will set up a single-threaded scheduler only but I'll soon convert this to a multi-threaded scheduler. For simple programs you shouldn't see any difference in execution, but some library features are still busted. Last I checked 95% of the run-pass tests succeeded with RUST_NEWRT set. The [main issue] for the entire scheduler rewrite is #4419. Within that one there is a description of the design and links to other related topics. [error handling]: https://mail.mozilla.org/pipermail/rust-dev/2013-April/003746.html [read performance]: https://github.com/mozilla/rust/pull/6313#issuecomment-17577510 [scheduling performance]: https://mail.mozilla.org/pipermail/rust-dev/2013-May/004127.html [benchmarks]: https://github.com/brson/rust-sched-bench [main issue]: https://github.com/mozilla/rust/issues/4419 The remainder of this email describes the most significant remaining work items. ## Add remaining implementations of I/O traits core::rt::io defines several traits for synchronous I/O, including Reader and Writer. We have a non-blocking TCP implementation in core::rt::io::net::tcp but that's it. We need non-blocking implementations for files, UDP, unix pipes, then also blocking implementations of the same, based not on uv, but on plain file descriptors and sockets. https://github.com/mozilla/rust/issues/4248 ## Design string encoding and decoding for Reader/Writer traits How do we deal with string encoding of I/O? The existing implementation uses extension methods on Readers and Writers, but this is not sufficient because it doesn't maintain any state. Need a better understanding of the requirements here, but these might involve new decorator types. https://github.com/mozilla/rust/issues/6164 ## Design and implement some solution for select / async events We need a way to efficiently wait on multiple types of events at once, including port receives, I/O reads, socket accepts, timers. This has some very complicated requirements to satisfy, as detailed in the linked issue, and I'm not sure what the right abstractions are here. This is super important and the biggest risk to the whole effort. If anybody has opinions about this topic I would love to hear them. https://github.com/mozilla/rust/issues/6842 ## Make I/O threadsafe I/O types must perform I/O on the scheduler on which they were created, but they are also sendable. This means that when we perform I/O we must check that we are on the correct scheduler, and if not then reschedule the running task. This complexity also infects 'select' and could conceivably lead to some untenable situations at runtime that can do nothing but `fail!`. https://github.com/mozilla/rust/issues/6843 ## stdin/out/err Need to create non-blocking access to the global resources stdin/stdout/stderr. Currently I'm thinking these will be Readers and Writers backed by ports, with some protocol for obtaining exclusive access. https://github.com/mozilla/rust/issues/6846 ## Port existing core::io users to core::rt::io::native In preparation for removing core::io we need to start porting existing users to the blocking implementations (which don't yet exist) of the new I/O API. This will involve identifying and porting missing features and completing various other I/O tasks. https://github.com/mozilla/rust/issues/6850 ## Lock free data structures There are several concurrent data structures used in the scheduler that are currently implemented with locks and need to be reimplemented without because they are heavily contended. The easiest of these are the MessageQueue and the SleeperList. MessageQueue is a multiple-producer, single-consumer unbounded queue used for sending messages between schedulers. SleeperList is a multiple-producer, multiple-consumer bounded stack used to track which schedulers are 'asleep'. https://github.com/mozilla/rust/issues/6837 https://github.com/mozilla/rust/issues/6838 ## Work stealing Multithreading is currently not implemented using work stealing, but instead using a shared work queue. Adding work stealing will require converting WorkQueue to a deque and adding the 'thief' phase of the work stealing algorithm to the scheduler. Locating work queues to steal from will involve creating further lock-free data structures. Some ideas are outlined on the issue tracker. James Miller has an implementation of a lock free deque that we can use for this. Multiple people have interest in this topic so let's make sure we coordinate. https://github.com/mozilla/rust/issues/3095 ## Implement stack growth We need to make the new tasks support segmented stacks. For the most part this will involve copying lots of fiddly bits from the previous implementation, but I want to make the caching story in this implementation simpler, with each scheduler having a single stack pool, instead of having some of the stacks originate in the scheduler and some in the task. This will be easier once fast_ffi is finished, but it will likely require adding a new attribute to LLVM to suppress the segmented stack function prologue. https://github.com/mozilla/rust/issues/6844 ## Remove the old scheduler We can probably get this done relatively soon. There are some features not implemented yet and some unimplemented features that we can just drop, at least temporarily (pipes select). This can be done even before finishing I/O, since the blocking core::io will continue working fine. https://github.com/mozilla/rust/issues/6587 ## Implement a simple HTTP client/server library I really want to be able to demonstrate a fast and convenient HTTP library. https://github.com/mozilla/rust/issues/6167 If you've read this far then thanks for your time. I'm giving you a virtual high five! -Brian From robert at ocallahan.org Thu May 30 21:09:10 2013 From: robert at ocallahan.org (Robert O'Callahan) Date: Fri, 31 May 2013 16:09:10 +1200 Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: <51A7986B.1000708@mozilla.com> References: <51A7986B.1000708@mozilla.com> Message-ID: FWIW shadowed local variable declarations have been a source of some frustrating bugs in Gecko. In a big function you see a use of 'x', and a declaration of 'x', and assume they're related, but they're not. Rob -- q?qIqfq qyqoquq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qtqhqeqmq.q qAqnqdq qiqfq qyqoquq qdqoq qgqoqoqdq qtqoq qtqhqoqsqeq qwqhqoq qaqrqeq qgqoqoqdq qtqoq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qdqoq qtqhqaqtq.q" -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeaye at arrownext.com Thu May 30 23:10:37 2013 From: jeaye at arrownext.com (Jeaye) Date: Thu, 30 May 2013 23:10:37 -0700 Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: References: <51A7986B.1000708@mozilla.com> Message-ID: <51A83EDD.2070908@arrownext.com> I quite like the feature and find it particularly useful for using similar variables for different, but related tasks (different in that it warrants another initialization, but similar in that it is beneficial to keep the same variable name). I don't feel too strongly either way though. |// Without (explicit scoping) fn foo() { { let x = &something; ...do_with_x... } { let x = &something_else; ...do_else_with_x... } } // With (redeclared local vars) fn foo() { let x = &something; ...do_with_x... let x = &something_else; ...do_else_with_x... }| J On 05/30/2013 09:09 PM, Robert O'Callahan wrote: > FWIW shadowed local variable declarations have been a source of some > frustrating bugs in Gecko. In a big function you see a use of 'x', and > a declaration of 'x', and assume they're related, but they're not. > > Rob > -- > q"qIqfq qyqoquq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qyqoquq,q > qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq > qsqiqnqnqeqrqsq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qtqhqeqmq.q > qAqnqdq qiqfq qyqoquq qdqoq qgqoqoqdq qtqoq qtqhqoqsqeq qwqhqoq > qaqrqeq qgqoqoqdq qtqoq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq > qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qdqoq qtqhqaqtq.q" > > > _______________________________________________ > 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 Fri May 31 00:11:05 2013 From: me at kevincantu.org (Kevin Cantu) Date: Fri, 31 May 2013 00:11:05 -0700 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: <51A63BBC.9080701@mozilla.com> Message-ID: Relatively crude tools like `run rust` or `rustx` go a long way, but they're not a substitute for properly learning the module system or for having a good REPL handy. It seems silly to bin an experimental feature out of the fear that the number one request of new users exploring the language will, itself, scare them away. Maybe for now just stick in a warning when it starts up: "RUSTI IS STILL AN EXPERIMENTAL BETA FEATURE! If you have a problem, try our more reliable `rust run`, instead. And volunteers are needed! :D" Kevin -- Kevin Cantu On Wed, May 29, 2013 at 5:50 PM, Thad Guidry wrote: > RUST RUN. FTW. :-) > > > On Wed, May 29, 2013 at 4:29 PM, John Clements wrote: > >> >> On May 29, 2013, at 10:32 AM, Graydon Hoare wrote: >> >> ... >> > >> > I agree that a 'rust run' command, or indeed exploiting our support for >> > shebang comments[1], should be sufficient for most users. But I'm not >> > convinced the repl serves no purpose, yet (though it's true, I don't use >> > seem to ever use it; I also write surprisingly little rust code these >> > days). People ask for it, and it doesn't really bend the language any to >> > support it. It _is_ a code-maintenance cost, of course, so I'm also >> > curious what others think in terms of the balance of costs/benefits. >> >> My vote: dump it. This might sound surprising from a Schemer, but >> probably not from a Racketeer. Making the top-level work correctly soaked >> up far too much time in the Racket environment. There's nothing more >> infuriating than getting something to work in the REPL and then discovering >> that it doesn't work in compiled code? unless it's struggling for weeks to >> get something to work in the REPL, only to discover that it works just fine >> in compiled code. >> >> I think that the principal use case for a REPL is interactive exploration >> of what rust programs mean, and I think that the best way to support this >> is to have a nice clean "rust run", and possibly some sugar that makes >> evaluating and printing the result of a single expression more convenient. >> >> My opinion only. >> >> John >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > > _______________________________________________ > 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 jon.mb at proinbox.com Fri May 31 01:37:37 2013 From: jon.mb at proinbox.com (John Mija) Date: Fri, 31 May 2013 09:37:37 +0100 Subject: [rust-dev] Rust and Go In-Reply-To: <51A65C48.90006@proinbox.com> References: <51A65C48.90006@proinbox.com> Message-ID: <51A86151.8060700@proinbox.com> After of to do a lot of research, I think that Go never would be widely used on the web so it's a waste of time to try integrate it with Rust (or with Servo). And the main reason is Dart, a language designed for the web which is heavily promoted by Google: https://gist.github.com/paulmillr/1208618/raw/a9edc5df513a8b810c8fc83cdf291ee8ac2f8abe/dart.txt http://news.dartlang.org/2013/05/dart-project-co-founders-answer-your.html The truth is that I expected to be able to use Go in both front-end server and client but it has not been designed for it, although Dart is it. El 29/05/13 20:51, John Mija escribi?: > How could be integrated the Go language in Rust? > > If somebody were to write a Go compiler to be integrated in Rust[1], > which path would be the best one? To create bindings to commands > [568][acgl] [2] or write the SSA library/interpreter [3] in Rust? > > [1] "to be integrated in other language": I refer to can compile Go code > without to use an OS call to execute the command, just like a browser > built in C++ has integrated JavaScript or like Lua can be integrated > with C. > > [2]: http://golang.org/src/cmd/ > [3]: http://godoc.org/code.google.com/p/go.tools/ssa > http://godoc.org/code.google.com/p/go.tools/ssa/interp > > * * * > > What reasons could want somebody to use Go from Rust? > > + It could be used in programs where you want give power to users to run > some tasks, i.e. into a database; today, it's being added JS to some DBMSs > > + To Run web scripts in Go --into a fork of Servo-- which will allow > create powerful applications easily with a great performance and easily > of debugging. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > From sh4.seo at samsung.com Fri May 31 01:44:10 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Fri, 31 May 2013 08:44:10 +0000 (GMT) Subject: [rust-dev] Using new I/O error handling Message-ID: <23054192.29811369989850304.JavaMail.weblogic@epv6ml13> Is it actually possible to use new I/O error handling at the moment? It seems to me that it is not possible to get at std::rt::io::io_error at all, because conditions are private and do not work cross-crate. https://github.com/mozilla/rust/issues/5446 https://github.com/mozilla/rust/issues/6009 From zack at z0w0.me Fri May 31 01:49:07 2013 From: zack at z0w0.me (Zack Corr) Date: Fri, 31 May 2013 18:49:07 +1000 Subject: [rust-dev] A case for removing rusti In-Reply-To: References: <51A63BBC.9080701@mozilla.com> Message-ID: There's already an experimental notice. On 31 May 2013 17:11, "Kevin Cantu" wrote: > Relatively crude tools like `run rust` or `rustx` > go a long way, but they're not a substitute for properly learning the > module system or for having a good REPL handy. It seems silly to bin an > experimental feature out of the fear that the number one request of new > users exploring the language will, itself, scare them away. > > Maybe for now just stick in a warning when it starts up: "RUSTI IS STILL > AN EXPERIMENTAL BETA FEATURE! If you have a problem, try our more reliable > `rust run`, instead. And volunteers are needed! :D" > > Kevin > > > > -- > Kevin Cantu > > > On Wed, May 29, 2013 at 5:50 PM, Thad Guidry wrote: > >> RUST RUN. FTW. :-) >> >> >> On Wed, May 29, 2013 at 4:29 PM, John Clements > > wrote: >> >>> >>> On May 29, 2013, at 10:32 AM, Graydon Hoare wrote: >>> >>> ... >>> > >>> > I agree that a 'rust run' command, or indeed exploiting our support for >>> > shebang comments[1], should be sufficient for most users. But I'm not >>> > convinced the repl serves no purpose, yet (though it's true, I don't >>> use >>> > seem to ever use it; I also write surprisingly little rust code these >>> > days). People ask for it, and it doesn't really bend the language any >>> to >>> > support it. It _is_ a code-maintenance cost, of course, so I'm also >>> > curious what others think in terms of the balance of costs/benefits. >>> >>> My vote: dump it. This might sound surprising from a Schemer, but >>> probably not from a Racketeer. Making the top-level work correctly soaked >>> up far too much time in the Racket environment. There's nothing more >>> infuriating than getting something to work in the REPL and then discovering >>> that it doesn't work in compiled code? unless it's struggling for weeks to >>> get something to work in the REPL, only to discover that it works just fine >>> in compiled code. >>> >>> I think that the principal use case for a REPL is interactive >>> exploration of what rust programs mean, and I think that the best way to >>> support this is to have a nice clean "rust run", and possibly some sugar >>> that makes evaluating and printing the result of a single expression more >>> convenient. >>> >>> My opinion only. >>> >>> John >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >> >> >> >> -- >> -Thad >> http://www.freebase.com/view/en/thad_guidry >> >> _______________________________________________ >> 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 niko at alum.mit.edu Fri May 31 05:10:45 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 31 May 2013 08:10:45 -0400 Subject: [rust-dev] Question about lifetimes in type parameters In-Reply-To: <51A75B80.9080400@crsr.net> References: <51A4FC17.6090803@crsr.net> <20130529095503.GA22384@Mr-Bennet> <51A67953.7010308@crsr.net> <20130530100947.GJ3607@Mr-Bennet> <51A75B80.9080400@crsr.net> Message-ID: <20130531121045.GE3002@Mr-Bennet> Hi, sorry I haven't had a chance to look at this yet, I'll try to get to it today! Niko On Thu, May 30, 2013 at 09:00:32AM -0500, Tommy M. McGuire wrote: > On 05/30/2013 05:09 AM, Niko Matsakis wrote: > > On Wed, May 29, 2013 at 04:55:31PM -0500, Tommy M. McGuire wrote: > >> The problem is that I want to use a completely unrelated vector as the > >> argument to find() instead of an alias for part of the buffer or a pair > >> of indices into the buffer. > >> > >> Currently, with my quick change to incoming, the code > >> > >> let kkey : &[u8] = key; // key : ~[u8] > >> match dictionary.find(&kkey) { > >> > >> produces: > >> > >> 55:38 error: borrowed value does not live long enough > >> let kkey : &[u8] = key; > >> ^~~ > >> 67:1 note: borrowed pointer must be valid for the lifetime > >> &br_named({repr: 83, ctxt: 0}) as defined on the block at 48:0... > >> ... > >> 65:5 note: ...but borrowed value is only valid for the block at 50:46 > >> > >> The lifetime '&br_named(...)' stuff should be "'b", the lifetime > >> parameter of the function (the block at 48:0) that is associated with > >> the keys and values from the HashMap (was LinearMap) and the buffer. > > > > This seems like a bug (also, what a lousy error message! sorry.), I > > will further investigate. > > Thanks! (The error message changed when I updated incoming, so it's > something recent.) > > I'm not sure it is a bug, though. I may not be understanding lifetimes > well enough, but I think the interaction between that and generics is > problematic. In this case, there doesn't seem to be enough information > to tell the difference between find(), for which the lifetime argument > is not terribly useful, and insert(), where it would be. > > > -- > Tommy M. McGuire > mcguire at crsr.net From corey at octayn.net Fri May 31 06:01:22 2013 From: corey at octayn.net (Corey Richardson) Date: Fri, 31 May 2013 09:01:22 -0400 Subject: [rust-dev] Buildbot stat reporting Message-ID: Especially for isrustfastyet, more stats reported from the buildbots would be wonderful, especially binary size and memory usage (maybe only on linux, with cgroups if possible) or pass timing. Is it possible to have this added? From graydon at mozilla.com Fri May 31 08:40:27 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 31 May 2013 08:40:27 -0700 Subject: [rust-dev] Buildbot stat reporting In-Reply-To: References: Message-ID: <51A8C46B.20705@mozilla.com> On 31/05/2013 6:01 AM, Corey Richardson wrote: > Especially for isrustfastyet, more stats reported from the buildbots > would be wonderful, especially binary size and memory usage (maybe > only on linux, with cgroups if possible) or pass timing. > > Is it possible to have this added? Yes, I have been sketching mechanisms -- "reliable" ones we can use for such purposes -- for this for a while. It's not at the top of my priority list -- gc is that -- but I'm definitely working on several sub-tasks of it in spare moments. I have mixed feelings about how to do this. In the crudest sense, I have a small shell script that can report such things via cgroups on linux. So they could be plotted and/or measured-by-bors for the sake of integration testing, assuming we can pick a narrow enough "regression" margin to block the worst offenses. The mozilla rust group has agreed in principle to adapting bors to "prevent perf regressions" as well. Wiring that up would probably take on the order of a week of work; I have most of the pieces sketched out and working now. Secondarily, I would like all rust processes to have substantially more ability to measure and report-on _themselves_ when running, and could (for example) measure various counter-maximum values on exit for the sake of reporting to bors / isrustfastyet. On that level, there is much more work to do. I filed a few bugs earlier in the week which others are quite welcome to work on; I will try to get to them eventually but I suspect others will be able to complete the work much faster than me: https://github.com/mozilla/rust/issues/6810 https://github.com/mozilla/rust/issues/6808 https://github.com/mozilla/rust/issues/6812 https://github.com/mozilla/rust/issues/6816 These are all under the new tag I-instrumentation. If you have other ideas for ways of instrumenting rust programs to make their performance characteristics less opaque, please file more such bugs and/or get hacking! This sort of work is often fruitful. (Finally, I have a wip patch that will make #[bench] benchmarks much more useful by supporting dump-reload-compare operations on the whole benchmark-set for a given crate. These may wind up too fine grained to be used for regression-blocking on landings. We'll have to see. I suspect something like #6812 above may help solidify mechanical reasoning around that sort of thing.) -Graydon From graydon at mozilla.com Fri May 31 08:45:41 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 31 May 2013 08:45:41 -0700 Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: References: <51A7986B.1000708@mozilla.com> Message-ID: <51A8C5A5.9030208@mozilla.com> On 30/05/2013 9:09 PM, Robert O'Callahan wrote: > FWIW shadowed local variable declarations have been a source of some > frustrating bugs in Gecko. In a big function you see a use of 'x', and a > declaration of 'x', and assume they're related, but they're not. I'll take that as a vote for a lint flag. Maybe set to warning level by default? (Our lints can be set from anything between allow and forbid, the latter meaning not just "error" but also "nobody else can override this in this crate, I don't care what they think") -Graydon From niko at alum.mit.edu Fri May 31 08:57:09 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 31 May 2013 11:57:09 -0400 Subject: [rust-dev] version numbers in rust source Message-ID: <20130531155709.GG3002@Mr-Bennet> I was reading Armstrong's [review of Elixir][1] and I thought this paragraph was interesting, given our recent discussions about backwards compatibility in Rust. Basically he argues for tagging code with the version of the language it is targeting. I think this is a good idea too, though I don't know how helpful it is. The only language I knew of that took this approach was XSLT, but I guess Erlang does too. It'd be interesting to know how helpful it is for migrating and so forth. ``` XML files always start This is great. Reading the first line of an XML file is like listening to the opening bars of Rachmaninoff?s third piano concerto. A sublime experience. All praise to the XML designers, hallowed be their names, give these guys some Turing prizes. Putting the language version in all source files is essential. Why is this? Early Erlang did not have list comprehensions. Suppose that we give a modern Erlang module to an old Erlang compiler and ask it to compile it. The modern code has list comprehensions, but the old compiler doesn?t know about list comprehensions so the old compiler thinks this is a syntax error. If a version3 Erlang compiler is given a file that starts: -version(5,0). Then it should say ** auuuuugggghhhhhh ** Oh bother and blast, I am mere version 3 compiler and cannot see into the future. You have given me a version 5 program. This means my time on earth has come. You will have to kill me. You will uninstall me, and install a version five compiler. I will be no more. I will cease to exist. Goodbye old friend. I have a headache. I'm going to have a rest... ** It?s the first law of data design: All data that might change in the future should be tagged with a version number. and a module is data. ``` Niko [1] http://joearms.github.io/2013/05/31/a-week-with-elixir.html From corey at octayn.net Fri May 31 09:00:39 2013 From: corey at octayn.net (Corey Richardson) Date: Fri, 31 May 2013 12:00:39 -0400 Subject: [rust-dev] version numbers in rust source In-Reply-To: <20130531155709.GG3002@Mr-Bennet> References: <20130531155709.GG3002@Mr-Bennet> Message-ID: Doesn't racket also do this with its `#lang ` construct? On Fri, May 31, 2013 at 11:57 AM, Niko Matsakis wrote: > I was reading Armstrong's [review of Elixir][1] and I thought this > paragraph was interesting, given our recent discussions about > backwards compatibility in Rust. Basically he argues for tagging code > with the version of the language it is targeting. I think this is a > good idea too, though I don't know how helpful it is. The only > language I knew of that took this approach was XSLT, but I guess > Erlang does too. It'd be interesting to know how helpful it is for > migrating and so forth. > > ``` > XML files always start > > > > This is great. Reading the first line of an XML file is like listening to the opening bars of Rachmaninoff?s third piano concerto. A sublime experience. All praise to the XML designers, hallowed be their names, give these guys some Turing prizes. > > Putting the language version in all source files is essential. Why is this? > > Early Erlang did not have list comprehensions. Suppose that we give a modern Erlang module to an old Erlang compiler and ask it to compile it. The modern code has list comprehensions, but the old compiler doesn?t know about list comprehensions so the old compiler thinks this is a syntax error. > > If a version3 Erlang compiler is given a file that starts: > > -version(5,0). > > Then it should say > > ** auuuuugggghhhhhh ** > > Oh bother and blast, I am mere version 3 compiler > and cannot see into the future. > > You have given me a version 5 program. This means > my time on earth has come. > > You will have to kill me. You will uninstall me, > and install a version five compiler. I will be > no more. I will cease to exist. > > Goodbye old friend. > > I have a headache. I'm going to have a rest... > ** > > It?s the first law of data design: > > All data that might change in the future should be > tagged with a version number. > > and a module is data. > ``` > > > Niko > > [1] http://joearms.github.io/2013/05/31/a-week-with-elixir.html > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From talex5 at gmail.com Fri May 31 09:28:32 2013 From: talex5 at gmail.com (Thomas Leonard) Date: Fri, 31 May 2013 17:28:32 +0100 Subject: [rust-dev] version numbers in rust source In-Reply-To: <20130531155709.GG3002@Mr-Bennet> References: <20130531155709.GG3002@Mr-Bennet> Message-ID: On 31 May 2013 16:57, Niko Matsakis wrote: > I was reading Armstrong's [review of Elixir][1] and I thought this > paragraph was interesting, given our recent discussions about > backwards compatibility in Rust. Basically he argues for tagging code > with the version of the language it is targeting. I think this is a > good idea too, though I don't know how helpful it is. The only > language I knew of that took this approach was XSLT, but I guess > Erlang does too. It'd be interesting to know how helpful it is for > migrating and so forth. E does the same thing. It's particularly handy if you want to make backwards-incompatible changes to syntax without breaking existing code. E includes one properties file for each version of the language, saying which features should be enabled or disabled for each version. Here's an example with lots of comments: http://wiki.erights.org/wiki/Syntax-props-default.txt -- Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA From lucian.branescu at gmail.com Fri May 31 09:44:19 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Fri, 31 May 2013 17:44:19 +0100 Subject: [rust-dev] version numbers in rust source In-Reply-To: <20130531155709.GG3002@Mr-Bennet> References: <20130531155709.GG3002@Mr-Bennet> Message-ID: On 31 May 2013 16:57, Niko Matsakis wrote: > The only language I knew of that took this approach was XSLT, but I guess > Erlang does too. It'd be interesting to know how helpful it is for > migrating and so forth. > Clojure's Leiningen projects declare Clojure itself as a dependency, with an explicit version https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L38 Perhaps it would be less annoying to declare it on a mod/crate/pkg level? -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Fri May 31 09:47:22 2013 From: clements at brinckerhoff.org (John Clements) Date: Fri, 31 May 2013 09:47:22 -0700 Subject: [rust-dev] version numbers in rust source In-Reply-To: References: <20130531155709.GG3002@Mr-Bennet> Message-ID: On May 31, 2013, at 9:00 AM, Corey Richardson wrote: > Doesn't racket also do this with its `#lang ` construct? Yes. In fact, I commented recently on the racket mailing list that I had a bunch of code written in #lang mzscheme ? that was still running fine in the modern-day engine. John From vadimcn at gmail.com Fri May 31 10:18:54 2013 From: vadimcn at gmail.com (Vadim) Date: Fri, 31 May 2013 10:18:54 -0700 Subject: [rust-dev] Scheduler and I/O work items for the summer In-Reply-To: <51A80DF8.3000608@mozilla.com> References: <51A80DF8.3000608@mozilla.com> Message-ID: > ## Design and implement some solution for select / async events > > We need a way to efficiently wait on multiple types of events at once, > including port receives, I/O reads, socket accepts, timers. This has some > very complicated requirements to satisfy, as detailed in the linked issue, > and I'm not sure what the right abstractions are here. This is super > important and the biggest risk to the whole effort. If anybody has opinions > about this topic I would love to hear them. > > https://github.com/mozilla/**rust/issues/6842 > > Hi Brian, So you mention .NET asyncs in the linked issue... The .NET way of doing this is to have functions that initiate async operation and return a future. You then explicitly wait for that future to resolve. If several asyncs need to be done concurrently, you start them all, then pass a list of futures to a helper function that returns another future, which resolves when all underlying futures had resolved. Another helper function allows to wait until any one of the futures resolves. Putting all this together (loosely translating C# into Rust), you'd write something like this: let operations = [start_operation1(), start_operation2(), ...]; let timer = sleep(timeout); // returns future that resolves after the specified timeout expires let top_level_future = resolve_when_any( [resolve_when_all(operations), timer] ); await top_level_future; // wait until the future has been resolved. if (timer.is_complete()) // we timed out else // all operations completed (or failed) before timer has expired Composition of futures works out pretty nicely, however it also has downsides: 1. The simple case of a single blocking i/o operation now looks like this "result = await(start_operatoin())" instead of just "result = operation()" .NET solves this by providing both synchronous and asynchronous variants of each operation in most cases. 2. Each i/o operation now needs to allocate heap memory for the future object. This has been known to create GC performance problems for .NET web apps which process large numbers of small requests. If these can live on the stack, though, maybe this wouldn't be a problem for Rust. As a side note, your list doesn't have anything regarding cancellation of async operations. In the example above you'd probably want to attempt to cancel outstanding i/o operations when timeout expires. .NET provides standard infrastructure for this, and I think that Rust will need one too. HTH, Vadim -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri May 31 10:34:44 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 31 May 2013 10:34:44 -0700 Subject: [rust-dev] version numbers in rust source In-Reply-To: <20130531155709.GG3002@Mr-Bennet> References: <20130531155709.GG3002@Mr-Bennet> Message-ID: <51A8DF34.4040600@mozilla.com> On 13-05-31 08:57 AM, Niko Matsakis wrote: > I was reading Armstrong's [review of Elixir][1] and I thought this > paragraph was interesting, given our recent discussions about > backwards compatibility in Rust. Basically he argues for tagging code > with the version of the language it is targeting. I think this is a > good idea too, though I don't know how helpful it is. The only > language I knew of that took this approach was XSLT, but I guess > Erlang does too. It'd be interesting to know how helpful it is for > migrating and so forth. This bug has been open for some time: https://github.com/mozilla/rust/issues/3392 I'd be happy to take a patch from anyone who wants to implement it. It's a small thing to finish. -Graydon From daniel at fdr.io Fri May 31 11:55:00 2013 From: daniel at fdr.io (Daniel Farina) Date: Fri, 31 May 2013 11:55:00 -0700 Subject: [rust-dev] Please tell me about making rustc faster Message-ID: I've been poking around in rustc, after noting that compile times are much longer than I'd expect. So while some micro optimizations may help, I'm wondering if anyone has given a lot of thought as to how to make the llvm passes faster or parallel, because this is something like more than half the battle. What's worrisome is Rust's typical compilation model encourages large crates that are one compilation unit, unlike, say, a pile of individual C files each emitting an object file that admittedly must be linked... but at least the instruction selector can be run in parallel. Does this present a sticky problem? From sebastian.sylvan at gmail.com Fri May 31 12:02:04 2013 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Fri, 31 May 2013 12:02:04 -0700 Subject: [rust-dev] Please tell me about making rustc faster In-Reply-To: References: Message-ID: There appears to be tons of general optimization issues here: https://github.com/mozilla/rust/issues?labels=I-slow&state=open On Fri, May 31, 2013 at 11:55 AM, Daniel Farina wrote: > I've been poking around in rustc, after noting that compile times are > much longer than I'd expect. > > So while some micro optimizations may help, I'm wondering if anyone > has given a lot of thought as to how to make the llvm passes faster or > parallel, because this is something like more than half the battle. > > What's worrisome is Rust's typical compilation model encourages large > crates that are one compilation unit, unlike, say, a pile of > individual C files each emitting an object file that admittedly must > be linked... but at least the instruction selector can be run in > parallel. Does this present a sticky problem? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Sebastian Sylvan -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel at fdr.io Fri May 31 12:21:11 2013 From: daniel at fdr.io (Daniel Farina) Date: Fri, 31 May 2013 12:21:11 -0700 Subject: [rust-dev] Please tell me about making rustc faster In-Reply-To: References: Message-ID: On Fri, May 31, 2013 at 12:02 PM, Sebastian Sylvan wrote: > There appears to be tons of general optimization issues here: > https://github.com/mozilla/rust/issues?labels=I-slow&state=open Many of these are standard library issues or code generation issues. Some are about rustc's compilation times in particular, but their level of background or detail don't give me a lot of confidence that I have a reasonable broad understanding of what the state of play is. From danielmicay at gmail.com Fri May 31 12:25:31 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 31 May 2013 15:25:31 -0400 Subject: [rust-dev] Please tell me about making rustc faster In-Reply-To: References: Message-ID: On Fri, May 31, 2013 at 2:55 PM, Daniel Farina wrote: > I've been poking around in rustc, after noting that compile times are > much longer than I'd expect. > > So while some micro optimizations may help, I'm wondering if anyone > has given a lot of thought as to how to make the llvm passes faster or > parallel, because this is something like more than half the battle. > > What's worrisome is Rust's typical compilation model encourages large > crates that are one compilation unit, unlike, say, a pile of > individual C files each emitting an object file that admittedly must > be linked... but at least the instruction selector can be run in > parallel. Does this present a sticky problem? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev LLVM is very fast, the problem is we're generating very bloated, bad IR pre-optimization. From thadguidry at gmail.com Fri May 31 13:14:47 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Fri, 31 May 2013 15:14:47 -0500 Subject: [rust-dev] Scheduler and I/O work items for the summer In-Reply-To: <51A80DF8.3000608@mozilla.com> References: <51A80DF8.3000608@mozilla.com> Message-ID: > > ## Design and implement some solution for select / async events > > We need a way to efficiently wait on multiple types of events at once, > including port receives, I/O reads, socket accepts, timers. This has some > very complicated requirements to satisfy, as detailed in the linked issue, > and I'm not sure what the right abstractions are here. This is super > important and the biggest risk to the whole effort. If anybody has opinions > about this topic I would love to hear them. > > https://github.com/mozilla/**rust/issues/6842 My 2 cents worth nothing :-) and I've replied inside the issue with the same idea... It seems to be very similar in tone to what Vadim described for .NET asyncs where you wait for a timeout or all operations (steps) to complete from an abstract view. This idea comes out of the Data Architect world that I live in. It's more along the lines of that basic idea that your pitching which I call "receivership". In Pentaho Data Integration, there is a process step called "Block this step until steps finish". What it does is Block a single step in an execution flow until a selected step or even multiple steps somewhere in the chain or process has completed it's execution and returned a True for it's "execution complete flag" where a launched listener is waiting and watching. It's a generic wrapper if you will, for additional next steps to perform, but those next steps do not get called, do not get any input, and no variables are passed to them until the child Blocking step has seen from (there's a listener process launched for each step or steps choosen to watch) all its parent or parents steps somewhere say that it's own execution has finished and lets the listener know. I think the "Block this step until steps finish" just waits for all those listeners it is watching to say it's OK to proceed with it's own set of next steps. -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri May 31 14:45:37 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 31 May 2013 14:45:37 -0700 Subject: [rust-dev] Please tell me about making rustc faster In-Reply-To: References: Message-ID: <51A91A01.7060805@mozilla.com> On 13-05-31 11:55 AM, Daniel Farina wrote: > I've been poking around in rustc, after noting that compile times are > much longer than I'd expect. > > So while some micro optimizations may help, I'm wondering if anyone > has given a lot of thought as to how to make the llvm passes faster or > parallel, because this is something like more than half the battle. > > What's worrisome is Rust's typical compilation model encourages large > crates that are one compilation unit, unlike, say, a pile of > individual C files each emitting an object file that admittedly must > be linked... but at least the instruction selector can be run in > parallel. Does this present a sticky problem? Long term, we don't think so. Short term, it's annoying to all of us; we're struggling with splitting time between completing features, fixing bugs, working on residual bits of lingering design problems, and (sadly, often last) optimizing the codegen. We should spend more time on it. Most of the problem comes from us generating too much LLVM code (and code that is hard for LLVM to work with). Much of _that_ comes from technical debt in the lowering pass, src/librustc/middle/trans. By necessity, trans is one of the oldest pieces of the compiler; and by unfortunate historical reality, we've changed enough assumptions about runtime representations enough times through the life of this compiler that trans is now generating a lot of unnecessary code. There is some instrumentation there to measure code generation by source. A few useful incantations are: # count LLVM instructions by trans function-call stack $ rustc -Z count-llvm-insns foo.rs | xdu and: # list symbols in the resulting binary sorted by size $ objdump -t libfoo.so | awk '/\.text/ { printf("%d\t%s\n", strtonum("0x" $5), $6) }' | c++filt | sort -n and: # visualize the instruction graph of a given compilation unit # first generate foo.bc, the llvm bitcode for foo.rs $ rustc --save-temps foo.rs # then generate a dot file for every function's CFG $ opt -analyze -dot-cfg foo.bc # then do graph layout on, say, the "::main" dot file # and convert to SVG; pick other dot files for other functions $ dot -Tsvg -ograph.svg <(c++filt References: <51A91A01.7060805@mozilla.com> Message-ID: On Fri, May 31, 2013 at 2:45 PM, Graydon Hoare wrote: > On 13-05-31 11:55 AM, Daniel Farina wrote: >> I've been poking around in rustc, after noting that compile times are >> much longer than I'd expect. >> >> So while some micro optimizations may help, I'm wondering if anyone >> has given a lot of thought as to how to make the llvm passes faster or >> parallel, because this is something like more than half the battle. >> >> What's worrisome is Rust's typical compilation model encourages large >> crates that are one compilation unit, unlike, say, a pile of >> individual C files each emitting an object file that admittedly must >> be linked... but at least the instruction selector can be run in >> parallel. Does this present a sticky problem? > > Long term, we don't think so. Short term, it's annoying to all of us; > we're struggling with splitting time between completing features, fixing > bugs, working on residual bits of lingering design problems, and (sadly, > often last) optimizing the codegen. We should spend more time on it. > > Most of the problem comes from us generating too much LLVM code (and > code that is hard for LLVM to work with). Much of _that_ comes from > technical debt in the lowering pass, src/librustc/middle/trans. By > necessity, trans is one of the oldest pieces of the compiler; and by > unfortunate historical reality, we've changed enough assumptions about > runtime representations enough times through the life of this compiler > that trans is now generating a lot of unnecessary code. I see. I did notice the translation pass is one of the other big fish, the other one being type checking. Looks like the translation, in addition to taking a long time, also generates a lot of work for LLVM with that time. Is the general idea there that employing a better understanding of Rust's higher level structures will allow quicker elimination of a lot of the low-level IR? Is there a general flavor to the unnecessary code being generated that is known, or is this a subject of some research? > There is some instrumentation there to measure code generation by > source. A few useful incantations are: > > # count LLVM instructions by trans function-call stack > $ rustc -Z count-llvm-insns foo.rs | xdu > > and: > > # list symbols in the resulting binary sorted by size > $ objdump -t libfoo.so | > awk '/\.text/ { printf("%d\t%s\n", strtonum("0x" $5), $6) }' | > c++filt | > sort -n > > and: > > # visualize the instruction graph of a given compilation unit > > # first generate foo.bc, the llvm bitcode for foo.rs > $ rustc --save-temps foo.rs > > # then generate a dot file for every function's CFG > $ opt -analyze -dot-cfg foo.bc > > # then do graph layout on, say, the "::main" dot file > # and convert to SVG; pick other dot files for other functions > $ dot -Tsvg -ograph.svg <(c++filt > # then take a look at it > $ firefox graph.svg Thanks, this is quite helpful. From banderson at mozilla.com Fri May 31 15:45:32 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 31 May 2013 15:45:32 -0700 Subject: [rust-dev] Scheduler and I/O work items for the summer In-Reply-To: References: <51A80DF8.3000608@mozilla.com> Message-ID: <51A9280C.6050304@mozilla.com> On 05/31/2013 10:18 AM, Vadim wrote: > > ## Design and implement some solution for select / async events > > We need a way to efficiently wait on multiple types of events at > once, including port receives, I/O reads, socket accepts, timers. > This has some very complicated requirements to satisfy, as > detailed in the linked issue, and I'm not sure what the right > abstractions are here. This is super important and the biggest > risk to the whole effort. If anybody has opinions about this topic > I would love to hear them. > > https://github.com/mozilla/rust/issues/6842 > > > Hi Brian, > > So you mention .NET asyncs in the linked issue... The .NET way of > doing this is to have functions that initiate async operation and > return a future. You then explicitly wait for that future to > resolve. If several asyncs need to be done concurrently, you start > them all, then pass a list of futures to a helper function that > returns another future, which resolves when all underlying futures had > resolved. Another helper function allows to wait until any one of the > futures resolves. Putting all this together (loosely translating C# > into Rust), you'd write something like this: > > let operations = [start_operation1(), start_operation2(), ...]; > let timer = sleep(timeout); // returns future that resolves after the > specified timeout expires > > let top_level_future = resolve_when_any( > [resolve_when_all(operations), timer] ); > > await top_level_future; // wait until the future has been resolved. > > if (timer.is_complete()) > // we timed out > else > // all operations completed (or failed) before timer has expired Thank you for the clear example. I like this model. With this problem in general I think the obvious solutions amount to taking one of two approaches: translate I/O events into pipe events; translate pipe events into I/O events. Solving the problem efficiently for either one is rather simpler than solving both. The example you show is promising model that looks like it could naively be implemented by buffering I/O into pipes. bblum and I talked about an implementation that would work well for this approach, but it has costs. I imagine it working like this. 1) The resolve_xxx function partitions the elements into pipesy types and I/O types. 3) For each of the I/O types it creates a new pipe, and registers a uv event. Note that because of I/O-scheduler affinity some of these may cause the task to migrate between threads. 4) Now we just wait on all the pipes. > > > Composition of futures works out pretty nicely, however it also has > downsides: > 1. The simple case of a single blocking i/o operation now looks like > this "result = await(start_operatoin())" instead of just "result = > operation()" .NET solves this by providing both synchronous and > asynchronous variants of each operation in most cases. I think we would want to do this too for efficiency reasons. The above outline has two major costs: the first is the extra pipes and the second is the buffering of the I/O. For example, the synchronous read method looks like `read(buf: &mut [u8])` where the buf is typically allocated on the stack. In the future scenario presumably it would be more like `read() -> Future<~[u8]>`, forcing a heap allocation, but maybe `read(buf: &mut [u8]) -> Future<&mut [u8]>` is workable. > 2. Each i/o operation now needs to allocate heap memory for the future > object. This has been known to create GC performance problems for > .NET web apps which process large numbers of small requests. If these > can live on the stack, though, maybe this wouldn't be a problem for Rust. Haha, yep that's a concern. > > > As a side note, your list doesn't have anything regarding cancellation > of async operations. In the example above you'd probably want to > attempt to cancel outstanding i/o operations when timeout expires. > .NET provides standard infrastructure for this, and I think that Rust > will need one too. Yes. > > HTH, > Vadim > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri May 31 17:33:45 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 31 May 2013 17:33:45 -0700 Subject: [rust-dev] Scheduler and I/O work items for the summer In-Reply-To: References: <51A80DF8.3000608@mozilla.com> Message-ID: <51A94169.7060902@mozilla.com> On 05/31/2013 01:14 PM, Thad Guidry wrote: > > > ## Design and implement some solution for select / async events > > We need a way to efficiently wait on multiple types of events at > once, including port receives, I/O reads, socket accepts, timers. > This has some very complicated requirements to satisfy, as > detailed in the linked issue, and I'm not sure what the right > abstractions are here. This is super important and the biggest > risk to the whole effort. If anybody has opinions about this topic > I would love to hear them. > > https://github.com/mozilla/rust/issues/6842 > > > My 2 cents worth nothing :-) and I've replied inside the issue with > the same idea... It seems to be very similar in tone to what Vadim > described for .NET asyncs where you wait for a timeout or all > operations (steps) to complete from an abstract view. > > This idea comes out of the Data Architect world that I live in. It's > more along the lines of that basic idea that your pitching which I > call "receivership". > > In Pentaho Data Integration, there is a process step called "Block > this step until steps finish". What it does is Block a single step in > an execution flow until a selected step or even multiple steps > somewhere in the chain or process has completed it's execution and > returned a True for it's "execution complete flag" where a launched > listener is waiting and watching. > > It's a generic wrapper if you will, for additional next steps to > perform, but those next steps do not get called, do not get any input, > and no variables are passed to them until the child Blocking step has > seen from (there's a listener process launched for each step or steps > choosen to watch) all its parent or parents steps somewhere say that > it's own execution has finished and lets the listener know. I think > the "Block this step until steps finish" just waits for all those > listeners it is watching to say it's OK to proceed with it's own set > of next steps. > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry Thad, I think my lack of knowledge in this domain is hurting my comprehension, and sadly the JavaDocs are pretty impenetrable on casual observation, but this does sound similar in effect to an approach based on futures. Perhaps you could sketch out in the issue a simple Rust-like example of receivership. -Brian -------------- next part -------------- An HTML attachment was scrubbed... URL: From robert at ocallahan.org Fri May 31 18:49:44 2013 From: robert at ocallahan.org (Robert O'Callahan) Date: Sat, 1 Jun 2013 13:49:44 +1200 Subject: [rust-dev] Variables with the same name in the same scope In-Reply-To: <51A8C5A5.9030208@mozilla.com> References: <51A7986B.1000708@mozilla.com> <51A8C5A5.9030208@mozilla.com> Message-ID: On Sat, Jun 1, 2013 at 3:45 AM, Graydon Hoare wrote: > I'll take that as a vote for a lint flag. Maybe set to warning level by > default? > > (Our lints can be set from anything between allow and forbid, the latter > meaning not just "error" but also "nobody else can override this in this > crate, I don't care what they think") > lint flag is better than nothing. However, like coding style, I prefer that machine-checkable code constraints should be strictly and uniformly enforced. Being able to explicitly set severity in the crate is better than what we have for C/C++, but over time it could still inhibit people moving code between crates. Rob -- q?qIqfq qyqoquq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qtqhqeqmq.q qAqnqdq qiqfq qyqoquq qdqoq qgqoqoqdq qtqoq qtqhqoqsqeq qwqhqoq qaqrqeq qgqoqoqdq qtqoq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qdqoq qtqhqaqtq.q" -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri May 31 21:10:54 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 31 May 2013 21:10:54 -0700 Subject: [rust-dev] Using new I/O error handling In-Reply-To: <23054192.29811369989850304.JavaMail.weblogic@epv6ml13> References: <23054192.29811369989850304.JavaMail.weblogic@epv6ml13> Message-ID: <51A9744E.80102@mozilla.com> On 05/31/2013 01:44 AM, Sanghyeon Seo wrote: > Is it actually possible to use new I/O error handling at the moment? It seems to me that > it is not possible to get at std::rt::io::io_error at all, because conditions are private and > do not work cross-crate. > > https://github.com/mozilla/rust/issues/5446 > https://github.com/mozilla/rust/issues/6009 > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev You are right that it is not possible because of those errors. I believe that the fix for #6009 is 1cbf0a8 and has been snapshotted, so io_error and read_error can have their /*pub*/ uncommented.