Re: [rust-dev] Rustaceans - Rust User Groups
On 11/08/15 16:12, Simon Flynn wrote: Hi Rustaceans, With the rust-dev mailing list in a semi-abanandonded state, Hi Simon, Are you aware of https://users.rust-lang.org/ ? we have decided Who is we? to create a new place where people can gather to talk all thing Rust, but in particular to help organize local meetups and other gatherings (e.g. conferences, open days etc). https://www.rustaceans.com/ I regularly attend the meetups in Paris. They are organized on meetup.com/Rust-Paris and on #rust-fr IRC. I don’t remember hearing of a desire for yet another communication channel. Did someone ask for paris-rustace...@rustaceans.com? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Reading numbers from a mmap
On 10/12/14 18:08, Matt wrote: Sorry if this has been covered before, and also that I'm a complete noob, but I'm thinking about trying a first project in Rust, and trying to learn enough to get started. My plan is for an on-disk key-value store. I'm going to end up writing arrays of numbers to disk, and then needing to efficiently read them out of a mmap-ed file. So I'm wondering how in Rust you efficiently/zero-copy-ly take some slice of a read-only mmap and treat it as e.g. a vector of ints? I see Vec.from_raw_parts() and Vec.from_raw_buf(), but I don't really understand the difference between them, and also they seem like they just give you a vector of the pointer's type, so I don't know how you use them convert the u8s you get from MemoryMap.data() into a vector of a different type, e.g. 32 bit ints. It seems like there should be a higher level API for this kind of thing, where casting a slice of a read-only memory buffer into an immutable vector is not an unsafe operation (I mean, you can do that in Python ;) Either I don't see it in the docs, or it doesn't exist yet; just wondering which :) Vec is probably not what you want, as it owns its memory and frees it when going out of scope. Use a slice instead. Assuming that’s what you get from mmap, you can create a slice from a raw pointer and a length: http://doc.rust-lang.org/std/slice/fn.from_raw_mut_buf.html http://doc.rust-lang.org/std/slice/fn.from_raw_buf.html Something like (untested): use std::slice::from_raw_mut_buf; use std::mem::size_of; use libc::c_void; // Whatever you do for mmap: let (void_pointer, byte_length): (*mut c_void, uint) = ...; let i32_pointer: *mut i32 = void_pointer as *mut i32; let i32_length: uint = byte_length / size_of::i32(); let slice: mut [i32] = from_raw_mut_buf(i32_pointer, i32_length); Then you can index into `slice`. You’re responsible for making sure that the mmap lives at least as long as `slice` does. (Its lifetime it tied to that of `i32_pointer`.) Most type annotations can probably be inferred, I added them to show what’s going on. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] On the use of unsafe
On 21/09/14 07:34, Daniel Micay wrote: It's not intended to be used for anything other than memory safety. It’s also used to maintain invariants, such as the bytes inside a String being valid UTF-8: String::push_bytes() is unsafe, but String::push_str() is not. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] [ANN] rust-url
On 01/08/14 00:08, Daniel Fath wrote: Is rust-url compatible with rust-uri? And if not are there any plans to support URI specification with it? Is there a project called rust-uri? I can’t find it. rust-url supports URIs because they’re really the same thing as URLs. It implements the URL standard, which uses the term for both: http://url.spec.whatwg.org/#goals : * Standardize on the term URL. URI and IRI are just confusing. In practice a single algorithm is used for both so keeping them distinct is not helping anyone. For example: ``` extern crate url; use url::Url; let isbn_url = Url::parse(urn:isbn:0-486-27557-4#chapter6).unwrap(); assert(isbn_url.scheme == urn.to_sting()); assert(isbn_url.non_relative_scheme_data() == Some(isbn:0-486-27557-4)); assert(isbn_url.query == None); assert(isbn_url.fragment == Some(chapter6.to_sting())); ``` The only interesting thing here is that urn is a non-relative scheme: Other than the scheme, query string, and fragment identifier, URLs in that scheme (as in data, mailto, and others) only have a scheme data string. For URLs in a relative scheme like http, instead of a single string the scheme data is a username, password, host, port number, and path. (Some of which are optional or can be empty.) -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] [ANN] rust-url
Hi Rustaceans, rustc comes with an `url` crate (previously a `extra::url` module) for parsing an serializing URLs. This crate is now deprecated: https://github.com/rust-lang/rust/commit/491bd299 The replacement is rust-url, which solves a number of issues that the old url crate had and adds some features that were missing: http://servo.github.io/rust-url/ rust-url is not distributed with rustc, but builds easily with Cargo. Please use the GitHub issue tracker for any feedback on the documentation, bugs, feature requests, etc. Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Migrating libs out of rust-lang/rust
On 29/07/14 23:30, Alex Crichton wrote: [...] We plan to implement any necessary infrastructure to ensure that the crates move out of the rust repository maintain the same level of quality they currently have. Will these crates’ documentation be available online? In rust-url, rust-cssparser, and Servo, I have Travis-CI setup to generate documentation with rustdoc and, for successful builds on master, upload it to GitHub Pages. The end result looks like this: http://servo.github.io/rust-cssparser/cssparser/index.html See at the end of this email for how this works. Long term, I’d like Rust to have an official package index, like Python’s PyPI: https://pypi.python.org/ PyPI provides free hosting for documentation of Python projects. I’d like Rust to have something like this too. GitHub Pages works and exists now, but I’m not a fan of generated files in the source repository, even in a separate branch. To this extent, the current process for moving a crate out of the standard distribution will be as follows: 1. A member of the core team will be contacted to create the repository `rust-lang/$foo`. 2. A PR will be made against `rust-lang/$foo` I’ve just checked: GitHub does not allow forking (and therefore making PRs to) an empty repository, so the person creating the repository will have to at least check the Initialize this repository with a README checkbox to make a dummy first commit. with the current copy of the code from `rust-lang/rust`. This PR will be expected to have the following source structure: * Cargo.toml - a manifest to build this repo as a cargo package * .travis.yml - configuration to run automated tests on travis. A sample can be found for hexfloat [1] * LICENSE-{MIT,APACHE} - copied over from rust-lang/rust * src/ - the same source structure as the folder in rust-lang/rust This should also include a README.md file containing at least of copy of the crate’s docstring. 3. A PR will be made against `rust-lang/rust` which will flag the relevant library as `#[deprecated]` with a message pointing at `rust-lang/$foo` In order to ensure that these repositories continue to stay up to date, we will have the following process in place: 1. Each repository will be hooked up to Travis CI and will be built each night once the new nightlies are available. How will this be achieve? http://www.rust-ci.org/ does it, but I’d like to see something more official and tied to the rust-lang.org binary nightlies rather than the Ubuntu PPA. [...] Regarding documentation on GitHub pages mentioned earlier, the script doing it looks like this: https://github.com/servo/rust-cssparser/blob/331e5695dc/.travis.yml The `meta http-equiv=refresh ...` line is so that the URL http://servo.github.io/rust-cssparser/ is not a 404 error. (rustdoc does not generate anything there.) ghp-import resets a git branch (defaults to gh-pages) to contain exactly what’s in a given directory, regardless of what the branch previously contained. The secure line is created with `travis encrypt -r servo/rust-cssparser TOKEN=[hex string]`, where [hex string] is a GitHub access token for a user with push access to the repository. (I created https://github.com/rustdoc for this purpose.) http://docs.travis-ci.com/user/encryption-keys/ https://help.github.com/articles/creating-an-access-token-for-command-line-use -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Migrating libs out of rust-lang/rust
On 30/07/14 15:59, Alex Crichton wrote: We plan to implement any necessary infrastructure to ensure that the crates move out of the rust repository maintain the same level of quality they currently have. Will these crates’ documentation be available online? At this time there are no plans for this, but we're certainly open to options! This sounds like a significant regression :/ The need for these is a little less pressing now that `cargo doc` is implemented, but this is still a very important aspect to these crates. Yeah, we can easily have Travis run `cargo doc`. The question is where to host the result. There's a cron job running which will trigger each build each night after the nightlies have finished building, and the .travis.yml script for these repos are all wired to nightlies rather than the PPA. Could the source code for this cron job be published, with instructions on how to get API keys or whatever Travis wants? I tried https://github.com/patrickkettner/travis-ping , but only got a mysterious error messages and didn’t feel like debugging that code. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] London Rust meetup: 2014-08-14
Hello Rustaceans, The next London meetup is on August 14. Come and say hi! Nick Cameron a.k.a nrc will be giving a talk on DST. http://www.meetup.com/Rust-London-User-Group/events/196222722/ We’re also looking for speakers for this or future events. Let me know if you’re interested! Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] London Rust meetup: 2014-08-14
On 24/07/14 10:18, Ilya Dmitrichenko wrote: Hi Simon, I and @farcaller where thinking to prepare a talk on Zinc project (http://zinc.rs/). That looks cool. Do you want to present on August 14? What length of the talks you guys do? The length is flexible, this is only the second time we’re doing in this in London so we’re still figuring it all out. Just remember that the event is in the evening and that there may be another talk in the same event. To give a number that I totally just made up, anything up to 30 minutes sounds good. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust Guidelines
On 13/07/14 19:18, Tony Arcieri wrote: On Fri, Jul 11, 2014 at 11:49 AM, Aaron Turon atu...@mozilla.com mailto:atu...@mozilla.com wrote: The best part: approved guidelines can turn into (1) new github issues to bring libstd into line and (2) an authoritative way to resolve debates on libstd PRs. How about a gofmt-like source code reformatting utility? As far as I can tell, everyone agrees it would be great to have. We just need someone to make it. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Impending change in RPATH behavior when linking to Rust dynamic libraries
On 08/07/14 23:57, Brian Anderson wrote: *Running rustc directly from the build directory will no longer work by default*. To do this either set LD_LIBRARY_PATH or pass --enable-rpath to the configure script. Does this also apply to running a (nightly) binary distribution from where the tarball was extracted, without installing it? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust CI
On 18/06/14 10:11, Hans Jørgen Hoel wrote: Rust Ci wasn't working for a period due to problems with building the nightly PPA for the platform used by Travis (required GCC version was bumped with no way to specify alternative to configure script). This has been fixed for a while, but it turns out that many Travis auth tokens has expired in the mean time. Are there advantages or disadvantages with using nightlies from the PPA rather than those from rust-lang.org? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] strings in sets/maps
On 06/06/2014 16:34, Diggory Hardy wrote: Related: how to do this in a match? let s = abc.to_owned(); match s { abc = ... match s.as_slice() { // ... -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to find Unicode string length in rustlang
On 29/05/2014 08:25, Kevin Ballard wrote: This is a temporary issue. Once DST lands we will likely implement Derefstr for String, which will make all str methods work transparently on String. Until then, is there a reason not to have String implement the StrSlice trait? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] cannot borrow `st` as mutable more than once at a time
On 29/05/2014 19:22, Vladimir Matveev wrote: Hi, Christophe, Won't wrapping the first `for` loop into curly braces help? I suspect this happens because of `for` loop desugaring, which kind of leaves the iterator created by `execute_query()` in scope (not really, but only for borrow checker). If that’s the case, it sounds like a bug with an easy fix. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to find Unicode string length in rustlang
On 28/05/2014 15:13, Daniel Micay wrote: On 28/05/14 10:07 AM, Benjamin Striegel wrote: I think that the naming of `len` here is dangerously misleading. Naive ASCII-users will be free to assume that this is counting codepoints rather than bytes. I'd prefer the name `byte_len` in order to make the behavior here explicit. It doesn't need to exist at all, because `as_bytes().len()` is available. Sure, but in that case many other things in libstd do not need to exist either, they’re just there for convenience. +1 to rename to .byte_len() or .utf8_len(). (See https://github.com/mozilla/rust/issues/14131 ) -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] box ref foo?
On 27/05/2014 18:27, Tommi wrote: What is the meaning of this 'box ref foo' syntax found in the tutorial over at __http://doc.rust-lang.org/tutorial.html#references (Sorry for uglifying the link, my posts seem to get flagged as spam if they contain links) In short, it's: enum Shape { Sphere(Boxf32) } let shape = Sphere(box 1.0f32); let r = match shape { Sphere(box ref radius) = *radius }; I thought the 'box' keyword meant: allocate on heap and wrap into a Box. That doesn't make sense to me in the context of 'box ref radius'. That’s what it means in an expression, but the arms of a 'match' statement start with patterns, not expressions. In a pattern, the 'box' keyword means deconstruct a BoxT type to access the T inside. The 'ref' keyword (which can be used without 'box') means to take a T reference rather than move the value. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How to implement a singleton ?
On 15/05/2014 08:59, Christophe Pedretti wrote: I am trying to implement a Singleton (an object which instantiate only once, successive instantiations returning the object itself). Any tutorial for this ? any idea ? example ? best practice ? Kimundi published this macro to define lazily initialized statics, which look to me equivalent to singletons although there is no instanciation involved: https://gist.github.com/Kimundi/8782487 http://www.reddit.com/r/rust/comments/1wvxcn/lazily_initialized_statics/ I believe this is only memory-safe with types that satisfy the `Share` kind. http://static.rust-lang.org/doc/master/core/kinds/trait.Share.html -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Building a static array of pointers
On 05/04/2014 12:00, Corey Richardson wrote: A C-style array is written `*T`, much like in C (note: I'm not saying `T*` and `T[]` are the same type, I know they aren't) *T in Rust is not an array, it is a raw pointer. It may happen to point to the start of an array that you could unsafely access with .offset() and ptr::read(), but you can not index it like an array. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Building a static array of pointers
On 05/04/2014 13:28, Vladimir Pouzanov wrote: Also tried defining something along the lines of *[extern unsafe fn()], but I guess size is also required in this case. This will probably work once we have DST, but it will result in a fixed-size pointer to an array, rather than the actual array like [extern unsafe fn(), ..4] whose size is proportional to the number of elements. DST: https://github.com/mozilla/rust/issues/6308 -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] 0.10 prerelease testing
On 02/04/2014 18:43, Corey Richardson wrote: On Wed, Apr 2, 2014 at 1:34 PM, Steve Klabnik st...@steveklabnik.com wrote: I compiled from source just yesterday, but everything's been going swimmingly! I just have one comment on 0.10: It seems like println was removed from the prelude. While I can totally appreciate that most people will use println!, which is automatically use-able, it _is_ making my 'hello world' examples significantly more complex, since basically every one of them needs to either import println or use println!({}, foo); I'm not sure if this is a good or bad thing, just wanted to raise that as a possible issue. It has been raised, as an extension to the macro, that invocation with a single, non-string literal, could expand into `println!({}, $that_arg)` rather than requiring the `{}`. This sounds even better than having both println() and println!() (in the prelude) with non-obvious differences. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Static_assert on a hash
On 30/03/2014 09:50, Vladimir Pouzanov wrote: I have a chunk of code that toggles different functions on hardware pins, that looks like this: enum Function { GPIO = 0, F1 = 1, F2 = 2, F3 = 3, } fn set_mode(port: u8, pin: u8, fun: Function) What I would like to have is an enum of human-readable values instead of F1/F2/F3 [...] let fun_idx: u8 = FUNCTIONS[port][pin][fun] I don’t know if you can directly access the static strings for the variants’ names behind this, but you can use #[deriving(Show)] to get a string representation of any enum value: For example: #[deriving(Show)] enum Function { GPIO = 0, F1 = 1, F2 = 2, F3 = 3, } fn main() { let f = GPIO; println!({:?}, f) let s: ~str = format!({:?}, f); println!({}, s) } Output: GPIO GPIO -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Static_assert on a hash
On 30/03/2014 10:30, Vladimir Pouzanov wrote: That shifts the issue even more into runtime, doesn't it? My goal is to find a way to resolve a tuple of (u8, u8, FuncNameEnum) to u8, where FuncNameEnum is a long enum of all possible functions. And I need to do that in compile time. One way I see that is to make a really long list of enums like: PORT0_PIN0_GPIO, PORT0_PIN0_RD1, ... for all possible port/pin/function combinations, then I can make a macro to match on that to port/pin/fun u8 (that are actually used to configure registers). The only thing is that I'd like to pass port and pin in as u8 values, that makes it much more readable. Well... Maybe it's time to do some big macro for matching all the stuff and hope that compiler will optimise it anyway. I’m sorry, it looks like I completely misunderstood your original message. But then it’s still not clear to me what you’re trying to do. Could you explain in more details, with more context? For example, what is it you call a function? It seems not to be Rust function declared with the `fn` keyword. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: Updated RFC process
On 12/03/2014 01:11, Brian Anderson wrote: * Fork the RFC repohttp://github.com/rust-lang/rfcs * Copy `-template.md` to `active/-my-feature.md` (where 'my-feature' is descriptive. don't assign an RFC number yet). * Fill in the RFC * Submit a pull request. The pull request is the time to get review of the design from the larger community. * Build consensus and integrate feedback. RFCs that have broad support are much more likely to make progress than those that don't receive any comments. * Eventually, somebody on the [core team] will either accept the RFC by merging the pull request and assigning the RFC a number, at which point the RFC is 'active', or reject it by closing the pull request. Should the mailing list be involved in this process, as a way to get more people discussing RFCs? (Maybe automatically with a bot sending email for every PR in the RFC repo.) On the other hand, we probably don’t want to fragment the discussion between GitHub issues and email. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: Conventions for well-behaved iterators
On 04/03/2014 14:42, Tommi wrote: I agree that this should be an ill-behaved iterator, but my point is that according to the specification [1], this is_not_ an ill-behaved iterator, it's a completely valid one. Given that self.n is less than 10, it correctly returns some elements as Some(...) and then it returns None. After it has returned None, according to specification [1], it is allowed to return whatever it wants. Yes, it is valid per the *current* definition of Iterator in the Rust documentation. The point of this thread is to change this definition. Therefore I'd be inclined to say that the bug in my example is in calling fold on an iterator whose all elements have been exhausted, but that seems just silly and fragile. Yes it’s fragile. I’m proposing the change to avoid such fragility. [1]: The Iterator protocol states that an iterator yields a (potentially-empty, potentially-infinite) sequence of values, and returns None to signal that it's finished. The Iterator protocol does not define behavior after None is returned. A concrete Iterator implementation may choose to behave however it wishes, either by returning None infinitely, or by doing something else. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] issue numbers in commit messages
On 17/02/2014 23:50, Nick Cameron wrote: At worst you could just use the issue number for the PR. In order to get a PR number you need to have commits to submit, with already-composed messages. But I think all non-trivial commits _should_ have an issue associated. GitHub PRs *are* issues. Requiring *another* issue when someone has code to submit already is not useful IMO. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] RFC: Conventions for well-behaved iterators
Hi, The Rust documentation currently makes iterators behavior undefined after .next() has returned None once. http://static.rust-lang.org/doc/master/std/iter/trait.Iterator.html The Iterator protocol does not define behavior after None is returned. A concrete Iterator implementation may choose to behave however it wishes, either by returning None infinitely, or by doing something else. http://static.rust-lang.org/doc/master/guide-container.html In general, you cannot rely on the behavior of the next() method after it has returned None. Some iterators may return None forever. Others may behave differently. This is unfortunate. Code that accepts any iterator as input and does with it anything more complicated than a single 'for' loop will have to be defensive in order to not fall into undefined behavior. The type system can not enforce anything about this, but I’d like that we consider having conventions about well-behaved iterators. --- Proposal: 0. An iterator is said to be well-behaved if, after its .next() method has returned None once, any subsequent call also returns None. 1. Iterators *should* be well-behaved. 2. Iterators in libstd and other libraries distributed with rustc *must* be well-behaved. (I.e. not being well-behaved is a bug.) 3. When accepting an iterator as input, it’s ok to assume it’s well-behaved. 4. For iterator adaptors in particular, 3. means that 1. and 2. only apply for well-behaved input. (So that, eg. std::iter::Map can stay as straightforward as it is, and does not need to be coded defensively.) --- Does the general idea sound like something y’all want? I’m not overly attached to the details. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: Conventions for well-behaved iterators
On 13/02/2014 16:09, Olivier Renaud wrote: As you said, the type system can not enforce this rule, that's why the documentation have no choice but to say the behavior is undefined. Just because we can not make them automatically-enforced rules doesn’t mean we can’t have conventions. I’m suggesting that we adopt a convention that iterators *should* be well-behaved. If the code you write relies on None being returned forever, then you should use the Fuse iterator adaptor, that wraps an existing iterator and enforces this behavior: http://static.rust-lang.org/doc/master/std/iter/trait.Iterator.html#method.fuse http://static.rust-lang.org/doc/master/guide-container.html#iterator-adaptors -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: Conventions for well-behaved iterators
On 13/02/2014 19:56, Daniel Micay wrote: Enforcing this invariant makes many adaptors more complex. For example, the `filter` adaptor would need to maintain a boolean flag and branch on it. I'm fine with the current solution of a `fuse` adaptor because it moves all of the responsibility to a single location, and user-defined adaptors don't need to get this right. My entire email was about specifically *not* enforcing anything, only convention. Filter is in the exact same category as Map: it’s only expected to be well-behaved when its input is. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] What form should the official Rust binary installers for Unixes take?
On 12/02/2014 23:27, Benjamin Striegel wrote: there is a plan for llvm before 1.0. What does this refer to? Last I checked we were certain to still be using a custom LLVM as of 1.0. Apparently using upstream LLVM is desired, but not a blocker for 1.0: https://github.com/mozilla/rust/issues/4259#issuecomment-34094922 https://github.com/mozilla/rust/wiki/Meeting-weekly-2014-02-04#wiki-llvm -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Something odd I just noticed with mut and pattern matching
On 16/01/2014 16:13, Tommy M. McGuire wrote: I found something odd with mutablity and pattern matching. let file = File::open_mode(Path::new(test), Truncate, Write); match file { Some(f) = f.write_str( hello ), None = fail!(not a file) } results in a cannot borrow immutable local variable as mutable error, as expected. But, let mut file = File::open_mode(Path::new(test), Truncate, Write); match file { Some(f) = f.write_str( hello ), None = fail!(not a file) } also results in a cannot borrow immutable local variable as mutable error, and let file = File::open_mode(Path::new(test), Truncate, Write); match file { Some(mut f) = f.write_str( hello ), None = fail!(not a file) } works, while let mut file = File::open_mode(Path::new(test), Truncate, Write); match file { Some(mut f) = f.write_str( hello ), None = fail!(not a file) } results in a variable does not need to be mutable warning. Shouldn't the third option also fail (and possibly the second option succeed)? Something immutable can become mutable when it’s moved. Matching an enum member without ref moves. It would be a different story (I think) if your pattern was Some(ref mut f). -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 23/12/2013 20:55, Benjamin Striegel wrote: I too think it would be a big mistake to allow let patterns to be refutable, when we've already tried and rejected allowing the same in match statements (ancient Rust history quiz: who else remembers `match check`?). For those of us that were not around or do not remember, can you explain what was tried and rejected? I sometimes find myself writing a `_ = ()` arm for match and wish it could be implied… and sometimes `_ = fail!()`. That the two are sometimes used is probably a sign that the status quo (require it to be explicit) is better. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] See pull request #11129 (was: Re: Let’s avoid having both foo() and foo_opt())
FYI, made a pull request according to this proposal: https://github.com/mozilla/rust/pull/11129 -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] See pull request #11129
On 23/12/2013 22:19, Liigo Zhuang wrote: Code full of .unwrap() is not good smell I think. I agree, and I wrote in the first email that it is one of the downsides. But doubling the API (from_utf8 and from_utf8_opt) is also not a good smell, so it’s a compromise to find. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] See pull request #11129
On 23/12/2013 22:26, Kevin Ballard wrote: Even with refutable `let`s, I think there's still a good case for having `.unwrap()`-style APIs on enums, which is that often you need to unwrap an enum inside a larger expression. A refutable `let` only works if you're actually using a `let`-binding to begin with. Please don’t change the subject of (at least this part of) this thread. This is about having both variations of an API (using task failure or returning Option) vs. only the latter (and using unwrap() when task failure is desired.) It is not about refutable let vs. unwrap-style methods. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 09/12/2013 15:53, Damien Radtke wrote: I have no idea if it would be feasible in the standard library, but wouldn't the ideal solution be having one function (e.g. from_utf8()) that could return two possible values, a bare result and an Option? Letting the compiler decide which version to use based on type inference like this: let result: ~str = from_utf8(...); let result: Option~str = from_utf8(...); Assuming both of them are passed invalid UTF8, then the first version would fail, but the second version would just return None. Again, I don't know if it's possible given the current implementation, but I do think it would be helpful to have a picture of the ideal, and then decide on whatever solution comes closest. It is possible to have a generic return value, see for example the .collect() method of iterators. https://github.com/mozilla/rust/blob/4e0cb316fc980f00e1b74f3fdb7a842b540be280/src/libstd/iter.rs#L447 But it involves creating a trait, and implementing it for every supported type. IMO it’s a lot more involved than what we would want for every operation that may fail on invalid input. As a side note, even if the standard library sticks with two variants for each option function, I would prefer the default one return an Option and have the variant fail on invalid input. Task failure at runtime is a nastier surprise than an invalid type error at compile time, especially for new users who aren't entirely sure of the difference. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 07/12/2013 01:07, spir wrote: Maybe it's only me, but this not at at all clear to my eyes. My imagined soluton (for a totally different lang) was something like this, on the caller side: ucodes = s.utf8_decode()! // source should be correct, error on failure ucodes = s.utf8_decode()? // logical failure expected, return None or whatnot This is interesting, but I’d like to discuss what to do in this particular language, Rust that is trying to go to 1.0 and will probably not accept such syntax change :) -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 07/12/2013 01:14, Huon Wilson wrote: I personally think a better solution is something like Haskell's do notation[1], where you can chain several computations that return Option.. such that if any intermediate one returns None, the later ones are not evaluated and the whole expression returns None, which saves having to call .get()/.unwrap()/.expect() a lot. We have that, it’s Option’s .and_then() method. This can work for types like Result too (in fact, the Haskell implementation of `do` is sugar around some monad functions, so any monad can be used there; we currently don't have the power to express the monad typeclass/trait in Rust so the fully general form probably isn't possible as a syntax extension yet, although a limited version is). -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Let’s avoid having both foo() and foo_opt()
We have some functions and methods such as [std::str::from_utf8](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that may succeed and give a result, or fail when the input is invalid. 1. Sometimes we assume the input is valid and don’t want to deal with the error case. Task failure works nicely. 2. Sometimes we do want to do something different on invalid input, so returning an `OptionT` works best. And so we end up with both `from_utf8` and `from_utf8`. This particular case is worse because we also have `from_utf8_owned` and `from_utf8_owned_opt`, to cover everything. Multiplying names like this is just not good design. I’d like to reduce this pattern. Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on the Option. I think we should rename every `foo_opt()` function or method to just `foo`, remove the old `foo()` behavior, and tell people (through documentation) to use `foo().unwrap()` if they want it back? The downsides are that unwrap is more verbose and gives less helpful error messages on task failure. But I think it’s worth it. What do you think? (PS: I’m guilty of making this worse in #10828, but I’d like to discuss this before sending pull requests with invasive API changes.) -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 06/12/2013 20:48, Corey Richardson wrote: I'm in favor of this but it makes things less pretty. Is the choice really between pretty and fast? I don’t think this is about speed. My concern is that having two almost-identical names for functions that do almost the same thing is not a good design, and should be avoided if possible. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 06/12/2013 20:55, Léo Testard wrote: Hi, Just a suggestion, don't know what it's worth... For the not helpful error message thing, couldn't we extend the option API, to be able to specify at the creation of a None value the error string that will be displayed if one calls unwrap() on this value ? This may be useful in several situations. That would require making the memory representation of every Option bigger. Just for the (hopefully) uncommon case of task failure, it’s not worth the cost in my opinion. We could instead have .unwrap() that take an error message, but that leaves the responsibility to the user of the API. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 06/12/2013 21:44, Brian Anderson wrote: I agree in this case (and probably a lot of cases), especially since this is a relatively uncommon operation and since (I think) we're prefering 'get' to 'unwrap' and that's even shorter. There are some cases where I think failure is the right option by default though; in particular I was worried you were going to bring up the 'send' and 'recv' methods on channels which fail when disconnected. In this case I think it won't be common to handle the failure since it indicates some logic error, and these are very common operations. Maybe this should be a case-by-case decision, but send/try_send and recv/try_recv have the same issue as from_utf8/from_utf8_opt of two slightly different names for almost the same thing. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 06/12/2013 21:50, Eric Reed wrote: Personally, I prefer making functions that don't fail and use Option or Result and then composing them with functions that fail for certain outputs, but I think I'm in the minority there. Yes, this is what I’m suggesting. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 07/12/2013 00:12, Gaetan wrote: I am in favor of two version of the api: from_str which has already done the unwrap, and a from_str_safe for instance that returns a Result or option. This is what we have now. (Eg. from_utf8() and from_utf8_opt()) The point of my initial email was to argue against this. I think we should try to avoid doubling the amount of API. Or perhaps allow the propagation of Option/Result. This is why we have methods like .map() and .and_then() -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Let’s avoid having both foo() and foo_opt()
On 07/12/2013 00:49, spir wrote: About the latter, in particular it should be obvious in code, without knowledge of language arcanes or weird idioms, that (or whether) the caller expects a success unconditionally -- because (and in other words that) the anomalous case just does not belong to this app; this is critical information to the reader. How to do that right? If my proposal is accepted (returning Option is favored), then calling .unwrap() is the way to express that success is expected. unwrap() causes task failure when called with None. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Meeting-weekly-2013-12-03, str.from_utf8
Hi, In response to: https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-12-03#strfrom_utf8 Yes, error handling other than strict/fail requires allocation. I suggest taking the pull request for the special case of non-allocating strict UTF-8, and keeping error handling for a future, larger API that also handles other encodings (and incremental processing): https://github.com/mozilla/rust/pull/10701 https://github.com/mozilla/rust/wiki/Proposal-for-character-encoding-API [On invalid UTF-8 bytes] brson: One has a condition that lets you replace a bad character I believe this is not implemented. The current not_utf8 condition lets you do the entire decoding yourself. acrichto: We could truncate by default. I am very much opposed to this. Truncating silently loses data (potentially lots of it!) It should not be implemented, let alone be the default. jack: In python, you have to specify how you want it transformed. Truncate vs. replace with '?', etc. Maybe there should be an alternate version that takes the transform. pnkfelix: But doesn't work with slices... jack: There's truncate, replace, and fail. Python does not have truncate. It has ignore (skip invalid byte sequences but continue with the rest of the input), strict (fail), and replace (with � U+FFFD REPLACEMENT CHARACTER). You don’t have to specify an error handling, strict is the default. Ignore is bad IMO as it silently loses data (although it’s not as bad as truncate) though it could have uses I’m not thinking of right now. Side note: Regarding failing vs. returning an Option or Result: I’d be in favor of only having the latter. Having two versions of the same API (foo() and foo_opt()) is ugly, and it’s easy to get value or fail from an Option with .unwrap() -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Rust forum
On 02/12/2013 16:21, David Piepgrass wrote: That would be so. much. better. than a mailing list. Hi. Could you expand on this? I don’t necessarily disagree, but as the one proposing change it’s up to you to convince everyone else :) -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] How would you map one vector to a vector of a different element type?
Le 02/11/2013 21:05, Leah Hanson a écrit : Thanks, Brendan. :) You’re trying to move the ~strs out of the vector. You’ll need to use `move_iter`: Is this moving about moving memory around or about promising the compiler that I won't use those elements of the vector again? ~str is an owned string that can only have one owner. If you move it (give away ownership) you can not use it anymore. The compiler verifies that. This is why move_iter() consumes a vector (takes ownership), while iter() only gives you references ( pointers) to the elements. This allows the memory to be freed when the owner disappears, without garbage collection or reference counting. ~~~ let ports = do myvect.move_iter().map |s| { let (pport, cchan) = stream(); do spawn { cchan.send(fun(s)) } pport }.to_owned_vec(); There is still a problem because something (I guess the `do spawn {...}`) is a heap closure. * error: cannot move out of captured outer variable in a heap closure o cchan.send(fun(s)) I think that this error message is complaining because I'm trying to move s, the ~str that the `do spawn {...}` closes over, to a new task. And I'm not allowed to move it because it is apparently a heap closure. Is there some other kind of closure that does work here? Or some way to make this not a closure? I’m not sure, but you may need to use spawn_with to move something into a task: do spawn_with(s) |s| { ... } -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposed API for character encodings
Le 21/09/2013 16:38, Olivier Renaud a écrit : I'd expect this offset to be absolute. After all, the only thing that the programmer can do with this information at this point is to report it to the user ; if the programmer wanted to handle the error, he could have done it by using a trap. A relative offset has no meaning outside of the processing loop, whereas an absolute offset can still be useful even outside of the program (if the source of the stream is a file, then an absolute offset will give the exact location of the error in the file). A counter is super cheap, I would'nt worry about its cost. Actually, it just has to be incremented once for each call to 'feed'. Well to get the position inside a given chunk of input you still have to count individual bytes. (Maybe with Iterator::enumerate?) Unless maybe we do dirty pointer arithmetic… If possible, I’d rather find a way to not have to pay that cost in the common case where the error handling is *not* abort and DecodeError is never used. This is also a bit annoying as each implementation will have to repeat the counting logic, but maybe it’s still worth it. Note : for the encoder, you will have to specify wether the offset is a 'code point' count or a 'code unit' count. Yes. I don’t know yet. If we do [1] and make the input generic it will probably have to be code points. [1] https://mail.mozilla.org/pipermail/rust-dev/2013-September/005662.html Otherwise, it may be preferable to match Str::slice and count UTF-8 bytes. (Which I suppose is what you call code units?) -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposed API for character encodings
Le 20/09/2013 20:07, Olivier Renaud a écrit : I have one more question regarding the error handling : in DecodeError, what does 'input_byte_offset' mean ? Is it relative to the 'invalid_byte_sequence' or to the beginning of the decoded stream ? Good point. I’m not sure. (Remember I make this up as we go along :).) If it’s from the entirety of the input this would require decoders to keep count, which is unnecessary work in cases where you don’t use it. (eg. with the Replace error handling.) So it could be from the beginning of the input in the last call to .feed() to the begining of the invalid byte sequence, *which can be negative*, in case the invalid sequence started in an earlier .feed() call. What do you think it should be? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposed API for character encodings
. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposed API for character encodings
Le 20/09/2013 13:40, Henri Sivonen a écrit : On Tue, Sep 10, 2013 at 6:47 PM, Simon Sapinsimon.sa...@exyr.org wrote: /// Call this to indicate the end of the input. /// The Decoder instance should be discarded afterwards. /// Some encodings may append some final output at this point. /// May raise the decoding_error condition. fn flush(output: mut ~str) - OptionDecodeError; Please call this finish instead of calling it flush. In other APIs, for example JDK APIs, flush really just means flushing the current buffers instead of ending the stream, so calling the method that does end-of-stream processing flush would be confusing. flush is the name that rust-encoding uses, but I argee that finish is better for what it does. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposed API for character encodings
Le 10/09/2013 16:47, Simon Sapin a écrit : TR;DR: the actual proposal is at the end of this email. I moved this to the wiki, to better deal with updates: https://github.com/mozilla/rust/wiki/Proposal-for-character-encoding-API -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposed API for character encodings
Le 19/09/2013 13:39, Jeffery Olson a écrit : As to the implementation: rust-encoding has a lot that could be adapted. https://github.com/__lifthrasiir/rust-encoding https://github.com/lifthrasiir/rust-encoding Can someone comment on whether we should look at adapting what's in str::from_utf8 (really, str::raw::from_buf_len is where the action is) and str::from_utf16 for this? Everyone in IRC I ask says that they are correct.. they're also highly optimized.. are they appropriate for this API? And if not, are comfortable having two totally separate paths for string decoding? I don’t think anybody is advocating duplicating implementations of the same thing. My understanding is that UTF8Decoder and the existing API in std::str will end up calling the same code. That code could be libstd’s existing implementation extended for error handling, or rust-encoding’s, or something else. I don’t have a strong opinion about it. UTF-16 is a bit special, because libstd’s existing APIs deal with native-endian [u16], while encoding APIs will need both UTF-16-LE and UTF-16-BE on [u8]. I don’t know how much can be shared. But once again, I’m more interested in getting the API and the behavior right. I trust the smart people working on Rust to refactor and optimize the implementation over time. Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposed API for character encodings
Le 11/09/2013 17:19, Marvin Löbel a écrit : On 09/10/2013 05:47 PM, Simon Sapin wrote: Hi, TR;DR: the actual proposal is at the end of this email. Rust today has good support for UTF-8 which new content definitely should use, but many systems still have to deal with legacy content that uses other character encodings. There are several projects around to implement more encodings in Rust. The most further along in my opinion is rust-encoding, notably because it implements the right specification. rust-encoding: https://github.com/lifthrasiir/rust-encoding The spec: http://encoding.spec.whatwg.org/ It has more precise definitions of error handling than some original RFCs, and better reflects the reality of legacy content on the web. There was some discussion in the past few days about importing rust-encoding (or part of it) into Rust’s libstd or libextra. Before that, I think it is important to define a good API. The spec defines one for JavaScript, but we should not copy that exactly. rust-encoding’s API is mostly good, but I think that error handling could be simplified. In abstract terms, an encoding (such as UTF-8) is made of a decoder and an encoder. A decoder converts a stream of bytes into a stream of text (Unicode scalar values, ie. code points excluding surrogates), while an encoder does the reverse. This does not cover other kinds of stream transformation such as base64, compression, encryption, etc. Bytes are represented in Rust by u8, text by str/char. (Side note: Because of constraints imposed by JavaScript and to avoid costly conversions, Servo will probably use a different data type for representing text. This encoding API could eventually become generic over a Text trait, but I think that it should stick to str for now.) The most convenient way to represent a stream is with a vector or string. This however requires the whole input to be in memory before decoding/encoding can start, and that to be finished before any of the output can be used. It should definitely be possible to eg. decode some content as it arrives from the network, and parse it in a pipeline. The most fundamental type API is one where the user repeatedly pushes chunks of input into a decoder/encoders object (that may maintain state between chunks) and gets the output so far in return, then signals the end of the input. In iterator adapter where the users pulls output from the decoder which pulls from the input can be nicer, but is easy to build on top of a push-based API, while the reverse requires tasks. Iteratoru8 and Iteratorchar are tempting, but we may need to work on big chucks at a time for efficiency: Iterator~[u8] and Iterator~str. Or could single-byte/char iterators be reliably inlined to achieve similar efficiency? Finally, this API also needs to support several kinds of errors handling. For example, a decoder should abort at the invalid byte sequence for XML, but insert U+FFFD (replacement character) for HTML. I’m not decided yet whether to just have the closed set of error handling modes defined in the spec, or make this open-ended with conditions. Based on all the above, here is a proposed API. Encoders are ommited, but they are mostly the same as decoders with [u8] and str swapped. /// Types implementing this trait are algorithms /// such as UTF8, UTF-16, SingleByteEncoding, etc. /// Values of these types are encodings as defined in the WHATWG spec: /// UTF-8, UTF-16-LE, Windows-1252, etc. trait Encoding { /// Could become an associated type with a ::new() constructor /// when the language supports that. fn new_decoder(self) - ~Decoder; /// Simple, one shot API. /// Decode a single byte string that is entirely in memory. /// May raise the decoding_error condition. fn decode(self, input: [u8]) - Result~str, DecodeError { // Implementation (using a Decoder) left out. // This is a default method, but not meant to be overridden. } } /// Takes the invalid byte sequence. /// Return a replacement string, or None to abort with a DecodeError. condition! { pub decoding_error : ~[u8] - Option~str; } struct DecodeError { input_byte_offset: uint, invalid_byte_sequence: ~[u8], } /// Each implementation of Encoding has one corresponding implementation /// of Decoder (and one of Encoder). /// /// A new Decoder instance should be used for every input. /// A Decoder instance should be discarded after DecodeError was returned. trait Decoder { /// Call this repeatedly with a chunck of input bytes. /// As much as possible of the decoded text is appended to output. /// May raise the decoding_error condition. fn feed(input: [u8], output: mut ~str) - OptionDecodeError; /// Call this to indicate the end of the input. /// The Decoder instance should be discarded afterwards. /// Some encodings may append some final output at this point. /// May raise the decoding_error condition. fn flush
[rust-dev] Proposed API for character encodings
DecoderIteratorI { input_iterator: I, priv state: DecoderIteratorStateI, } implI: Iterator~[u8] DecoderIteratorI { fn new(input_iterator: I) - DecoderIteratorI { // Implementation left out. } /// Consume the whole input iterator and return a single decoded string. /// May raise the decoding_error condition. fn concat(mut self) - Result~str, DecodeError { // Implementation left out. } } implI: Iterator~[u8] IteratorResult~str, DecodeError for DecoderIteratorI { /// Call .next() once on the input iterator and decode the result. /// May raise the decoding_error condition. /// Returns None after DecodeError was returned once, /// even if the input iterator is not exhausted yet. fn next(mut self) - OptionResult~str, DecodeError { // Implementation left out. } } Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] App runtime based on Servo
Le 31/08/2013 20:22, John Mija a écrit : From my point of view, there is no technology related to User Interfaces more advanced than web-based (HTML5/CSS3). [...] Now, what do think about to have a similar technology but using Servo? To being able to develop desktop apps in Rust (or Go via bindings to Rust libraris) and JS or Dart for the UI. I don’t know about adding Go or Dart to the mix, but it is definitely one of Servo’s goals to be embeddable as a library in a larger application. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Augmented assignment
Le 23/08/2013 19:47, Matthieu Monrocq a écrit : The most trivial mistake is to have `+=` and `+` defined so that `a += 5` has a different result than `a = a + 5` Would it work to make `a += b` always expand to `a = a + b`, and have that not be overridable? Or am I missing something else? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] HTML5 parser
Le 14/08/2013 08:59, Archos a écrit : I think that Servo is using a binding to a C library to parsing HTML5 (from Nginx). Right now, Servo is using Hubbub, from the NetSurf project. How is Nginx related to this? http://www.netsurf-browser.org/projects/hubbub/ But now, Google has opened-sources Gumbo, a C Library for Parsing HTML5. So it could be used until that somebody builds a parser in pure Rust. https://github.com/google/gumbo-parser That’s cool, but what would it buy us to switch from one C library to another? Is Gumbo better than Hubbub? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Adding else on for loops, like Python
Le 13/08/2013 01:19, Ian P. Cooke a écrit : I'm reminded of the work done at Microsoft the showed that Observable and Enumerable were duals (e.g. http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf http://csl.stanford.edu/%7Echristos/pldi2010.fit/meijer.duality.pdf ) The relevant idea is that a richer interface that includes wether the the subject completed normally or via exception is very useful especially when it comes to composition of such things. as for something concrete: -1 for for-else. I don't like the reuse of 'else' and it's not a construct most people use often. I’m not too attached to the name. Do you have suggestions on how it could work? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Adding else on for loops, like Python
Le 11/08/2013 23:18, Jens Nockert a écrit : for i in iterations { … if converged { break; } } if iterations.finished() { fail!(Oh noes, it did not converge); } The only way to implement .finished() non destructively (so that, when returning false, it does not eat an element) is with a Peekable iterator as in this pull request: https://github.com/mozilla/rust/pull/8428 Then .finished() is .peek().is_none(). But this is unnecessary overhead if you don’t otherwise use .peek(). The for-loop already knows how it exited. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Adding else on for loops, like Python
Le 12/08/2013 18:23, Micah Chalmer a écrit : The for-loop already knows how it exited. It only knows if something explicitly makes it know. This boils down to one of two things: either the boolean flag approach as discussed earlier, or the compiler turning every break in the block into an explicit call to the else block. No, it’s the opposite. The for-else loop jumps to the else block when the iterator’s next() returns None. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Adding else on for loops, like Python
Le 12/08/2013 20:16, Corey Richardson a écrit : On Mon, Aug 12, 2013 at 2:54 PM, Simon Sapin simon.sa...@exyr.org wrote: fn main() { let v = ~[1u, 7, 42, 0]; let mut it = v.move_iter().enumerate(); for_!((i, v) in it { if v == 42 { printfln!(Found it at %u, i); break } } else {e println(Not found); }) } v.move_iter().position(|a| a == 42) One of Rust's strengths compared to Python is that we can implement traits on adaptors and have generic methods. That’s good, but this was only a trivial example to demonstrate the macro. I’m not that interested about position() itself. What triggered me starting this thread is this: https://github.com/SimonSapin/servo-style/blob/c1b7e157b/media_queries.rs#L101 This is parsing a comma-separated list of Media Queries from an iterator of tokens. Invalid comma-separated parts evaluate to false. So on a syntax error, we consume the iterator until finding a comma, or the end of the input. We want to do two different things in each case. The `loop { match iter.next() { … }}` pattern works out okay in this case, but a for-else loop would have been much nicer IMO. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Adding else on for loops, like Python
Le 11/08/2013 06:53, Tom Lee a écrit : I think your code will be more explicit if you declare a mut bool check its state post-`break`. :) Resorting to boolean flags to cope with insufficient control flow feels like Basic, which makes me sad :( -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Adding else on for loops, like Python
Hi, Now that the for loop is based on external iterators, can we reconsider for-else? Proposal: for i in iter { // ... } else { // ... } The optional else block is executed when the for loop stops without exhausting the iterator, ie. when break is used. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Adding else on for loops, like Python
Le 10/08/2013 15:56, Jordi Boggiano a écrit : On 10.08.2013 16:10, Simon Sapin wrote: Proposal: for i in iter { // ... } else { // ... } The optional else block is executed when the for loop stops without exhausting the iterator, ie. when break is used. Maybe that's common to python devs, but I would expect else to be executed if the iterator yielded nothing/was empty. I agree that would also be useful, but I don’t know how to have both. It is what Jinja2 is doing. (A templating language for Python.) For what it’s worth, I find else-on-empty especially useful in templates (ie. generating stuff based on some data) and else-on-exhaustion especially useful in data-manipulation code. IMO if you break you'll already be in a conditional of some sort in the for body, so you can add more code there. Yes, it’s trivial to do stuff when you break. The trick is doing stuff when you *don’t*. Without this proposal, the options are: * Using a boolean flag, flipped when you break * Avoiding the for loop entirely, using iter.next(), and doing stuff when receiving None. … none of which is great. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Adding else on for loops, like Python
Le 10/08/2013 15:10, Simon Sapin a écrit : Proposal: for i in iter { // ... } else { // ... } The optional else block is executed when the for loop stops without exhausting the iterator, ie. when break is used. Typical usage is finding an element in a container and have a default/fallback: for element is container.iter() { if is_relevant(element) { do_something_with(element); break } } else { not_found() } -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Text encoding
Le 29/07/2013 18:58, Fredrik Håård a écrit : I wrote an implementation of text encoding/decoding for ISO*-Unicode in Rust, available here:https://github.com/haard/rust-codecs I use approximately the same technique as the cpython implementation, and it works by parsing unicode.org specifications and generating Rust source; a charmap for each encoding and a codecs.rs which can be used to encode/decode text. The implementation depends on std::unicode being public, which it is not right now. Although it is in need of cleanup, more than the single naive testcase, and adding stream handling etc to the API, since I got a working version (aka the fun part), I thought it best to ask if an implementation along those lines could be considered for inclusion? If so I'll dedicate some time to clean it up, otherwise I'll find something else to work on instead. Hi, This looks great, thanks a lot for sharing! Please choose a software license (preferably an open-source one ;)) and add a LICENSE file to the repository. Servo will eventually need an implementation (ideally in Rust) of http://encoding.spec.whatwg.org/ , which has a lot in common with what you’re doing. Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] 'in' for for loops and alloc exprs
Le 25/07/2013 01:56, Graydon Hoare a écrit : for pattern in expr { ... } Yes please. - The 'do' form starts to look a little lonely / incongruous. We use it presently for passing-in-a-closure when a function takes an optional value, such as: do hashmap.find_or_insert_with(k) { def() } Given we're discussing macro-izing the other main use of 'do' to generate an owning thunk Trait object, It's not entirely clear to me that this pattern alone warrants keeping 'do'. Aren’t there other uses of 'do'? do std::task::spawn { // ... } -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Can Rust allow a bitwise equality test?
Le 19/07/2013 10:17, Thiez a écrit : I think something along these lines should do: fn bitwise_compareT(a: T, b: T) - bool { use std::{ptr,sys,cast,uint}; let size = sys::size_of::T(); unsafe { let a: u8 = cast::transmute(a); let b: u8 = cast::transmute(b); for uint::range(0,size) |n| { if *ptr::offset(a,n) != *ptr::offset(b,n){ return false } } } true } Note that it won't work for strings and vectors. It could be slightly more efficient by comparing in larger chunks than u8, but LLVM will probably figure that out. There’s code in libstd that uses libc::memcpm instead of an explicit loop: https://github.com/mozilla/rust/blob/06fec5243b/src/libstd/vec.rs#L2091 Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] bikeshedding println() and friends
Le 14/07/2013 03:39, Jack Moffitt a écrit : I propose instead: 1) Do away with the formatting stuff as the default. print!() and println!() should just take a variable number of arguments, and each one should be printed in its default string representation with a space between each one. This is how Clojure's (and Python's?) print and println work. This would change code like this: println!(The result is %f, foo); to this: println!(The result is, foo) It's much easier. There are no formatting codes to remember and it does exaclty what you want in most cases. Consider: println!(a, ,b, c, d=, d); This seems great for the standard printf-style debugging. If formatting is needed, it's easy to get to: println!(My name is, name, and I scored, fmt!(%0.2f, score)); 2) Since println!() is likely to be used the most often, I feel like it should have a shorter name. Ie, we should call it just print!(), and have a newline-less version with a different name, or perhaps a different style of invocation of the macro. I like this. For comparison, Python 3 has a single print() function that takes a variable number of positional parameters (including zero), and two optional keyword-only parameters sep=' ' and end='\n'. In my experience 'end' is not used often. When it is, it is most often set to the emtpty string. 'sep' is even less used. So maybe it’s okay to not have so much flexibility, and require complex cases to fall back on fmt!() -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Nightly builds of incoming for Arch Linux
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 ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] PSA: ~string is probably not what you want
Le 28/04/2013 21:49, Patrick Walton a écrit : As Daniel pointed out, it isn't so bad. I didn't realize that we already borrow on the left hand side, so you can write: fn main() { let x = ~foo; if foo == x { println(yep); } } Using `if constant == variable` rather than the reverse is sometimes called a Yoda condition and considered bad style, but that’s purely aesthetic. It’s still good that this works as expected. We just need to borrow on the right hand side too, so that `x == foo` works. I can think of ways to do it; none are particularly pretty, but I suspect we could make it work. But the situation is not so dire now. Is there a reason that both sides of the == operator should not behave the same? Like many operators == seems like it should be symmetric, ie. a == b are always the same for any a and b (and their types, presumably.) Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] String encode/decode
Le 11/04/2013 16:30, Fredrik Håård a écrit : So, I take it no-one is working on codecs, is anyone interested in codecs? Hi, A while ago I started implementing in Rust the WHATWG Encoding specification: http://encoding.spec.whatwg.org/ In addition to the actual algorithms (and precise error handling), the spec defines a set of labels that should be used for legacy web content. For example, when getting 'Content-Type: text/html;charset=ISO-8859-1', it’s the Windows-1252 encoding that should actually be used. It’s also important that labels *not* on the list are not supported. UTF-7 for example has known security issues. Servo will need this eventually. A general-purpose library might want to support encodings that are not supported on the web, such as UTF-32. One should be careful to provide a separate API, so as not to expose these encodings to the web. My implementation is very much incomplete and kind of abandoned at the moment. I expect to start working on it again in the next few months. If someone wants to take it up in the meantime, feel free to do so. Or start from scratch, there really isn’t much there. https://github.com/SimonSapin/rust-webencodings I've started prototyping a solution patterned on Python (i.e. a tool to generate specific codec modules from the specs). What does patterned on Python mean? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Simple question
Le 04/02/2013 15:29, Renato Lenzi a écrit : Hi there. How can i use power operator? that is: let x1 = 7; let x2 = 8; let mut x3; x3 = x1 ** x2; ? it seems this doesn't work Hi, AFAIK there is no operator for this, but libcore has a float::pow_with_uint function: http://static.rust-lang.org/doc/core/float.html#function-pow_with_uint For a float power, I find traces of a f64::pow function but it’s undocumented… -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Autiincrement values in loops
Le 01/02/2013 13:28, Alexander Stavonin a écrit : Thanks, it better than nothing, but… It works only for i++; how can I write /i += 2 /or /i--/? The range() function is very simple: https://github.com/mozilla/rust/blob/release-0.5/src/libcore/int-template.rs#L48 #[inline(always)] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: T, hi: T, it: fn(T) - bool) { let mut i = lo; while i hi { if !it(i) { break } i += 1 as T; } } It’s quite easy to write your own variant with a step parameter: pub pure fn range_step(lo: int, hi: int, step: int, it: fn(int) - bool) { let mut i = lo; while i hi { if !it(i) { break } i += step; } } Maybe range_step() could be added to libcore? -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Autiincrement values in loops
Le 01/02/2013 13:38, Lucian Branescu a écrit : It's also possible to write something like python's enumerate, to get: for enumerate(some_vector) Ii, e| { ... } In general, rust loops are closer to Python's and functional map than C++'s looping constructs. Python’s enumerate() works on any iterable, not just lists. Is it possible to chain rust for-loops to get something that works not just on vectors? The best I can think of (untested) is: fn enumerateT(inner_loop: fn(fn(T) - bool), it: fn(uint, T) - bool) { let i = 0u; for inner_loop |el| { if !it(i, el) { break } i += 1; } } for enumarate(|it| { some_str.each_char(it) }) |i, ch| { … } … but it’s not pretty, and doesn’t work with eg. vec::each2 which gives two arguments to its own `it`. -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Autiincrement values in loops
Le 01/02/2013 14:50, Benjamin Striegel a écrit : Though note that this function is relatively new, you'll need to be on a recent unstable version rather than 0.5. Is it a bug that it’s not documented? http://static.rust-lang.org/doc/core/int.html -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Hash Table
Le 31/01/2013 09:39, piyush agarwal a écrit : How can we implement hash table in rust ..or there is any built-in type for it. Hi, Have you looked into the std::map module? If that does not fit your use case, I think the underlying hash is in core::hash. http://static.rust-lang.org/doc/std/map.html http://static.rust-lang.org/doc/core/hash.html Cheers, -- Simon Sapin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev