Re: [rust-dev] Deprecating rustpkg
2014-02-02 Thomas Leonard tal...@gmail.com: [ I don't want to start another argument, but since you guys are discussing 0install, maybe I can provide some useful input... ] I don't follow this. Whether the developer uses 0install to get the build dependencies doesn't make any difference to the generated binary. Of course, you *can* distribute the binary using 0install too, but you're not required to. I probably have left this part in that formulation by accident. I apologize for that, I had been writing this message in several passes. Yes, of course it does not matter for the developer where he gets build dependencies from, provided these dependencies are readily available for the build process and are easily managed. 0install doesn't automatically check out Git repositories (although that would be handy). Here's how we currently do it: - Your program depends on libfoo = 1.0-post - The latest released version of libfoo is only 1.0 - You git clone the libfoo repository yourself and register the metadata (feed) file inside it: $ git clone git://.../libfoo $ 0install add-feed libfoo/feed.xml - 0install now sees that libfoo 1.0 and 1.0-post are both available. Since your program requires libfoo = 1.0-post, it will select the Git checkout version. Seems to be a lot of manual work. This could be automated by Rust package/build manager, though. Given a set of requirements, 0install will tell you where some suitable versions of the dependencies are. For example: $ cd /tmp $ git clone https://github.com/0install/hello-scons.git $ cd hello-scons $ 0install download Hello-scons.xml --source --show - URI: /tmp/hello-scons/Hello-scons.xml Version: 1.1-post Path: /tmp/hello-scons - URI: http://0install.net/2006/3rd-party/SCons.xml Version: 2.0.1 Path: /var/cache/0install.net/implementations/sha1new=86311df9d410de36d75bc51762d2927f2f045ebf - URI: http://repo.roscidus.com/python/python Version: 2.7.6-1 Path: (package:arch:python2:2.7.6-1:x86_64) This says that the build dependencies are: - This package's source code (in /tmp/hello-scons) - The SCons build tool (which 0install has placed in /var/cache) - Python (provided by the distribution) The source could also specify library dependencies. How do you get this information to the build tool? The usual way is to tell 0install how to run the build tool in the XML. In this case, by running SCons on the project's SConstruct file. But you could get the information to it some other way. For example, a rustpkg tool that invokes 0install download ... --source --xml behind the scenes and does something with the machine-readable selections document produced. Thanks for the explanation, I didn't know that 0install can run build tools and that it could provide the information about libraries locations. This certainly answers my question. How should I specify build dependencies for people who want to hack on my package? List them in the XML file that is in your project's source repository. Users should then be able to clone your git repository and build, with build dependencies handled for them. Again, didn't know that 0install can handle build dependencies. This is all about run time dependencies, but I think the discussion here is about build time, right? You'll have the same issues with any system. Usually build dependencies are a superset of runtime dependencies, aren't they? Nonetheless, this was not about runtime dependencies, this was about general approach. But I think given your explanation of 0install operation this point can be discarded. I think any build tool (including go, cabal, pip, rustpkg) will have this problem. Ideally, you want distributions to be able to turn upstream packages into their preferred format automatically. Whatever system you settle on this should be possible, as long as you have some kind of machine-readable dependency information. Yes, you're quite correct on that ideally upstream packages should be converted to distribution packages automatically. For the new hypothetical build system I see it like the following: a maintainer downloads sources for a package, invokes some distro-specific tool which in turn invokes `rustpkg` to build the package and assemble dependency information, which is then converted to a distribution package. Then the maintainer manually adds external dependencies to the list. Something like that is already done for Haskell in Arch Linux, for example. It seems that it could be done with 0install, at least, to some extent. Zero install may have integration with package systems, but looks like it is very brittle. According to [this page](http://0install.net/distribution-integration.html) it is package owner's duty to specify how native package dependencies should be resolved in each distribution. This is extremely fragile. I don't use Debian, for example,
Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax
Just because Any is a trait doesn't mean it doesn't break parametricity. Look at this: http://static.rust-lang.org/doc/master/src/std/home/rustbuild/src/rust-buildbot/slave/doc/build/src/libstd/any.rs.html#37-63 Because we have `implT: 'static Any for T`, it can be used with *any type* (except borrowed data), including type parameters, whether or not they declare the `T: Any` bound explicitly (which is essentially redundant in this situation). The proper thing would be for the compiler to generate an `impl Any for MyType` for each individual type separately, rather than a single generic impl which is valid for all types. I also think we should guarantee parametricity for safe code and make `size_of` an unsafe fn. Its legitimate uses in unsafe code (e.g. smart pointers) are well encapsulated and don't expose parametricity violations, and I don't believe safe code has a legitimate reason to use it (does it?). On Sun, Feb 2, 2014 at 3:27 AM, Eric Reed ecr...@cs.washington.edu wrote: I'm going to respond to Any and size_of separately because there's a significant difference IMO. It's true that Any and trait bounds on type parameters in general can let function behavior depend on the passed type, but only in the specific behavior defined by the trait. Everything that's not a trait function is still independent of the passed type (contrast this with a setup where this wasn't true. `fn fooA() - int' could return 2i for int and spin up a tetris game then crash for uint). Any just happens to be powerful enough to allow complete variance, which is expected since it's just dynamic typing, but there's an important distinction still: behavior variance because of Any *is* part of the function because you need to do explicit type tests. I wasn't aware of mem::size_of before, but I'm rather annoyed to find out we've started adding bare A - B functions since it breaks parametricity. I'd much rather put size_of in a trait, at which point it's just a weaker version of Any. Being able to tell how a function's behavior might vary just from the type signature is a very nice property, and I'd like Rust to keep it. Now, onto monomorphization. I agree that distinguishing static and dynamic dispatch is important for performance characterization, but static dispatch != monomorphization (or if it currently does, then it probably shouldn't) because not all statically dispatched code needs to be monomorphizied. Consider a function like this: fn fooA, B(ox: Option~A, f: |~A| - ~B) - Option~B { match ox { Some(x) = Some(f(x)), None = None, } } It's quite generic, but AFAIK there's no need to monomorphize it for static dispatch. It uses a constant amount of stack space (not counting what `f' uses when called) and could run the exact same code for any types A or B (check discriminant, potentially call a function pointer, and return). I would guess most cases require monomorphization, but I consider universal monomorphization a way of implementing static dispatch (as opposed to partial monomorphization). I agree that understanding monomorphization is important for understanding the performance characteristics of code generated by *rustc*, but rustc != Rust. Unless universal monomorphization for static dispatch makes its way into the Rust language spec, I'm going to consider it an implementation detail for rustc. On Sat, Feb 1, 2014 at 3:31 PM, Corey Richardson co...@octayn.net wrote: On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed ecr...@cs.washington.edu wrote: Responses inlined. Hey all, bjz and I have worked out a nice proposal[0] for a slight syntax change, reproduced here. It is a breaking change to the syntax, but it is one that I think brings many benefits. Summary === Change the following syntax: ``` struct FooT, U { ... } implT, U TraitT for FooT, U { ... } fn fooT, U(...) { ... } ``` to: ``` forallT, U struct Foo { ... } forallT, U impl TraitT for FooT, U { ... } forallT, U fn foo(...) { ... } ``` The Problem === The immediate, and most pragmatic, problem is that in today's Rust one cannot easily search for implementations of a trait. Why? `grep 'impl Clone'` is itself not sufficient, since many types have parametric polymorphism. Now I need to come up with some sort of regex that can handle this. An easy first-attempt is `grep 'impl(.*?)? Clone'` but that is quite inconvenient to type and remember. (Here I ignore the issue of tooling, as I do not find the argument of But a tool can do it! valid in language design.) I think what I've done in the past was just `grep impl | grep Clone'. A deeper, more pedagogical problem, is the mismatch between how `struct Foo... { ... }` is read and how it is actually treated. The straightforward, left-to-right reading says There is a struct Foo which, given the types ... has the members This
[rust-dev] Proposal: Unify closure and proc declaration syntax?
Hello rust-dev, I imagine there are reasons I've not considered for why proc declaration syntax is the way it is, but I couldn't find any discussion on this list or in the issues so thought I'd make a proposal. I think it would be nice if procs and closures had a more similar syntax. Specifically I'd like to see proc loose it's function like () parameter list and gain the block like || params list as closures have. So rather than the current: spawn(proc(x,y) { /* Do some work. */ }); We would write: spawn(proc |x,y| { /* Do some work. */ }); A minor change, for sure, but I find the later easier to visually parse and recognize as a closure. With the current syntax I find that for a split second it looks to me like a function call to some function proc with a block after it. I thought for a moment that maybe proc was a function with a final hidden block argument and that this was a magic syntactic sugar for giving this proc function a block (kind of like the old do syntax) but then I read the parser and learned that proc is in fact part of the syntax. There are probably some caveats that I haven't considered since I'm not 100% familiar with all of the closure types. If there is a glaring reason why this is a bad idea please do tell; else let's discuss. Thanks for reading! ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposal: Unify closure and proc declaration syntax?
It might be good to revisit proc syntax, but I don't think that it's yet time for that. There's a nebulous plan in the works involving reimplementing closures as traits (or... something?) and how that shakes out would likely impact the syntax that we want to provide. On Mon, Feb 3, 2014 at 11:26 AM, Jake Kerr koda...@gmail.com wrote: Hello rust-dev, I imagine there are reasons I've not considered for why proc declaration syntax is the way it is, but I couldn't find any discussion on this list or in the issues so thought I'd make a proposal. I think it would be nice if procs and closures had a more similar syntax. Specifically I'd like to see proc loose it's function like () parameter list and gain the block like || params list as closures have. So rather than the current: spawn(proc(x,y) { /* Do some work. */ }); We would write: spawn(proc |x,y| { /* Do some work. */ }); A minor change, for sure, but I find the later easier to visually parse and recognize as a closure. With the current syntax I find that for a split second it looks to me like a function call to some function proc with a block after it. I thought for a moment that maybe proc was a function with a final hidden block argument and that this was a magic syntactic sugar for giving this proc function a block (kind of like the old do syntax) but then I read the parser and learned that proc is in fact part of the syntax. There are probably some caveats that I haven't considered since I'm not 100% familiar with all of the closure types. If there is a glaring reason why this is a bad idea please do tell; else let's discuss. Thanks for reading! ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Using Default Type Parameters
On Mon, Feb 3, 2014 at 8:41 AM, Gábor Lehel glaebho...@gmail.com wrote: On Mon, Feb 3, 2014 at 7:55 AM, Corey Richardson co...@octayn.net wrote: Default typarams are awesome, but they're gated, and there's some concern that they'll interact unpleasantly with extensions to the type system (most specifically, I've seen concern raised around HKT, where there is conflicting tension about whether to put the defaults at the start or end of the typaram list). Just for reference, this was discussed here: https://github.com/mozilla/rust/pull/11217 (The tension is essentially that with default type args you want to put the least important types at the end, so they can be defaulted, while with HKT you want to put them at the front, so they don't get in the way of abstracting over the important ones.) Thinking out loud: could parameters be keyed, like named functions arguments ? If they were, then their position would matter little. -- Matthieu ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Using Default Type Parameters
Possibly, but it's not particularly well-trodden ground (I think Ur/Web might have something like it?). And would you really want to write `HashMapKey: int, Value: ~str`? On Mon, Feb 3, 2014 at 6:34 PM, Matthieu Monrocq matthieu.monr...@gmail.com wrote: On Mon, Feb 3, 2014 at 8:41 AM, Gábor Lehel glaebho...@gmail.com wrote: On Mon, Feb 3, 2014 at 7:55 AM, Corey Richardson co...@octayn.netwrote: Default typarams are awesome, but they're gated, and there's some concern that they'll interact unpleasantly with extensions to the type system (most specifically, I've seen concern raised around HKT, where there is conflicting tension about whether to put the defaults at the start or end of the typaram list). Just for reference, this was discussed here: https://github.com/mozilla/rust/pull/11217 (The tension is essentially that with default type args you want to put the least important types at the end, so they can be defaulted, while with HKT you want to put them at the front, so they don't get in the way of abstracting over the important ones.) Thinking out loud: could parameters be keyed, like named functions arguments ? If they were, then their position would matter little. -- Matthieu ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Syntax for custom type bounds
On Sat, Feb 01, 2014 at 03:42:45PM -0800, Vadim wrote: Since 'a FooT currently means the return value is a reference into something that has lifetime 'a, 'a FooT feels like a natural extension for saying the return value is a reference-like thing whose safety depends on something that has lifetime 'a still being around. Foo'a,T, of the other hand... it is not obvious to me why would it necessarily mean that. It does not, in fact, *necessarily* mean that, though certainly it most commonly does. It will depend on the definition of the `Foo` type and how the lifetime parameter is used within the type, as you say. It seems then that you did not mean for `'a FooT` to be syntactic sugar for `Foo'a, T` but rather a new kind of type: kind of a by value that is limited to 'a. I've been around Rust for almost a year now, and certainly since the time the current lifetime notation has been introduced, and I *still *could not explain to somebody, why a lifetime parameter appearing among the type parameters of a trait or a struct refers to the lifetime of that trait or struct. As I wrote above, a lifetime parameter does not by itself have any effect, just like a type parameter. Both type and lifetime parameters are simply substituted into the struct body, and any limitations arise from there. That is, if I have struct Foo'a { x: 'a int } then `Foo'xyz` is limited to the lifetime `'xyz` because `Foo` contains a field `x` whose type is (after substitution) `'xyz int`, and that *field* cannot escape the lifetime `'xyz`. Thus, there are in fact corner cases where the lifetime parameter has no effect, and so it is not the case that `SomeType'xyz` is necessarily limited to `'xyz` (the most obvious being when 'xyz is unused within the struct body, as you suggest). Niko ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax
Actually this isn't the case. fn fooT: Any(t: T) - TypeId { t.get_type_id() } compiles just fine, but fn barT(t: T) - TypeId { t.get_type_id() } fails with error: instantiating a type parameter with incompatible type `T`, which does not fulfill `'static`. Just T does not imply T: 'static, so parametricity is not violated. I had the same thought about making size_of and friends unsafe functions. I think that might be a reasonable idea. On Mon, Feb 3, 2014 at 5:35 AM, Gábor Lehel glaebho...@gmail.com wrote: Just because Any is a trait doesn't mean it doesn't break parametricity. Look at this: http://static.rust-lang.org/doc/master/src/std/home/rustbuild/src/rust-buildbot/slave/doc/build/src/libstd/any.rs.html#37-63 Because we have `implT: 'static Any for T`, it can be used with *any type* (except borrowed data), including type parameters, whether or not they declare the `T: Any` bound explicitly (which is essentially redundant in this situation). The proper thing would be for the compiler to generate an `impl Any for MyType` for each individual type separately, rather than a single generic impl which is valid for all types. I also think we should guarantee parametricity for safe code and make `size_of` an unsafe fn. Its legitimate uses in unsafe code (e.g. smart pointers) are well encapsulated and don't expose parametricity violations, and I don't believe safe code has a legitimate reason to use it (does it?). On Sun, Feb 2, 2014 at 3:27 AM, Eric Reed ecr...@cs.washington.eduwrote: I'm going to respond to Any and size_of separately because there's a significant difference IMO. It's true that Any and trait bounds on type parameters in general can let function behavior depend on the passed type, but only in the specific behavior defined by the trait. Everything that's not a trait function is still independent of the passed type (contrast this with a setup where this wasn't true. `fn fooA() - int' could return 2i for int and spin up a tetris game then crash for uint). Any just happens to be powerful enough to allow complete variance, which is expected since it's just dynamic typing, but there's an important distinction still: behavior variance because of Any *is* part of the function because you need to do explicit type tests. I wasn't aware of mem::size_of before, but I'm rather annoyed to find out we've started adding bare A - B functions since it breaks parametricity. I'd much rather put size_of in a trait, at which point it's just a weaker version of Any. Being able to tell how a function's behavior might vary just from the type signature is a very nice property, and I'd like Rust to keep it. Now, onto monomorphization. I agree that distinguishing static and dynamic dispatch is important for performance characterization, but static dispatch != monomorphization (or if it currently does, then it probably shouldn't) because not all statically dispatched code needs to be monomorphizied. Consider a function like this: fn fooA, B(ox: Option~A, f: |~A| - ~B) - Option~B { match ox { Some(x) = Some(f(x)), None = None, } } It's quite generic, but AFAIK there's no need to monomorphize it for static dispatch. It uses a constant amount of stack space (not counting what `f' uses when called) and could run the exact same code for any types A or B (check discriminant, potentially call a function pointer, and return). I would guess most cases require monomorphization, but I consider universal monomorphization a way of implementing static dispatch (as opposed to partial monomorphization). I agree that understanding monomorphization is important for understanding the performance characteristics of code generated by *rustc*, but rustc != Rust. Unless universal monomorphization for static dispatch makes its way into the Rust language spec, I'm going to consider it an implementation detail for rustc. On Sat, Feb 1, 2014 at 3:31 PM, Corey Richardson co...@octayn.netwrote: On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed ecr...@cs.washington.edu wrote: Responses inlined. Hey all, bjz and I have worked out a nice proposal[0] for a slight syntax change, reproduced here. It is a breaking change to the syntax, but it is one that I think brings many benefits. Summary === Change the following syntax: ``` struct FooT, U { ... } implT, U TraitT for FooT, U { ... } fn fooT, U(...) { ... } ``` to: ``` forallT, U struct Foo { ... } forallT, U impl TraitT for FooT, U { ... } forallT, U fn foo(...) { ... } ``` The Problem === The immediate, and most pragmatic, problem is that in today's Rust one cannot easily search for implementations of a trait. Why? `grep 'impl Clone'` is itself not sufficient, since many types have parametric polymorphism. Now I need to come up with some sort of regex that can handle this. An easy first-attempt is `grep
Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax
On Mon, Feb 3, 2014 at 5:20 PM, Eric Reed ecr...@cs.washington.edu wrote: Actually this isn't the case. fn fooT: Any(t: T) - TypeId { t.get_type_id() } compiles just fine, but fn barT(t: T) - TypeId { t.get_type_id() } fails with error: instantiating a type parameter with incompatible type `T`, which does not fulfill `'static`. Just T does not imply T: 'static, so parametricity is not violated. I had the same thought about making size_of and friends unsafe functions. I think that might be a reasonable idea. The 'static bound is there as a workaround for an implementation limitation. In all likelihood, it will no longer be required in the future as it has no fundamental relation to reflection. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Proposal: Change Parametric Polymorphism Declaration Syntax
On Mon, Feb 3, 2014 at 11:20 PM, Eric Reed ecr...@cs.washington.edu wrote: Actually this isn't the case. fn fooT: Any(t: T) - TypeId { t.get_type_id() } compiles just fine, but fn barT(t: T) - TypeId { t.get_type_id() } fails with error: instantiating a type parameter with incompatible type `T`, which does not fulfill `'static`. Just T does not imply T: 'static, so parametricity is not violated. 'static is not even a trait per se (as far as I understand it), it merely states the lifetime which data must be valid for. I would not expect this to imply oh, and you can also try casting it to any type. I'm not sure what a precise definition of parametricity is that we could apply here, but I'd be very surprised if this flies. It should mean something like only information that is provided may be used, not if no information is provided, nothing may be assumed, but if even a little information is provided, well feel free to do whatever you like. I had the same thought about making size_of and friends unsafe functions. I think that might be a reasonable idea. On Mon, Feb 3, 2014 at 5:35 AM, Gábor Lehel glaebho...@gmail.com wrote: Just because Any is a trait doesn't mean it doesn't break parametricity. Look at this: http://static.rust-lang.org/doc/master/src/std/home/rustbuild/src/rust-buildbot/slave/doc/build/src/libstd/any.rs.html#37-63 Because we have `implT: 'static Any for T`, it can be used with *any type* (except borrowed data), including type parameters, whether or not they declare the `T: Any` bound explicitly (which is essentially redundant in this situation). The proper thing would be for the compiler to generate an `impl Any for MyType` for each individual type separately, rather than a single generic impl which is valid for all types. I also think we should guarantee parametricity for safe code and make `size_of` an unsafe fn. Its legitimate uses in unsafe code (e.g. smart pointers) are well encapsulated and don't expose parametricity violations, and I don't believe safe code has a legitimate reason to use it (does it?). On Sun, Feb 2, 2014 at 3:27 AM, Eric Reed ecr...@cs.washington.eduwrote: I'm going to respond to Any and size_of separately because there's a significant difference IMO. It's true that Any and trait bounds on type parameters in general can let function behavior depend on the passed type, but only in the specific behavior defined by the trait. Everything that's not a trait function is still independent of the passed type (contrast this with a setup where this wasn't true. `fn fooA() - int' could return 2i for int and spin up a tetris game then crash for uint). Any just happens to be powerful enough to allow complete variance, which is expected since it's just dynamic typing, but there's an important distinction still: behavior variance because of Any *is* part of the function because you need to do explicit type tests. I wasn't aware of mem::size_of before, but I'm rather annoyed to find out we've started adding bare A - B functions since it breaks parametricity. I'd much rather put size_of in a trait, at which point it's just a weaker version of Any. Being able to tell how a function's behavior might vary just from the type signature is a very nice property, and I'd like Rust to keep it. Now, onto monomorphization. I agree that distinguishing static and dynamic dispatch is important for performance characterization, but static dispatch != monomorphization (or if it currently does, then it probably shouldn't) because not all statically dispatched code needs to be monomorphizied. Consider a function like this: fn fooA, B(ox: Option~A, f: |~A| - ~B) - Option~B { match ox { Some(x) = Some(f(x)), None = None, } } It's quite generic, but AFAIK there's no need to monomorphize it for static dispatch. It uses a constant amount of stack space (not counting what `f' uses when called) and could run the exact same code for any types A or B (check discriminant, potentially call a function pointer, and return). I would guess most cases require monomorphization, but I consider universal monomorphization a way of implementing static dispatch (as opposed to partial monomorphization). I agree that understanding monomorphization is important for understanding the performance characteristics of code generated by *rustc*, but rustc != Rust. Unless universal monomorphization for static dispatch makes its way into the Rust language spec, I'm going to consider it an implementation detail for rustc. On Sat, Feb 1, 2014 at 3:31 PM, Corey Richardson co...@octayn.netwrote: On Sat, Feb 1, 2014 at 6:24 PM, Eric Reed ecr...@cs.washington.edu wrote: Responses inlined. Hey all, bjz and I have worked out a nice proposal[0] for a slight syntax change, reproduced here. It is a breaking change to the syntax, but it is one that I think brings many benefits. Summary
[rust-dev] Handling I/O errors
Greetings Rustaceans! Upon updating your nightly builds tonight some of you may realize that all I/O code will fail to compile. Fear not, this simply means that #11946 has landed! The summary of this change is the same as its title, remove io::io_error. This is quite a far-reaching change, despite its simple summary. All I/O now returns a value of type `io::IoResultT` which is just a typedef to `ResultT, IoError`. By returning a Result from all function calls, it's not much cleaner to handle errors (condition syntax is quite awkward), less overhead (registering a condition handler was expensive), and clearer what I/O should do now (should you raise? should you return a 0 value?). Handling errors is always a tricky situation, so the compiler now provides you two tools to assist you in handling errors: 1. The new unused_must_use lint. This lint mode will tell you when you don't use an IoResultT. The purpose of this lint is to help you find out where in your program you're silently ignoring errors (often by accident). If you want even more warnings, you can turn on the unused_result lint which will warn about *all* unused results, not just those of type Result/IoResult. 2. The new if_ok!() macro. This macro has a fairly simple definition [0], and the idea is to return-early if an Err is encountered, and otherwise unwrap the Ok value. Some sample usage looks like: fn fun1() - io::IoResultint { ... } fn fun2() - io::IoResultuint { ... } fn fun3() - io::IoResult() { ... } fn foo() - io::IoResultuint { if_ok!(fun3()); let val = if_ok!(fun1()) as uint + if_ok!(fun2()); Ok(val) } These two tools are in place to help you handle errors unobtrusively as well as identify locations where you've forgotten to handle errors. Sorry about the awful rebasings you'll have to do in advance, but it's worth it! [0] - https://github.com/mozilla/rust/blob/master/src/libstd/macros.rs#L202-L204 ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Handling I/O errors
By returning a Result from all function calls, it's not much cleaner to handle errors Oops, wrong word there, I meant to indicate that it *is* much cleaner to handle errors with Result rather than conditions. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Nick Cameron joins the Rust team at Mozilla
Welcome Nick! I can't wait to see that 1.0 issue count go down! On Mon, Feb 3, 2014 at 6:20 PM, Brian Anderson bander...@mozilla.com wrote: Hi Rusties, I'm just thrilled to announce today that Nick Cameron (nrc) has joined Mozilla's Rust team full-time. Nick has a PhD in programming language theory from Imperial College London and has been hacking on Gecko's graphics and layout for two years, but now that he's all ours you'll be seeing him eradicate critical Rust bugs by the dozens. Good luck, Nick, and welcome to the party. Regards, Brian ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Will smart-pointer deref operator allow making iter::ByRef more generic?
Hi, I was looking at some structs in Rust that implement the Decorator pattern - structs that take some value, wrap it, and then provider the same interface as the value that they are wrapping while providing some extra behavior. BufferedReader is an example here - it takes another Reader and provides buffering functionality while still presenting the same interface. Anyway, I noticed that there seem to be two different patterns that are being used in Rust to do this - some structs take ownership of the value to be wrapped while other structs take a borrowed reference to the object to be wrapped. Both approaches have advantages and disadvantages. If you take ownership you have the advantage that the resulting struct is Send, however if all you have is a reference to the object you want to wrap, it won't work. The following, for example won't compile: let mut r = File::open(Path::new(/)).unwrap(); let br = BufferedReader::new(mut r); If the wrapping struct takes a reference, the example above will work. However, the resulting struct won't be Send. So, in both cases, the result is that some use-cases won't work. I noticed that the iter module addressed this issue with the ByRef struct. All Iterators that wrap other iterators take ownership of the value to be wrapped. If you want to prevent that, you can use ByRef (which hold a reference to the value to be wrapped) and pass it to the wrapping Iterator which takes ownership of the ByRef instance as opposed to the iterator you are wrapping. The problem with ByRef, though, is that it only works for Iterators. Its possible to implement different versions of ByRef for other types as well. However, this seems a bit tedious. This is a relatively common and fairly useful pattern, so it would seem that it would be nice to be able to support all of the use cases for all types. Anyway, its my understanding that future plans for Rust call for a custom derefence trait to be added to allow for the implementation of custom smart pointers. What I was wondering if that trait would also allow for making iter::ByRef into a smart pointer that could provide this type of behavior for any type as opposed to just Iterators. If that's the case, it seems like all of the structs that implement the decorator pattern could be modified to take the value they are wrapping by value and let the caller use the ByRef struct if they would prefer not to transfer ownership of the value to be wrapped. The upsides are that it seems that this would allow all use cases to be met and it would make all the Decorators consistent; the downside is that it would making wrapping a borrowed reference a little bit more verbose. I don't think that would be all that bad, though. This doesn't look too bad to me: let mut r = File::open(Path::new(/)).unwrap(); let br = BufferedReader::new(ByRef::new(mut r)); Thoughts? Things I'm wrong on? Thanks, -Palmer Cox ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Nick Cameron joins the Rust team at Mozilla
Fantastic! Good luck, Nick! On Mon, Feb 3, 2014 at 6:51 PM, Alex Crichton a...@crichton.co wrote: Welcome Nick! I can't wait to see that 1.0 issue count go down! On Mon, Feb 3, 2014 at 6:20 PM, Brian Anderson bander...@mozilla.com wrote: Hi Rusties, I'm just thrilled to announce today that Nick Cameron (nrc) has joined Mozilla's Rust team full-time. Nick has a PhD in programming language theory from Imperial College London and has been hacking on Gecko's graphics and layout for two years, but now that he's all ours you'll be seeing him eradicate critical Rust bugs by the dozens. Good luck, Nick, and welcome to the party. Regards, Brian ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Handling I/O errors
it is guaranteed to happen on all readers I meant all finite readers, such as those for normal disk files. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Will smart-pointer deref operator allow making iter::ByRef more generic?
I don't think so, because the fact that the particular instance of T implements the Deref trait cannot have any effect on the decorator code, since it's not in the bounds for T. What instead would work is to change the language so that if type Type implements Trait and all Trait methods take self or mut self (as opposed to by value self or ~self), then an implementation of Trait for 'a mut Type is automatically generated (with the obvious implementation). Likewise if all Trait methods take self, then an implementation of Trait for 'a Type is also automatically generated. Then what you want to do will just work without the need of any wrapper or special syntax. One could then, as an additional step, automatically generate an implementation of Trait for MutDerefType if Trait is implemented by mut Type (possibly due to the above technique), but this would not be required for the example. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Nick Cameron joins the Rust team at Mozilla
Congratulations! On Mon, Feb 3, 2014 at 10:11 PM, Tim Kuehn tku...@cmu.edu wrote: Fantastic! Good luck, Nick! On Mon, Feb 3, 2014 at 6:51 PM, Alex Crichton a...@crichton.co wrote: Welcome Nick! I can't wait to see that 1.0 issue count go down! On Mon, Feb 3, 2014 at 6:20 PM, Brian Anderson bander...@mozilla.com wrote: Hi Rusties, I'm just thrilled to announce today that Nick Cameron (nrc) has joined Mozilla's Rust team full-time. Nick has a PhD in programming language theory from Imperial College London and has been hacking on Gecko's graphics and layout for two years, but now that he's all ours you'll be seeing him eradicate critical Rust bugs by the dozens. Good luck, Nick, and welcome to the party. Regards, Brian ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev