From jesse9jones at gmail.com Sun Jul 1 15:47:13 2012 From: jesse9jones at gmail.com (Jesse Jones) Date: Sun, 1 Jul 2012 15:47:13 -0700 Subject: [rust-dev] Library organization Message-ID: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> I'm confused about how I can structure libraries. Let's say I have a whizbang library. It's complex enough that I want whiz and bang submodules, but that's just an implementation detail: I'd like clients of the libraries to use the public API with just an `import whizbang;`. I had thought something like the following would work: whizbang.rs import whiz::*; import bang::*; export whiz1, whiz2; export bang1; whiz.rs: fn whiz1() {} fn whiz2() {} bang.rs: fn bang1() {} And it does work?but only within the whizbang project. whiz.rs, for example, can use bang1 without even doing an import. But external libraries have to do whizbang::whiz::whiz1. -- Jesse From banderson at mozilla.com Sun Jul 1 22:52:25 2012 From: banderson at mozilla.com (Brian Anderson) Date: Sun, 1 Jul 2012 22:52:25 -0700 (PDT) Subject: [rust-dev] New closure syntax In-Reply-To: <2084369659.26104.1341204060430.JavaMail.root@mozilla.com> Message-ID: <1839032448.28419.1341208345624.JavaMail.root@mozilla.com> Greetings, Today Rust has a new closure syntax: let two_three_four = [1, 2, 3].map( |i| i + 1 ); That's it - `|args| expression`. You are going to want to sprinkle them everywhere because they are irresistible. Capture clauses still go alongside the arguments. Usually these aren't required, but occasionally one needs an explicit copy or move if copying would be expensive: let x = cat, y = dog, z = turnip; let party = |w, move x, copy y| w + x + y + z; Argument and return type annotations are optional. let party = |x: Cat, y: Dog| -> Octopus x + y; When your lambdas get bigger you can put the body in a block: spawn( || { let x = foo(); loop { etc(); } }); The new `do` syntax lets you write higher order functions more like language-level control structures by moving the closure outside of the argument list. This replaces the previous syntax for making sugared block calls. do unpack_slice(rhs) |p, len| { for range(0, len) |i| { ... } } Empty argument lists can be omitted in both `for` and `do` do spawn { ... } Yep! -Brian From lindsey at rockstargirl.org Mon Jul 2 10:46:44 2012 From: lindsey at rockstargirl.org (Lindsey Kuper) Date: Mon, 2 Jul 2012 10:46:44 -0700 Subject: [rust-dev] Addressing "the hashtable problem" with type classes In-Reply-To: References: <4ED85346.4000409@alum.mit.edu> Message-ID: On Fri, Jun 29, 2012 at 12:54 PM, Lindsey Kuper wrote: > So, I want to get an actual-running-code example of the instance > coherence problem as it stands in Rust, and Niko's example here seems > like a good place to start. ?Is "impl hash for uint" a typo for "impl > of hash for uint"? For those playing at home, yes, the missing "of" was a typo. Here's a version that compiles (with the addition of `/~` at the end of the vector, if your version of Rust uses the transitional vector syntax) and runs that demonstrates instance coherence: http://pastebin.com/TfReiNUR . Thanks to gwillen on IRC for contributing it. Lindsey From lindsey at rockstargirl.org Mon Jul 2 11:26:47 2012 From: lindsey at rockstargirl.org (Lindsey Kuper) Date: Mon, 2 Jul 2012 11:26:47 -0700 Subject: [rust-dev] Integer literal suffix inference Message-ID: A couple of weeks ago, Rust gained suffix inference for integer literals. Up until this change, to write an integer literal that had any type other than `int`, you had to add a suffix to it. This was especially annoying with uint literals, which had to be written with a `u` suffix; it was a type error to write `let x: uint = 3;` because the 3 lacked a suffix. This is no longer the case. Now, if you write an integer literal without a suffix (3, -500, etc.), the compiler will try to infer its type based on type annotations and function signatures in the surrounding program context. For example, in the following program the type of `x` is inferred to be u16 because it is passed to a function that takes a u16 argument: let x = 3; fn identity_u16(n: u16) -> u16 { n } identity_u16(x); It works in patterns, too: let account_balance = 45u64; alt account_balance { 0 { log(error, "not enough") } 1 to 99 { log(error, "enough") } _ { log(error, "whoa") } } But if the program gives conflicting information about what the type of the unsuffixed literal should be (that is, if the typing context overconstrains the type), you'll get an error message, as in the following: let x = 3; fn identity_u8(n: u8) -> u8 { n } fn identity_u16(n: u16) -> u16 { n } identity_u8(x); // after this, `x` is assumed to have type `u8` identity_u16(x); // raises a type error (expected `u16` but found `u8`) In the absence of any type annotations (that is, if the typing context underconstrains the type), Rust will assume that an unsuffixed integer literal has type int. This is is a fairly arbitrary choice, but it helps with backwards compatibility, since in the past, unsuffixed integer literals were always of type int. let n = 50; log(error, n); // n is an int Of course, if you don't want the types of your integer literals to be inferred, it's fine to keep writing them with suffixes. Enjoy! Lindsey From garethdanielsmith at gmail.com Mon Jul 2 11:30:01 2012 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Mon, 02 Jul 2012 19:30:01 +0100 Subject: [rust-dev] Integer literal suffix inference In-Reply-To: References: Message-ID: <4FF1E8A9.4020304@gmail.com> Hurrah! Thank you. Gareth From banderson at mozilla.com Mon Jul 2 11:59:59 2012 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 02 Jul 2012 11:59:59 -0700 Subject: [rust-dev] Library organization In-Reply-To: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> Message-ID: <4FF1EFAF.4040307@mozilla.com> On 07/01/2012 03:47 PM, Jesse Jones wrote: > I'm confused about how I can structure libraries. Let's say I have a whizbang library. It's complex enough that I want whiz and bang submodules, but that's just an implementation detail: I'd like clients of the libraries to use the public API with just an `import whizbang;`. I had thought something like the following would work: > > whizbang.rs > import whiz::*; > import bang::*; > > export whiz1, whiz2; > export bang1; > > whiz.rs: > fn whiz1() {} > fn whiz2() {} > > bang.rs: > fn bang1() {} > > And it does work?but only within the whizbang project. whiz.rs, for example, can use bang1 without even doing an import. But external libraries have to do whizbang::whiz::whiz1. > I would expect this to work as written. core.rs does similar things to expose option::some, none, etc. Perhaps it's because of a resolve bug. core doesn't use `import::*` for example, so maybe reexporting an import star is funky. From graydon at mozilla.com Mon Jul 2 12:13:48 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 02 Jul 2012 12:13:48 -0700 Subject: [rust-dev] Library organization In-Reply-To: <4FF1EFAF.4040307@mozilla.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> Message-ID: <4FF1F2EC.6020206@mozilla.com> On 02/07/2012 11:59 AM, Brian Anderson wrote: > On 07/01/2012 03:47 PM, Jesse Jones wrote: >> I'm confused about how I can structure libraries. Let's say I have a >> whizbang library. It's complex enough that I want whiz and bang >> submodules, but that's just an implementation detail: I'd like clients >> of the libraries to use the public API with just an `import >> whizbang;`. I had thought something like the following would work: >> >> whizbang.rs >> import whiz::*; >> import bang::*; >> >> export whiz1, whiz2; >> export bang1; >> >> whiz.rs: >> fn whiz1() {} >> fn whiz2() {} >> >> bang.rs: >> fn bang1() {} >> >> And it does work?but only within the whizbang project. whiz.rs, for >> example, can use bang1 without even doing an import. But external >> libraries have to do whizbang::whiz::whiz1. >> > > I would expect this to work as written. core.rs does similar things to > expose option::some, none, etc. Perhaps it's because of a resolve bug. > core doesn't use `import::*` for example, so maybe reexporting an import > star is funky. I can see two possibilities: #1: The bug report is ambiguous. It's not clear whether the reporter wants to be able, in external libraries, to write: import whizbang; // import from where? bang1(); // import didn't mention this or something else. That example, as written, won't work for 2 reasons: 'import' and 'use' are different directives, and anyway import only imports the name 'whizbang', not any of the sub-names. I _would_ expect the following example to work: use whizbang; // link in the library whizbang::bang1(); // access through the linked name #2: There might be a bug in resolve concerning the import/export interaction. This is ... if true, one of a long set of bugs that we have so many of on resolve that patrick is presently rewriting that module of the compiler from scratch (about to merge probably this week) to approach the resolve algorithm in an entirely different fashion. If it's just #1, try the other example and see how it fares. If it's #2, I'd suggest waiting until the resolve rewrite lands and then trying again to see if the bug goes away. There were a ton of weird corner cases surrounding globbed imports in the old code. We're pretty convinced it wasn't even well-defined (global order-sensitivity, infinite loop possibilities, all sorts of awfulness). -Graydon From graydon at mozilla.com Mon Jul 2 12:14:14 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 02 Jul 2012 12:14:14 -0700 Subject: [rust-dev] Integer literal suffix inference In-Reply-To: References: Message-ID: <4FF1F306.1030909@mozilla.com> On 02/07/2012 11:26 AM, Lindsey Kuper wrote: > Of course, if you don't want the types of your integer literals to be > inferred, it's fine to keep writing them with suffixes. > > Enjoy! \o/ I think this might have been toe-stub bug #1 on our list. We're going to have to adjust the language FAQ. -Graydon From KKelleher at homesite.com Mon Jul 2 12:48:52 2012 From: KKelleher at homesite.com (Kelleher, Kevin) Date: Mon, 2 Jul 2012 15:48:52 -0400 Subject: [rust-dev] porting to Microsoft C++? In-Reply-To: <4FF1F2EC.6020206@mozilla.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com><4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> Message-ID: <86C0AFCD4D4A3441AB65AEEF450E80842F0919CF@CAMCLSEXC01.camelot.local> I'm asking about this as something I might like to try myself: Has any thought been given to removing the dependence on MinGW? I'm sure there must be very good reasons for using that compiler, and on looking through the email archive, the bikesheds and proposals, the issue isn't even mentioned, so it's clearly not regarded as important. And honestly, on my part, it's purely an aesthetic consideration. But still, when I downloaded Rust this morning, I had to spend a little time looking up the issue about the missing libgcc_s_dw2-1.dll, and then was a bit dismayed at the size of the MinGW download. So... would I be foolish to try to port and compile the code using Microsoft's C++? The idea would be to produce Rust binaries that don't require additional downloads. Kevin This message (including any attachments) is intended only for the use of the individual or entity to which it is addressed and may contain information that is non-public, proprietary, privileged, confidential, and exempt from disclosure under applicable law or may constitute as attorney work product. If you are not the intended recipient, you are hereby notified that any use, dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, notify us immediately by telephone and (i) destroy this message if a facsimile or (ii) delete this message immediately if this is an electronic communication. Thank you. From pwalton at mozilla.com Mon Jul 2 12:51:05 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 02 Jul 2012 12:51:05 -0700 Subject: [rust-dev] porting to Microsoft C++? In-Reply-To: <86C0AFCD4D4A3441AB65AEEF450E80842F0919CF@CAMCLSEXC01.camelot.local> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com><4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <86C0AFCD4D4A3441AB65AEEF450E80842F0919CF@CAMCLSEXC01.camelot.local> Message-ID: <4FF1FBA9.8010302@mozilla.com> On 7/2/12 12:48 PM, Kelleher, Kevin wrote: > I'm asking about this as something I might like to try myself: > > Has any thought been given to removing the dependence on MinGW? > > I'm sure there must be very good reasons for using that compiler, > and on looking through the email archive, the bikesheds and proposals, > the issue isn't even mentioned, so it's clearly not regarded > as important. > > And honestly, on my part, it's purely an aesthetic consideration. > > But still, when I downloaded Rust this morning, I had to spend > a little time looking up the issue about the missing > libgcc_s_dw2-1.dll, and then was a bit dismayed at the > size of the MinGW download. > > So... would I be foolish to try to port and compile the code using > Microsoft's C++? The idea would be to produce Rust binaries > that don't require additional downloads. I started on this a year or two ago, but didn't finish due to some weird vtable issues which may well be gone now. There's some support code still lying around for it (src/rt/msvc). I think it would be a good project. Patrick From arcata at gmail.com Mon Jul 2 13:18:20 2012 From: arcata at gmail.com (Joe Groff) Date: Mon, 2 Jul 2012 13:18:20 -0700 Subject: [rust-dev] porting to Microsoft C++? In-Reply-To: <4FF1FBA9.8010302@mozilla.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <86C0AFCD4D4A3441AB65AEEF450E80842F0919CF@CAMCLSEXC01.camelot.local> <4FF1FBA9.8010302@mozilla.com> Message-ID: On Mon, Jul 2, 2012 at 12:51 PM, Patrick Walton wrote: > I started on this a year or two ago, but didn't finish due to some weird > vtable issues which may well be gone now. There's some support code still > lying around for it (src/rt/msvc). I think it would be a good project. LLVM and Clang also have growing support for targeting Windows sans Mingw, which could be a lower-friction option than porting the runtime code to Microsoft-flavored C++ as Clang's Windows support matures. -Joe From KKelleher at homesite.com Mon Jul 2 13:27:41 2012 From: KKelleher at homesite.com (Kelleher, Kevin) Date: Mon, 2 Jul 2012 16:27:41 -0400 Subject: [rust-dev] porting to Microsoft C++? In-Reply-To: References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com><4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com><86C0AFCD4D4A3441AB65AEEF450E80842F0919CF@CAMCLSEXC01.camelot.local><4FF1FBA9.8010302@mozilla.com> Message-ID: <86C0AFCD4D4A3441AB65AEEF450E80842F091A79@CAMCLSEXC01.camelot.local> That sounds pretty good, and I'm guessing is probably more in line with the way things are already. I'll take a look at that. Thanks! Kevin -----Original Message----- From: rust-dev-bounces at mozilla.org [mailto:rust-dev-bounces at mozilla.org] On Behalf Of Joe Groff Sent: Monday, July 02, 2012 4:18 PM To: Patrick Walton Cc: rust-dev at mozilla.org Subject: Re: [rust-dev] porting to Microsoft C++? On Mon, Jul 2, 2012 at 12:51 PM, Patrick Walton wrote: > I started on this a year or two ago, but didn't finish due to some > weird vtable issues which may well be gone now. There's some support > code still lying around for it (src/rt/msvc). I think it would be a good project. LLVM and Clang also have growing support for targeting Windows sans Mingw, which could be a lower-friction option than porting the runtime code to Microsoft-flavored C++ as Clang's Windows support matures. -Joe _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev This message (including any attachments) is intended only for the use of the individual or entity to which it is addressed and may contain information that is non-public, proprietary, privileged, confidential, and exempt from disclosure under applicable law or may constitute as attorney work product. If you are not the intended recipient, you are hereby notified that any use, dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, notify us immediately by telephone and (i) destroy this message if a facsimile or (ii) delete this message immediately if this is an electronic communication. Thank you. From sebastian.sylvan at gmail.com Mon Jul 2 13:55:48 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Mon, 2 Jul 2012 13:55:48 -0700 Subject: [rust-dev] Integer literal suffix inference In-Reply-To: References: Message-ID: On Mon, Jul 2, 2012 at 11:26 AM, Lindsey Kuper wrote: > A couple of weeks ago, Rust gained suffix inference for integer literals. This makes me unreasonably happy. Funny how little things cause annoyance well past their actual impact. -- Sebastian Sylvan From catamorphism at gmail.com Mon Jul 2 15:04:47 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Mon, 2 Jul 2012 15:04:47 -0700 Subject: [rust-dev] Meeting agenda Message-ID: Since Niko is on vacation, I thought I would post link to the agenda for tomorrow: https://etherpad.mozilla.org/Meeting-weekly-2012-07-03 Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From jesse9jones at gmail.com Mon Jul 2 18:22:04 2012 From: jesse9jones at gmail.com (Jesse Jones) Date: Mon, 2 Jul 2012 18:22:04 -0700 Subject: [rust-dev] Library organization In-Reply-To: <4FF1F2EC.6020206@mozilla.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> Message-ID: It's case 2. In a single whizbang library I have three modules like so: whizbang.rs import whiz::*; import bang::*; export whiz1, whiz2; export bang1; whiz.rs: fn whiz1() {} fn whiz2() {} bang.rs: fn bang1() {} Then in an exe I want to be able to use whizbang items without worry about about the physical organization of the component modules. For example, I wanted to be able to do something like: client.rs import whizbang; fn foo() { whizbang::bang1(); } Which sounds like it is supposed to work. -- Jesse On Jul 2, 2012, at 12:13 PM, Graydon Hoare wrote: > On 02/07/2012 11:59 AM, Brian Anderson wrote: >> On 07/01/2012 03:47 PM, Jesse Jones wrote: >>> I'm confused about how I can structure libraries. Let's say I have a >>> whizbang library. It's complex enough that I want whiz and bang >>> submodules, but that's just an implementation detail: I'd like clients >>> of the libraries to use the public API with just an `import >>> whizbang;`. I had thought something like the following would work: >>> >>> whizbang.rs >>> import whiz::*; >>> import bang::*; >>> >>> export whiz1, whiz2; >>> export bang1; >>> >>> whiz.rs: >>> fn whiz1() {} >>> fn whiz2() {} >>> >>> bang.rs: >>> fn bang1() {} >>> >>> And it does work?but only within the whizbang project. whiz.rs, for >>> example, can use bang1 without even doing an import. But external >>> libraries have to do whizbang::whiz::whiz1. >>> >> >> I would expect this to work as written. core.rs does similar things to >> expose option::some, none, etc. Perhaps it's because of a resolve bug. >> core doesn't use `import::*` for example, so maybe reexporting an import >> star is funky. > > I can see two possibilities: > > #1: The bug report is ambiguous. It's not clear whether the reporter > wants to be able, in external libraries, to write: > > import whizbang; // import from where? > bang1(); // import didn't mention this > > or something else. That example, as written, won't work for 2 > reasons: 'import' and 'use' are different directives, and anyway > import only imports the name 'whizbang', not any of the sub-names. > I _would_ expect the following example to work: > > use whizbang; // link in the library > whizbang::bang1(); // access through the linked name > > #2: There might be a bug in resolve concerning the import/export > interaction. This is ... if true, one of a long set of bugs > that we have so many of on resolve that patrick is presently > rewriting that module of the compiler from scratch (about to > merge probably this week) to approach the resolve algorithm > in an entirely different fashion. > > If it's just #1, try the other example and see how it fares. If it's #2, I'd suggest waiting until the resolve rewrite lands and then trying again to see if the bug goes away. There were a ton of weird corner cases surrounding globbed imports in the old code. We're pretty convinced it wasn't even well-defined (global order-sensitivity, infinite loop possibilities, all sorts of awfulness). > > -Graydon > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From zackcorr95 at gmail.com Mon Jul 2 18:27:31 2012 From: zackcorr95 at gmail.com (Zack Corr) Date: Tue, 3 Jul 2012 11:27:31 +1000 Subject: [rust-dev] Library organization In-Reply-To: References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> Message-ID: Have you tried importing bang1 only (without the import all glob)? -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Mon Jul 2 19:29:58 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 02 Jul 2012 19:29:58 -0700 Subject: [rust-dev] porting to Microsoft C++? In-Reply-To: References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <86C0AFCD4D4A3441AB65AEEF450E80842F0919CF@CAMCLSEXC01.camelot.local> <4FF1FBA9.8010302@mozilla.com> Message-ID: <4FF25926.7010502@mozilla.com> On 02/07/2012 1:18 PM, Joe Groff wrote: > On Mon, Jul 2, 2012 at 12:51 PM, Patrick Walton wrote: >> I started on this a year or two ago, but didn't finish due to some weird >> vtable issues which may well be gone now. There's some support code still >> lying around for it (src/rt/msvc). I think it would be a good project. > > LLVM and Clang also have growing support for targeting Windows sans > Mingw, which could be a lower-friction option than porting the runtime > code to Microsoft-flavored C++ as Clang's Windows support matures. We have every intention to move in this direction. I'll be commencing on a rewrite of the rustc driver at some point in the next several months (hopefully not really affecting the language-per-se any) and this rewrite will revolve around the driver portions of clang, which is now in-tree with our build and is perfectly happy to target msvc for the assembly and linkage work (as well as compiling C/C++ parts). See issues #1768, #1879, #1862, #2373 and related bugs. -Graydon From graydon at mozilla.com Mon Jul 2 19:33:12 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 02 Jul 2012 19:33:12 -0700 Subject: [rust-dev] Library organization In-Reply-To: References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> Message-ID: <4FF259E8.1090300@mozilla.com> On 02/07/2012 6:22 PM, Jesse Jones wrote: > Then in an exe I want to be able to use whizbang items without worry about about the physical organization of the component modules. For example, I wanted to be able to do something like: > > client.rs > import whizbang; > > fn foo() > { > whizbang::bang1(); > } > > Which sounds like it is supposed to work. Right. But only if you did 'use whizbang;' you have not mentioned yet in any of your examples whether you put a 'use whizbang;' in the code. Writing 'import whizbang;' only remaps names within a single crate; 'use' is the directive you have to write in order to get _linkage_ to occur (that is: for the whizbang library to appear in the namespace client.rs at all). Can you try that? -Graydon From graydon at mozilla.com Mon Jul 2 19:57:07 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 02 Jul 2012 19:57:07 -0700 Subject: [rust-dev] New closure syntax In-Reply-To: <1839032448.28419.1341208345624.JavaMail.root@mozilla.com> References: <1839032448.28419.1341208345624.JavaMail.root@mozilla.com> Message-ID: <4FF25F83.5070308@mozilla.com> On 01/07/2012 10:52 PM, Brian Anderson wrote: > Today Rust has a new closure syntax: > > let two_three_four = [1, 2, 3].map( |i| i + 1 ); That's pretty great. Especially since it runs entirely in stack allocations. Whee. > let x = cat, y = dog, z = turnip; > let party = |w, move x, copy y| w + x + y + z; > > Argument and return type annotations are optional. > > let party = |x: Cat, y: Dog| -> Octopus x + y; These are some remarkable parties. > Empty argument lists can be omitted in both `for` and `do` > > do spawn { > ... > } > > Yep! Cool. Looks like it'll handle a lot of control abstractions without looking strange; I was a doubter but now I'm a believer. Bravo! -Graydon From KKelleher at homesite.com Tue Jul 3 06:57:05 2012 From: KKelleher at homesite.com (Kelleher, Kevin) Date: Tue, 3 Jul 2012 09:57:05 -0400 Subject: [rust-dev] porting to Microsoft C++? In-Reply-To: <4FF25926.7010502@mozilla.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com><4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com><86C0AFCD4D4A3441AB65AEEF450E80842F0919CF@CAMCLSEXC01.camelot.local><4FF1FBA9.8010302@mozilla.com> <4FF25926.7010502@mozilla.com> Message-ID: <86C0AFCD4D4A3441AB65AEEF450E80842F1322CD@CAMCLSEXC01.camelot.local> That is great news. - Kevin -----Original Message----- From: rust-dev-bounces at mozilla.org [mailto:rust-dev-bounces at mozilla.org] On Behalf Of Graydon Hoare Sent: Monday, July 02, 2012 10:30 PM To: rust-dev at mozilla.org Subject: Re: [rust-dev] porting to Microsoft C++? On 02/07/2012 1:18 PM, Joe Groff wrote: > On Mon, Jul 2, 2012 at 12:51 PM, Patrick Walton wrote: >> I started on this a year or two ago, but didn't finish due to some >> weird vtable issues which may well be gone now. There's some support >> code still lying around for it (src/rt/msvc). I think it would be a good project. > > LLVM and Clang also have growing support for targeting Windows sans > Mingw, which could be a lower-friction option than porting the runtime > code to Microsoft-flavored C++ as Clang's Windows support matures. We have every intention to move in this direction. I'll be commencing on a rewrite of the rustc driver at some point in the next several months (hopefully not really affecting the language-per-se any) and this rewrite will revolve around the driver portions of clang, which is now in-tree with our build and is perfectly happy to target msvc for the assembly and linkage work (as well as compiling C/C++ parts). See issues #1768, #1879, #1862, #2373 and related bugs. -Graydon _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev This message (including any attachments) is intended only for the use of the individual or entity to which it is addressed and may contain information that is non-public, proprietary, privileged, confidential, and exempt from disclosure under applicable law or may constitute as attorney work product. If you are not the intended recipient, you are hereby notified that any use, dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, notify us immediately by telephone and (i) destroy this message if a facsimile or (ii) delete this message immediately if this is an electronic communication. Thank you. From christian at siefkes.net Tue Jul 3 13:15:41 2012 From: christian at siefkes.net (Christian Siefkes) Date: Tue, 03 Jul 2012 22:15:41 +0200 Subject: [rust-dev] Installing Rust? Message-ID: <4FF352ED.8090808@siefkes.net> Hi all, I recently discovered Rust and would love to explore it a bit, but I have trouble installing a current version. Following , I tried wget http://dl.rust-lang.org/dist/rust-0.3.tar.gz but that gives ERROR 403: Forbidden. On the other hand, , refers to v0.2 from Mar 29 as the latest version. I installed that version successfully, but it seems to be pretty outdated compared to the API reference on the website. For args: [str], args.len() works, but if I try args.tail() or args.head(), I get error: attempted access of field tail on type [str], but no public field or method with that name was found Could anyone kindly explain how to actually install a sufficiently current version of Rust on Linux (Debian testing, in my case)? Thanks in advance Christian -- |------- Dr. Christian Siefkes ------- christian at siefkes.net ------- | Homepage: http://www.siefkes.net/ | Blog: http://www.keimform.de/ | Peer Production Everywhere: http://peerconomy.org/wiki/ |---------------------------------- OpenPGP Key ID: 0x346452D8 -- For we each of us deserve everything, every luxury that was ever piled in the tombs of the dead kings, and we each of us deserve nothing, not a mouthful of bread in hunger. Have we not eaten while another starved? Will you punish us for that? Will you reward us for the virtue of starving while others ate? No man earns punishment, no man earns reward. Free your mind of the idea of *deserving*, the idea of *earning*, and you will begin to be able to think. -- Ursula K. Le Guin, The Dispossessed -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From graydon at mozilla.com Tue Jul 3 13:20:09 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 03 Jul 2012 13:20:09 -0700 Subject: [rust-dev] Installing Rust? In-Reply-To: <4FF352ED.8090808@siefkes.net> References: <4FF352ED.8090808@siefkes.net> Message-ID: <4FF353F9.2010801@mozilla.com> On 7/3/2012 1:15 PM, Christian Siefkes wrote: > Could anyone kindly explain how to actually install a sufficiently current > version of Rust on Linux (Debian testing, in my case)? 0.2 is the most recent release, but yes, it's sadly a few months behind; you'll need to work from git to get newer. We'll have another release out in the next week or so, if you prefer to wait for that. From that point on we'll be making snapshots of the docs on a per-release basis so you can view docs that are contemporary with the release you download. Sorry, still pretty development-y. We're hoping to stabilize this process in coming months. All acutely aware of how much in-flux it is. -Graydon From stefan.plantikow at googlemail.com Wed Jul 4 01:38:13 2012 From: stefan.plantikow at googlemail.com (Stefan Plantikow) Date: Wed, 04 Jul 2012 10:38:13 +0200 Subject: [rust-dev] Installing Rust? In-Reply-To: <4FF353F9.2010801@mozilla.com> References: <4FF352ED.8090808@siefkes.net> <4FF353F9.2010801@mozilla.com> Message-ID: <4FF400F5.4050705@googlemail.com> Am Tue Jul 3 22:20:09 2012 schrieb Graydon Hoare: > On 7/3/2012 1:15 PM, Christian Siefkes wrote: > >> Could anyone kindly explain how to actually install a sufficiently >> current >> version of Rust on Linux (Debian testing, in my case)? > > 0.2 is the most recent release, but yes, it's sadly a few months > behind; you'll need to work from git to get newer. We'll have another > release out in the next week or so, if you prefer to wait for that. > From that point on we'll be making snapshots of the docs on a > per-release basis so you can view docs that are contemporary with the > release you download. > > Sorry, still pretty development-y. We're hoping to stabilize this > process in coming months. All acutely aware of how much in-flux it is. Will there be an update of the tutorial and spec for the release? It has become somewhat tricky to know what syntax works without tracking git on a daily basis (regions, classes). Greets, Stefan. PS: Even though I don't have much time right now for it, I love how rust is progressing! Keep rolling :) From christian at siefkes.net Wed Jul 4 08:00:20 2012 From: christian at siefkes.net (Christian Siefkes) Date: Wed, 04 Jul 2012 17:00:20 +0200 Subject: [rust-dev] Installing Rust? In-Reply-To: <4FF353F9.2010801@mozilla.com> (sfid-H20120703-222011-+015.38-1@spamfilter.osbf.lua) References: <4FF352ED.8090808@siefkes.net> <4FF353F9.2010801@mozilla.com> (sfid-H20120703-222011-+015.38-1@spamfilter.osbf.lua) Message-ID: <4FF45A84.4070603@siefkes.net> On 07/03/2012 10:20 PM, Graydon Hoare wrote: > On 7/3/2012 1:15 PM, Christian Siefkes wrote: > 0.2 is the most recent release, but yes, it's sadly a few months behind; > you'll need to work from git to get newer. We'll have another release out in > the next week or so, if you prefer to wait for that. From that point on > we'll be making snapshots of the docs on a per-release basis so you can view > docs that are contemporary with the release you download. Thanks, if it's just a week or so, I'll wait for the next release. I very much like what I've seen from rust so far -- looks like a very powerful combination of machine-near, practical, and functional. Great work! On a side note, http://doc.rust-lang.org/doc/core/index.html works (redirecting to dl.rust-lang.org), but without the "index.html", it gives an Access Denied error. Same for http://doc.rust-lang.org/doc/std/ instead of http://doc.rust-lang.org/doc/std/index.html . That's unexpected, and slightly annoying. Best regards Christian -- |------- Dr. Christian Siefkes ------- christian at siefkes.net ------- | Homepage: http://www.siefkes.net/ | Blog: http://www.keimform.de/ | Peer Production Everywhere: http://peerconomy.org/wiki/ |---------------------------------- OpenPGP Key ID: 0x346452D8 -- If a child wants to grow up to be a cowgirl, she ought to be able to do it, or else this world ain't worth living in. I want every little girl--and every boy, for that matter--to be free to realize their fantasies. Anything less than that is unacceptable to me. -- Tom Robbins, Even Cowgirls Get the Blues -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From graydon at mozilla.com Wed Jul 4 08:20:22 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 04 Jul 2012 08:20:22 -0700 Subject: [rust-dev] Installing Rust? In-Reply-To: <4FF400F5.4050705@googlemail.com> References: <4FF352ED.8090808@siefkes.net> <4FF353F9.2010801@mozilla.com> <4FF400F5.4050705@googlemail.com> Message-ID: <4FF45F36.3010209@mozilla.com> On 04/07/2012 1:38 AM, Stefan Plantikow wrote: > Will there be an update of the tutorial and spec for the release? It has > become somewhat tricky to know what syntax works without tracking git on > a daily basis (regions, classes). Yes, we are now updating both on a release-by-release basis and will be keeping versions of both (all docs, API included) pinned to each release visible on the website (of course the docs are also included _in_ the release artifacts, and can also be viewed there). I apologize again for the ongoing churn. We're ... "front loading" as much of it as we can -- that is, pushing through the most-disruptive planned changes as soon as we are sure they're on the roadmap -- such that we can get to a stable point we're comfortable supporting for a longer period, within the next few releases. I keep meaning to publish a roadmap showing where we (at least, the mozilla-employed developers) are going between here and there. We have actually had this discussion in some detail and are pretty clear on the remaining work. Perhaps I'll find time to post this week. > PS: Even though I don't have much time right now for it, I love how rust > is progressing! Keep rolling :) Thanks. Means a lot to hear we're pointed in a good direction. -Graydon From behdad at behdad.org Wed Jul 4 06:55:13 2012 From: behdad at behdad.org (Behdad Esfahbod) Date: Wed, 04 Jul 2012 09:55:13 -0400 Subject: [rust-dev] Unicode vs hex escapes in Rust Message-ID: <4FF44B41.2020903@behdad.org> Hi Graydon et al, I started learning Rust today, and while it's building, I'm going through the tutorial. I understand that it's quite outdated (points to 0.1 still), but here's a couple things I spotted: Under 3.6.2 Other literals: * This: "A newline (Unicode character 32)" should say 10 instead of 32! * Here: "\xHH, \uHHHH, \UHHHHHHHH Unicode escapes", I strongly suggest that \xHH be modified to allow inputting direct UTF-8 bytes. For ASCII it doesn't make any different. For Latin1, it gives the impression that strings are stored in Latin1, which is not the case. It would also make C / Python escaped strings directly usable in Rust. Ie. '\xE2\x98\xBA' would be a single character equivalent to '\u263a', not three Latin1 characters. Under 4.4 Loops: * This: "loop is the preferred way of writing while true" doesn't match the example that follows it, which still uses "while true". Cheers, behdad From graydon at mozilla.com Wed Jul 4 11:53:57 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 04 Jul 2012 11:53:57 -0700 Subject: [rust-dev] Unicode vs hex escapes in Rust In-Reply-To: <4FF44B41.2020903@behdad.org> References: <4FF44B41.2020903@behdad.org> Message-ID: <4FF49145.3080500@mozilla.com> On 12-07-04 6:55 AM, Behdad Esfahbod wrote: > I started learning Rust today, and while it's building, I'm going through the > tutorial. I understand that it's quite outdated (points to 0.1 still), but > here's a couple things I spotted: > > Under 3.6.2 Other literals: > > * This: "A newline (Unicode character 32)" should say 10 instead of 32! Oops! Fixed. Sharp eyes. > * Here: "\xHH, \uHHHH, \UHHHHHHHH Unicode escapes", I strongly suggest that > \xHH be modified to allow inputting direct UTF-8 bytes. For ASCII it doesn't > make any different. For Latin1, it gives the impression that strings are > stored in Latin1, which is not the case. It would also make C / Python > escaped strings directly usable in Rust. Ie. '\xE2\x98\xBA' would be a single > character equivalent to '\u263a', not three Latin1 characters. Heh. This is interesting! I hadn't noticed yet but you're not _entirely_ giving the whole story. - \xNN means a utf8 byte: python2, python3 'bytes' literals, perl, go, C, C++, C++-0x u8 literals, and ruby - \xNN means a unicode codepoint: python3 'string' literals, javascript, scheme (at least racket follows spec; others get it randomly wrong by implementation), and current rust. - \xNN illegal, but the octal version means a unicode codepoint: java. So, my inclination is to follow your suggestion and actually go with the C and C++ style. But it's not exactly universal! Filed as bug #2800. It's quick, I might pick it off today. > * This: "loop is the preferred way of writing while true" doesn't match the > example that follows it, which still uses "while true". Already fixed in the tutorial online: http://dl.rust-lang.org/doc/tutorial.html#loops Thanks for the sharp feedback, keep it coming :) -Graydon From christian at siefkes.net Wed Jul 4 13:12:02 2012 From: christian at siefkes.net (Christian Siefkes) Date: Wed, 04 Jul 2012 22:12:02 +0200 Subject: [rust-dev] Unicode vs hex escapes in Rust In-Reply-To: <4FF49145.3080500@mozilla.com> (sfid-H20120704-205401-+023.18-1@spamfilter.osbf.lua) References: <4FF44B41.2020903@behdad.org> <4FF49145.3080500@mozilla.com> (sfid-H20120704-205401-+023.18-1@spamfilter.osbf.lua) Message-ID: <4FF4A392.3040706@siefkes.net> On 07/04/2012 08:53 PM, Graydon Hoare wrote: > On 12-07-04 6:55 AM, Behdad Esfahbod wrote: >> * Here: "\xHH, \uHHHH, \UHHHHHHHH Unicode escapes", I strongly suggest >> that >> \xHH be modified to allow inputting direct UTF-8 bytes. For ASCII it doesn't >> make any different. For Latin1, it gives the impression that strings are >> stored in Latin1, which is not the case. It would also make C / Python >> escaped strings directly usable in Rust. Ie. '\xE2\x98\xBA' would be a >> single >> character equivalent to '\u263a', not three Latin1 characters. > > Heh. This is interesting! I hadn't noticed yet but you're not _entirely_ > giving the whole story. > > - \xNN means a utf8 byte: python2, python3 'bytes' literals, > perl, go, C, C++, C++-0x u8 literals, and ruby > > - \xNN means a unicode codepoint: python3 'string' literals, > javascript, scheme (at least racket follows spec; others > get it randomly wrong by implementation), and current rust. > > - \xNN illegal, but the octal version means a unicode codepoint: > java. > > So, my inclination is to follow your suggestion and actually go with the C > and C++ style. But it's not exactly universal! personally, I find the current behavior of Rust less risky and more logical. If you can write '\u263a', why would you want to write the cumbersome '\xE2\x98\xBA' instead? Moreover, it's dangerous--just writing '\xE2\x98' or '\xE2' would result in a broken UTF-8 string. Perl and C couldn't avoid that since they are older then Unicode/UTF-8, but what would be the point of allowing it in Rust? No such danger exists in the current implementation, where every \xNN sequence refers to a Unicode codepoint < 256 (which also happens to be Latin1 character, but that's just because Unicode is a superset of Latin1). The current implementation is simple and consistent: all escapes refer to code points, none refers to bytes. If your code point is below 2^8, you can use any of "\xHH, \u00HH, \U000000HH", if it's below 2^16, you can use either of "\uHHHH, \U0000HHHH", otherwise you have to use "\UHHHHHHHH". Nice and sane. Admittedly, if string literals should be useful not only for entering UTF-8 sequences, but for entering arbitrary byte sequences ([u8]), than Behdad's proposal makes more sense. But for such purposes, wouldn't it be better to specify them directly as u8 vectors, e.g. [0xE2,0x98,0xBA] ? Best regards Christian -- |------- Dr. Christian Siefkes ------- christian at siefkes.net ------- | Homepage: http://www.siefkes.net/ | Blog: http://www.keimform.de/ | Peer Production Everywhere: http://peerconomy.org/wiki/ |---------------------------------- OpenPGP Key ID: 0x346452D8 -- If people are good only because they fear punishment, and hope for reward, then we are a sorry lot indeed. -- Albert Einstein -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From graydon at mozilla.com Thu Jul 5 11:18:36 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 05 Jul 2012 11:18:36 -0700 Subject: [rust-dev] Unicode vs hex escapes in Rust In-Reply-To: <4FF4A392.3040706@siefkes.net> References: <4FF44B41.2020903@behdad.org> <4FF49145.3080500@mozilla.com> (sfid-H20120704-205401-+023.18-1@spamfilter.osbf.lua) <4FF4A392.3040706@siefkes.net> Message-ID: <4FF5DA7C.8080507@mozilla.com> On 12-07-04 1:12 PM, Christian Siefkes wrote: > personally, I find the current behavior of Rust less risky and more logical. > If you can write '\u263a', why would you want to write the cumbersome > '\xE2\x98\xBA' instead? Moreover, it's dangerous--just writing '\xE2\x98' or > '\xE2' would result in a broken UTF-8 string. Perl and C couldn't avoid that > since they are older then Unicode/UTF-8, but what would be the point of > allowing it in Rust? Oh, a good point, but we wouldn't accept it during parsing. I don't want to get into the game of allowing strings in that aren't valid utf8. Use a [u8] for that. The string-specific reasons I can see for this are: - You want to denote some utf8 bytes and you want to avoid doing the work of figuring out which codepoint it decodes to. For example if you were writing a crude tool that emitted rust string literals by doing byte-at-a-time copies of text files. - You want to copy a string literal from C or C++. Neither of these are _great_ reasons, but they feel like enough to consider the change. I'm not actually sure how to interpret the "risk" Behdad suggested of users thinking strings are latin-1 (as in: why they would, and how to mitigate that). I mean, maybe if the user believed that \xNN was the only escape form, no longer escapes? I don't know, it's 2012 and I am sort of perplexed that anyone would think strings would be anything other than unicode-of-some-sort. Anyone looking at \xNN and wanting to write longer escapes would, I expect, google "rust unicode escapes", or try writing "\uNNNN" or something :) > No such danger exists in the current implementation, where every \xNN > sequence refers to a Unicode codepoint < 256 (which also happens to be > Latin1 character, but that's just because Unicode is a superset of Latin1). > The current implementation is simple and consistent: all escapes refer to > code points, none refers to bytes. If your code point is below 2^8, you can > use any of "\xHH, \u00HH, \U000000HH", if it's below 2^16, you can use > either of "\uHHHH, \U0000HHHH", otherwise you have to use "\UHHHHHHHH". Nice > and sane. I agree. This is the counterargument and the one I had in mind when picking the current scheme. Any other feelings / rationales for deciding one way or another? I'm not super clear on which way to go on this. > Admittedly, if string literals should be useful not only for entering UTF-8 > sequences, but for entering arbitrary byte sequences ([u8]), than Behdad's > proposal makes more sense. But for such purposes, wouldn't it be better to > specify them directly as u8 vectors, e.g. [0xE2,0x98,0xBA] ? Definitely. This is really only an interop question, in my mind, not an expressivity one. That is: how likely is our behavior to be an unwelcome surprise when someone's trying to do something specific with a string-literal? -Graydon From graydon at mozilla.com Thu Jul 5 16:23:23 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 05 Jul 2012 16:23:23 -0700 Subject: [rust-dev] New wiki pages: roadmap & detailed release notes Message-ID: <4FF621EB.2000109@mozilla.com> Hi, After consultation with the others in mozilla's core rust-developer group, I've published a roadmap for the next few releases, hopefully covering all the user-perturbing features or changes we're intending to land between now and the time we branch off a "stable" version of the language. If you see something missing, or find something horribly objectionable, now would be a good time to mention it. The wiki page containing the roadmap is here: https://github.com/mozilla/rust/wiki/Note-development-roadmap In parallel with this, Brian has been writing up more-detailed release notes for the nearly-complete 0.3 release, so we will hopefully not be quite as opaque about "what changed" from release-to-release, from here on in. Those notes are here: https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes We'll try to keep adding-to and updating these pages as time passes. -Grayadon From a.stavonin at gmail.com Thu Jul 5 17:35:49 2012 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Fri, 6 Jul 2012 09:35:49 +0900 Subject: [rust-dev] Usage of 'copy' keyword Message-ID: Can someone give a good enough explanation of 'copy' keyword usage? I can't find it neither in documentation nor tutorial. Regards, Alexander. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jesse9jones at gmail.com Thu Jul 5 18:00:23 2012 From: jesse9jones at gmail.com (Jesse Jones) Date: Thu, 5 Jul 2012 18:00:23 -0700 Subject: [rust-dev] Library organization In-Reply-To: <4FF5FF46.7020607@mozilla.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <4FF259E8.1090300@mozilla.com> <4FF5FF46.7020607@mozilla.com> Message-ID: <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> I didn't mean to do a private reply: my email client does that by default and I don't always remember to fix the reply address. As far as my problem goes I think it's something you guys have a handle on. But to be clear, what I want to do is write a library with a public API yet have the freedom to physically structure the library however I want. So I want clients to be able to pull in the public API with a single import even if the items were defined in different modules. And this did not work: clients of my library had to use multiple imports. Here is the actual library code where I re-export the public API: https://github.com/jesse99/rrdf/blob/master/src/rrdf.rs. The thought was that clients could then do `import rrdf::*;` but what they have to do instead is crap like: import rrdf::object::*; import rrdf::store::*; -- Jesse On Jul 5, 2012, at 1:55 PM, Graydon Hoare wrote: > On 12-07-03 5:45 PM, Jesse Jones wrote: >> I know about the distinction between use and import, and I do have a `use whiz bang`. And I can use my library. It's just more inconvenient than I'd like: I have to use 3+ imports to access the public API. > > Ok. Sorry to sound obtuse, but I'm not sure what it is you'd prefer to be writing (nor where these 3 imports are occurring in your client code). The initial report made it sound like something was literally not working; if this is an aesthetic-preference thing, that's a different sort of issue, but maybe we can make some headway on that too. > > Can you write down "what you have to write now" to make it work, and "what you'd prefer to be writing"? Even if it's sort of wish-list-y? > > (Replying to you privately as you replied in private; though this is perfectly fine to discuss on the list and I'm happy to do it there, if that was unintentional.) > > -Graydon > From banderson at mozilla.com Thu Jul 5 19:07:55 2012 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 05 Jul 2012 19:07:55 -0700 Subject: [rust-dev] Library organization In-Reply-To: <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <4FF259E8.1090300@mozilla.com> <4FF5FF46.7020607@mozilla.com> <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> Message-ID: <4FF6487B.6050900@mozilla.com> On 07/05/2012 06:00 PM, Jesse Jones wrote: > I didn't mean to do a private reply: my email client does that by default and I don't always remember to fix the reply address. > > As far as my problem goes I think it's something you guys have a handle on. But to be clear, what I want to do is write a library with a public API yet have the freedom to physically structure the library however I want. So I want clients to be able to pull in the public API with a single import even if the items were defined in different modules. And this did not work: clients of my library had to use multiple imports. > > Here is the actual library code where I re-export the public API: https://github.com/jesse99/rrdf/blob/master/src/rrdf.rs. The thought was that clients could then do `import rrdf::*;` but what they have to do instead is crap like: > import rrdf::object::*; > import rrdf::store::*; That's surprising. Perhaps it's a problem specifically relating to cross-crate reexporting. Regardless, this kind of thing is still somewhat of a black art, sometimes involving fighting the whims of the broken resolve pass, but it should be possible. In the future you will probably be able to reexport an entire module interface in a single line, something vaguely like: export foo::*; export bar::*; mod foo { ... } mod bar { ... } From banderson at mozilla.com Thu Jul 5 19:26:59 2012 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 05 Jul 2012 19:26:59 -0700 Subject: [rust-dev] Usage of 'copy' keyword In-Reply-To: References: Message-ID: <4FF64CF3.1050802@mozilla.com> On 07/05/2012 05:35 PM, Alexander Stavonin wrote: > Can someone give a good enough explanation of 'copy' keyword usage? I > can't find it neither in documentation nor tutorial. In Rust we are trying to make it so that it isn't possible to accidentally make expensive or logically incorrect copies of values, so there are some types that may not be copied implicitly. When you try to write code that requires a copy of one of these types then rustc makes you insert the word 'copy' to prove you know what you are doing. There are two reasons a type may not be implicitly copyable: 1) The type has mutable fields. Stateful types are usually considered to have 'identity' and you don't typically want to be making incidental copies of these because it is easy to end up thinking you are working with two variables representing the same thing, when you are actually working with two different things with different states. 2) Types that require allocation to create and are uniquely owned are expensive to copy because they must allocate new memory. This includes unique boxes and unique closures. Local boxes and closures do not have this property because copying them just shares a pointer to the same allocation. As an example, strings are unique types (currently - this will change) so they are not implicitly copyable. let x = "hello"; let y = x; // copying x let z = x; // moving x (last use) If you write this now rustc will issue a warning about `y = x` because in order to assign x to y it needs to make a copy. In the future this will just be an error. To make it go away you write `let y = copy x`. (The final line that assigns x to z illustrates the 'last use' rule, where rust will convert the last use of most variables into a move, eliminating the need for many explicit copies. That line is required for this example because otherwise `let y = x` gets converted to a move automatically. Last use behavior will probably go away in the future because it is too clever for humans to reason about). From jesse9jones at gmail.com Thu Jul 5 20:13:48 2012 From: jesse9jones at gmail.com (Jesse Jones) Date: Thu, 5 Jul 2012 20:13:48 -0700 Subject: [rust-dev] New wiki pages: roadmap & detailed release notes In-Reply-To: <4FF621EB.2000109@mozilla.com> References: <4FF621EB.2000109@mozilla.com> Message-ID: <9B9B9608-6337-49F5-961B-B886AF20F306@gmail.com> Can the difference between the exchange and local heaps be clarified in the release notes? -- Jesse On Jul 5, 2012, at 4:23 PM, Graydon Hoare wrote: > Hi, > > After consultation with the others in mozilla's core rust-developer group, I've published a roadmap for the next few releases, hopefully covering all the user-perturbing features or changes we're intending to land between now and the time we branch off a "stable" version of the language. If you see something missing, or find something horribly objectionable, now would be a good time to mention it. > > The wiki page containing the roadmap is here: > > https://github.com/mozilla/rust/wiki/Note-development-roadmap > > In parallel with this, Brian has been writing up more-detailed release notes for the nearly-complete 0.3 release, so we will hopefully not be quite as opaque about "what changed" from release-to-release, from here on in. > > Those notes are here: > > https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes > > We'll try to keep adding-to and updating these pages as time passes. > > -Grayadon > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From a.stavonin at gmail.com Thu Jul 5 21:01:15 2012 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Fri, 6 Jul 2012 13:01:15 +0900 Subject: [rust-dev] Usage of 'copy' keyword In-Reply-To: References: Message-ID: Sorry, my fault. I've found everything. 2012/7/6 Alexander Stavonin > Can someone give a good enough explanation of 'copy' keyword usage? I > can't find it neither in documentation nor tutorial. > > Regards, > Alexander. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Thu Jul 5 21:42:12 2012 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Fri, 6 Jul 2012 00:42:12 -0400 Subject: [rust-dev] New wiki pages: roadmap & detailed release notes In-Reply-To: <9B9B9608-6337-49F5-961B-B886AF20F306@gmail.com> References: <4FF621EB.2000109@mozilla.com> <9B9B9608-6337-49F5-961B-B886AF20F306@gmail.com> Message-ID: I think that eholk's work on reimplementing ports and chans as Singularity-style channel contracts could use a mention, as well as its current status (16x speedup, or something?) On Thu, Jul 5, 2012 at 11:13 PM, Jesse Jones wrote: > Can the difference between the exchange and local heaps be clarified in > the release notes? > > -- Jesse > > On Jul 5, 2012, at 4:23 PM, Graydon Hoare wrote: > > > Hi, > > > > After consultation with the others in mozilla's core rust-developer > group, I've published a roadmap for the next few releases, hopefully > covering all the user-perturbing features or changes we're intending to > land between now and the time we branch off a "stable" version of the > language. If you see something missing, or find something horribly > objectionable, now would be a good time to mention it. > > > > The wiki page containing the roadmap is here: > > > > https://github.com/mozilla/rust/wiki/Note-development-roadmap > > > > In parallel with this, Brian has been writing up more-detailed release > notes for the nearly-complete 0.3 release, so we will hopefully not be > quite as opaque about "what changed" from release-to-release, from here on > in. > > > > Those notes are here: > > > > https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes > > > > We'll try to keep adding-to and updating these pages as time passes. > > > > -Grayadon > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From zackcorr95 at gmail.com Thu Jul 5 22:31:33 2012 From: zackcorr95 at gmail.com (Zack Corr) Date: Fri, 6 Jul 2012 15:31:33 +1000 Subject: [rust-dev] Library organization In-Reply-To: <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <4FF259E8.1090300@mozilla.com> <4FF5FF46.7020607@mozilla.com> <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> Message-ID: On Fri, Jul 6, 2012 at 11:00 AM, Jesse Jones wrote: > I didn't mean to do a private reply: my email client does that by default > and I don't always remember to fix the reply address. > > As far as my problem goes I think it's something you guys have a handle > on. But to be clear, what I want to do is write a library with a public API > yet have the freedom to physically structure the library however I want. So > I want clients to be able to pull in the public API with a single import > even if the items were defined in different modules. And this did not work: > clients of my library had to use multiple imports. > > Here is the actual library code where I re-export the public API: > https://github.com/jesse99/rrdf/blob/master/src/rrdf.rs. The thought was > that clients could then do `import rrdf::*;` but what they have to do > instead is crap like: > import rrdf::object::*; > import rrdf::store::*; > Try something like `import some_object = rrdf::object::some_object;` and then `export some_object`. That sort of thing works for me. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cnjamesdeng at gmail.com Thu Jul 5 22:41:59 2012 From: cnjamesdeng at gmail.com (James Deng) Date: Fri, 6 Jul 2012 15:41:59 +1000 Subject: [rust-dev] Rust Syntax Suggestions Message-ID: Hi all, I am a language enthusiast. I found that Rust is an elegant combination of procedure, functional and concurrent paradigm, thus can be a promising practical system programming language. Among all that fantastic features, my favorite one is the ad-hoc polymorphism, aka type class from Haskell. I have some suggestions about Rust's syntax. - Replace "let" with "val", and "let mut" with "var", like Scala does. - Replace module name separator "::" with "/" as Scheme, which is shorter and and cleaner I think. Regarding to grammar, I think current type kind constraint (a: copy) is not flexible, I think the type constraint (Ord a, F a b => defs...) is more powerful and flexible. In addition, it seems that current Rust relies on crates(.rs) to form module hierarchy. I don't think it's intuitive. When programmers see a module path, they want to have a sense where the module resides. I think the module hierarchy system in Haskell is a good compromise between power and simplicity. -- James Deng Intelligent Systems Laboratory School of Computing and Mathematics University of Western Sydney http://cnjdeng.appspot.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Thu Jul 5 22:49:49 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Thu, 5 Jul 2012 22:49:49 -0700 Subject: [rust-dev] Rust Syntax Suggestions In-Reply-To: References: Message-ID: On Thu, Jul 5, 2012 at 10:41 PM, James Deng wrote: > Hi all, > > I am a language enthusiast. I found that Rust is an elegant combination of > procedure, functional and concurrent paradigm, thus can be a promising > practical system programming language. Among all that fantastic features, my > favorite one is the ad-hoc polymorphism, aka type class from Haskell. > It's great that you like it! As I'm sure you realize, Rust has type classes (expressed with the keywords "iface" for class declarations and "impl" for class instances, though the syntax is still subject to change) that are based on Haskell's type classes. > I have some suggestions about Rust's syntax. > > Replace "let" with "val", and "let mut" with "var", like Scala does. We have discussed this, and you should be able to find the relevant issues by searching the issue tracker. > Replace module name separator "::" with "/" as Scheme, which is shorter and > and cleaner I think. I don't think anyone has suggested this before. However, I think it would cause a parsing ambiguity, since '/' is also the division operator. > > Regarding to grammar, I think current type kind constraint (a: copy) is not > flexible, I think the type constraint (Ord a, F a b => defs...) is more > powerful and flexible. Do you mean that we don't support multi-parameter type classes? If so, that's true, but it's somewhat deliberate on our part. In Haskell, multi-parameter type classes have spawned two different language extensions (type functions and functional dependencies) that, while differing mainly syntactically, have caused a bit of acrimony about which is better. We decided not to shave that yak just now. However, this could change in the future if there are compelling reasons for MPTCs in the first round of applications implemented in Rust. > > In addition, it seems that current Rust relies on crates(.rs) to form module > hierarchy. I don't think it's intuitive. When programmers see a module path, > they want to have a sense where the module resides. I think the module > hierarchy system in Haskell is a good compromise between power and > simplicity. > I'm not sure I understand -- Rust has nested modules, which are actually more expressive than Haskell's module system. An example might be good. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From jesse9jones at gmail.com Fri Jul 6 09:57:45 2012 From: jesse9jones at gmail.com (Jesse Jones) Date: Fri, 6 Jul 2012 09:57:45 -0700 Subject: [rust-dev] Library organization In-Reply-To: References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <4FF259E8.1090300@mozilla.com> <4FF5FF46.7020607@mozilla.com> <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> Message-ID: <46F29296-54E2-4EEB-AA70-9BA4349A8016@gmail.com> On Jul 5, 2012, at 10:31 PM, Zack Corr wrote: > On Fri, Jul 6, 2012 at 11:00 AM, Jesse Jones wrote: > I didn't mean to do a private reply: my email client does that by default and I don't always remember to fix the reply address. > > As far as my problem goes I think it's something you guys have a handle on. But to be clear, what I want to do is write a library with a public API yet have the freedom to physically structure the library however I want. So I want clients to be able to pull in the public API with a single import even if the items were defined in different modules. And this did not work: clients of my library had to use multiple imports. > > Here is the actual library code where I re-export the public API: https://github.com/jesse99/rrdf/blob/master/src/rrdf.rs. The thought was that clients could then do `import rrdf::*;` but what they have to do instead is crap like: > import rrdf::object::*; > import rrdf::store::*; > > Try something like `import some_object = rrdf::object::some_object;` and then `export some_object`. That sort of thing works for me. Tried this, but clients couldn't get at the constructors for the object enum. I did: #[doc = "API for the rrdf library."]; import to_str::to_str; import core::dvec::*; import std::map::hashmap; import std::time::tm; // This is a convenience for internal modules. import object::*; import query::*; import solution::*; import store::*; // These are the exports for clients of rrdf. // Clients should not use items from other modules. import object = object::object; export object; import subject = store::subject; export subject; import predicate = store::predicate; export predicate; import triple = store::triple; export triple; import namespace = store::namespace; export namespace; import entry = store::entry; export entry; import extension_fn = store::extension_fn; export extension_fn; import store = store::store; export store; import create_store = store::create_store; export create_store; import make_triple_blank = store::make_triple_blank; export make_triple_blank; import make_triple_str = store::make_triple_str; export make_triple_str; import make_triple_uri = store::make_triple_uri; export make_triple_uri; import get_blank_name = store::get_blank_name; export get_blank_name; import selector = sparql::selector; export selector; import compile = sparql::compile; export compile; import solution_row = solution::solution_row; export solution_row; import solution = solution::solution; export solution; And then a client of the library did: import rrdf::*; vec::push(entries, ("snmp:" + name, string_value(*s, ""))); which gave me: "error: unresolved name: string_value". -- Jesse From graydon at mozilla.com Fri Jul 6 10:09:31 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 06 Jul 2012 10:09:31 -0700 Subject: [rust-dev] Unicode vs hex escapes in Rust In-Reply-To: <4FF70D2F.8000809@behdad.org> References: <4FF44B41.2020903@behdad.org> <4FF49145.3080500@mozilla.com> <4FF70D2F.8000809@behdad.org> Message-ID: <4FF71BCB.20706@mozilla.com> On 12-07-06 9:07 AM, Behdad Esfahbod wrote: >> So, my inclination is to follow your suggestion and actually go with the C and >> C++ style. But it's not exactly universal! > > Thanks for the survey! Indeed. Programming languages is not my strong suit. There was some further followup here, as well as in the bug: https://github.com/mozilla/rust/issues/2800 and I wonder if you could take a moment to comment further (indeed, if anyone wants to simply state their pre-existing bias here, it's not a bad topic to just "take a survey" on): Given the following: - our strings _are_ forced to be well-formed utf8 -- that is, we won't in any case allow you to write a non-utf8 byte in the middle of a string. - Sub-0x7f and super-0x1000 codepoints are unaffected by this choice, no matter what we do, as their escapes are unambiguous. It seems to me we're really only talking about the likelihood of a user wanting to denote, directly, the 0x80 .. 0xff utf8 code units. And comparing that with the likelihood of a user wanting to denote a codepoint in that codepoint range, _as a codepoint_, and have it expand to the appropriate utf8 code units. I remain torn on it. Most responses I've got so far err towards "do what C does", but there's reason to suspect that is a bad move also, since C strings don't enforce utf8-ness. Further thoughts? Which cases do you find yourself writing utf8 code units in? -Graydon From christian at siefkes.net Fri Jul 6 10:32:26 2012 From: christian at siefkes.net (Christian Siefkes) Date: Fri, 06 Jul 2012 19:32:26 +0200 Subject: [rust-dev] Unicode vs hex escapes in Rust In-Reply-To: <4FF5DA7C.8080507@mozilla.com> (sfid-H20120705-201840-+028.98-1@spamfilter.osbf.lua) References: <4FF44B41.2020903@behdad.org> <4FF49145.3080500@mozilla.com> <4FF4A392.3040706@siefkes.net> <4FF5DA7C.8080507@mozilla.com> (sfid-H20120705-201840-+028.98-1@spamfilter.osbf.lua) Message-ID: <4FF7212A.50603@siefkes.net> On 07/05/2012 08:18 PM, Graydon Hoare wrote: > The string-specific reasons I can see for this are: > > - You want to denote some utf8 bytes and you want to avoid doing > the work of figuring out which codepoint it decodes to. For > example if you were writing a crude tool that emitted rust string > literals by doing byte-at-a-time copies of text files. Since Rust source files are UTF-8, a crude tool could simple copy these bytes into the output as is, without having to encode them at all. As I understand it. > - You want to copy a string literal from C or C++. That wouldn't generally work anyway, since there are other C-style escape sequences that Rust doesn't support, such as \a\f\v for alert/form feed/vertical tab. In fact, reading through the tutorial I was pleasantly surprised by the minimalism and clarity of Rust's escape sequences--sufficiently similar to C but without the outdated and illogical stuff. So I don't really see those reasons. Otherwise I have already stated by preferences. Best regards Christian -- |------- Dr. Christian Siefkes ------- christian at siefkes.net ------- | Homepage: http://www.siefkes.net/ | Blog: http://www.keimform.de/ | Peer Production Everywhere: http://peerconomy.org/wiki/ |---------------------------------- OpenPGP Key ID: 0x346452D8 -- .-. /v\ L I N U X // \\ >Phear the Penguin< /( )\ ^^-^^ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From lindsey at rockstargirl.org Fri Jul 6 15:04:52 2012 From: lindsey at rockstargirl.org (Lindsey Kuper) Date: Fri, 6 Jul 2012 15:04:52 -0700 Subject: [rust-dev] Traits proposal Message-ID: Two of the changes mentioned in the development roadmap that Graydon sent out earlier this week were "Extend interfaces to full traits" and "Enforce implementation coherence". Those are addressed by this proposal for unifying traits and interfaces: https://github.com/mozilla/rust/wiki/Proposal-for-unifying-traits-and-interfaces This work is already starting to get underway, as evidenced by occasional references to "traitfaces" that you might have seen go by on IRC and Twitter (e.g., https://twitter.com/littlecalculist/statuses/217867708212051969) (don't worry, we're not actually going to call them that). But I haven't made any announcement of the proposal here on rust-dev yet, so here it is. Feedback welcome! Lindsey From behdad at behdad.org Fri Jul 6 09:07:11 2012 From: behdad at behdad.org (Behdad Esfahbod) Date: Fri, 06 Jul 2012 12:07:11 -0400 Subject: [rust-dev] Unicode vs hex escapes in Rust In-Reply-To: <4FF49145.3080500@mozilla.com> References: <4FF44B41.2020903@behdad.org> <4FF49145.3080500@mozilla.com> Message-ID: <4FF70D2F.8000809@behdad.org> On 07/04/2012 02:53 PM, Graydon Hoare wrote: > On 12-07-04 6:55 AM, Behdad Esfahbod wrote: > >> * Here: "\xHH, \uHHHH, \UHHHHHHHH Unicode escapes", I strongly suggest that >> \xHH be modified to allow inputting direct UTF-8 bytes. For ASCII it doesn't >> make any different. For Latin1, it gives the impression that strings are >> stored in Latin1, which is not the case. It would also make C / Python >> escaped strings directly usable in Rust. Ie. '\xE2\x98\xBA' would be a single >> character equivalent to '\u263a', not three Latin1 characters. > > Heh. This is interesting! I hadn't noticed yet but you're not _entirely_ > giving the whole story. > > - \xNN means a utf8 byte: python2, python3 'bytes' literals, > perl, go, C, C++, C++-0x u8 literals, and ruby > > - \xNN means a unicode codepoint: python3 'string' literals, > javascript, scheme (at least racket follows spec; others > get it randomly wrong by implementation), and current rust. > > - \xNN illegal, but the octal version means a unicode codepoint: > java. > > So, my inclination is to follow your suggestion and actually go with the C and > C++ style. But it's not exactly universal! Thanks for the survey! Indeed. Programming languages is not my strong suit. Cheers, behdad From graydon at mozilla.com Fri Jul 6 16:15:50 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 06 Jul 2012 16:15:50 -0700 Subject: [rust-dev] Library organization In-Reply-To: <46F29296-54E2-4EEB-AA70-9BA4349A8016@gmail.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <4FF259E8.1090300@mozilla.com> <4FF5FF46.7020607@mozilla.com> <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> <46F29296-54E2-4EEB-AA70-9BA4349A8016@gmail.com> Message-ID: <4FF771A6.9000101@mozilla.com> On 12-07-06 9:57 AM, Jesse Jones wrote: > Tried this, but clients couldn't get at the constructors for the object enum. At the moment (aside from a lot of bugs in resolve that will get hammered out, many quite soon in the new resolve code) there's also the fact that constructors are visibility-controlled independent of enum type names. This might change, but for now I think you actually need to export the _whole set_ of constructors, one at a time. (Yes, very very much not optimal and something we'll eliminate; just trying to get your code to the place where the client API is what you want) -Graydon From jesse9jones at gmail.com Fri Jul 6 18:40:09 2012 From: jesse9jones at gmail.com (Jesse Jones) Date: Fri, 6 Jul 2012 18:40:09 -0700 Subject: [rust-dev] Library organization In-Reply-To: <4FF771A6.9000101@mozilla.com> References: <867B3B6E-4473-4839-9B82-432A2C19788F@gmail.com> <4FF1EFAF.4040307@mozilla.com> <4FF1F2EC.6020206@mozilla.com> <4FF259E8.1090300@mozilla.com> <4FF5FF46.7020607@mozilla.com> <57610BB1-7B1B-4279-917A-8D8C6DB8BB16@gmail.com> <46F29296-54E2-4EEB-AA70-9BA4349A8016@gmail.com> <4FF771A6.9000101@mozilla.com> Message-ID: Ugly as sin, but it does do what I want. Thanks. -- Jesse On Jul 6, 2012, at 4:15 PM, Graydon Hoare wrote: > On 12-07-06 9:57 AM, Jesse Jones wrote: > >> Tried this, but clients couldn't get at the constructors for the object enum. > > At the moment (aside from a lot of bugs in resolve that will get hammered out, many quite soon in the new resolve code) there's also the fact that constructors are visibility-controlled independent of enum type names. This might change, but for now I think you actually need to export the _whole set_ of constructors, one at a time. > > (Yes, very very much not optimal and something we'll eliminate; just trying to get your code to the place where the client API is what you want) > > -Graydon From sebastian.sylvan at gmail.com Fri Jul 6 18:47:54 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Fri, 6 Jul 2012 18:47:54 -0700 Subject: [rust-dev] Traits proposal In-Reply-To: References: Message-ID: On Fri, Jul 6, 2012 at 3:04 PM, Lindsey Kuper wrote: > Two of the changes mentioned in the development roadmap that Graydon > sent out earlier this week were "Extend interfaces to full traits" and > "Enforce implementation coherence". Those are addressed by this > proposal for unifying traits and interfaces: > > https://github.com/mozilla/rust/wiki/Proposal-for-unifying-traits-and-interfaces That last hash table example makes me uneasy because the proposed solution doesn't really solve the problem very nicely at all. If I have a 'hash' trait in a module Hash, and then two different hash function providers FastHash (TM) and QuickHash (TM) want to provide hash functions for use with a hash table, they can not actually be used with any standard types, (without requiring first wrapping every key inside some per-hash-function wrapper type. This is ugly and kinda defeats the point of overloading - if we want to pick the implementation explicitly at each use site, why not just pass in the function dictionary explicitly instead of wrapping the arguments in a special "marker" type whose sole purpose is to make the compiler pick the right instance? This seems.. quite painful. I would be extremely unlikely to use a 'hash' trait in a hash table implementation for this reason. I'd store the hash function as a closure in the table itself, and set it up at construction (this way you can pass in any hash function provider at construction). It almost seems like the guidance for library writers would be to avoid traits because they reduce the ability for users to compose different behaviors (or at the very least each library would provide two versions of everything - one which uses a trait, and one which takes the method dictionary at construction time and stores it with the data structure). Not sure what the right solution is. I think Haskell's system is too inflexible, but this is even less flexible. Maybe there are better options in the literature somewhere? Maybe parameterizing modules is the answer - the Hash module can define instances for pre-existing types using functions that are passed in by the importer of the module (the same module imported twice but parameterized differently would be treated as two independent modules)? -- Sebastian Sylvan From pwalton at mozilla.com Fri Jul 6 19:02:30 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 06 Jul 2012 19:02:30 -0700 Subject: [rust-dev] Traits proposal In-Reply-To: References: Message-ID: <4FF798B6.2070701@mozilla.com> On 7/6/12 6:47 PM, Sebastian Sylvan wrote: > This seems.. quite painful. I would be extremely unlikely to use a > 'hash' trait in a hash table implementation for this reason. I'd store > the hash function as a closure in the table itself, and set it up at > construction (this way you can pass in any hash function provider at > construction). It almost seems like the guidance for library writers > would be to avoid traits because they reduce the ability for users to > compose different behaviors (or at the very least each library would > provide two versions of everything - one which uses a trait, and one > which takes the method dictionary at construction time and stores it > with the data structure). Yes, it's a drawback. I think Haskell's "sort" and "sortBy" pairs of functions are an okay solution (which is basically what you're proposing), although not optimal. Most of the time you use the trait version of the hash table; in the case in which you need a non-default hash function, you use the virtually-dispatched version. Keep in mind that named impls (as implemented now, and as proposed for Haskell) don't really solve the hash table problem, though; if I instantiate a hash table and call insert() with the trait instantiated for str with FastHash, then I might pass that hash table to someone else who calls get() with the trait instantiated for str at QuickHash. Niko has proposed a general solution, which is basically a refined version of the newtype proposal: allow types to be refined with trait implementations. So a hash table might have type HashMap. This is closely related to just wrapping str in a newtype, with better ergonomics. I think the system as proposed could be extended to accommodate this if it proves necessary; you would essentially have named implementations (or newtypes, if you prefer to look at it that way) that you could wrap values in and get out a wrapped version with different trait implementations. These wrapped types could be treated as true subtypes, so that coercion back and forth is free. But it seems to me that it's worth trying the proposed system and seeing how expressive it turns out to be in practice; we can always layer the more sophisticated system on top in the future without breaking anything. The ergonomic benefits of not having to import implementations in the common case makes coherence worth it, I think. Patrick From garethdanielsmith at gmail.com Sat Jul 7 03:29:06 2012 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Sat, 07 Jul 2012 11:29:06 +0100 Subject: [rust-dev] Dealing with ` illegal borrow unless pure` errors In-Reply-To: References: <4FE629CA.9030807@gmail.com> Message-ID: <4FF80F72.7020503@gmail.com> On 24/06/12 19:51, Niko Matsakis wrote: > > Are there other ways of fixing the issue? > > > There is one other way. You can restructure the caller. The most > ambitious would be to change the field from mutable to immutable, but > often that does not work. In that case, you can also update the type > of the record from @{mut f: option} to @{mut f: @option}. You > would then call the function with `*r.f` (where `r` is the record). > This is permitted because, while the `f` field is mutable, the field > does not store the option but rather a pointer to the option. The > *option itself* is stored in immutable memory (that is, the @ box). This means putting wrapping every mutable field *of a type not passed by value* inside a shared box (because every mutable field might need passing to a function). This means that updating the field requires memory allocation, and reading the field requires following a pointer indirection. This seems disproportionately expensive. If these concerns are real (I think they are but I don't that much about rust) then surely there is a better solution? Gareth -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Sat Jul 7 19:35:47 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Sat, 07 Jul 2012 19:35:47 -0700 Subject: [rust-dev] Dealing with ` illegal borrow unless pure` errors In-Reply-To: <4FEA26F9.4090806@gmail.com> References: <4FE629CA.9030807@gmail.com> <4FEA26F9.4090806@gmail.com> Message-ID: <4FF8F203.2030000@alum.mit.edu> Hi Gareth, Your recent e-mail reminded me that I never responded to this one. Sorry about that, I was on vacation. >> There is one other way. You can restructure the caller. The most >> ambitious would be to change the field from mutable to immutable, but >> often that does not work. In that case, you can also update the type >> of the record from @{mut f: option} to @{mut f: @option}. You >> would then call the function with `*r.f` (where `r` is the record). >> This is permitted because, while the `f` field is mutable, the field >> does not store the option but rather a pointer to the option. The >> *option itself* is stored in immutable memory (that is, the @ box). > > This makes sense. However I feel it encourages me to wrap all mutable > record/class fields in @ boxes, which to me seems awkward to > read/write and probably inefficient too. I didn't mean to imply that this was a superior solution, merely that it was another solution. It is not always suitable but, in some cases, the @ boxes may already have been allocated, or the cost of allocation may be insignificant. In general I think the most widely applicable answer is that if you want to put an enum into a mutable field, just make sure that it is cheaply copyable. So don't have `option` but rather `option<@my_big_record>`. This is probably a good idea anyway, since you don't want to be copying big things around all the time. >> Is there potential for the copy to be cheap enough to use >> `option` (without the pointer)? I feel that by-copy is simpler to >> reason about and also easier to read/write. I don't know what's best. We may want to have two functions/methods, one which expects a pointer and one which doesn't. The copy of an option is not inherently expensive: its cost will naturally depend on T. Certainly we want a *option variant for those cases where T is something prohibitively expensive to copy, such as a unique pointer, or where it has identity. We may want both versions for other reasons. In the mode world, it is common to run up against mode mismatches: the function is declared with mode ++, for example, but is being used in a context where && is required. The equivalent in a region world would be a function that expects T being used in a context where *T is expected. It's also possible we could write a generic conversion wrapper to deal with this situation, something like: fn to_val(f: fn(T) -> U, x: *T) -> U { f(*x) } Niko From lists.rust at dbp.mm.st Sun Jul 8 17:16:11 2012 From: lists.rust at dbp.mm.st (Daniel Patterson) Date: Sun, 8 Jul 2012 20:16:11 -0400 Subject: [rust-dev] Using hashmaps with str values without warnings? Message-ID: <8B12CAE1-CAAE-484B-98E5-82826CB3FDD5@dbp.mm.st> I have a data type that is: hashmap Right now, when I create it (with map::str_hash()), and do anything with it (.insert, .each, .size), it gives me the warning "instantiating copy type parameter with a not implicitly copyable type". Is there any way to tell it that it is okay to copy the strings it contains? And is this going to be a bad idea; if so, what is the alternative? Is there any way that when I insert values I can give ownership to the hashmap? Thanks, Daniel From erick.tryzelaar at gmail.com Mon Jul 9 09:42:47 2012 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Mon, 9 Jul 2012 09:42:47 -0700 Subject: [rust-dev] Using hashmaps with str values without warnings? In-Reply-To: <8B12CAE1-CAAE-484B-98E5-82826CB3FDD5@dbp.mm.st> References: <8B12CAE1-CAAE-484B-98E5-82826CB3FDD5@dbp.mm.st> Message-ID: Good morning, On Sun, Jul 8, 2012 at 5:16 PM, Daniel Patterson wrote: > I have a data type that is: > > hashmap Hashmaps require the value to be copyable, so try boxing the value, as in: hashmap. From garethdanielsmith at gmail.com Mon Jul 9 11:00:05 2012 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Mon, 09 Jul 2012 19:00:05 +0100 Subject: [rust-dev] Dealing with ` illegal borrow unless pure` errors In-Reply-To: <4FF8F203.2030000@alum.mit.edu> References: <4FE629CA.9030807@gmail.com> <4FEA26F9.4090806@gmail.com> <4FF8F203.2030000@alum.mit.edu> Message-ID: <4FFB1C25.3070304@gmail.com> On 08/07/12 03:35, Niko Matsakis wrote: > Your recent e-mail reminded me that I never responded to this one. > Sorry about that, I was on vacation. No problem. You deserved a vacation with all the work you are doing on rust. > In general I think the most widely applicable answer is that if you > want to put an enum into a mutable field, just make sure that it is > cheaply copyable. So don't have `option` but rather > `option<@my_big_record>`. This is probably a good idea anyway, since > you don't want to be copying big things around all the time. I think that makes sense. >>> Is there potential for the copy to be cheap enough to use >>> `option` (without the pointer)? I feel that by-copy is simpler to >>> reason about and also easier to read/write. > > I don't know what's best. We may want to have two functions/methods, > one which expects a pointer and one which doesn't. The copy of an > option is not inherently expensive: its cost will naturally depend > on T. Certainly we want a *option variant for those cases where T > is something prohibitively expensive to copy, such as a unique > pointer, or where it has identity. > > We may want both versions for other reasons. In the mode world, it is > common to run up against mode mismatches: the function is declared > with mode ++, for example, but is being used in a context where && is > required. The equivalent in a region world would be a function that > expects T being used in a context where *T is expected. It's also > possible we could write a generic conversion wrapper to deal with this > situation, something like: > > fn to_val(f: fn(T) -> U, x: *T) -> U { f(*x) } I can't claim to know what is best either. Hopefully it will become more obvious over time, especially if/when argument modes are removed (please!). Thanks Gareth From bruant.d at gmail.com Mon Jul 9 14:44:33 2012 From: bruant.d at gmail.com (David Bruant) Date: Mon, 09 Jul 2012 23:44:33 +0200 Subject: [rust-dev] Traits proposal In-Reply-To: References: Message-ID: <4FFB50C1.2020703@gmail.com> A paper [1] describes 2 issues with traits (and a suggests a solution, but that's not what's bringing me here) : statelessness and lack of visibility control. In the proposal, the statelessness is taken care of in an interestingly elegant manner: implementing the traitface ("intraitface"? nah, that's pretty horrible) for a given type. The instance of some type contains or rather "is" the state. As far as I can tell, the visibility control issue is not taken care of. What it means is that when a trait is composed of other traits, the instances of these traits have every single method of all the traits. This doesn't help in defining well-encapsulated objects since it may leaks implementation details (of "low-level" trait functions) About conflict resolution "we might want to do that eventually, but we can punt for now and just do what Rust already does if a type implements multiple interfaces that define a method with the same name -- that is, raise a compile-time "multiple applicable methods in scope" error." Consider the following case: // Some library(ies) provide t1 and t2 trait t1{ fn foo() -> () } trait t2{ fn bar() -> () } // Your own code defines t3 trait t3 < t1, t2{ } One day, the t1 author adds a 'bar' method. When you want to update your dependency, if the language doesn't provide support for conflit resolution, then your program stops compiling and any solution you can come up with involves messing around with third-party code. This is unrealistic. I shouldn't have to mess with third-party code to fix problems that arise in my own code. It has to be noted that in absence of visibility control mechanisms, conflicts are even more likely, so the problem I've just described has greater likelihood to occur. I hope this example was convincing enough to prove that conflic resolution should be part of the first trait iteration. David Le 07/07/2012 00:04, Lindsey Kuper a ?crit : > Two of the changes mentioned in the development roadmap that Graydon > sent out earlier this week were "Extend interfaces to full traits" and > "Enforce implementation coherence". Those are addressed by this > proposal for unifying traits and interfaces: > > https://github.com/mozilla/rust/wiki/Proposal-for-unifying-traits-and-interfaces > > This work is already starting to get underway, as evidenced by > occasional references to "traitfaces" that you might have seen go by > on IRC and Twitter (e.g., > https://twitter.com/littlecalculist/statuses/217867708212051969) > (don't worry, we're not actually going to call them that). But I > haven't made any announcement of the proposal here on rust-dev yet, so > here it is. Feedback welcome! [1] http://soft.vub.ac.be/Publications/2009/vub-prog-tr-09-04.pdf From pwalton at mozilla.com Mon Jul 9 16:33:41 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 09 Jul 2012 16:33:41 -0700 Subject: [rust-dev] Traits proposal In-Reply-To: <4FFB50C1.2020703@gmail.com> References: <4FFB50C1.2020703@gmail.com> Message-ID: <4FFB6A55.1040900@mozilla.com> On 7/9/12 2:44 PM, David Bruant wrote: > As far as I can tell, the visibility control issue is not taken care of. > What it means is that when a trait is composed of other traits, the > instances of these traits have every single method of all the traits. > This doesn't help in defining well-encapsulated objects since it may > leaks implementation details (of "low-level" trait functions) I have to admit to not having considered this in the design. However, I think it's probably solvable the way we solve it in max/min classes: the individual methods on a trait can be marked module-private. Patrick From bruant.d at gmail.com Tue Jul 10 04:15:59 2012 From: bruant.d at gmail.com (David Bruant) Date: Tue, 10 Jul 2012 13:15:59 +0200 Subject: [rust-dev] Traits proposal In-Reply-To: <4FFB6A55.1040900@mozilla.com> References: <4FFB50C1.2020703@gmail.com> <4FFB6A55.1040900@mozilla.com> Message-ID: <4FFC0EEF.6050309@gmail.com> Le 10/07/2012 01:33, Patrick Walton a ?crit : > On 7/9/12 2:44 PM, David Bruant wrote: >> As far as I can tell, the visibility control issue is not taken care of. >> What it means is that when a trait is composed of other traits, the >> instances of these traits have every single method of all the traits. >> This doesn't help in defining well-encapsulated objects since it may >> leaks implementation details (of "low-level" trait functions) > > I have to admit to not having considered this in the design. However, > I think it's probably solvable the way we solve it in max/min classes: > the individual methods on a trait can be marked module-private. I'm not sure it works. Consider the following (I'm not very familiar with Rust syntax, so I apologize in advance for mistakes I would make): trait Dot{ fn drawDot(x:int, y:int) -> () } trait Shapes < Dot{ fn drawLine(/*...*/){ // use drawDot } fn drawCircle(/*...*/){ // use drawDot } // ... } trait Character < Shapes { fn drawCharacter(/*...*/){ // use basic shapes (and maybe dots) to draw a character } } I wish that instanciating a character (for a given type) shows the drawCharacter method, but not any of the low-level drawing methods. I don't think it's possible to make Dot and Shape methods module private since Character could be in a different module (maybe I'm wrong, in which case, I'm interested in seeing an example). Character needs these methods to be implemented, but doesn't wish these methods to be provided in its interface. Why having both classes and traits? Both are mechanisms to enable code reuse. I guess I should restate my question: In which case would I use traits over classes or classes over traits? David From sebastian.sylvan at gmail.com Tue Jul 10 08:45:36 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Tue, 10 Jul 2012 08:45:36 -0700 Subject: [rust-dev] Traits proposal In-Reply-To: <4FFC0EEF.6050309@gmail.com> References: <4FFB50C1.2020703@gmail.com> <4FFB6A55.1040900@mozilla.com> <4FFC0EEF.6050309@gmail.com> Message-ID: On Tue, Jul 10, 2012 at 4:15 AM, David Bruant wrote: > > Why having both classes and traits? Both are mechanisms to enable code > reuse. > I guess I should restate my question: In which case would I use traits over > classes or classes over traits? As I understand it traits are the code-reuse parts, and classes are little more than named records that actually bring a bunch of traits together into an actual type. I.e. you don't inherit from other classes. Traits are used to specify reusable bags of methods, and classes are used to actually provide data types on which to run those methods. -- Sebastian Sylvan From graydon at mozilla.com Tue Jul 10 08:52:57 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 10 Jul 2012 08:52:57 -0700 Subject: [rust-dev] Traits proposal In-Reply-To: <4FFC0EEF.6050309@gmail.com> References: <4FFB50C1.2020703@gmail.com> <4FFB6A55.1040900@mozilla.com> <4FFC0EEF.6050309@gmail.com> Message-ID: <4FFC4FD9.5010800@mozilla.com> On 7/10/2012 4:15 AM, David Bruant wrote: > I wish that instanciating a character (for a given type) shows the > drawCharacter method, but not any of the low-level drawing methods. I > don't think it's possible to make Dot and Shape methods module private > since Character could be in a different module (maybe I'm wrong, in > which case, I'm interested in seeing an example). Character needs these > methods to be implemented, but doesn't wish these methods to be provided > in its interface. If it is truly an extension of the shape trait, then it necessarily re-exports them. That's what subtyping means on interfaces: you support the full interface of the supertype. If you only want to reuse certain implementation routines, don't make them part of the interface. Make them helper functions defined in the module exporting the shape type. They'll be no less privileged than members of the shape trait would be; those can only make self-calls on the shape interface anyways. Various subtypes may use (or not-use) those helpers in implementing themselves, as they see fit. It feels you're looking for a reason why visibility has to be controlled on a type-internal basis ("protected" vs. "private") rather than a module-basis? I don't (personally) know of any; I think the former is just a different way of denoting the latter. It's still just scoped static access-control. And it too has weird boundary cases that don't quite work right (friend and such). > Why having both classes and traits? Both are mechanisms to enable code > reuse. > I guess I should restate my question: In which case would I use traits > over classes or classes over traits? Traits can be recombined arbitrarily. Classes can at most just be extended linearly, and at the moment we don't even support that (and may never; it's not clear we'll need it). -Graydon From bruant.d at gmail.com Tue Jul 10 09:04:43 2012 From: bruant.d at gmail.com (David Bruant) Date: Tue, 10 Jul 2012 18:04:43 +0200 Subject: [rust-dev] Traits proposal In-Reply-To: References: <4FFB50C1.2020703@gmail.com> <4FFB6A55.1040900@mozilla.com> <4FFC0EEF.6050309@gmail.com> Message-ID: <4FFC529B.4020700@gmail.com> Le 10/07/2012 17:45, Sebastian Sylvan a ?crit : > On Tue, Jul 10, 2012 at 4:15 AM, David Bruant wrote: >> Why having both classes and traits? Both are mechanisms to enable code >> reuse. >> I guess I should restate my question: In which case would I use traits over >> classes or classes over traits? > As I understand it traits are the code-reuse parts, and classes are > little more than named records that actually bring a bunch of traits > together into an actual type. I.e. you don't inherit from other > classes. Inheritance is very often associated with classes, so I didn't expect that (I'm probably spending too much time with Java users :-p) > Traits are used to specify reusable bags of methods, and > classes are used to actually provide data types on which to run those > methods. This model is very interesting. But if it's the case, why is it possible to implement a trait per type? I'm referring to (in the proposal): impl int: Ord { fn lt(a: self) -> bool { self < a } fn eq(a: self) -> bool { self == a } } In this case, the state is carried by the type (here 'int', which is a bad example) which could be of arbitrarily complex structure with nested vectors, tuples and records. If I can "concretize" a trait for an arbitrarily complex structure, why would I create classes? Or could classes be seen as syntactic sugar over traits+types? If it's the case, then the visibility control mechanism doesn't seem necessary for traits anymore since visibility would be more a concern for classes than for traits. David From graydon at mozilla.com Tue Jul 10 09:51:24 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 10 Jul 2012 09:51:24 -0700 Subject: [rust-dev] Traits proposal In-Reply-To: <4FFC529B.4020700@gmail.com> References: <4FFB50C1.2020703@gmail.com> <4FFB6A55.1040900@mozilla.com> <4FFC0EEF.6050309@gmail.com> <4FFC529B.4020700@gmail.com> Message-ID: <4FFC5D8C.1030707@mozilla.com> On 7/10/2012 9:04 AM, David Bruant wrote: > If I can "concretize" a trait for an arbitrarily complex structure, why > would I create classes? Or could classes be seen as syntactic sugar over > traits+types? Sugar, mostly. We're still trying to decide how sweet to make it. Also they introduce a nominal type, whereas many of our types are structural (i.e. two copies of the same type definition are type-equal). We're still not entirely sure if we can or should be merging the other nominal data constructor ('enum') with 'class', or if that's trying to force things that are better off remaining separate[1]. > If it's the case, then the visibility control mechanism doesn't seem > necessary for traits anymore since visibility would be more a concern > for classes than for traits. That's the idea, yes. -Graydon [1]: For those following along at home, I cannot help but point out the symmetry between the "case-class vs. enums" question and how we previously removed tuples in favour of "just records and enums", then got annoyed with the cases we wanted to write as tuples, so added them back in. Strictly speaking, redundant; but hey, so is everything beyond rule 110, doesn't keep us from quibbling over syntax. From bruant.d at gmail.com Tue Jul 10 10:50:07 2012 From: bruant.d at gmail.com (David Bruant) Date: Tue, 10 Jul 2012 19:50:07 +0200 Subject: [rust-dev] Traits proposal In-Reply-To: <4FFC5D8C.1030707@mozilla.com> References: <4FFB50C1.2020703@gmail.com> <4FFB6A55.1040900@mozilla.com> <4FFC0EEF.6050309@gmail.com> <4FFC529B.4020700@gmail.com> <4FFC5D8C.1030707@mozilla.com> Message-ID: <4FFC6B4F.4050007@gmail.com> Le 10/07/2012 18:51, Graydon Hoare a ?crit : > On 7/10/2012 9:04 AM, David Bruant wrote: > >> If I can "concretize" a trait for an arbitrarily complex structure, why >> would I create classes? Or could classes be seen as syntactic sugar over >> traits+types? > > Sugar, mostly. We're still trying to decide how sweet to make it. Also > they introduce a nominal type, whereas many of our types are > structural (i.e. two copies of the same type definition are > type-equal). We're still not entirely sure if we can or should be > merging the other nominal data constructor ('enum') with 'class', or > if that's trying to force things that are better off remaining > separate[1]. > >> If it's the case, then the visibility control mechanism doesn't seem >> necessary for traits anymore since visibility would be more a concern >> for classes than for traits. > > That's the idea, yes. > > -Graydon > > [1]: For those following along at home, I cannot help but point out > the symmetry between the "case-class vs. enums" question and how we > previously removed tuples in favour of "just records and enums", then > got annoyed with the cases we wanted to write as tuples, so added them > back in. Strictly speaking, redundant; but hey, so is everything > beyond rule 110, doesn't keep us from quibbling over syntax. I don't know this precedent so I can't talk about it much, but a quote by Dave Herman on es-discuss [1] got me thinking a lot: "Completeness is an anti-goal for syntax". It got me thinking about what a goal for syntax should be. And my answer is: convenience to manipulate the underlying VM. Otherwise, we probably would still be all writing in assembly. So completeness is an anti-goal for syntax, but so is minimalism (aka "redundancy chasing"). Minimalism is certainly a good idea for virtual machine basic constructs, but it doesn't make it a good idea for syntax. Anyway, my 2 cents on this question. Thanks all for your answers on traits and classes, David [1] https://mail.mozilla.org/pipermail/es-discuss/2012-May/023045.html From bruant.d at gmail.com Tue Jul 10 12:13:56 2012 From: bruant.d at gmail.com (David Bruant) Date: Tue, 10 Jul 2012 21:13:56 +0200 Subject: [rust-dev] Concurrency and synchronous blocking Message-ID: <4FFC7EF4.4070803@gmail.com> Hi, I've recently watched a Google I/O talk on Go Concurrency Patterns [1] and I find some patterns worrisome. Go has made some choices, but I'd like to understand how Rust addresses these issues. Disclaimer on my background: I've learned programming mostly in C, then a bit of Lisp, a good share of Java, then for the last few years an intense dive into JavaScript (including node.js for almost a year). It's very likely that this cultural background influences (a lot!) my view on programming languages (something about a hammer and a nail). Most of my concerns are appearant in the following piece of Go code (32'41'' in the video): c:= make(chan Result) go func() { c <- Web(query) } () go func() { c <- Image(query) } () go func() { c <- Video(query) } () timeout := time.After(80*time.Milliseconds) for i:=0; i<3; i++ { select{ case result := <-c results = append(results, result) case <- timeout fmt.Println("timed out"); return } } return The intention here is to do a search in different servers (Web, Image, Video) and produce a result ('append' function) with these results. 3 goroutines (background tasks) and the "main" goroutine synchronously blocks on either the c channel (on which each coroutine may write eventually) or the timeout. My analysis goes as follow: Due to synchronous wait, the 3 server queries have to be done in 3 goroutines, otherwise, they would block the "main" goroutine or one another. Each goroutine costs something (both for memory creation and certainly scheduling too). Then, because of synchronous blocking, again, you need a select block to enable multiplexed listening of blocking waits. Finally, maybe it was only for the purpose of an example, but the 'i' variable is an abstraction of exactly nothing. What we really care about is either that the result is fully composed (after all partial results came back) or we timedout and this code doesn't make this expectation straightforward to read. Somewhere in the video is mentionned that synchronous blocking is a feature meant for concurrent tasks synchronization. My experience with JavaScript is synchronisation is the exception rather than the normal case, but that might be the biais I talked about above (and I use promises for synchronisation for their expressivness). So I have several questions regarding Rust: * Is synchronous blocking possible? * How does Rust deal with concurrent tasks synchronization? * How would you write the above example in Rust? * Do you think it's satisfying in terms of expressiveness? Rust is being used in the Servo project, itself aiming at building a web browser. We've seen in the Snappy effort (and some other before that) that encouraging asynchronisity is key in building responsive and efficient software, hence all my questions about Rust take on synchronisity. David [1] http://www.youtube.com/watch?v=f6kdp27TYZs From banderson at mozilla.com Tue Jul 10 18:05:08 2012 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 10 Jul 2012 18:05:08 -0700 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: <4FFC7EF4.4070803@gmail.com> References: <4FFC7EF4.4070803@gmail.com> Message-ID: <4FFCD144.9030001@mozilla.com> On 07/10/2012 12:13 PM, David Bruant wrote: > Hi, > > I've recently watched a Google I/O talk on Go Concurrency Patterns [1] > and I find some patterns worrisome. Go has made some choices, but I'd > like to understand how Rust addresses these issues. > Disclaimer on my background: I've learned programming mostly in C, then > a bit of Lisp, a good share of Java, then for the last few years an > intense dive into JavaScript (including node.js for almost a year). > It's very likely that this cultural background influences (a lot!) my > view on programming languages (something about a hammer and a nail). > > Most of my concerns are appearant in the following piece of Go code > (32'41'' in the video): > > c:= make(chan Result) > go func() { c <- Web(query) } () > go func() { c <- Image(query) } () > go func() { c <- Video(query) } () > > timeout := time.After(80*time.Milliseconds) > for i:=0; i<3; i++ { > select{ > case result := <-c > results = append(results, result) > case <- timeout > fmt.Println("timed out"); > return > } > } > return > > The intention here is to do a search in different servers (Web, Image, > Video) and produce a result ('append' function) with these results. > 3 goroutines (background tasks) and the "main" goroutine synchronously > blocks on either the c channel (on which each coroutine may write > eventually) or the timeout. > > My analysis goes as follow: > Due to synchronous wait, the 3 server queries have to be done in 3 > goroutines, otherwise, they would block the "main" goroutine or one > another. Each goroutine costs something (both for memory creation and > certainly scheduling too). Tasks do have a memory cost, but it is theoretically quite low. Rust tasks on linux currently have somewhere around 4K of overhead, and that's around 3K more than we would like and think is possible. Most of that is dedicated to the call stack, and there are a lot of potential future optimizations to minimize the cost of creating a task (by e.g. reusing them). The intent is that you should not have to think about whether using a task is too expensive, because it is cheap. I'm not familiar with how the JavaScript event loop works but I imagine that it has similar responsibilities to the Rust scheduler. Instead of calling callbacks in response to events though the Rust scheduler resumes execution of tasks. > Then, because of synchronous blocking, again, you need a select block to > enable multiplexed listening of blocking waits. > Finally, maybe it was only for the purpose of an example, but the 'i' > variable is an abstraction of exactly nothing. What we really care about > is either that the result is fully composed (after all partial results > came back) or we timedout and this code doesn't make this expectation > straightforward to read. > > Somewhere in the video is mentionned that synchronous blocking is a > feature meant for concurrent tasks synchronization. My experience with > JavaScript is synchronisation is the exception rather than the normal > case, but that might be the biais I talked about above (and I use > promises for synchronisation for their expressivness). > > So I have several questions regarding Rust: > * Is synchronous blocking possible? I don't understand the term 'synchronous blocking' (as opposed to just 'blocking'). Receiving a value from a Rust port does block a task. Sending on a channel does not (whereas Go channels do block on send). We consider channels to be asynchronous, based on the sending behavior (vs. Go's synchronous channels). > * How does Rust deal with concurrent tasks synchronization? Channels are the primary synchronization primitive in Rust. > * How would you write the above example in Rust? I would basically write it like the Go example. If it didn't have to also wait for the timeout then I would instead use a vector of futures. Here is that Go code translated to current Rust. // Boilerplate use std; import comm::{port, chan, methods, select2}; import task::{spawn}; import iter::repeat; import either::{left, right}; import std::timer::delayed_send; import std::uv_global_loop; import io::println; type query = (); fn web(q: query) -> () { () } fn image(q: query) -> () { () } fn video(q: query) -> () { () } fn main() { let query = (); // Our 'query' // Need an I/O task in order to send a message after // a timeout. This is a temporary wart. let iotask = uv_global_loop::get(); // In rust you need a port for the receiver and a channel // for the sender let query_port = port(); let query_chan = query_port.chan(); let timeout_port = port(); let timeout_chan = timeout_port.chan(); let mut results = []; spawn(|| query_chan.send(web(query)) ); spawn(|| query_chan.send(image(query)) ); spawn(|| query_chan.send(video(query)) ); // Ask for a message on timeout_chan after 80ms delayed_send(iotask, 80, timeout_chan, ()); for repeat(3) { // This is the only form of 'select' we have right now. // If you need to wait on multiple ports then you are out // of luck alt select2(query_port, timeout_port) { left(result) { results += [result]; } right(timeout) { println("timed out"); break; } } } } > * Do you think it's satisfying in terms of expressiveness? No, but not for the reasons you suggest. Rust's split between ports and channels cause a lot of boilerplate, and the lack on an N-ary select function or control structure is a big omission. Rust's libraries in general need to be designed better. > > Rust is being used in the Servo project, itself aiming at building a web > browser. We've seen in the Snappy effort (and some other before that) > that encouraging asynchronisity is key in building responsive and > efficient software, hence all my questions about Rust take on synchronisity. Here's an experiment. So if we were doing JavaScript-style concurrency in Rust we might write let mut results = []; let mut timeout = false; let add_result = |result| { if !timeout { results += [result]; if results.len() == 3 { do_something_with_results(results); } } }; // These should all do their work and call callbacks asynchronously do web(query) |result| { add_results(result); } do image(query) |result| { add_result(result); } do video(query) |result| { add_result(result); } do on_timeout(80) { timeout = true; } This of course isn't how Rust works because none of those calls can happen asynchronously on a single task. But task-based concurrency does allow similar patterns, except that all the callbacks end up in different tasks and cannot mutate their original environment. We would make `fn web` spawn another task where it performs the query and executes the callback. fn web(q: query, callback: fn~(r: result)) { do spawn { callback(execute_query(q)); } } And the state we are manipulating would get its own task: enum msg { msg_result(result), msg_timeout } let result_chan = spawn_listener |msg| { let mut results = []; let mut timeout = false; loop { alt msg.recv() { msg_result(r) { ... } msg_timeout { ... } } } }; let add_result = |result| result_chan.send(result); // etc. At that point you can call the `web`, `image`, `video` and `on_timeout` functions in the continuation style. This is fairly viable pattern in Rust because we have awesome unique closures that can be safely sent across tasks. Putting the state into a different task where you can mutate it involves more work than JavaScript, but with the benefit that all this work will happen in parallel. Regards, Brian From a.stavonin at gmail.com Tue Jul 10 18:24:47 2012 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Wed, 11 Jul 2012 10:24:47 +0900 Subject: [rust-dev] Reflection system Message-ID: I've found mentions of Reflection system in "Doc detailed release notes", unfortunatly the explanation is totally unclear for me. After that, I found reflect-visit-data.rs file, which was not too helpfull. Is it possible to clarify Reflection system description, provide some use cases, etc? -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Tue Jul 10 18:30:03 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Tue, 10 Jul 2012 18:30:03 -0700 Subject: [rust-dev] Reflection system In-Reply-To: References: Message-ID: On Tue, Jul 10, 2012 at 6:24 PM, Alexander Stavonin wrote: > I've found mentions of Reflection system in "Doc detailed release notes", > unfortunatly the explanation is totally unclear for me. After that, I found > reflect-visit-data.rs file, which was not too helpfull. Is it possible to > clarify Reflection system description, provide some use cases, etc? The reflection system is still experimental. I'm not sure what Graydon's plans are as far as documenting it in this release, but if it's not documented in this release, certainly expect documentation in a future release. But as with everything we do, using it at your own risk and asking questions on IRC is encouraged! Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From sebastian.sylvan at gmail.com Tue Jul 10 18:41:09 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Tue, 10 Jul 2012 18:41:09 -0700 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: <4FFCD144.9030001@mozilla.com> References: <4FFC7EF4.4070803@gmail.com> <4FFCD144.9030001@mozilla.com> Message-ID: On Tue, Jul 10, 2012 at 6:05 PM, Brian Anderson wrote: > Tasks do have a memory cost, but it is theoretically quite low. Rust tasks > on linux currently have somewhere around 4K of overhead, and that's around > 3K more than we would like and think is possible. Most of that is dedicated > to the call stack, and there are a lot of potential future optimizations to > minimize the cost of creating a task (by e.g. reusing them). The intent is > that you should not have to think about whether using a task is too > expensive, because it is cheap. It would be cool if tasks started out more like PPL/TBB/Cilk tasks and transitioned into the current thread-like construct and allocated stack space only if needed. I.e. the first time a task needs to yield its underlying "worker thread" (because it's about to block) it would go through the work of allocating a stack (and heap?) and copy its state into it. This would make task-parallel type things very cheap since in that scenario most tasks would just run to completion on the worker thread's task (and heap?), while still allowing you to use the same mechanism for longer running tasks. Tasks which have a clear non-avoidable yield point in them could just allocate all this up-front of course. Maybe this is a bit too magical and there should just be a different task-like concept that maps better to task-parallelism. I have to say that the latest PPL/TBB task API (they're basically the same) is a joy to use. I would conjecture that they're much faster than Rust's tasks in the fast path, although I haven't benchmarked, because they don't try to be threads, they're just little jobs that run on the stack of the worker thread (if they block, they will block the underlying worker thread - which falls back to the OS scheduling an overprovisioned set of worker threads onto the actual CPU threads). See e.g. this page for some example code (though it also shows some parallel for_each and stuff like that): http://msdn.microsoft.com/en-us/library/dd492427(v=vs.110).aspx -- Sebastian Sylvan From pwalton at mozilla.com Tue Jul 10 19:11:08 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 10 Jul 2012 19:11:08 -0700 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: References: <4FFC7EF4.4070803@gmail.com> <4FFCD144.9030001@mozilla.com> Message-ID: <4FFCE0BC.70604@mozilla.com> On 7/10/12 6:41 PM, Sebastian Sylvan wrote: > It would be cool if tasks started out more like PPL/TBB/Cilk tasks and > transitioned into the current thread-like construct and allocated > stack space only if needed. I.e. the first time a task needs to yield > its underlying "worker thread" (because it's about to block) it would > go through the work of allocating a stack (and heap?) and copy its > state into it. This is hard in Rust because we don't have moving GC. We're working on it, but it will be quite a ways off. Even if we had moving GC, we still couldn't take a thread stack and move it somewhere, since arbitrary data can be pinned to the stack frame as a consequence of the way unsafe and borrowed pointers work. There are, however, other optimizations we can do: * As part of pipes, implement a blocking send-and-yield-to-target function that transitions straight to the new task without a trip through the scheduler. This basically optimizes down into a context switch, which should be on the order of a function call that saves and restores all registers. * Have a thread-local set of "new stacks" always ready for use. * Avoid creating a heap for a new task until the first malloc. So in the fully optimized world the fast send-and-yield-to-target path might look like: 1. Grab a preallocated task structure and stack segment for the new task. This is just the head of a linked list stored in TLS; no locking is necessary. 2. Assuming the arguments to the task fit in registers, copy the registers into the new task structure. 3. Context switch; exchange all registers with the registers in the new task. This may be competitive with Cilk. Can't predict without benchmarks, of course, but this seems reasonably likely to be fast. Patrick From fw at deneb.enyo.de Wed Jul 11 10:27:41 2012 From: fw at deneb.enyo.de (Florian Weimer) Date: Wed, 11 Jul 2012 19:27:41 +0200 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: <4FFC7EF4.4070803@gmail.com> (David Bruant's message of "Tue, 10 Jul 2012 21:13:56 +0200") References: <4FFC7EF4.4070803@gmail.com> Message-ID: <87zk761a42.fsf@mid.deneb.enyo.de> * David Bruant: > Most of my concerns are appearant in the following piece of Go code > (32'41'' in the video): > > c:= make(chan Result) > go func() { c <- Web(query) } () > go func() { c <- Image(query) } () > go func() { c <- Video(query) } () > > timeout := time.After(80*time.Milliseconds) > for i:=0; i<3; i++ { > select{ > case result := <-c > results = append(results, result) > case <- timeout > fmt.Println("timed out"); > return > } > } > return This approach is fundamentally broken. If the timeout ever kicks in, goroutines will pile up without bounds. In the current Go implementation, the timeout has to be moved inside the goroutines. (Theoretically, Go could support cancellation of goroutines, but this is something really thorny, carries a distributed overhead and does not seem to be particularly attractive.) > My analysis goes as follow: > Due to synchronous wait, the 3 server queries have to be done in 3 > goroutines, otherwise, they would block the "main" goroutine or one > another. Each goroutine costs something (both for memory creation and > certainly scheduling too). Goroutine allocation is very cheap (or it can be made so at least). Actually, part of the allocation cost is distributed throughout the program: segmented stacks and the increased size of the overall root set. The scheduling overhead is low if there is just one actual thread available for executing goroutines. The select will switch to one of the newly created goroutines and execute that until it blocks on the connect. There is no preemption, so no cycles are wasted on that. It should be possible to avoid context switches in the same way as the leader/follower pattern does. (I have not checked if the current implementation does that.) From ash.gti at gmail.com Wed Jul 11 16:33:41 2012 From: ash.gti at gmail.com (Harrison, John) Date: Wed, 11 Jul 2012 16:33:41 -0700 Subject: [rust-dev] Calling C varg args from rust Message-ID: <55AA7035-05FF-4CBF-A7A1-0ED2FE203F9D@gmail.com> Is it currently possible to call a var arg function, say printf, from rust? Or is there a recommended work around at the moment for doing so? -- John Harrison -------------- next part -------------- An HTML attachment was scrubbed... URL: From mictadlo at gmail.com Wed Jul 11 16:40:15 2012 From: mictadlo at gmail.com (Mic) Date: Thu, 12 Jul 2012 09:40:15 +1000 Subject: [rust-dev] rust to JavaScript Message-ID: Hello, Any plans to allow rust to compile to JavaScript like dart http://www.youtube.com/watch?v=YxogQGnMA9Y . Cheers, Mic -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Wed Jul 11 17:40:02 2012 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 11 Jul 2012 17:40:02 -0700 Subject: [rust-dev] Calling C varg args from rust In-Reply-To: <55AA7035-05FF-4CBF-A7A1-0ED2FE203F9D@gmail.com> References: <55AA7035-05FF-4CBF-A7A1-0ED2FE203F9D@gmail.com> Message-ID: <4FFE1CE2.4090503@mozilla.com> On 07/11/2012 04:33 PM, Harrison, John wrote: > Is it currently possible to call a var arg function, say printf, from > rust? Or is there a recommended work around at the moment for doing so? It is not possible in general, though declaring and using varargs functions without the vararg argument works (it's just not very useful). The workaround I use is to define a little file called glue.c to wrap the varargs call, then statically link it to the crate. Statically linking just works, more or less, so if I have glue.a and my Rust code, project.rs contains: extern mod glue { my_printf(f: *c_str, i: int); } Then calling `rustc -L . project.rs` should work. -Brian From banderson at mozilla.com Wed Jul 11 17:43:19 2012 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 11 Jul 2012 17:43:19 -0700 Subject: [rust-dev] rust to JavaScript In-Reply-To: References: Message-ID: <4FFE1DA7.8020703@mozilla.com> On 07/11/2012 04:40 PM, Mic wrote: > Hello, > Any plans to allow rust to compile to JavaScript like dart > http://www.youtube.com/watch?v=YxogQGnMA9Y . No firm plans, but I would like to have an emscripten build target. From hatahet at gmail.com Wed Jul 11 18:06:39 2012 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 11 Jul 2012 18:06:39 -0700 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: <87zk761a42.fsf@mid.deneb.enyo.de> References: <4FFC7EF4.4070803@gmail.com> <87zk761a42.fsf@mid.deneb.enyo.de> Message-ID: On Wed, Jul 11, 2012 at 10:27 AM, Florian Weimer wrote: > > > This approach is fundamentally broken. If the timeout ever kicks in, > goroutines will pile up without bounds. I just want to be clear on your comment. You mean the goroutines would pile up, or the channel will grow without bounds? Thanks -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Wed Jul 11 19:55:45 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 11 Jul 2012 19:55:45 -0700 Subject: [rust-dev] Release candidates Message-ID: <4FFE3CB1.4070002@mozilla.com> Hi, I've posted release candidates for 0.3 to the rust download server. These are still preliminary; I'd like to get a few shows-of-hands that they work right before announcing anything. In particular, the windows builds. This was an awkward build for windows as it appears gcc 4.7 (the "new" versions of mingw) can't build us properly, so you have to be using a 4.5 compiler / libgcc. That is, you need to use this mingw: http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/mingw-get-inst-20110802/mingw-get-inst-20110802.exe/download and select its built-in package lists, not "the latest". Alternatively, if you're lucky enough to still have a 4.5-based mingw from last time around, it should still work. Annoyingly, we are still somewhat stuck in a narrow window of bootstrap capability due to libuv's aggressive use of newer system calls and such, so centOS 5.x and earlier (glibc pre-2.6) are known not to work for this series. We'll try to get that business sorted out in future releases, Anyway, that aside, here are some links. Please let me know what's wrong with them (if anything obvious), which platforms they work or don't-work on, any minor fixes to throw in last-minute: http://dl.rust-lang.org/dist/rust-0.3.tar.gz http://dl.rust-lang.org/dist/rust-0.3-install.exe Thanks, -Graydon From sebastian.sylvan at gmail.com Wed Jul 11 21:34:12 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Wed, 11 Jul 2012 21:34:12 -0700 Subject: [rust-dev] Release candidates In-Reply-To: <4FFE3CB1.4070002@mozilla.com> References: <4FFE3CB1.4070002@mozilla.com> Message-ID: On Wed, Jul 11, 2012 at 7:55 PM, Graydon Hoare wrote: > Hi, > > I've posted release candidates for 0.3 to the rust download server. These > are still preliminary; I'd like to get a few shows-of-hands that they work > right before announcing anything. In particular, the windows builds. Tried it, seems to work. The hello world example on the website no longer compiles. This is the only way I could make it compile: for (&[1,2,3]).each |i| { println(#fmt("hello, %d", i)); } Is that right? That parenthesis around the vector literal is a bit unfortunate. I couldn't get rid of the ampersand because it would fail to compile with a "deprecated vec expr" error. -- Sebastian Sylvan From fw at deneb.enyo.de Wed Jul 11 22:52:06 2012 From: fw at deneb.enyo.de (Florian Weimer) Date: Thu, 12 Jul 2012 07:52:06 +0200 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: (Ziad Hatahet's message of "Wed, 11 Jul 2012 18:06:39 -0700") References: <4FFC7EF4.4070803@gmail.com> <87zk761a42.fsf@mid.deneb.enyo.de> Message-ID: <87bojlil15.fsf@mid.deneb.enyo.de> * Ziad Hatahet: > On Wed, Jul 11, 2012 at 10:27 AM, Florian Weimer wrote: >> >> >> This approach is fundamentally broken. If the timeout ever kicks in, >> goroutines will pile up without bounds. > I just want to be clear on your comment. You mean the goroutines would pile > up, or the channel will grow without bounds? The goroutines would pile up. From hatahet at gmail.com Wed Jul 11 23:47:32 2012 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 11 Jul 2012 23:47:32 -0700 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: <87bojlil15.fsf@mid.deneb.enyo.de> References: <4FFC7EF4.4070803@gmail.com> <87zk761a42.fsf@mid.deneb.enyo.de> <87bojlil15.fsf@mid.deneb.enyo.de> Message-ID: Ah, you mean after repeated invocations of the containing function in case the timeout event keeps firing? -- Ziad On Wed, Jul 11, 2012 at 10:52 PM, Florian Weimer wrote: > * Ziad Hatahet: > > > On Wed, Jul 11, 2012 at 10:27 AM, Florian Weimer > wrote: > >> > >> > >> This approach is fundamentally broken. If the timeout ever kicks in, > >> goroutines will pile up without bounds. > > > I just want to be clear on your comment. You mean the goroutines would > pile > > up, or the channel will grow without bounds? > > The goroutines would pile up. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fw at deneb.enyo.de Wed Jul 11 23:53:11 2012 From: fw at deneb.enyo.de (Florian Weimer) Date: Thu, 12 Jul 2012 08:53:11 +0200 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: (Ziad Hatahet's message of "Wed, 11 Jul 2012 23:47:32 -0700") References: <4FFC7EF4.4070803@gmail.com> <87zk761a42.fsf@mid.deneb.enyo.de> <87bojlil15.fsf@mid.deneb.enyo.de> Message-ID: <87ehohcvxk.fsf@mid.deneb.enyo.de> * Ziad Hatahet: > Ah, you mean after repeated invocations of the containing function in case > the timeout event keeps firing? Yes, that's the problem. In most cases I've seen, the cause for a timeout does not go away quickly, so such a programming pattern tends to spread the congestion even further. I think there has been quite a bit of research in the Erlang context how processes can avoid increasing load in an already overloaded situation, but I can't find the papers right now. From steven099 at gmail.com Thu Jul 12 00:25:48 2012 From: steven099 at gmail.com (Steven Blenkinsop) Date: Thu, 12 Jul 2012 03:25:48 -0400 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: References: <4FFC7EF4.4070803@gmail.com> <87zk761a42.fsf@mid.deneb.enyo.de> <87bojlil15.fsf@mid.deneb.enyo.de> Message-ID: On Thursday, July 12, 2012, Ziad Hatahet wrote: > Ah, you mean after repeated invocations of the containing function in case > the timeout event keeps firing? > The timeout will only fire once and exit cleanly whether the value is received or not, since the channel has a buffer of 1. The issue is that, if the timeout is received before any values are read off c, then the three goroutines will hang on the send operations forever (unless the program exits, or you get a deadlock). One solution, if you know the number of goroutines, is to put a fixed size buffer on the channel, which is just an extra parameter for make. Another solution is to add a done channel, and close it when you get the timeout: c := make(chan Result) done := make(chan struct{}) // make sure done closes before function // exits, letting remaining goroutines exit. defer close(done) // convenience function to encapsulate pattern dispatch := func(f func(string)) { select { case c <- f(query): case <-done: // this case becomes available once done is closed } } go dispatch(Web) go dispatch(Image) go dispatch(Video) timeout := time.After(80*time.Milliseconds) for len(results) < 3 { select { case result := <-c: results = append(results, result) case <- timeout: fmt.Println("timed out") return } } return -------------- next part -------------- An HTML attachment was scrubbed... URL: From bruant.d at gmail.com Thu Jul 12 00:32:09 2012 From: bruant.d at gmail.com (David Bruant) Date: Thu, 12 Jul 2012 09:32:09 +0200 Subject: [rust-dev] rust to JavaScript In-Reply-To: References: Message-ID: <4FFE7D79.9040802@gmail.com> Le 12/07/2012 01:40, Mic a ?crit : > Hello, > Any plans to allow rust to compile to JavaScript like dart > http://www.youtube.com/watch?v=YxogQGnMA9Y . > To the best of my knowledge, Rust compiles down to LLVM and Emscripten compiles from LLVM to JS, so it seems like the hardest part of the job is already done. David From niko at alum.mit.edu Thu Jul 12 07:12:02 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 12 Jul 2012 07:12:02 -0700 Subject: [rust-dev] Release candidates In-Reply-To: References: <4FFE3CB1.4070002@mozilla.com> Message-ID: <4FFEDB32.6070302@alum.mit.edu> On 7/11/12 9:34 PM, Sebastian Sylvan wrote: > The hello world example on the website no longer compiles. This is the > only way I could make it compile: > for (&[1,2,3]).each |i| { > println(#fmt("hello, %d", i)); > } > > Is that right? That parenthesis around the vector literal is a bit > unfortunate. I couldn't get rid of the ampersand because it would fail > to compile with a "deprecated vec expr" error. This is probably right at the moment. Unfortunate indeed. Soon [1, 2, 3] are to be "undeprecated" with a new meaning which would cause the code as originally written to work again. Niko From niko at alum.mit.edu Thu Jul 12 07:15:06 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 12 Jul 2012 07:15:06 -0700 Subject: [rust-dev] rust to JavaScript In-Reply-To: <4FFE7D79.9040802@gmail.com> References: <4FFE7D79.9040802@gmail.com> Message-ID: <4FFEDBEA.6080003@alum.mit.edu> On 7/12/12 12:32 AM, David Bruant wrote: > To the best of my knowledge, Rust compiles down to LLVM and Emscripten > compiles from LLVM to JS, so it seems like the hardest part of the job > is already done. Maybe so, but there remains a good bit of work. Emscripten requires non-trivial libraries and so forth to be ported as well (although we might be able to compile them down to C with clang and then emscripten them in turn, have to try it and see how far we get). Certainly there is no pthread or stack-switching implementation for Javascript so I guess we'll have to rewrite at least the scheduler! We might end up having to model each Rust thread with a web worker or something like that, as a first attempt anyhow. Niko From graydon at mozilla.com Thu Jul 12 07:56:19 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 12 Jul 2012 07:56:19 -0700 Subject: [rust-dev] Release candidates In-Reply-To: References: <4FFE3CB1.4070002@mozilla.com> Message-ID: <4FFEE593.6030105@mozilla.com> On 11/07/2012 9:34 PM, Sebastian Sylvan wrote: > The hello world example on the website no longer compiles. This is the > only way I could make it compile: > for (&[1,2,3]).each |i| { > println(#fmt("hello, %d", i)); > } > > Is that right? That parenthesis around the vector literal is a bit > unfortunate. I couldn't get rid of the ampersand because it would fail > to compile with a "deprecated vec expr" error. Curious; is &[ not binding "really tight"? Like .. in the parser? I thought we agreed it sort of had to be that way. -Graydon From niko at alum.mit.edu Thu Jul 12 09:55:46 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 12 Jul 2012 09:55:46 -0700 Subject: [rust-dev] fn type proposal Message-ID: <4FFF0192.7030709@alum.mit.edu> What do people think about the proposal I outlined here: http://smallcultfollowing.com/babysteps/blog/2012/07/12/fn-types/ Inlined below: I am trying to put the final nails in the regions coffin now. One of the big remaining areas is dealing with function and iface types. This proposal is certainly influenced by my previous proposals. However, we have backed away from the idea of dynamically-sized types for vectors and so I will do the same here. ### The design My current design includes the following kinds of function types (written as I expect them to commonly be written; some details are omitted): - `&fn(S) -> T` - `@fn(S) -> T` - `~fn(S) -> T` Similar types apply to iface types (using the iface `to_str` as an example): - `&to_str` - `@to_str` - `~to_str` These types work like their corresponding pointer types, so a value of type `@fn(S) -> T` or `~fn(S) -> T` can be "borrowed" into a `&fn(S) -> T`. (Today, there is a subtyping relationship) Similarly, the explicit syntax for creating closures will become `@fn(s: S) -> T { ... }` and `~fn(s: S) -> T { ... }`. I will make it legal to omit the argument and return types and infer them from context. The closures produced from such expressions are always copying closures, in that they copy or move values from their environment when created. The sugared notation `|s| expr` as well as the `do` and `for` loop notation will use inference to decide which of the three kinds of closures is produced. If a sugared closure resolves to a `&fn`, then a "by-reference" closure will be produced. That is, one which can modify the values in its enclosing environment. Otherwise, a copying closure is created. (As today) #### Borrowed closures Borrowed closures in their most explicit form are written `&r/fn(S) -> T`. They are like `fn()` today but they are associated with a region `r` (the notation for region pointers is changed from `&r.T` to `&r/T`, for those of you following along). The region type system will ensure they do not escape, so we can lift the various restrictions about using borrowed closures only within parameters and so forth. This will require some tweaks to various analyses (notably borrowck) that take advantage of the limited possibilities of the current by-reference closures. I don't think this will be terribly difficult. Including an explicit region also *enables* a lot of very useful things. Closures which reference their environment can be stored in other data structures. Further, we should be able to make use of the region bound to allow borrowed closures to deinitialize variables in their environment---see below for more details. #### Shared closures Shared closures, written like `@fn(S) -> T`, are exactly like the `fn@(S) -> T` that we use today. They consist of a shared, boxed environment which may close over arbitrary data. They cannot close over borrowed pointers. #### Unique closures Unique closures in their most explicit form are written like `~fn:K(S) -> T`, where `K` is a set of bounds like those found on type parameters. If `K` is omitted it defaults to `send`. They cannot close over borrowed pointers and, furthermore, all data that they do close over must conform to the given bound. I expect it will rarely be necessary to write an explicit bound, but it may be useful sometimes to write `~fn:send copy(S) -> T`, to indicate that the data that is closed over is not only sendable but also copyable. Unlike all other closure types, unique closures are themselves sendable provided that `send` is listed among the bounds `K`. #### Representation, bare functions The representation of function pointers will remain a pair `(code, env)` of pointers. This is not as pure as my prior proposals but has some advantages, not the least of which being that it will require less code churn to achieve. It should also make bare functions more efficiently represented. The bare function type goes away entirely, to be replaced with an inference technique similar to what Lindsey did with integer literal inference. #### Preventing capture There is one annoying complication. As they have no region bounds, we need to prevent the `@fn()` and `~fn()` types from closing over borrowed pointers. I plan to do this by introducing a new kind `owned` which means "copyable and does not contain borrowed pointers". Functions can only close over owned data. The reason that a kind is necessary is due to the possibility of functions like the following: iface foo { fn foo(); } fn generator(a: A) -> @fn() { @fn() { a.foo() } } This function closes over `a`. So now if we invoked `generator()` with `A` bound to a type like `&int`, it would close over region data. Any time the returned closure is used, it would make use of that region data. Because the region does not appear in the type of the closure (`@fn()`), the type system would be powerless to prevent this borrowed pointer from leaking out beyond its lifetime. Bad. In my current design, the function above would be illegal. One would have to write: iface foo { fn foo(); } fn generator(a: A) -> @fn() { @fn() { a.foo() } } Note that the bound `owned` replaced `copy`. Without this bound it would not be legal to copy `a` into the closure. This bound also prevents `generator()` from being called with a borrowed pointer. This is actually a simplified approach. Another option might be to add region bounds on all `fn` types. We could then allow `fn` types to close over borrowed pointers. I hestitate to do this though because I think that the region bounds on `@fn` and `~fn` would want different defaults than all other region references. For example, all region references appearing in a function signature default to a region parameter, including those that appear within shared boxes and so forth (this will not be a common occurrence, I think, but of course it can happen). So if I write: fn some_func(x: &int, y: @&int) { ... } then both `x` and `*y` have the same lifetime (the default lifetime parameter). If we were consistent, then, it would mean that a function like this: fn some_func(x: &int, f: @fn(int)) { ... } would imply that the lifetime of `x` and the region bound of `f` would both be the same as well (the default lifetime parameter). But this is likely not what you wanted; probably you planned to store `f` into a data structure or something and actually wanted a region bound of `&static` (that is, does not close over region data). Basically, the difference between an `@fn` type and other shared types with regard to regions is that we never know what an `@fn` closes over. With a normal shared type, we only add region bounds when regions are actually used: but for `@fn` we'd have to choose a different default. Maybe this is not so bad, but even if we added region bounds to `@fn`, we'd *still* need the `owned` kind, or else we'd need to be able to add region bounds to type variables. This all seems like layers and layers of complexity that won't be necessary, as a `@fn` type that closes over borrowed pointers isn't all that useful (there are places I can imagine it being useful, though). Anyway this part is actually easily tweaked if it seems more expressiveness is warranted. ### Goals that are achieved by this proposal **Stack-allocated and sendable iface instances.** I've wanted this for a long time. **More flexibility with stack-allocated closures.** The current requirement that all closures which go into data structures be heap-allocated is sometimes a real drag. It means that things like the visitor pattern we implement in rustc can't make use of borrowed pointers---though this would also be ameliorated with traits, I suppose. But anyhow. **Prefix-sigils.** Postfix sigils like `fn@` are so Rust 0.2. **Support for sendable, copyable unique closures.** Now that `send` no longer implies `copy`, we need to distinguish these things. **Fewer closure types.** We currently have way too many (5, I think). With this proposal there are still three, but they look and feel like one. Mostly this is achieved through better inference techniques for native functions and eliminating the "any closure" type (which, admittedly, I introduced). ### Goals that *might* be achieved by this proposal **Moving within closures.** Actually I only *think* this can be done safely. This is a fairly complex topic. The basic goal is to be able to write something like this `fold()` operation (here I am using some non-implemented things, like unary move, in place of the current `<-` and last use): fn fold(iter: &iterable, b0: B, op: &fn(B, &A) -> B) -> B { let b = move b0; for iter.each |a| { b = op(move b, a); } ret b; } The interesting part is that we move the intermediate value `b` out of the stack frame in the call to `op()` and then replace it with a new value before the next iteration of the loop. Note that the loop body here is actually a closure. This may seem trivially safe, but given the possibility of recursion it is not so. We need to prove that the closure never recurses while some upvars are uninitialized. I *think* regions give us the tools to do that: we can see that the region of `op` is bigger than the method body itself (it's a region parameter, in fact). This implies that `op()` cannot reach the closure which is executing, which is defined with a tighter region. However, there are some complications I haven't thought through---for example, what if we provided the closure as an argument to `op()`? This will turn out being quite complex in the end I fear. Maybe there is a better way. ### Goals that are *not* achieved by this proposal **One-shot closures.** We still have no support for one-shot closures. It is becoming increasingly clear that these would be helpful: it is common to want to move some value into the closure and then move it out again, and the current unique closure design does not permit this. You can work around it with a series of painful swaps and calls to `option::unwrap()`, but it's inefficient and inelegant. pcwalton ran an idea by me which basically converted today's `fn~` into a one-shot closure: if you wanted to call the closure mutiple times, you had to copy it. This has a certain appeal but it doesn't work with the system as it is today nor the system I proposed just now, because `fn~` (at least today) can be upcast to `fn`. We'd have to make `fn~` not borrowable. I was initially enthusiastic about this idea but am now less so. It seems to be a strike against orthogonality: `~fn()` types would behave differently from all other closure types. I'd rather give them a different name, like procedures or even `~fn1()`, to make the distinction more clear. Not sure what is best here. From banderson at mozilla.com Thu Jul 12 11:32:37 2012 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 12 Jul 2012 11:32:37 -0700 Subject: [rust-dev] Release candidates In-Reply-To: <4FFEE593.6030105@mozilla.com> References: <4FFE3CB1.4070002@mozilla.com> <4FFEE593.6030105@mozilla.com> Message-ID: <4FFF1845.4030206@mozilla.com> On 07/12/2012 07:56 AM, Graydon Hoare wrote: > On 11/07/2012 9:34 PM, Sebastian Sylvan wrote: > >> The hello world example on the website no longer compiles. This is the >> only way I could make it compile: >> for (&[1,2,3]).each |i| { >> println(#fmt("hello, %d", i)); >> } >> >> Is that right? That parenthesis around the vector literal is a bit >> unfortunate. I couldn't get rid of the ampersand because it would fail >> to compile with a "deprecated vec expr" error. > > Curious; is &[ not binding "really tight"? Like .. in the parser? I > thought we agreed it sort of had to be that way. > I think dot has the highest precedence of all. From banderson at mozilla.com Thu Jul 12 11:32:44 2012 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 12 Jul 2012 11:32:44 -0700 Subject: [rust-dev] Release candidates In-Reply-To: <4FFEDB32.6070302@alum.mit.edu> References: <4FFE3CB1.4070002@mozilla.com> <4FFEDB32.6070302@alum.mit.edu> Message-ID: <4FFF184C.9060500@mozilla.com> On 07/12/2012 07:12 AM, Niko Matsakis wrote: > On 7/11/12 9:34 PM, Sebastian Sylvan wrote: >> The hello world example on the website no longer compiles. This is the >> only way I could make it compile: >> for (&[1,2,3]).each |i| { >> println(#fmt("hello, %d", i)); >> } >> >> Is that right? That parenthesis around the vector literal is a bit >> unfortunate. I couldn't get rid of the ampersand because it would fail >> to compile with a "deprecated vec expr" error. > > This is probably right at the moment. Unfortunate indeed. Soon [1, 2, > 3] are to be "undeprecated" with a new meaning which would cause the > code as originally written to work again. > Let's change the example to show off a more attractive corner of the language. From davidb at davidb.org Thu Jul 12 09:44:07 2012 From: davidb at davidb.org (David Brown) Date: Thu, 12 Jul 2012 16:44:07 +0000 (UTC) Subject: [rust-dev] Release candidates References: <4FFE3CB1.4070002@mozilla.com> Message-ID: On 2012-07-12, Graydon Hoare wrote: > Anyway, that aside, here are some links. Please let me know what's wrong > with them (if anything obvious), which platforms they work or don't-work > on, any minor fixes to throw in last-minute: > > http://dl.rust-lang.org/dist/rust-0.3.tar.gz > http://dl.rust-lang.org/dist/rust-0.3-install.exe On x86_64 Arch Linux, I get the error log below. Interestingly, if I just type make again, it builds what appears to be a perfectly functional rustc. I do still have my own 'python' in my path to python2, since Arch makes 'python' point to v3 by default. I can try removing that if you think it might work. David make[6]: Entering directory `/home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt' MKDIR: /home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang/runtime/compiler-rt/clang_linux/full-i386/i386/SubDir.lib COMPILE: clang_linux/full-i386/i386: /home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt/lib/absvdi2.c 0 clang 0x0000000001b00ad2 1 clang 0x0000000001b00ff9 2 libc.so.6 0x00002b7735002020 3 clang 0x0000000000e9a19a 4 clang 0x0000000000e9b643 5 clang 0x0000000000e9db42 clang::runUninitializedVariablesAnalysis(clang::DeclContext const&, clang::CFG const&, clang::AnalysisDeclContext&, clang::UninitVariablesHandler&, clang::UninitVariablesAnalysisStats&) + 1586 6 clang 0x0000000000c99643 clang::sema::AnalysisBasedWarnings::IssueWarnings(clang::sema::AnalysisBasedWarnings::Policy, clang::sema::FunctionScopeInfo*, clang::Decl const*, clang::BlockExpr const*) + 947 7 clang 0x00000000009f5908 clang::Sema::PopFunctionScopeInfo(clang::sema::AnalysisBasedWarnings::Policy const*, clang::Decl const*, clang::BlockExpr const*) + 328 8 clang 0x0000000000a8335a clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool) + 506 9 clang 0x00000000009d3787 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) + 183 10 clang 0x000000000097e0dc clang::Parser::ParseFunctionDefinition(clang::Parser::ParsingDeclarator&, clang::Parser::ParsedTemplateInfo const&, llvm::SmallVector*) + 1148 11 clang 0x0000000000989020 clang::Parser::ParseDeclGroup(clang::Parser::ParsingDeclSpec&, unsigned int, bool, clang::SourceLocation*, clang::Parser::ForRangeInit*) + 1008 12 clang 0x0000000000978652 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsingDeclSpec&, clang::AccessSpecifier) + 146 13 clang 0x0000000000978c22 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::ParsedAttributes&, clang::AccessSpecifier) + 786 14 clang 0x000000000097cf96 clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::Parser::ParsingDeclSpec*) + 2438 15 clang 0x000000000097d192 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&) + 194 16 clang 0x0000000000975ebc clang::ParseAST(clang::Sema&, bool, bool) + 268 17 clang 0x0000000000841ace clang::CodeGenAction::ExecuteAction() + 62 18 clang 0x00000000006f3014 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 340 19 clang 0x00000000006d9a42 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1090 20 clang 0x00000000006d2f91 cc1_main(char const**, char const**, char const*, void*) + 8465 21 clang 0x00000000006c671d main + 7757 22 libc.so.6 0x00002b7734fee725 __libc_start_main + 245 23 clang 0x00000000006d02e9 Stack dump: 0. Program arguments: /home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/Release+Asserts/bin/clang -cc1 -triple i386-unknown-linux-gnu -emit-obj -disable-free -main-file-name absvdi2.c -pic-level 2 -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.22.0.20120323 -momit-leaf-frame-pointer -coverage-file /home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang/runtime/compiler-rt/clang_linux/full-i386/i386/SubDir.lib/absvdi2.o -resource-dir /home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/Release+Asserts/bin/../lib/clang/3.2 -isysroot /home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt/SDKs/linux -fmodule-cache-path /var/tmp/clang-module-cache -internal-isystem /home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt/SDKs/linux/usr/local/include -internal-isystem /home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/Release+Asserts/bin/../lib/clang/3.2/include -internal-externc-isystem /home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt/SDKs/linux/include -internal-externc-isystem /home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt/SDKs/linux/usr/include -O3 -Wall -Werror -fdebug-compilation-dir /home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang/runtime/compiler-rt -ferror-limit 19 -fmessage-length 119 -mstackrealign -fgnu-runtime -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-fragile-abi -fdiagnostics-show-option -fcolor-diagnostics -o /home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang/runtime/compiler-rt/clang_linux/full-i386/i386/SubDir.lib/absvdi2.o -x c /home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt/lib/absvdi2.c 1. parser at end of file 2. /home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt/lib/absvdi2.c:23:1: parsing function body '__absvdi2' clang: error: unable to execute command: Segmentation fault clang: error: clang frontend command failed due to signal (use -v to see invocation) clang: note: diagnostic msg: Please submit a bug report to http://llvm.org/bugs/ and include command line arguments and all diagnostic information. clang: note: diagnostic msg: Preprocessed source(s) and associated run script(s) are located at: clang: note: diagnostic msg: /tmp/absvdi2-5bBI7j.i clang: note: diagnostic msg: /tmp/absvdi2-5bBI7j.sh make[6]: *** [/home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang/runtime/compiler-rt/clang_linux/full-i386/i386/SubDir.lib/absvdi2.o] Error 254 make[6]: Leaving directory `/home/davidb/rust/rust-0.3/src/llvm/projects/compiler-rt' make[5]: *** [BuildRuntimeLibraries] Error 2 make[5]: Leaving directory `/home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang/runtime/compiler-rt' make[4]: *** [compiler-rt/.makeall] Error 2 make[4]: Leaving directory `/home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang/runtime' make[3]: *** [all] Error 1 make[3]: Leaving directory `/home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools/clang' make[2]: *** [clang/.makeall] Error 2 make[2]: Leaving directory `/home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/tools' make[1]: *** [all] Error 1 make[1]: Leaving directory `/home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu' make: *** [/home/davidb/rust/rust-0.3/b/llvm/x86_64-unknown-linux-gnu/Release+Asserts/bin/llvm-config] Error 2 From graydon at mozilla.com Thu Jul 12 16:10:23 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 12 Jul 2012 16:10:23 -0700 Subject: [rust-dev] Rust 0.3 released Message-ID: <4FFF595F.5030708@mozilla.com> Mozilla and the Rust community are pleased to announce version 0.3 of the Rust compiler and associated tools. Snapshot documentation and all the links in this email are available on our website: http://www.rust-lang.org Version 0.3 should still be considered an alpha release, suitable for early adopters and language enthusiasts. Please file bugs at http://github.com/mozilla/rust/issues This release is available as both a tarball and a windows installer: * http://dl.rust-lang.org/dist/rust-0.3.tar.gz http://dl.rust-lang.org/dist/rust-0.3.tar.gz.asc SHA256 (of .tar.gz): b34c895b9596abb6942d1688e6a5189b08b92e2507234779779c1af91e9ae84e * http://dl.rust-lang.org/dist/rust-0.3-install.exe http://dl.rust-lang.org/dist/rust-0.3-install.exe.asc SHA256 (of .exe): eb5578506f3df4e55b062223b0d31cfeb28023c0daa37dfcee502b5ce8d0dc80 Please note that the windows installer requires a somewhat specific version of MinGW and Msys to operate; recent builds of MinGW provide versions of GCC that are incompatible. Rust presently builds and tests with release 20110802, containing GCC 4.5. This can be installed separately from sourceforge: http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/mingw-get-inst-20110802/mingw-get-inst-20110802.exe/download Also note that in addition to this announcement we are now posting more detailed release notes on the wiki, as well as a longer-term roadmap. We hope these documents serve as helpful guides to evaluating the state of the project: https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes https://github.com/mozilla/rust/wiki/Note-development-roadmap Thanks to everybody who has contributed[1]. Regards, The Rust Team Version 0.3 (July 2012) ------------------------ * ~1900 changes, numerous bugfixes * New coding conveniences * Integer-literal suffix inference * Per-item control over warnings, errors * #[cfg(windows)] and #[cfg(unix)] attributes * Documentation comments * More compact closure syntax * 'do' expressions for treating higher-order functions as control structures * *-patterns (wildcard extended to all constructor fields) * Semantic cleanup * Name resolution pass and exhaustiveness checker rewritten * Region pointers and borrow checking supersede alias analysis * Init-ness checking is now provided by a region-based liveness pass instead of the typestate pass; same for last-use analysis * Extensive work on region pointers * Experimental new language features * Slices and fixed-size, interior-allocated vectors * #!-comments for lang versioning, shell execution * Destructors and iface implementation for classes; type-parameterized classes and class methods * 'const' type kind for types that can be used to implement shared-memory concurrency patterns * Type reflection * Removal of various obsolete features * Keywords: 'be', 'prove', 'syntax', 'note', 'mutable', 'bind', 'crust', 'native' (now 'extern'), 'cont' (now 'again') * Constructs: do-while loops ('do' repurposed), fn binding, resources (replaced by destructors) * Compiler reorganization * Syntax-layer of compiler split into separate crate * Clang (from LLVM project) integrated into build * Typechecker split into sub-modules * New library code * New time functions * Extension methods for many built-in types * Arc: atomic-refcount read-only / exclusive-use shared cells * Par: parallel map and search routines * Extensive work on libuv interface * Much vector code moved to libraries * Syntax extensions: #line, #col, #file, #mod, #stringify, #include, #include_str, #include_bin * Tool improvements * Cargo automatically resolves dependencies [1] Contributors to Rust 0.3: Alexander Stavonin Arkaitz Jimenez Armin Ronacher Ben Blum Ben Striegel Benjamin Herr Benjamin Kircher Brian Anderson Eric Holk Erick Tryzelaar Evan McClanahan Gareth Daniel Smith Glenn Willen Grahame Bowland Graydon Hoare Haitao Li Jeff Olson Jesse Ruderman Jon Morton Jonathan Sternberg Josh Matthews Joshua Wise Jyun-Yan You Kevin Cantu Lindsey Kuper Margaret Meyerhofer Marijn Haverbeke Michael Sullivan Niko Matsakis Patrick Walton Paul Stansifer Ryan Scheel Ted Horst Tim Chevalier Tycho Sci Zack Corr From banderson at mozilla.com Thu Jul 12 16:30:25 2012 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 12 Jul 2012 16:30:25 -0700 Subject: [rust-dev] Rust 0.3 released In-Reply-To: <4FFF595F.5030708@mozilla.com> References: <4FFF595F.5030708@mozilla.com> Message-ID: <4FFF5E11.7010205@mozilla.com> On 07/12/2012 04:10 PM, Graydon Hoare wrote: > Mozilla and the Rust community are pleased to announce version 0.3 of > the Rust compiler and associated tools. Congrats and thanks to all! From catamorphism at gmail.com Thu Jul 12 19:42:09 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Thu, 12 Jul 2012 19:42:09 -0700 Subject: [rust-dev] Pushing to incoming (for those who have commit access) Message-ID: Hello, This message is directed at people who have commit access and push directly to the main Rust github repo. The rest of you may ignore it. Over the last few days, there has been more breakage than usual on the incoming branch. The idea of incoming is that you can push changes without having to push to try first and wait for the bots to cycle. However, it's still considerate to run "make check" on your local machine before pushing to incoming. I've had to revert several patches (from several different people, so I'm not pointing fingers at anyone) and wait for repeated builds on *my* machine in order to push changes that I've had ready to go (other than rebasing) for over a day. It's more courteous if you at least test your code on your own machine. It's okay to push, see that something fails on a platform you don't use, and then back it out or fix it promptly; but when a particular commit causes all platforms to fail, it's hard to see why that made it into the repository to begin with. It's easier for each person to be responsible for running make check than for every person to potentially have to untangle a mess of commits from everybody else before making a small amount of progress. Let's all try to be mindful of the happiness and productivity of everyone else on the team :-) Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From zackcorr95 at gmail.com Thu Jul 12 20:26:33 2012 From: zackcorr95 at gmail.com (Zack Corr) Date: Fri, 13 Jul 2012 13:26:33 +1000 Subject: [rust-dev] Release candidates In-Reply-To: References: <4FFE3CB1.4070002@mozilla.com> Message-ID: On Fri, Jul 13, 2012 at 2:44 AM, David Brown wrote: > > On x86_64 Arch Linux, I get the error log below. Interestingly, if I > just type make again, it builds what appears to be a perfectly > functional rustc. Arch Linux uses GCC 4.7.* currently which fails with Rust's version of LLVM on x86_64 (x86 works fine) for some reason, I mentioned this on #2641. I too got it to work on my x86_64 Arch Linux VPS by building again after the dump came up. It's probably the same as the issue on the latest MinGW. >From what I could find from the issue described on the LLVM bug trackerand the Redhat bug tracker , adding `-fno-tree-pre` to the GCC commands allows it to be built and this issue is supposedly fixed in the latest LLVM. But apparently Rust's LLVM is already merged with 3.1, so I have no clue why it still fails (those issues could be different to the issue compiling Rust). -------------- next part -------------- An HTML attachment was scrubbed... URL: From sebastian.sylvan at gmail.com Thu Jul 12 23:41:47 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Thu, 12 Jul 2012 23:41:47 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax Message-ID: Hi Rust team! First of all, congratulations on the 0.3 release! I have a bikeshed proposal to selectively simplify Rust's syntax in a way that has the side benefit of applying "negative syntactic pressure" on expensive constructs. It boils down to this: remove all special syntax for heap allocations and heap pointers. Keep special syntax for borrowed pointers, keep special syntax for fixed size vectors. E.g. a heap pointer might be ptr. Allocating a block of uninitialized memory of type T might be heap_alloc(), with the normal literals used to initialize it. Now, this sounds a bit crazy, and I'm pretty sure it won't be adopted, but I'd appreciate it if you gave it a moment's serious consideration and thought about what the impact would really be. I don't think it would cost as much as you might initially think (modern C++ does essentially this with all the shared_ptr etc., and many of the actual allocation calls are hidden behind constructor functions anyway) and there are strong wins. The two main benefits would be: 1. Reduce the complexity of the syntax. In particular, reduce the amount of "special symbols". You've all heard jokes about Perl looking like line-noise, I'm sure. Reducing the amount of special characters you need to know about before understanding code is a win. Getting rid of some of the symbols and treating those types in a more regular way would also kill a lot of design problems like "what does a heap allocated fixed-sized vector literal look like"? Even more importantly, it would make it easier to see what a complicated type means because it would follow simple nesting rules that you already understand, because it's the same rules that apply to user-defined types. It would also make library-pointer types look like the "real thing" (e.g. arc). 2. Apply selective negative pressure to constructs which should be avoided if possible. IMO good syntax makes "preferable" constructs easy to write, and non-preferable constructs harder. Rust does a pretty good job here already (e.g. sharing mutable memory between tasks is suitably clunky). I personally think that heap allocations deserve to be in the "non-preferable" category, too. They add memory management overhead (GC/refcounting). They reduce locality. They add waste (header words, the pointer itself, maybe ref counts, etc.). They increase fragmentation. I believe controlling allocations will be essential to good performance in the future, as heap sizes grow massive (esp. for GC which is O(live_objects)). Heap allocations are absolutely essential sometimes, of course, but it's preferable by far to try to store the data on the stack or interior to the owning data structure, or in a big memory pool, and use borrowed pointers to access it indirectly - only resort to heap pointers if there is no other option. This is also why I think the *only* syntactically preferred pointer should be the borrowed pointer. IMO, Rust makes it far too easy to allocate memory on various heaps - just add a little sigil and you're done. C makes you appreciate the implications of what you're about to do when you type "malloc". Anyway, as I said, I don't think this will gain much traction, but it's one of those small niggles that I would do differently if I was designing the language, so I thought I'd float it for consideration. Thanks for your time! -- Sebastian Sylvan From mail at shomodj.com Fri Jul 13 05:52:34 2012 From: mail at shomodj.com (Boris Shomodjvarac) Date: Fri, 13 Jul 2012 14:52:34 +0200 Subject: [rust-dev] Release candidates In-Reply-To: References: <4FFE3CB1.4070002@mozilla.com> Message-ID: <50001A12.6020009@shomodj.com> On 13/07/12 05:26, Zack Corr wrote: > On Fri, Jul 13, 2012 at 2:44 AM, David Brown > wrote: > > On x86_64 Arch Linux, I get the error log below. Interestingly, if I > just type make again, it builds what appears to be a perfectly > functional rustc. > > > Arch Linux uses GCC 4.7.* currently which fails with Rust's version of > LLVM on x86_64 (x86 works fine) for some reason, I mentioned this on > #2641 . I too got it to > work on my x86_64 Arch Linux VPS by building again after the dump came > up. It's probably the same as the issue on the latest MinGW. > > From what I could find from the issue described on the LLVM bug tracker > and the Redhat bug tracker > , adding > `-fno-tree-pre` to the GCC commands allows it to be built and this issue > is supposedly fixed in the latest LLVM. But apparently Rust's LLVM is > already merged with 3.1, so I have no clue why it still fails (those > issues could be different to the issue compiling Rust). Thx for the info. I just pushed 0.3 to AUR, at the moment I don't know how to fix the build bug, so I added "make || make" to the build script. You can install rust on archlinux using "yaourt -S rust" -- Understanding recursion is really easy, all you have to do is understand recursion. /Joe From graydon at mozilla.com Fri Jul 13 08:51:03 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 13 Jul 2012 08:51:03 -0700 Subject: [rust-dev] Pushing to incoming (for those who have commit access) In-Reply-To: References: Message-ID: <500043E7.1080903@mozilla.com> On 12/07/2012 7:42 PM, Tim Chevalier wrote: > It's easier for each person to be responsible for running make check > than for every person to potentially have to untangle a mess of > commits from everybody else before making a small amount of progress. Agreed. With the exception of Extenuating Circumstances (eg. trying to get a very specific git-history node pushed w/o rebasing) I suggest the following fire-and-forget command: git pull --rebase && make check && git push origin incoming Put it in a while loop if need be. If you're finding that "one of these running" backs up your work on "other changes that depend on it", you can also make 2 (or 3) git workspaces, each of which is set up to know about the others (rust1, rust2, rust3) and switch between them as one or another is cycling[1]. Final note: this state of affairs is temporary. There _will_ (eventually) be build automation that lets you more or less just submit a random git rev to an automated process that sequences the cheap-tests, rebasing, full-tests, perf measurements and final integration all for you. That day is not today though. I'm _just starting_ on the transition to buildbot today, and there are a lot of steps between here and there. -Graydon [1] Also salient: speeding up the test cycle. Anyone who feels like learning how our built-in profiler (and system profilers) works, you are free to corner me on IRC and have me walk you through it. Perf tuning is like bug-janitor duty. We all have to do it sometimes! From niko at alum.mit.edu Fri Jul 13 09:04:28 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 13 Jul 2012 09:04:28 -0700 Subject: [rust-dev] I would like to remove typestate. Message-ID: <5000470C.6060505@alum.mit.edu> Hello Rustics, Per recent discussions, I would very much like to remove code related to typestate. It seems that the current approach is not scaling up to real problems. There has been some discussion about alternative, lighterweight approaches. I am not opposed to such forward motion. However, the current code is holding me back from landing an improvement to region inference?and I have to choose now whether to refactor it or remove it. Given that we expect the system to change significantly and therefore that the current code will not be especially useful, I would prefer to remove it. In particular the problem centers around the checking and treatment of function preconditions. These are not currently represented as expressions but rather a special, more limited predicate form. They don't have node ids. Type checking then synthesizes expressions and creates node ids. The region code then gets confused because it relies on node ids as names for scopes and other things, and these synthesized node ids don't appear in the AST nor in the various tables based on the AST (they are, after all, synthesized). As I said, there are various ways to repair this situation, but given that the code is on life support, I'd rather not expend energy fixing it. My plan for removal would be to convert all remaining function preconditions into assertions. Last time I discussed this on IRC, Graydon objected I think because he was concerned that there were checks that were being relied upon but which would not be lost. I am not sure if converting existing checks into assertions assuages those concerns. Niko From pwalton at mozilla.com Fri Jul 13 09:20:23 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 13 Jul 2012 09:20:23 -0700 Subject: [rust-dev] I would like to remove typestate. In-Reply-To: <5000470C.6060505@alum.mit.edu> References: <5000470C.6060505@alum.mit.edu> Message-ID: <50004AC7.6020804@mozilla.com> On 07/13/2012 09:04 AM, Niko Matsakis wrote: > Hello Rustics, > > Per recent discussions, I would very much like to remove code related to > typestate. It seems that the current approach is not scaling up to real > problems. There has been some discussion about alternative, > lighterweight approaches. I am not opposed to such forward motion. I agree. I think that a design-by-contract system, which I'm not opposed to, will not share any code with the existing typestate system, so having that code around is not buying us anything. > As I said, there are various ways to repair this situation, but given > that the code is on life support, I'd rather not expend energy fixing > it. My plan for removal would be to convert all remaining function > preconditions into assertions. Last time I discussed this on IRC, > Graydon objected I think because he was concerned that there were > checks that were being relied upon but which would not be lost. I am > not sure if converting existing checks into assertions assuages those > concerns. What function preconditions remain? My understanding was that there weren't any in the Rust compiler and standard libraries... Patrick From niko at alum.mit.edu Fri Jul 13 09:47:53 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 13 Jul 2012 09:47:53 -0700 Subject: [rust-dev] I would like to remove typestate. In-Reply-To: <50004AC7.6020804@mozilla.com> References: <5000470C.6060505@alum.mit.edu> <50004AC7.6020804@mozilla.com> Message-ID: <50005139.30401@alum.mit.edu> On 7/13/12 9:20 AM, Patrick Walton wrote: > What function preconditions remain? My understanding was that there > weren't any in the Rust compiler and standard libraries... I think the only ones that remain are two in core::result and some in tests. There may be a few more here or there. Niko From bruant.d at gmail.com Fri Jul 13 11:58:40 2012 From: bruant.d at gmail.com (David Bruant) Date: Fri, 13 Jul 2012 20:58:40 +0200 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: <4FFCD144.9030001@mozilla.com> References: <4FFC7EF4.4070803@gmail.com> <4FFCD144.9030001@mozilla.com> Message-ID: <50006FE0.7080205@gmail.com> Le 11/07/2012 03:05, Brian Anderson a ?crit : > On 07/10/2012 12:13 PM, David Bruant wrote: >> (...) > Tasks do have a memory cost, but it is theoretically quite low. Rust > tasks on linux currently have somewhere around 4K of overhead, and > that's around 3K more than we would like and think is possible. Most > of that is dedicated to the call stack, and there are a lot of > potential future optimizations to minimize the cost of creating a task > (by e.g. reusing them). I haven't implemented a JavaScript event loop, but for comparison, that's more or less a list where each element is a function with some arguments. Very likely less than 1k (but with certainly other downsides) > The intent is that you should not have to think about whether using a > task is too expensive, because it is cheap. > I'm not familiar with how the JavaScript event loop works but I > imagine that it has similar responsibilities to the Rust scheduler. The idea is that a JavaScript "processing unit" (sorry, I don't know the correct term for this) has a stack and a message queue (the list I mentionned above). Each message is a function and some arguments. This function is called and when the call (and the nested ones) are complete, the next message is processed. There is no preemption. (there are some weird not-very-standards cases in browsers that break that rule). The message queue would be the equivalent of the Rust scheduler. I realized after posting my message that goroutines and Rust tasks could actually be implemented with a message queue (I'm not asking for that, I just realized it) with the difference that if some code gets stuck in an infinite loop, everything else is blocked and that may not be a good thing for a system language. I'm not sure. Maybe "some" preemption and the ability to kill a message (or the message being processed) could compensate. > Instead of calling callbacks in response to events though the Rust > scheduler resumes execution of tasks. I've been thinking about this particular point and about my experience with node.js. Node.js has been critized a lot for not enabling parallelism by defaut. By default, your code runs in one system process (it's possible that some functions use several system threads under the hood, but you can't do that in JavaScript code), but you can fork/spawn other processes. There is also a way to know the number of cpus in your machine http://nodejs.org/api/os.html#os_os_cpus My experience is that it feels very right to spawn as many processes than you have CPUs (in case your program has a need for such a thing). In that case, you're not leaving some CPUs unused, but at the same time, you don't have a lot of processes/threads that you hardware can't run and that cost memory and scheduling. >From what I understand, this level of control cannot be achieved with goroutines and Rust tasks. The only primitive means "create a new concurrency unit and let the system figure it out". The downside of that is that the Rust runtime need to create a lot of stacks and do some scheduling itself. It sounds like it costs more than what can be done in the Node.js model. I don't have the perfect solution here, but there is certainly a middleground to be found. > >> (...) >> >> So I have several questions regarding Rust: >> * Is synchronous blocking possible? > > I don't understand the term 'synchronous blocking' (as opposed to just > 'blocking'). It's the same thing. I use both terms interchangeably. Sorry for the confusion. > Receiving a value from a Rust port does block a task. Sending on a > channel does not (whereas Go channels do block on send). We consider > channels to be asynchronous, based on the sending behavior (vs. Go's > synchronous channels). > >> * How does Rust deal with concurrent tasks synchronization? > > Channels are the primary synchronization primitive in Rust. > >> * How would you write the above example in Rust? > > I would basically write it like the Go example. If it didn't have to > also wait for the timeout then I would instead use a vector of futures. I would use promises (equivalent of futures) as well. Is there a future/promise library in Rust? > Here is that Go code translated to current Rust. > > (...) Thanks for this example :-) >> * Do you think it's satisfying in terms of expressiveness? > No, but not for the reasons you suggest. Rust's split between ports > and channels cause a lot of boilerplate, and the lack on an N-ary > select function or control structure is a big omission. Rust's > libraries in general need to be designed better. Is it shared by the Rust community? How would you move forward from that situation? >> Rust is being used in the Servo project, itself aiming at building a web >> browser. We've seen in the Snappy effort (and some other before that) >> that encouraging asynchronisity is key in building responsive and >> efficient software, hence all my questions about Rust take on >> synchronisity. > > Here's an experiment. > > So if we were doing JavaScript-style concurrency in Rust we might write > > (...) > > This is fairly viable pattern in Rust because we have awesome unique > closures that can be safely sent across tasks. Putting the state into > a different task where you can mutate it involves more work than > JavaScript, but with the benefit that all this work will happen in > parallel. I removed the code, but that's all interesting (and it helps me understanding Rust better) and promising indeed, especially the paralellisation part. David From bruant.d at gmail.com Fri Jul 13 12:17:31 2012 From: bruant.d at gmail.com (David Bruant) Date: Fri, 13 Jul 2012 21:17:31 +0200 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: References: <4FFC7EF4.4070803@gmail.com> <4FFCD144.9030001@mozilla.com> Message-ID: <5000744B.70207@gmail.com> Le 11/07/2012 03:41, Sebastian Sylvan a ?crit : > On Tue, Jul 10, 2012 at 6:05 PM, Brian Anderson wrote: >> Tasks do have a memory cost, but it is theoretically quite low. Rust tasks >> on linux currently have somewhere around 4K of overhead, and that's around >> 3K more than we would like and think is possible. Most of that is dedicated >> to the call stack, and there are a lot of potential future optimizations to >> minimize the cost of creating a task (by e.g. reusing them). The intent is >> that you should not have to think about whether using a task is too >> expensive, because it is cheap. > It would be cool if tasks started out more like PPL/TBB/Cilk tasks and > transitioned into the current thread-like construct and allocated > stack space only if needed. That's probably a good step towards the middle ground I mentionned earlier. > I.e. the first time a task needs to yield > its underlying "worker thread" (because it's about to block) it would > go through the work of allocating a stack (and heap?) and copy its > state into it. This would make task-parallel type things very cheap > since in that scenario most tasks would just run to completion on the > worker thread's task (and heap?), while still allowing you to use the > same mechanism for longer running tasks. +1. The point is that there is a maximum number of processors (let's be honest, 2, 4 or 8 in current machines, maybe 16 soon, but we're not there yet), so spawing thousands of tasks and creating thousands of stacks that may need to be moved around and require scheduling is a clear waste of resources. Assigning concurrent tasks to the different processors (if things can run in parallel) with run-to-completion sounds more reasonable. And as you said if all the tasks being processed really take too long, then do some preemption and stack allocation to run a new task. > Tasks which have a clear > non-avoidable yield point in them could just allocate all this > up-front of course. Maybe this is a bit too magical and there should > just be a different task-like concept that maps better to > task-parallelism. What's a yield point? How do you create one in Rust? David From bruant.d at gmail.com Fri Jul 13 12:38:18 2012 From: bruant.d at gmail.com (David Bruant) Date: Fri, 13 Jul 2012 21:38:18 +0200 Subject: [rust-dev] Why the difference between functions and closures? Message-ID: <5000792A.5020609@gmail.com> Hi, Looking at the Rust documentation, I read: ---- Named functions, like those we've seen so far, may not refer to local variables decalared outside the function - they do not "close over their environment". For example you couldn't write the following: let foo = 10; fn bar() -> int { ret foo; // `bar` cannot refer to `foo` } Rust also supports closures, functions that can access variables in the enclosing scope. ---- I can't help but asking why can't named function close over their environment? In the case above, I see no harm in allowing the 'bar' function to access 'foo'. David From pwalton at mozilla.com Fri Jul 13 12:42:52 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 13 Jul 2012 12:42:52 -0700 Subject: [rust-dev] Why the difference between functions and closures? In-Reply-To: <5000792A.5020609@gmail.com> References: <5000792A.5020609@gmail.com> Message-ID: <50007A3C.8000202@mozilla.com> On 7/13/12 12:38 PM, David Bruant wrote: > I can't help but asking why can't named function close over their > environment? > In the case above, I see no harm in allowing the 'bar' function to > access 'foo'. Because named functions are always in scope (they're always mutually recursive), while locals are not. For example, these two are equivalent: fn f() { g(); fn g() { ... } } fn f() { fn g() { ... } g(); } But if we allowed items to close over variables, then that wouldn't be the case anymore. This cannot be allowed: fn f() { g(); let x = ...; fn g() { ... use x ... } } Because x has not yet been initialized. Yet the mutual recursion property is very useful; consider: fn f() { fn g() { ... h(); ... } fn h() { ... g(); ... } } If functions were not mutually recursive, you could not write this. Patrick From bruant.d at gmail.com Fri Jul 13 13:14:05 2012 From: bruant.d at gmail.com (David Bruant) Date: Fri, 13 Jul 2012 22:14:05 +0200 Subject: [rust-dev] Why the difference between functions and closures? In-Reply-To: <50007A3C.8000202@mozilla.com> References: <5000792A.5020609@gmail.com> <50007A3C.8000202@mozilla.com> Message-ID: <5000818D.30903@gmail.com> Le 13/07/2012 21:42, Patrick Walton a ?crit : > On 7/13/12 12:38 PM, David Bruant wrote: >> I can't help but asking why can't named function close over their >> environment? >> In the case above, I see no harm in allowing the 'bar' function to >> access 'foo'. > > Because named functions are always in scope (they're always mutually > recursive), while locals are not. For example, these two are equivalent: > fn f() { > g(); > fn g() { ... } > } > > fn f() { > fn g() { ... } > g(); > } > But if we allowed items to close over variables, then that wouldn't be > the case anymore. This cannot be allowed: > > fn f() { > g(); > let x = ...; > fn g() { ... use x ... } > } > > Because x has not yet been initialized. Tell me if I'm wrong, but it seems that a use-before-init can be detected statically at compile time. It wouldn't be the case for JavaScript, but I think it's feasible in Rust. Unless I'm missing something, named function could close over variables and the compiler could throw an error when a named function is being used in a use-before-init scenario. David From sully at msully.net Fri Jul 13 13:44:41 2012 From: sully at msully.net (Michael Sullivan) Date: Fri, 13 Jul 2012 13:44:41 -0700 Subject: [rust-dev] Thoughts on @-vector/generic-sequence creation interfaces Message-ID: rust currently has support for vectors allocated on the task-local heap (@[]s), but the support is essentially limited to creating @-vector literals and indexing into them. There is currently no other method of creating them. I've thought some about this, and I've collected my thoughts: * I want good, safe, interfaces for creating @-vectors. This is tricky, since @-vectors basically need to be immutable. They can't be resized if there might be more than one reference to them. * A believe that a common case for building @-vectors will be wanting to build up a vector that will then be immutable. * A common thing in other languages is to allocate an array with a fixed size that is either uninitialized or filled in with zeros/null-pointers. This doesn't work in rust, because we don't have null pointers. We could do this, but require a an initializing element. This works, but is somewhat irritating and requires that the elements be mutable. * A common idiom in rust code that builds up ~-vectors is to start with an empty vector and push elements onto the back. This seems like a fairly satisfying way to build up vectors, but can't directly work for @-vectors, which can't safely be updated in place. We could accomplish this by creating an "avec" - a @-vector equivalent to dvec that encapsulates the construction and can give back a @[] when done. We probably will want to do this, but I feel like having it as the only way of building @-vectors is somewhat unsatisfying, and it doesn't fit in well with my plans for generic sequence code, discussed below. So I think that "avec" should be one option for building @-vectors, but not the only one. * I don't want to have to duplicate basic sequence processing and producing code for different sequences; I think things like split, map, map2, filter, filter_map, concat, sep, unzip should all be written once and work for @[], ~[], dvec, avec, list, and dlist. It would also be super cool if the input and output sequences didn't always need to be the same: we ought to be able to map from a list to an @-vector. * I think that if we want to accomplish this by parameterizing over traits, we want some sort of static trait methods that we can call without already having an object that implements that trait. Otherwise, in order to generically create a new sequence, we need to already have a sequence of that type. * In order to create an interface that allows building up any of those sequence types, it needs to not depend on using some other wrapper type to manage the construction of it. My proposed solution to this is to use an imperative "push" based interface, but to use higher order functions to hide the vector under construction. @-vectors will be constructed with a `construct` function; `construct` takes as its argument a block that will build up the vector; `construct` will create an empty sequence under the hood, and call the block with a `push` closure that will push elements onto the hidden vector. When the block returns, `construct` will return the vector it has built up. The type, for @-vectors, would be: fn construct(build: fn(push: fn(+A))) -> self; An example of some code that could use it: // Some code that could use that, then: fn seq_range(uint lo, uint hi) -> @[uint] { do construct() |push| { for range(lo, hi) |i| { push(i); } } } The critical feature of this interface is that the actual vector is not exposed until after it has been constructed. The construct function will be implemented unsafely, but it is a safe interface. (If use of the vector needs to be interleaved with creation of it, then you probably need to use `avec`) One of the big advantages of this general interface is that it works well for lots of different types; this would work for basically any "sequence" type we have in rust. There are ways it can be extended, too, like having construct take a size hint. See https://gist.github.com/3101979, for some notes I wrote on my ideas about static trait methods. -sully From niko at alum.mit.edu Fri Jul 13 14:04:44 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 13 Jul 2012 14:04:44 -0700 Subject: [rust-dev] Why the difference between functions and closures? In-Reply-To: <5000818D.30903@gmail.com> References: <5000792A.5020609@gmail.com> <50007A3C.8000202@mozilla.com> <5000818D.30903@gmail.com> Message-ID: <50008D6C.7070609@alum.mit.edu> I think the situation is somewhat more complex than you suggest. First, heap-based closures like fn@ and fn~ copy values from the environment at the point of creation. This is particularly relevant for mutable variables. To allow for mutual recursion, we would need some sort of expression form that allows multiple functions to be declared simultaneously. This is not a bad idea, but nobody has proposed nor implemented a specific construct in this direction. In any case it is quite different from a nested bare fn, because there is a specific point of initialization vs bare functions that are always valid. For stack closures (i.e., closures that access the surrounding environment 'by reference', rather than copying values out), that issue is not relevant, but there are other issues. Essentially we must consider any free variables that are referenced by a stack closure to be "borrowed" for the duration of the closure. So it is important that we identify the point where the closure is created and the scope of the closure. What we don't want is something like this: fn foo() { let x = 10; // at point of creation, x is initialized let y = &fn() { ... use x ... }; send(x); // x is deinitialized y(); // references x, bad! } Of course, as the previous example suggests, we have to do this anyway once we generalize stack closures a bit so that they can be stored in variables and heap structures. So basically both issues are the same: if/when we permit named, mutually recursive closures, we will need to be careful about designating the point of creation for the closure and (in the case of stack closures) its lifetime. Niko On 7/13/12 1:14 PM, David Bruant wrote: > Le 13/07/2012 21:42, Patrick Walton a ?crit : >> On 7/13/12 12:38 PM, David Bruant wrote: >>> I can't help but asking why can't named function close over their >>> environment? >>> In the case above, I see no harm in allowing the 'bar' function to >>> access 'foo'. >> Because named functions are always in scope (they're always mutually >> recursive), while locals are not. For example, these two are equivalent: >> fn f() { >> g(); >> fn g() { ... } >> } >> >> fn f() { >> fn g() { ... } >> g(); >> } >> But if we allowed items to close over variables, then that wouldn't be >> the case anymore. This cannot be allowed: >> >> fn f() { >> g(); >> let x = ...; >> fn g() { ... use x ... } >> } >> >> Because x has not yet been initialized. > Tell me if I'm wrong, but it seems that a use-before-init can be > detected statically at compile time. It wouldn't be the case for > JavaScript, but I think it's feasible in Rust. > Unless I'm missing something, named function could close over variables > and the compiler could throw an error when a named function is being > used in a use-before-init scenario. > > David > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From banderson at mozilla.com Fri Jul 13 15:34:30 2012 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 13 Jul 2012 15:34:30 -0700 Subject: [rust-dev] Concurrency and synchronous blocking In-Reply-To: <50006FE0.7080205@gmail.com> References: <4FFC7EF4.4070803@gmail.com> <4FFCD144.9030001@mozilla.com> <50006FE0.7080205@gmail.com> Message-ID: <5000A276.3050209@mozilla.com> On 07/13/2012 11:58 AM, David Bruant wrote: > Le 11/07/2012 03:05, Brian Anderson a ?crit : >> On 07/10/2012 12:13 PM, David Bruant wrote: >>> (...) >> Tasks do have a memory cost, but it is theoretically quite low. Rust >> tasks on linux currently have somewhere around 4K of overhead, and >> that's around 3K more than we would like and think is possible. Most >> of that is dedicated to the call stack, and there are a lot of >> potential future optimizations to minimize the cost of creating a task >> (by e.g. reusing them). > I haven't implemented a JavaScript event loop, but for comparison, > that's more or less a list where each element is a function with some > arguments. Very likely less than 1k (but with certainly other downsides) > >> The intent is that you should not have to think about whether using a >> task is too expensive, because it is cheap. >> I'm not familiar with how the JavaScript event loop works but I >> imagine that it has similar responsibilities to the Rust scheduler. > The idea is that a JavaScript "processing unit" (sorry, I don't know the > correct term for this) has a stack and a message queue (the list I > mentionned above). Each message is a function and some arguments. This > function is called and when the call (and the nested ones) are complete, > the next message is processed. There is no preemption. (there are some > weird not-very-standards cases in browsers that break that rule). > The message queue would be the equivalent of the Rust scheduler. I > realized after posting my message that goroutines and Rust tasks could > actually be implemented with a message queue (I'm not asking for that, I > just realized it) with the difference that if some code gets stuck in an > infinite loop, everything else is blocked and that may not be a good > thing for a system language. I'm not sure. Maybe "some" preemption and > the ability to kill a message (or the message being processed) could > compensate. To be clear, Rust's scheduling is cooperative, so a badly-behaving Rust task can block and prevent others from making progress. This is mostly an issue to be aware of for native bindings. > >> Instead of calling callbacks in response to events though the Rust >> scheduler resumes execution of tasks. > I've been thinking about this particular point and about my experience > with node.js. > Node.js has been critized a lot for not enabling parallelism by defaut. > By default, your code runs in one system process (it's possible that > some functions use several system threads under the hood, but you can't > do that in JavaScript code), but you can fork/spawn other processes. > There is also a way to know the number of cpus in your machine > http://nodejs.org/api/os.html#os_os_cpus > My experience is that it feels very right to spawn as many processes > than you have CPUs (in case your program has a need for such a thing). > In that case, you're not leaving some CPUs unused, but at the same time, > you don't have a lot of processes/threads that you hardware can't run > and that cost memory and scheduling. > From what I understand, this level of control cannot be achieved with > goroutines and Rust tasks. The only primitive means "create a new > concurrency unit and let the system figure it out". The downside of that > is that the Rust runtime need to create a lot of stacks and do some > scheduling itself. It sounds like it costs more than what can be done in > the Node.js model. > I don't have the perfect solution here, but there is certainly a > middleground to be found. Rust does offer some more control than that. The runtime supports running multiple schedulers simultaneously - particularly so code that wants to truly block an OS thread (like libuv) can live in its own world. The scheduler that the main task (and any child tasks) runs in has by default the same number of threads as there are cores available. For more control you can create your own schedulers: let cores = get_num_cores(); // This functions doesn't exist yet for cores.times { do spawn_sched(single_threaded) { run_program() } } If run_program never spawns another task then they will effectively have their own OS thread. They will occasionally do yield checks and context switch back to the scheduler momentarily, but that context switch could conceivably be optimized out if there is only one task on the entire scheduler. > > >> >>> (...) >>> >>> So I have several questions regarding Rust: >>> * Is synchronous blocking possible? >> >> I don't understand the term 'synchronous blocking' (as opposed to just >> 'blocking'). > It's the same thing. I use both terms interchangeably. Sorry for the > confusion. > >> Receiving a value from a Rust port does block a task. Sending on a >> channel does not (whereas Go channels do block on send). We consider >> channels to be asynchronous, based on the sending behavior (vs. Go's >> synchronous channels). >> >>> * How does Rust deal with concurrent tasks synchronization? >> >> Channels are the primary synchronization primitive in Rust. >> >>> * How would you write the above example in Rust? >> >> I would basically write it like the Go example. If it didn't have to >> also wait for the timeout then I would instead use a vector of futures. > I would use promises (equivalent of futures) as well. Is there a > future/promise library in Rust? core::future exists, but could be better. In particular, futures are not sendable types, which severely limits how they can be composed. > >> Here is that Go code translated to current Rust. >> >> (...) > Thanks for this example :-) > >>> * Do you think it's satisfying in terms of expressiveness? >> No, but not for the reasons you suggest. Rust's split between ports >> and channels cause a lot of boilerplate, and the lack on an N-ary >> select function or control structure is a big omission. Rust's >> libraries in general need to be designed better. > Is it shared by the Rust community? How would you move forward from that > situation? I think that opinion is shared, but most Rust developers are waiting until the language settles down before focusing on libraries. As to the ergonomics of channels in Rust, I'm not sure what the solution is yet, but the existing channel implementation will likely be going away entirely. Eric Holk is working on a new primitive communication type called a 'pipe' that only does 1:1 communication, and can only send a single message. This alone is much more difficult to use that the current channels, but is also much faster. On top of that he is building channel contracts that define a protocol between two pipe endpoints that is enforced by the type system. Channel contracts additionally allow bounded protocols (ones that don't just send forever without receiving) to be implemented with fixed size buffers so that sending a message is never forced to allocate. There will be default implementations of common protocols. On top of all that I'm hoping that we define a new channel type that does N:M communication, is sendable, and doesn't require the port/channel distinction (like Go you can send and receive on the same object). For simple things you would probably just use a channel, but for performance you would use pipe protocols. -Brian From graydon at mozilla.com Fri Jul 13 16:45:51 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 13 Jul 2012 16:45:51 -0700 Subject: [rust-dev] I would like to remove typestate. In-Reply-To: <50005139.30401@alum.mit.edu> References: <5000470C.6060505@alum.mit.edu> <50004AC7.6020804@mozilla.com> <50005139.30401@alum.mit.edu> Message-ID: <5000B32F.50408@mozilla.com> On 12-07-13 9:47 AM, Niko Matsakis wrote: > On 7/13/12 9:20 AM, Patrick Walton wrote: >> What function preconditions remain? My understanding was that there >> weren't any in the Rust compiler and standard libraries... > > I think the only ones that remain are two in core::result and some in > tests. There may be a few more here or there. The code as it stands, it seems, is probably not doing anyone any favours, no. I want to try to figure out a way to support DBC-ish patterns in a way that works, but that feels to me like something the current code isn't likely to support. If you pull it, best to pull it from the manual and website too. No point advertising something unless we can provide it. -Graydon From graydon at mozilla.com Fri Jul 13 17:18:25 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 13 Jul 2012 17:18:25 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: References: Message-ID: <5000BAD1.4060002@mozilla.com> On 12-07-12 11:41 PM, Sebastian Sylvan wrote: > Hi Rust team! First of all, congratulations on the 0.3 release! Thanks. The whole team continues to impress me too, the amount of work this time around should not be understated (and not just churn; really thoughtful and high-quality refactorings, a lot of hard problems). > I have a bikeshed proposal to selectively simplify Rust's syntax in a > way that has the side benefit of applying "negative syntactic > pressure" on expensive constructs. It boils down to this: remove all > special syntax for heap allocations and heap pointers. Thus ~T becomes uniq, ~expr becomes uniq(expr), etc? > Allocating a block of > uninitialized memory of type T might be heap_alloc(), with the > normal literals used to initialize it. Note: we don't support allocating uninitialized memory. > Now, this sounds a bit crazy, and I'm pretty sure it won't be adopted, > but I'd appreciate it if you gave it a moment's serious consideration > and thought about what the impact would really be. I don't think it > would cost as much as you might initially think (modern C++ does > essentially this with all the shared_ptr etc., and many of the actual > allocation calls are hidden behind constructor functions anyway) and > there are strong wins. I agree that modern C++ does this, and it does relieve some syntactic pressure (slack which C++11 seems to have gleefully soaked up). I don't think that users having to write shared_ptr rather than @foo is quite so clearly a "strong win" in our case, though. > 1. Reduce the complexity of the syntax. In particular, reduce the > amount of "special symbols". You've all heard jokes about Perl looking > like line-noise, I'm sure. I think this is a bit unfair; perl isn't even a context-free grammar. I think we're in the same ballpark as Objective-C right now. And shrinking. > Reducing the amount of special characters > you need to know about before understanding code is a win. True, but it's in tension with conciseness / expressivity. I initially erred very much on the side of maintenance programmers in the design (verbosity and clarity over expressivity) and am gradually being dragged back towards the expressive side. This is one of numerous tensions in a language; almost nothing is a pure win/lose, all is tradeoffs. > Getting rid > of some of the symbols and treating those types in a more regular way > would also kill a lot of design problems like "what does a heap > allocated fixed-sized vector literal look like"? Unless you're planning on making our type parameters carry integer types -- danger! -- this proposal doesn't help there. > importantly, it would make it easier to see what a complicated type > means because it would follow simple nesting rules that you already > understand, because it's the same rules that apply to user-defined > types. It would also make library-pointer types look like the "real > thing" (e.g. arc). But they aren't. The compiler is doing a bunch of open-coding on those pointer types, including reasoning about the initialization-state of the pointee memory, enforcing kinds, generating visitors that walk through them, and pattern-matching on the structure. > 2. Apply selective negative pressure to constructs which should be > avoided if possible. Yeah. Again, this is in tension with "letting users write what they need to". Rust initially prohibited even _cyclic_ memory and made all private memory copy-on-write. Guess what was the first and most pressing request? Second-guessing users and telling them they don't want to do what they _do_ want to do is ... generally a losing game. @ and ~ are not beautiful, and surely if someone can avoid reaching for them I wager the noisiness and measurable performance cost is sufficient deterrence to make the user think twice. I might be wrong, but ... the largest single case of allocation is "", for example, and we _just_ started making it obvious that those allocate. (And we still have essentially _no_ code that emits static constants as read-only memory, aside from fixed-size and slice-strings, and integer constants. So ~"abc" actually hits the allocator every time, despite being a constant.) > preferred pointer should be the borrowed pointer. IMO, Rust makes it > far too easy to allocate memory on various heaps - just add a little > sigil and you're done. C makes you appreciate the implications of what > you're about to do when you type "malloc". Fair. It's true that we allocate too much presently. I believe a lot of this comes from a combination of incomplete constant optimization (see above), hiding the uniqueness of vectors and strings (no longer done as of 0.3), and not having had the requisite technologies at our disposal when writing the compiler, first-pass: our closures were weak, borrowed-pointers nonexistent, interior-vectors nonexistent, arenas nonexistent, etc. I would like to get some experience with using the new technology in earnest, before looking at blunter instruments as you're suggesting here. (Also: nobody's done the no-gc lint pass yet, but I fully intend to provide it. Might just do so idly now, it's quick work) > Anyway, as I said, I don't think this will gain much traction, but > it's one of those small niggles that I would do differently if I was > designing the language, so I thought I'd float it for consideration. Sure. I appreciate the concern, I just think the weight of evidence isn't _so_ clear that rust code "always" allocates too much, vs. the current code doing so. I think it'll take some time to see. Also there are a bunch of other factors at work, as I point out above (in terms of the compiler knowing all about these pointers). -Graydon From graydon at mozilla.com Fri Jul 13 18:02:39 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 13 Jul 2012 18:02:39 -0700 Subject: [rust-dev] Thoughts on @-vector/generic-sequence creation interfaces In-Reply-To: References: Message-ID: <5000C52F.8030307@mozilla.com> On 12-07-13 1:44 PM, Michael Sullivan wrote: > An example of some code that could use it: > // Some code that could use that, then: > fn seq_range(uint lo, uint hi) -> @[uint] { > do construct() |push| { > for range(lo, hi) |i| { > push(i); > } > } > } > > The critical feature of this interface is that the actual vector is > not exposed until after it has been constructed. The construct > function will be implemented unsafely, but it is a safe interface. (If > use of the vector needs to be interleaved with creation of it, then > you probably need to use `avec`) > > One of the big advantages of this general interface is that it works > well for lots of different types; this would work for basically any > "sequence" type we have in rust. There are ways it can be extended, > too, like having construct take a size hint. Yeah, I think the general shape of the interface is good. The size-unhinted version can (and perhaps should?) be layered on top of the size-hinted version; also I think you will want to pass the current index into the callback. (also: "construct"? hm, maybe build or alloc? init?) -Graydon From sebastian.sylvan at gmail.com Fri Jul 13 18:21:50 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Fri, 13 Jul 2012 18:21:50 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5000BAD1.4060002@mozilla.com> References: <5000BAD1.4060002@mozilla.com> Message-ID: On Fri, Jul 13, 2012 at 5:18 PM, Graydon Hoare wrote: > > Thus ~T becomes uniq, ~expr becomes uniq(expr), etc? > Yep. > >> Allocating a block of >> uninitialized memory of type T might be heap_alloc(), with the >> normal literals used to initialize it. > > > Note: we don't support allocating uninitialized memory. Sure, the heap_alloc could take the initial value as input and do whatever optimizations needed to make sure it never actually creates the literal on the stack just to copy it to the heap. >> Getting rid >> of some of the symbols and treating those types in a more regular way >> would also kill a lot of design problems like "what does a heap >> allocated fixed-sized vector literal look like"? > > > Unless you're planning on making our type parameters carry integer types -- > danger! -- this proposal doesn't help there. > Well vectors would retain their special syntax (fixed size arrays are pure goodness and should be syntactically preferred) so the size would be part of the vector type/literal. The point is that figuring out what a pointer to T looks like is easy (on both the type and constructor side), even if T is one of the special forms like vectors. It seems to me that you get into more head-aches when you need to figure out how to make multiple special forms of syntax interact nicely and without surprising people. > Yeah. Again, this is in tension with "letting users write what they need > to". Rust initially prohibited even _cyclic_ memory and made all private > memory copy-on-write. Guess what was the first and most pressing request? Sure, but as for allocations I think we have more experience about the benefits and dangers of making it pretty. Not necessarily in the way of having 100% analogous languages, but in the way of being able to look at languages that make heap allocation very common, and languages that make it a big deal. I agree with you that it may not be completely clear where Rust stands in this spectrum yet since it's sort of a psychological thing, but I think we can at least say that in general languages that make allocations ugly have done a better job at avoiding that particular performance pitfall in practice. Perhaps Rust's more robust support for interior data (compared to Lua or whatever) is enough, but if you can make allocations stick out even more while simultaneously simplifying the syntax then it may add up to being a good idea. Seb -- Sebastian Sylvan From bruant.d at gmail.com Sat Jul 14 04:12:28 2012 From: bruant.d at gmail.com (David Bruant) Date: Sat, 14 Jul 2012 13:12:28 +0200 Subject: [rust-dev] Traits proposal In-Reply-To: References: Message-ID: <5001541C.7070302@gmail.com> Hi, I'd like to bring a bit more of feedback. I've read Stateful Traits [1] and I was wondering how Rust intended to solve the issue mentionned in the paper related to statelessness: "However this simple model suffers from several limitations, in particular (i) trait reusability is impacted because the required interface is typically cluttered with uninteresting required accessors, (ii) client classes are forced to implement boilerplate glue code, (iii) the introduction of new state in a trait propagates required accessors to all client classes, (iv) public accessors break encapsulation of the client class." David [1] http://scg.unibe.ch/archive/papers/Berg07aStatefulTraits.pdf From stefan.plantikow at googlemail.com Sat Jul 14 04:39:56 2012 From: stefan.plantikow at googlemail.com (Stefan Plantikow) Date: Sat, 14 Jul 2012 13:39:56 +0200 Subject: [rust-dev] Traits proposal In-Reply-To: <5001541C.7070302@gmail.com> References: <5001541C.7070302@gmail.com> Message-ID: <928F82BF-FEA1-494E-918C-C232A5BF4A5D@googlemail.com> On 14 Jul 2012, at 13:12, David Bruant wrote: > Hi, > > I'd like to bring a bit more of feedback. I've read Stateful Traits > [1] > and I was wondering how Rust intended to solve the issue mentionned in > the paper related to statelessness: > "However this simple model suffers from several limitations, in > particular > (i) trait reusability is impacted because the required interface is > typically cluttered with uninteresting required accessors, > (ii) client classes are forced to implement boilerplate glue code, > (iii) the introduction of new state in a trait propagates required > accessors to all client classes, > (iv) public accessors break encapsulation of the client class." > Haven't read the paper but think such things can be circumvented with support for delegation quite nicely, somewhat similar to what go does. The idea is to have a syntax feature which allows to automatically redirect some calls to a member field. So instead of mixing in a trait with all state accessors one would delegate only the methods required by the interface type to a member field or a derived value. This would give a nice way to provide encapsulation and export only required interface calls without having to write all the boilerplate delegation methods. At some point I wrote a very rough syntax proposal for this in the Wiki but it's likely outdated now. If there would be interest for this, I'd try to come up with a new one. Basically what is needed is a way for specifying how to extract a value that implements an interface from self and some support for overwriting the derived methods and dealing with conflicts. One can also understand this as a mechanism for user-provided type conversion that is integrated with the type class system. Cheers, Stefan. From hatahet at gmail.com Sat Jul 14 05:04:10 2012 From: hatahet at gmail.com (Ziad Hatahet) Date: Sat, 14 Jul 2012 05:04:10 -0700 Subject: [rust-dev] Update download link on tutorial page Message-ID: Hi all, The link to the tarball and the CLI listing a few paragraphs down both point to version 0.2. They should be updated to the latest release :) Best, -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From stefan.plantikow at googlemail.com Sat Jul 14 05:05:22 2012 From: stefan.plantikow at googlemail.com (Stefan Plantikow) Date: Sat, 14 Jul 2012 14:05:22 +0200 Subject: [rust-dev] rust to JavaScript In-Reply-To: References: Message-ID: <49CE1AEC-7B2F-4DD3-80B2-F64AC2145BB8@googlemail.com> On 12 Jul 2012, at 1:40, Mic wrote: > Hello, > Any plans to allow rust to compile to JavaScript like dart > http://www.youtube.com/watch?v=YxogQGnMA9Y . > > I'd rather see a pluggable js/lisp/lua/.. interpreter that is able to handle arbitrary rust values once the reflection api matures to have a REPL for live inspection of running rust programs. Greets, Stefan. From niko at alum.mit.edu Sat Jul 14 18:32:33 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Sat, 14 Jul 2012 18:32:33 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: References: Message-ID: <50021DB1.4020709@alum.mit.edu> This is an interesting idea. I guess the key question is just *how* negative heap allocations are. I think you are likely overstating the case, or perhaps underestimating the extent to which the price of heap allocations can be ameliorated by optimizing the allocator. But I don't claim to have extensive data on this point. But I have another concern as well. Regardless of how expensive heap allocations are, they are likely to be frequently *necessary*. Much as I love borrowed pointers, they are only suitable for things whose lifetimes follow a stack discipline. Moreover, without a more complex type system, there will be cases that do follow a stack discipline but for which borrowed pointers are not complex enough to express. Given that, forcing uses to write `ptr` where in any other modern language they would probably just write `Foo` doesn't seem like it's going to win us any friends. `@Foo` seems a reasonable compromise to me. I guess my fears boil down to this: I am already concerned about Rust feeling too heavy-weight and ponderous. I like that Rust exposes things like the program stack and gives a fair amount of room for micro-optimization while still retaining type safety, but if that ends up making the language feel less convenient than e.g. Java it may not be worth it, given the speed/memory capabilities of today's computers (and tomorrow's). So I'm hesitant to make changes that tax users of GC more than we already do. Niko On 7/12/12 11:41 PM, Sebastian Sylvan wrote: > Hi Rust team! First of all, congratulations on the 0.3 release! > > I have a bikeshed proposal to selectively simplify Rust's syntax in a > way that has the side benefit of applying "negative syntactic > pressure" on expensive constructs. It boils down to this: remove all > special syntax for heap allocations and heap pointers. Keep special > syntax for borrowed pointers, keep special syntax for fixed size > vectors. E.g. a heap pointer might be ptr. Allocating a block of > uninitialized memory of type T might be heap_alloc(), with the > normal literals used to initialize it. > > Now, this sounds a bit crazy, and I'm pretty sure it won't be adopted, > but I'd appreciate it if you gave it a moment's serious consideration > and thought about what the impact would really be. I don't think it > would cost as much as you might initially think (modern C++ does > essentially this with all the shared_ptr etc., and many of the actual > allocation calls are hidden behind constructor functions anyway) and > there are strong wins. > > The two main benefits would be: > > 1. Reduce the complexity of the syntax. In particular, reduce the > amount of "special symbols". You've all heard jokes about Perl looking > like line-noise, I'm sure. Reducing the amount of special characters > you need to know about before understanding code is a win. Getting rid > of some of the symbols and treating those types in a more regular way > would also kill a lot of design problems like "what does a heap > allocated fixed-sized vector literal look like"? Even more > importantly, it would make it easier to see what a complicated type > means because it would follow simple nesting rules that you already > understand, because it's the same rules that apply to user-defined > types. It would also make library-pointer types look like the "real > thing" (e.g. arc). > > 2. Apply selective negative pressure to constructs which should be > avoided if possible. IMO good syntax makes "preferable" constructs > easy to write, and non-preferable constructs harder. Rust does a > pretty good job here already (e.g. sharing mutable memory between > tasks is suitably clunky). I personally think that heap allocations > deserve to be in the "non-preferable" category, too. They add memory > management overhead (GC/refcounting). They reduce locality. They add > waste (header words, the pointer itself, maybe ref counts, etc.). They > increase fragmentation. I believe controlling allocations will be > essential to good performance in the future, as heap sizes grow > massive (esp. for GC which is O(live_objects)). Heap allocations are > absolutely essential sometimes, of course, but it's preferable by far > to try to store the data on the stack or interior to the owning data > structure, or in a big memory pool, and use borrowed pointers to > access it indirectly - only resort to heap pointers if there is no > other option. This is also why I think the *only* syntactically > preferred pointer should be the borrowed pointer. IMO, Rust makes it > far too easy to allocate memory on various heaps - just add a little > sigil and you're done. C makes you appreciate the implications of what > you're about to do when you type "malloc". > > Anyway, as I said, I don't think this will gain much traction, but > it's one of those small niggles that I would do differently if I was > designing the language, so I thought I'd float it for consideration. > Thanks for your time! > From pwalton at mozilla.com Sun Jul 15 17:15:18 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 15 Jul 2012 17:15:18 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types Message-ID: <50035D16.4030001@mozilla.com> Currently, we've gone back on the concept of dynamically-sized types. I think that, while there were very good reasons for going back on them in the implementation (namely, that we want a pointer to a vector to be a fat pointer--one with start and length--internally, among other obscure reasons relating to region bounds for functions), they still possess an appealing amount of simplicity when describing the language to newcomers. One of the things that immediately strikes most as complex about Rust is the large number of pointer types, vector types, and function types. This has not really changed with the current proposals for vector reform and function reform. However, the way we present it and think about it *can* change, in order to conceptually simplify the language. Here is what I propose: 1. We have three (or four, if you count unsafe) types of pointers. @T is a garbage-collected, task-local pointer, like shared_ptr; it can be used anywhere within a single task. ~T is a unique pointer to the exchange heap; it can be sent between tasks. &T is a safe reference (borrowed) pointer to any allocation. 2. Function types, trait types, and vector types without a fixed size are *second-class* types. Because their sizes aren't known to the compiler, they can't be referred to in isolation; they can only be referred to with a pointer. Any of the three pointer types will do. Note that this rule is quite similar to C++; note the error that occurs when you try to compile this program: int foo(int x[]) { int y[]; y = x; return y[0]; } $ g++ -o test test.cpp test.cpp: In function ?int foo(int*)?: test.cpp:2:8: error: storage size of ?y? isn?t known The only difference is that we prevent the programmer from referring to the dynamically-sized type *at all* except through a pointer. In C++ it is allowed in some situations, but automatic conversions happen (from T[] to T *) to give it meaning. The Rust rule is simpler. 3. A pointer to a vector can be indexed, just like in C++. Unlike C++, bounds checks are performed and the task fails if an out-of-bounds access is attempted. 4. Again like C++, a pointer can be taken to any element of a vector, and this pointer can be indexed just like a pointer to the head of the vector. Because a pointer to just one element (which can't be indexed) and a pointer to a subrange of the vector (which can be) have different types, we need a special method for creating a pointer to a subrange of a vector. This method is called "slice": let x: &[int] = [ 1, 2, 3, 4, 5 ].slice(3, 5); printf!("%d %d", x[0], x[1]); // prints 4 5 In this way, we can present Rust as a language with three basic pointer types, one kind of vector type, one kind of function type (modulo unsafe, pure, one-shot if we want to add it, etc), and one kind of trait type. I think this could drastically decrease the perceived complexity of the language for newcomers without having to change anything in the language itself. Thoughts? Patrick From graydon at mozilla.com Sun Jul 15 17:22:43 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Sun, 15 Jul 2012 17:22:43 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <50035D16.4030001@mozilla.com> References: <50035D16.4030001@mozilla.com> Message-ID: <50035ED3.6090300@mozilla.com> On 15/07/2012 5:15 PM, Patrick Walton wrote: > In this way, we can present Rust as a language with three basic pointer > types, one kind of vector type, one kind of function type (modulo > unsafe, pure, one-shot if we want to add it, etc), and one kind of trait > type. I think this could drastically decrease the perceived complexity > of the language for newcomers without having to change anything in the > language itself. > > Thoughts? You're just talking about documentation and nomenclature when you say "presenting", yes? I mean, this sounds exactly like the semantics we wound up with, just an adjustment to the way we talk about them. I'm happy to try to consolidate terminology, just trying to make sure I'm reading your email right. -Graydon From pwalton at mozilla.com Sun Jul 15 17:31:42 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 15 Jul 2012 17:31:42 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <50035ED3.6090300@mozilla.com> References: <50035D16.4030001@mozilla.com> <50035ED3.6090300@mozilla.com> Message-ID: <500360EE.4090907@mozilla.com> On 07/15/2012 05:22 PM, Graydon Hoare wrote: > You're just talking about documentation and nomenclature when you say > "presenting", yes? I mean, this sounds exactly like the semantics we > wound up with, just an adjustment to the way we talk about them. I'm > happy to try to consolidate terminology, just trying to make sure I'm > reading your email right. Yes. It's purely how we document things and talk about them; no language changes. Patrick From gwillen at nerdnet.org Sun Jul 15 18:26:20 2012 From: gwillen at nerdnet.org (gwillen@gmail.com) Date: Sun, 15 Jul 2012 21:26:20 -0400 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <500360EE.4090907@mozilla.com> References: <50035D16.4030001@mozilla.com> <50035ED3.6090300@mozilla.com> <500360EE.4090907@mozilla.com> Message-ID: <1bfdd2fa-a46f-4911-903b-7f1d62c193a2@email.android.com> As a corner case, for purposes of impls, will it still be the case that e.g. an impl for @T will not match a type like @[U], as I believe is the case now? That, and any similar quirks in the language, will be a kink in this presentation (which I am otherwise quite fond of.) Glenn Patrick Walton wrote: On 07/15/2012 05:22 PM, Graydon Hoare wrote: > You're just talking about documentation and nomenclature when you say > "presenting", yes? I mean, this sounds exactly like the semantics we > wound up with, just an adjustment to the way we talk about them. I'm > happy to try to consolidate terminology, just trying to make sure I'm > reading your email right. Yes. It's purely how we document things and talk about them; no language changes. Patrick _____________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev !DSPAM:50035bc624011243112093! -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sun Jul 15 18:48:19 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 15 Jul 2012 18:48:19 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <1bfdd2fa-a46f-4911-903b-7f1d62c193a2@email.android.com> References: <50035D16.4030001@mozilla.com> <50035ED3.6090300@mozilla.com> <500360EE.4090907@mozilla.com> <1bfdd2fa-a46f-4911-903b-7f1d62c193a2@email.android.com> Message-ID: <500372E3.7030408@mozilla.com> On 07/15/2012 06:26 PM, gwillen at gmail.com wrote: > As a corner case, for purposes of impls, will it still be the case that > e.g. an impl for @T will not match a type like @[U], as I believe is the > case now? That, and any similar quirks in the language, will be a kink > in this presentation (which I am otherwise quite fond of.) Right. That's because all type parameters have to match against first-class types. If @T could match against @[U], then you'd be able to name a second-class type (namely [U]) in isolation via the parameter T, making it not second-class anymore. Patrick From gwillen at nerdnet.org Sun Jul 15 18:55:37 2012 From: gwillen at nerdnet.org (gwillen@gmail.com) Date: Sun, 15 Jul 2012 21:55:37 -0400 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <500372E3.7030408@mozilla.com> References: <50035D16.4030001@mozilla.com> <50035ED3.6090300@mozilla.com> <500360EE.4090907@mozilla.com> <1bfdd2fa-a46f-4911-903b-7f1d62c193a2@email.android.com> <500372E3.7030408@mozilla.com> Message-ID: <8e5b4c6a-91a1-4532-9260-7cc82970d74a@email.android.com> Ohhh, I see. Still, it's pretty counterintuitive if vectors are being presented as _though_ they are first class (which I do like, due to reducing the number of entities that have to be explained.) Not sure what a good alternative would be, but this did nail me once before I figured it out. Glenn Patrick Walton wrote: On 07/15/2012 06:26 PM, gwillen at gmail.com wrote: > As a corner case, for purposes of impls, will it still be the case that > e.g. an impl for @T will not match a type like @[U], as I believe is the > case now? That, and any similar quirks in the language, will be a kink > in this presentation (which I am otherwise quite fond of.) Right. That's because all type parameters have to match against first-class types. If @T could match against @[U], then you'd be able to name a second-class type (namely [U]) in isolation via the parameter T, making it not second-class anymore. Patrick !DSPAM:50036db4137201336712104! -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sun Jul 15 18:57:45 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 15 Jul 2012 18:57:45 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <8e5b4c6a-91a1-4532-9260-7cc82970d74a@email.android.com> References: <50035D16.4030001@mozilla.com> <50035ED3.6090300@mozilla.com> <500360EE.4090907@mozilla.com> <1bfdd2fa-a46f-4911-903b-7f1d62c193a2@email.android.com> <500372E3.7030408@mozilla.com> <8e5b4c6a-91a1-4532-9260-7cc82970d74a@email.android.com> Message-ID: <50037519.10903@mozilla.com> On 07/15/2012 06:55 PM, gwillen at gmail.com wrote: > Ohhh, I see. Still, it's pretty counterintuitive if vectors are being > presented as _though_ they are first class (which I do like, due to > reducing the number of entities that have to be explained.) Not sure > what a good alternative would be, but this did nail me once before I > figured it out. Well, I'd just say that vectors ([T]) aren't first-class, just as they aren't in C++. Fixed-length vectors and pointers to vectors are. Patrick From niko at alum.mit.edu Sun Jul 15 20:52:45 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Sun, 15 Jul 2012 20:52:45 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <50035D16.4030001@mozilla.com> References: <50035D16.4030001@mozilla.com> Message-ID: <5003900D.6080900@alum.mit.edu> I have lately become enamored with explaining the Rust type system in terms of *ownership*. Basically Rust types are either shared (co-owned), uniquely owned, or borrowed. The shared types all begin with the @ prefix: @T, @[], and @fn(). Each reference to a shared value is an equal owner, which is another way of saying that none of them are owners. Thus shared types can also be thought of as a kind of co-ownership. The uniquely owned types are either unique boxes, which begin with the ~ prefix: ~T, ~[], ~fn(), or value types (no prefix). Uniquely owned values are freed as soon as the reference goes out of scope or is reassigned. Borrowed types begin with the & prefix: &T, &[], &fn(). Borrowed values are neither owned nor co-owned: a borrowed pointer is always derived (perhaps indirectly) from some owning reference on the call stack. Owned types (@ or ~) can be converted to borrow values. This is not, of course, incompatible with explaining @[] as a kind of 'second class' form of @T. Niko On 7/15/12 5:15 PM, Patrick Walton wrote: > Currently, we've gone back on the concept of dynamically-sized types. > I think that, while there were very good reasons for going back on > them in the implementation (namely, that we want a pointer to a vector > to be a fat pointer--one with start and length--internally, among > other obscure reasons relating to region bounds for functions), they > still possess an appealing amount of simplicity when describing the > language to newcomers. > > One of the things that immediately strikes most as complex about Rust > is the large number of pointer types, vector types, and function > types. This has not really changed with the current proposals for > vector reform and function reform. However, the way we present it and > think about it *can* change, in order to conceptually simplify the > language. > > Here is what I propose: > > 1. We have three (or four, if you count unsafe) types of pointers. @T > is a garbage-collected, task-local pointer, like shared_ptr; it can be > used anywhere within a single task. ~T is a unique pointer to the > exchange heap; it can be sent between tasks. &T is a safe reference > (borrowed) pointer to any allocation. > > 2. Function types, trait types, and vector types without a fixed size > are *second-class* types. Because their sizes aren't known to the > compiler, they can't be referred to in isolation; they can only be > referred to with a pointer. Any of the three pointer types will do. > > Note that this rule is quite similar to C++; note the error that > occurs when you try to compile this program: > > int foo(int x[]) { > int y[]; > y = x; > return y[0]; > } > > $ g++ -o test test.cpp > test.cpp: In function ?int foo(int*)?: > test.cpp:2:8: error: storage size of ?y? isn?t known > > The only difference is that we prevent the programmer from referring > to the dynamically-sized type *at all* except through a pointer. In > C++ it is allowed in some situations, but automatic conversions happen > (from T[] to T *) to give it meaning. The Rust rule is simpler. > > 3. A pointer to a vector can be indexed, just like in C++. Unlike C++, > bounds checks are performed and the task fails if an out-of-bounds > access is attempted. > > 4. Again like C++, a pointer can be taken to any element of a vector, > and this pointer can be indexed just like a pointer to the head of the > vector. Because a pointer to just one element (which can't be indexed) > and a pointer to a subrange of the vector (which can be) have > different types, we need a special method for creating a pointer to a > subrange of a vector. This method is called "slice": > > let x: &[int] = [ 1, 2, 3, 4, 5 ].slice(3, 5); > printf!("%d %d", x[0], x[1]); // prints 4 5 > > In this way, we can present Rust as a language with three basic > pointer types, one kind of vector type, one kind of function type > (modulo unsafe, pure, one-shot if we want to add it, etc), and one > kind of trait type. I think this could drastically decrease the > perceived complexity of the language for newcomers without having to > change anything in the language itself. > > Thoughts? > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From ben.striegel at gmail.com Mon Jul 16 06:33:10 2012 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Mon, 16 Jul 2012 09:33:10 -0400 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <50035D16.4030001@mozilla.com> References: <50035D16.4030001@mozilla.com> Message-ID: This feels simpler, yes. But as long as we're talking about presentation, would it be possible to establish standard terminology to distinguish between dynamically-sized vectors and fixed-length vectors? People will tend to simply refer to both as "vectors" or "vecs", and confusion will result. It really doesn't matter what the final terms are, as long as they're distinct and easy to type. On Sun, Jul 15, 2012 at 8:15 PM, Patrick Walton wrote: > Currently, we've gone back on the concept of dynamically-sized types. I > think that, while there were very good reasons for going back on them in > the implementation (namely, that we want a pointer to a vector to be a fat > pointer--one with start and length--internally, among other obscure reasons > relating to region bounds for functions), they still possess an appealing > amount of simplicity when describing the language to newcomers. > > One of the things that immediately strikes most as complex about Rust is > the large number of pointer types, vector types, and function types. This > has not really changed with the current proposals for vector reform and > function reform. However, the way we present it and think about it *can* > change, in order to conceptually simplify the language. > > Here is what I propose: > > 1. We have three (or four, if you count unsafe) types of pointers. @T is a > garbage-collected, task-local pointer, like shared_ptr; it can be used > anywhere within a single task. ~T is a unique pointer to the exchange heap; > it can be sent between tasks. &T is a safe reference (borrowed) pointer to > any allocation. > > 2. Function types, trait types, and vector types without a fixed size are > *second-class* types. Because their sizes aren't known to the compiler, > they can't be referred to in isolation; they can only be referred to with a > pointer. Any of the three pointer types will do. > > Note that this rule is quite similar to C++; note the error that occurs > when you try to compile this program: > > int foo(int x[]) { > int y[]; > y = x; > return y[0]; > } > > $ g++ -o test test.cpp > test.cpp: In function ?int foo(int*)?: > test.cpp:2:8: error: storage size of ?y? isn?t known > > The only difference is that we prevent the programmer from referring to > the dynamically-sized type *at all* except through a pointer. In C++ it is > allowed in some situations, but automatic conversions happen (from T[] to T > *) to give it meaning. The Rust rule is simpler. > > 3. A pointer to a vector can be indexed, just like in C++. Unlike C++, > bounds checks are performed and the task fails if an out-of-bounds access > is attempted. > > 4. Again like C++, a pointer can be taken to any element of a vector, and > this pointer can be indexed just like a pointer to the head of the vector. > Because a pointer to just one element (which can't be indexed) and a > pointer to a subrange of the vector (which can be) have different types, we > need a special method for creating a pointer to a subrange of a vector. > This method is called "slice": > > let x: &[int] = [ 1, 2, 3, 4, 5 ].slice(3, 5); > printf!("%d %d", x[0], x[1]); // prints 4 5 > > In this way, we can present Rust as a language with three basic pointer > types, one kind of vector type, one kind of function type (modulo unsafe, > pure, one-shot if we want to add it, etc), and one kind of trait type. I > think this could drastically decrease the perceived complexity of the > language for newcomers without having to change anything in the language > itself. > > Thoughts? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Mon Jul 16 08:34:33 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 16 Jul 2012 08:34:33 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: References: <50035D16.4030001@mozilla.com> Message-ID: <50043489.5080105@mozilla.com> On 16/07/2012 6:33 AM, Benjamin Striegel wrote: > This feels simpler, yes. But as long as we're talking about > presentation, would it be possible to establish standard terminology to > distinguish between dynamically-sized vectors and fixed-length vectors? > People will tend to simply refer to both as "vectors" or "vecs", and > confusion will result. It really doesn't matter what the final terms > are, as long as they're distinct and easy to type. Possibly. But I don't think an additional term here will really help; I think Patrick's right on the money by comparing this to C and seeking to _minimize_ the presentation of variety at work in the model. Consider C seriously here. Would you say it has "fixed size" and "dynamic sized" array types? I mean, it kinda does: T[10] is a type (fixed) and *T is a type (dynamic), but T[] is ... a bit less than a type: $ cat >t.c int main() { int x[]; } ^D $ cc t.c t.c: In function main: t.c:2: error: array size missing in x You can't quite use it in places where a definite amount of allocated memory is expected; at least not without "implicitly" giving the size: $ cat >t.c int main() { int x[] = {1,2,3,4}; } ^D $ cc t.c $ And in most contexts (assignment to another value, passing to a function) it tends to drop the definite size and decay to a pointer, albeit a "narrow" one without bounds checks. Yet users mostly come to terms with this: once they have a mental model of which allocations are contained in others and which are pointers, the rules of the array types become (mostly) obvious consequences. I'd say we're following pretty much the same model, except we're maintaining the difference between a vec-pointer and an element-pointer, refusing to decay between the two, and the vec-pointer carries a bound so it can be bounds-checked. This is healthy! Randomly indexing element-pointers and hoping you stay in-bounds in C is the main source of memory errors there :) Our vectors aren't really "fixed-size" or "dynamic-size"; just the static types. All vectors are _some_ size, it's just that in some contexts (those where the vec is stored in the interior of some other allocation, including a stack frame) the user has to specify the size statically as part of a variable's type; whereas in others (heap allocations, allocations held in other frames and passed by pointer, etc.) the variable is a pointer so it doesn't have to statically encode the size of its pointee: all pointers are the same size (1 or 2 words, depending on whether bounds-checked) so allocating the variable is just allocating a pointer. -Graydon From mbrubeck at mozilla.com Mon Jul 16 10:53:12 2012 From: mbrubeck at mozilla.com (Matt Brubeck) Date: Mon, 16 Jul 2012 10:53:12 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <50035D16.4030001@mozilla.com> References: <50035D16.4030001@mozilla.com> Message-ID: <50045508.5080400@mozilla.com> On 07/15/2012 05:15 PM, Patrick Walton wrote: > 2. Function types, trait types, and vector types without a fixed size > are *second-class* types. Because their sizes aren't known to the > compiler, they can't be referred to in isolation; they can only be > referred to with a pointer. Any of the three pointer types will do. Yes! Speaking as a relative newcomer (I've dabbled in Rust off and on, but never felt like I understood the type system sufficiently), I think this shift in terminology is a significant improvement. It make it feel like there are far fewer things to remember. Just reading the proposal was like a small epiphany. One bit of syntax still seems tricky. If "unique pointer to T" is spelled ~T then it seems like the special case "unique pointer to fn()" should be spelled ~fn() instead of fn~(). I don't know whether this can be changed without causing other problems for the grammar. If it can, it would make things that much easier to remember (for me, at least). From catamorphism at gmail.com Mon Jul 16 11:15:19 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Mon, 16 Jul 2012 11:15:19 -0700 Subject: [rust-dev] Meeting agenda Message-ID: Meeting agenda for tomorrow: https://etherpad.mozilla.org/Meeting-weekly-2012-07-17 Add your issues! -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From pwalton at mozilla.com Mon Jul 16 11:23:19 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 16 Jul 2012 11:23:19 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <50045508.5080400@mozilla.com> References: <50035D16.4030001@mozilla.com> <50045508.5080400@mozilla.com> Message-ID: <50045C17.4050708@mozilla.com> On 7/16/12 10:53 AM, Matt Brubeck wrote: > One bit of syntax still seems tricky. If "unique pointer to T" is > spelled ~T then it seems like the special case "unique pointer to fn()" > should be spelled ~fn() instead of fn~(). I don't know whether this can > be changed without causing other problems for the grammar. If it can, > it would make things that much easier to remember (for me, at least). It'll be ~fn. See Niko's blog post here: http://smallcultfollowing.com/babysteps/blog/2012/07/12/fn-types/ Patrick From mbrubeck at mozilla.com Mon Jul 16 11:29:36 2012 From: mbrubeck at mozilla.com (Matt Brubeck) Date: Mon, 16 Jul 2012 11:29:36 -0700 Subject: [rust-dev] Presentation of our vector/function/trait types In-Reply-To: <50045C17.4050708@mozilla.com> References: <50035D16.4030001@mozilla.com> <50045508.5080400@mozilla.com> <50045C17.4050708@mozilla.com> Message-ID: <50045D90.4090406@mozilla.com> On 07/16/2012 11:23 AM, Patrick Walton wrote: > On 7/16/12 10:53 AM, Matt Brubeck wrote: >> One bit of syntax still seems tricky. If "unique pointer to T" is >> spelled ~T then it seems like the special case "unique pointer to fn()" >> should be spelled ~fn() instead of fn~(). > > It'll be ~fn. See Niko's blog post here: > > http://smallcultfollowing.com/babysteps/blog/2012/07/12/fn-types/ Perfect! Thanks for the link. From graydon at mozilla.com Mon Jul 16 12:25:17 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 16 Jul 2012 12:25:17 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: References: <5000BAD1.4060002@mozilla.com> Message-ID: <50046A9D.3020105@mozilla.com> On 12-07-13 7:21 PM, Bennie Kloosteman wrote: > We spend far more time reading than writing code and more time is > spend checking results , specs / emails /docs , compiling , code > organization and see where things fit etc - the time spend typing is > low . It is not just maintenance programmers but a lot of new code is > refactoring and bug fixing. Conciseness is of little benefit and IMHO > is dangerous as it makes language adoption harder this is especially so > for the libraries. And adoption is crucial for Rust. Yes, I'm familiar with this argument. It's exactly the same argument I presented when initially asked why Rust wrote rec(...) rather than {...}, had only a single namespace, had no type-directed dispatch, name overloading, environment capture, type parameter inference, name shadowing, integer-literal inference ... I lost all these arguments, and many more, to people who were upset about having to "write more than necessary". Adoption is driven by many factors. Expressivity _is_ one of them; though you'll note it's always been explicitly subordinate to safety, efficiency and practicality. We balance factors as best we can. Keep in mind that even seemingly simple concepts like "readable" are _very_ hard to quantify: Ada was "designed to be readable" and yet the verbosity appears to work _against_ it. Readers' eyes glaze over and are unable to quickly apprehend detail, have to keep too much in short-term memory. The argument for sigils boils down to one about ubiquity. Words we write (or read!) over and over again, we tend to abbreviate. Sigils are just the limit case of abbreviation: 1 symbol. Infix operators survive too, and numbers, and printf strings, and lots of little lexical peculiarities that require the reader to know how to scan them, but are so ubiquitous that they push us towards abbreviation. Readers and writers alike can find the abbreviated form easier to apprehend than the elaborated form. > Java and C# have a good balance focusing on 5-6 chars keywords with > very few 2 and 3 char ones ( int is the main one) . "Good" except for all those programmers who deride Java as far too verbose. Ask around, opinions vary. C# can't be compared to Java reasonably here as it contains far more abbreviated forms. Because of Anders Hejlsberg's taste, as far as I can tell. I'm not insulting it; he's got compelling taste! Taste plays a large role in language design, especially in places like this. A lot of conversations boil down to subjective judgment calls where it's not really worth saying much beyond "I find X distasteful, and I would prefer Y". > Anyway Rust is a new language it should not look like something from the > 70's meant for only mathematical types. I concur, taste-wise, with aiming for less-academic and less-mathematical terminology when possible (for example, I hope we do not wind up referring to ~ as 'affine' in any context other than casual conversations between designers). Hopefully this will improve more as we file down further redundancy in the language and ensure the remaining vocabulary is comprised of short, pithy, common words. As for the 70s ... any decade that produced C, ML, Forth, CLU, Mesa, Smalltalk, Pascal/Modula and Scheme is OK in my book. It's kinda the design-space where we're aiming, actually. Just less crashy. They didn't have quite as much internet in their face as we moderns do. -Graydon From graydon at mozilla.com Tue Jul 17 07:41:33 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 17 Jul 2012 07:41:33 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: References: <5000BAD1.4060002@mozilla.com> <50046A9D.3020105@mozilla.com> Message-ID: <5005799D.20404@mozilla.com> On 17/07/2012 12:40 AM, Bennie Kloosteman wrote: > The problem to me is the less the language but more the libraries , > habbits now will become embedded in the "language style" . We've always aimed for pluralism in the design: trying to make it sufficiently easy to write in functional style, imperative style, and (less strongly, but getting better) OO style. I feel like rust is not presently forcing either "language style" on users, but I suppose the libraries reflect the biases of the team. I'm not sure discussing this in its "most abstract" form is the most useful approach though. Perhaps if you could make your concerns a bit more clear in code ... perhaps pick a single file from the std or core lib (if it's not too much to ask) and modify it to the style you'd feel is more legible, we can discuss in a pull request? > Though in a world where all languages are safe and fast the other > factors are important. Ha! Call me when we get to that world. We're competing with C++, note. > Yes ubiquity is crucial so why cont instead of continue its not like you > use it often ... It's been changed to 'again'. I'm not going to discuss that bug any further, it's a total bikeshed and of no consequence. > Yes affine is bad , but also iface is marginal.. id prefer interface > due to erring on the side of verbosity. Changing to 'trait' in 0.4 (which is the most common name for the sorts of things they are). > Anyway I say this because I want it to succeed , and the libraries are > starting to form so the "style": they set is crucial and a 70s style is > not good .... If a library is full dblnlst , str_cp ,xml_p adoption > will be harder - its probably easier these days to learn a new language > than a new standard library as they will get big. Ok, the keyword stuff I'm not really interested in debating ad infinitum, there just aren't _enough_ of them for this to be worth a long discussion (and it's 5 chars vs. 6, seriously). The abbreviations in library code are a different matter. It's true that we have a bunch of abbreviated library names. Examples: vec (not Vector) cmp (not Compare) bitv (not BitVector) dbg (not Debug) dlist (not DoublyLinkedList or CircularList) iter (not Iterable) ptr (not Pointer) rand::rng (not Random::Generator, say) sys (not System) rt (not Runtime) Are these sorts of abbreviated names actually posing a problem to users? It feels to me like we're in a similar ballpark to the naming conventions of ... at least _some_ other language standard libraries: http://www.ruby-doc.org/stdlib-1.9.3/ http://docs.python.org/library/ http://golang.org/pkg/ http://en.cppreference.com/w/cpp Though obviously not the same style as Java, C# or (curiously) Haskell, I haven't heard a _lot_ of clear feedback on this point. Patrick has been advocating for us to change house style to writing type names as TypeNames, but aside from that ... is vowel-omission or abbreviation seriously an issue? (eg. python putting regular expressions in 're' or system services in 'sys'?) Maybe having more-verbose type names, but keeping module names short, is a good balance? -Graydon From christian at siefkes.net Tue Jul 17 07:52:38 2012 From: christian at siefkes.net (Christian Siefkes) Date: Tue, 17 Jul 2012 16:52:38 +0200 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005799D.20404@mozilla.com> (sfid-H20120717-164136-+038.19-1@spamfilter.osbf.lua) References: <5000BAD1.4060002@mozilla.com> <50046A9D.3020105@mozilla.com> <5005799D.20404@mozilla.com> (sfid-H20120717-164136-+038.19-1@spamfilter.osbf.lua) Message-ID: <50057C36.2030908@siefkes.net> Hi Graydon and all On 07/17/2012 04:41 PM, Graydon Hoare wrote: > Though obviously not the same style as Java, C# or (curiously) Haskell, I > haven't heard a _lot_ of clear feedback on this point. Patrick has been > advocating for us to change house style to writing type names as TypeNames, > but aside from that ... is vowel-omission or abbreviation seriously an > issue? (eg. python putting regular expressions in 're' or system services in > 'sys'?) Maybe having more-verbose type names, but keeping module names > short, is a good balance? I, for one, are fine with short names. Best regards Chris -- |------- Dr. Christian Siefkes ------- christian at siefkes.net ------- | Homepage: http://www.siefkes.net/ | Blog: http://www.keimform.de/ | Peer Production Everywhere: http://peerconomy.org/wiki/ |---------------------------------- OpenPGP Key ID: 0x346452D8 -- Vaterland nennt sich der Staat immer dann, wenn er sich anschickt, auf Menschenmord auszugehen. -- Friedrich D?rrenmatt -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From lists.rust at dbp.mm.st Tue Jul 17 07:57:46 2012 From: lists.rust at dbp.mm.st (Daniel Patterson) Date: Tue, 17 Jul 2012 10:57:46 -0400 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005799D.20404@mozilla.com> References: <5000BAD1.4060002@mozilla.com> <50046A9D.3020105@mozilla.com> <5005799D.20404@mozilla.com> Message-ID: On Jul 17, 2012, at 10:41 AM, Graydon Hoare wrote: > Ok, the keyword stuff I'm not really interested in debating ad infinitum, there just aren't _enough_ of them for this to be worth a long discussion (and it's 5 chars vs. 6, seriously). The abbreviations in library code are a different matter. It's true that we have a bunch of abbreviated library names. Examples: > > vec (not Vector) > cmp (not Compare) > bitv (not BitVector) > dbg (not Debug) > dlist (not DoublyLinkedList or CircularList) > iter (not Iterable) > ptr (not Pointer) > rand::rng (not Random::Generator, say) > sys (not System) > rt (not Runtime) > > Are these sorts of abbreviated names actually posing a problem to users? As an outsider/newbie to Rust, I think this is pretty much a non-issue. Names are always going to be hard without good documentation, and with it, they will always be easy to use. It is no easier to remember vector than vec, and I think learning the name is the smallest/easiest thing you need to do when you are learning a library. As long as they aren't confusing (like if the name for a vector were "dup" or something similarly irrelevant/arbitrary), I personally think it is great that they are short. Not to make it easier to _write_, but to make it easier to read code. I want to have to read the minimum number of characters, and ideally be able to have the most amount of content on a single screen, within reason (it has to be relevant). At least for me, it is similar with the core syntax. There aren't that many keywords, so learning them isn't going to be that hard no matter what they are, and short / relevant seems great to me. This isn't a language that is targeting people who've never programmed before, and for people who have, learning syntax is easy, so providing a syntax that makes it more pleasant to program in once you actually know the language (i.e., easier to read, based on shorter keywords etc) is a good thing. Too often I think there is a tendency to want to cater a language somewhat to people who've never used it before, even though the reality is that most people who are using it will know it well, and people who don't will be able to learn it based on good documentation, _not_ language features. As an aside / broader comment, I think that rust code looks great (with a few caveats, which are actively being worked on), and congratulate the team on managing to balance interesting semantics (which is the exciting part, of course), with syntax that actually makes me want to program in it (as much as people say syntax doesn't matter?. it does). I would be very happy if this allowed me be able to stop writing C++. So, keep up the good work. From ash.gti at gmail.com Tue Jul 17 10:02:40 2012 From: ash.gti at gmail.com (Harrison, John) Date: Tue, 17 Jul 2012 10:02:40 -0700 Subject: [rust-dev] Rust Official Style Guide? Message-ID: <99EA097C-B54F-408E-8CEB-24F80CB65042@gmail.com> In light of another discussion going on about style of rust std/core, I was wondering if there is an official style guide and/or a style checker? I think that is one of python's strengths. The style guide (pep8 see http://www.python.org/dev/peps/pep-0008/ ) is very valuable in that most python packages, core or third party, are consistent. Having tools like pylint are also very helpful to anyone writing python code because they will warn you when your not following pep8 or some other limited warnings. -- John Harrison -------------- next part -------------- An HTML attachment was scrubbed... URL: From lindsey at rockstargirl.org Tue Jul 17 10:31:27 2012 From: lindsey at rockstargirl.org (Lindsey Kuper) Date: Tue, 17 Jul 2012 10:31:27 -0700 Subject: [rust-dev] Rust Official Style Guide? In-Reply-To: <99EA097C-B54F-408E-8CEB-24F80CB65042@gmail.com> References: <99EA097C-B54F-408E-8CEB-24F80CB65042@gmail.com> Message-ID: On Tue, Jul 17, 2012 at 10:02 AM, Harrison, John wrote: > In light of another discussion going on about style of rust std/core, I was > wondering if there is an official style guide and/or a style checker? Although this is not quite what you're asking about, it's an opportune time to point out that there's a style guide for the Rust compiler and libraries: https://github.com/mozilla/rust/wiki/Note-style-guide . (I didn't know about it until I had been contributing for a while, so it's possible that others don't, either.) Lindsey From sebastian.sylvan at gmail.com Tue Jul 17 10:36:30 2012 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Tue, 17 Jul 2012 10:36:30 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005799D.20404@mozilla.com> References: <5000BAD1.4060002@mozilla.com> <50046A9D.3020105@mozilla.com> <5005799D.20404@mozilla.com> Message-ID: On Tue, Jul 17, 2012 at 7:41 AM, Graydon Hoare wrote: > Though obviously not the same style as Java, C# or (curiously) Haskell, I > haven't heard a _lot_ of clear feedback on this point. Patrick has been > advocating for us to change house style to writing type names as TypeNames, > but aside from that ... is vowel-omission or abbreviation seriously an > issue? (eg. python putting regular expressions in 're' or system services in > 'sys'?) Maybe having more-verbose type names, but keeping module names > short, is a good balance? IMO I like the shorter names. As long as it doesn't cause ambiguity. "vector" tells me nothing that "vec" doesn't, so saving some screen real-estate to speed up reading (and typing) is a win. It's not black-and-white though. If something is used infrequently enough that you don't expect people to remember it by heart, avoid short mnemonics in favour of descriptive names. If it's unsafe and should stick out like a sore thumb, avoid short names. For library stuff that's essentially just shy of being a built-in language feature (like vec, cmp, ptr, etc.) shorter names make sense IMO. -- Sebastian Sylvan From me at kevincantu.org Tue Jul 17 13:19:41 2012 From: me at kevincantu.org (Kevin Cantu) Date: Tue, 17 Jul 2012 13:19:41 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: References: <5000BAD1.4060002@mozilla.com> <50046A9D.3020105@mozilla.com> <5005799D.20404@mozilla.com> Message-ID: As an English speaking engineer, "vector" has real meaning and immediately recognize "vec" as an abbreviation of that, but a school kid in Shanghai (??) shouldn't need to know everything I do to start learning the language. Long names can be easier to discover the meanings of. Anyways, here's another good place to drop this link: http://www.youtube.com/watch?v=_ahvzDzKdB0&feature=gv (Growing a Language, by Guy Steele). :D -- Kevin Cantu On Tue, Jul 17, 2012 at 10:36 AM, Sebastian Sylvan wrote: > On Tue, Jul 17, 2012 at 7:41 AM, Graydon Hoare wrote: >> Though obviously not the same style as Java, C# or (curiously) Haskell, I >> haven't heard a _lot_ of clear feedback on this point. Patrick has been >> advocating for us to change house style to writing type names as TypeNames, >> but aside from that ... is vowel-omission or abbreviation seriously an >> issue? (eg. python putting regular expressions in 're' or system services in >> 'sys'?) Maybe having more-verbose type names, but keeping module names >> short, is a good balance? > > IMO I like the shorter names. As long as it doesn't cause ambiguity. > "vector" tells me nothing that "vec" doesn't, so saving some screen > real-estate to speed up reading (and typing) is a win. It's not > black-and-white though. If something is used infrequently enough that > you don't expect people to remember it by heart, avoid short mnemonics > in favour of descriptive names. If it's unsafe and should stick out > like a sore thumb, avoid short names. For library stuff that's > essentially just shy of being a built-in language feature (like vec, > cmp, ptr, etc.) shorter names make sense IMO. > > -- > Sebastian Sylvan > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From steven099 at gmail.com Tue Jul 17 13:38:24 2012 From: steven099 at gmail.com (Steven Blenkinsop) Date: Tue, 17 Jul 2012 16:38:24 -0400 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005799D.20404@mozilla.com> References: <5000BAD1.4060002@mozilla.com> <50046A9D.3020105@mozilla.com> <5005799D.20404@mozilla.com> Message-ID: On Tuesday, July 17, 2012, Graydon Hoare wrote: > > rand::rng (not Random::Generator, say) This one is redundant, and the redundancy is crowding out useful information. I know rng is a common initialization, but you'd get the same information across with rand::gen in the same space. Then, "generator" doesn't get relegated to one character out of eight, and you remove any possibility of reading it as random::range. -------------- next part -------------- An HTML attachment was scrubbed... URL: From eslaughter at mozilla.com Tue Jul 17 14:23:00 2012 From: eslaughter at mozilla.com (Elliott Slaughter) Date: Tue, 17 Jul 2012 14:23:00 -0700 (PDT) Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005799D.20404@mozilla.com> Message-ID: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> > From: "Graydon Hoare" > > Ok, the keyword stuff I'm not really interested in debating ad > infinitum, there just aren't _enough_ of them for this to be worth a > long discussion (and it's 5 chars vs. 6, seriously). The > abbreviations > in library code are a different matter. It's true that we have a > bunch > of abbreviated library names. Examples: > > vec (not Vector) > cmp (not Compare) > bitv (not BitVector) > dbg (not Debug) > dlist (not DoublyLinkedList or CircularList) > iter (not Iterable) > ptr (not Pointer) > rand::rng (not Random::Generator, say) > sys (not System) > rt (not Runtime) > > Are these sorts of abbreviated names actually posing a problem to > users? I definitely like short keywords, and I don't have a problem with short names in the standard library, but I am a little worried about the precedent being set for Rust code in general. Take, for example, trans/base.rs in the Rust code base. The code uses abbreviations fairly aggressively, including ccx, bcx, icx, ty, ti, insn, ptr, t, incr, sess, among others. None of these are especially difficult to figure out, but the time it takes to get used to the code is non-zero. Now imagine that third-party Rust libraries follow this example. Now I have to learn abbreviations for every library I use in my application. If for any reason I need to modify a third party library for my own purposes, I'll need to learn its internal abbreviations as well. Should we really be using short name everywhere? And if not, how do we encourage people to use readable names, given the example we are providing in the standard library? From catamorphism at gmail.com Tue Jul 17 14:37:58 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Tue, 17 Jul 2012 14:37:58 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> References: <5005799D.20404@mozilla.com> <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> Message-ID: On Tue, Jul 17, 2012 at 2:23 PM, Elliott Slaughter wrote: > Take, for example, trans/base.rs in the Rust code base. The code uses abbreviations fairly aggressively, including ccx, bcx, icx, ty, ti, insn, ptr, t, incr, sess, among others. None of these are especially difficult to figure out, but the time it takes to get used to the code is non-zero. > This could be addressed by better documentation (inline comments or something else). The advantage of that is that the documentation is confined to one part of a particular module that no one needs to re-read once they've learned what the abbreviations mean; in contrast, everyone pays the cost of using (both typing and reading) long names over and over. Also, since in Rust it's usually visually apparent what the type of a variable is, at least if it's a function argument or a top-level function, all you really need to do to figure out what "ccx" or "bcx" means is figure out their types. The piece that's missing right now is useful documentation for each type. > Now imagine that third-party Rust libraries follow this example. Now I have to learn abbreviations for every library I use in my application. If for any reason I need to modify a third party library for my own purposes, I'll need to learn its internal abbreviations as well. > Likewise, I think that's a documentation issue. > Should we really be using short name everywhere? And if not, how do we encourage people to use readable names, given the example we are providing in the standard library? To me, short versus long names are a matter of taste and not something we should dictate. Different contexts suggest different sorts of naming conventions. I trust anyone who is sensible enough to choose Rust to be sensible enough to choose those conventions for themselves :-) Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From pwalton at mozilla.com Tue Jul 17 14:39:37 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 17 Jul 2012 14:39:37 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> References: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> Message-ID: <5005DB99.4060609@mozilla.com> On 7/17/12 2:23 PM, Elliott Slaughter wrote: > Now imagine that third-party Rust libraries follow this example. Now > I have to learn abbreviations for every library I use in my > application. If for any reason I need to modify a third party library > for my own purposes, I'll need to learn its internal abbreviations as > well. > > Should we really be using short name everywhere? And if not, how do > we encourage people to use readable names, given the example we are > providing in the standard library? Agreed. I personally prefer longer, unabbreviated names (and camel-cased types) in user code for this reason. Keywords are a small fixed set of things that all users of the language must know, while user code contains an unbounded number of abbreviations in the limit. See resolve3 for an example of this (although perhaps my names are *too* long there...) In general I'm not a big fan of Unix-command-line-style abbreviation. It works and is elegant when programs are kept very small, but as programs grow larger and larger programmers have to page in and out abbreviations too often for easy reading. Functions like CreateOrRecycleThebesLayer() and UpdateDisplayItemDataForFrame() in Gecko may be lengthy, but they sure make digging through MXR easier. Unix was forced to abbreviate for the 6 character limit, but that doesn't exist anymore. In fact, modern Plan 9 code doesn't abbreviate nearly as often as we do; they just pick short names. Take esc.c (just as an example) from Go: http://code.google.com/p/go/source/browse/src/cmd/gc/esc.c We have escapes(), visit(), visitcodelist(), visitcode(), analyze(), escfunc(), escloopdepthlist(), escloopdepth(), esclist(), esc(), escassign(), esccall(), escflows(), escflood(), escwalk(), and esctag(). If we assume that the "esc" prefix is just C namespacing, then the only *abbreviation* there is "func". The rest are just short names. The resulting code reads much nicer than the Rust code in our compiler. Short names are fine and read well; abbreviations don't. (In fact, I prefer unabbreviated keywords in general; I'd prefer "return", "module", and "match", but I'm happy to yield to the tastes of the community and BDFL here, since I feel that abbreviated keywords have a much smaller cost than abbreviated user code.) Patrick From pwalton at mozilla.com Tue Jul 17 14:42:59 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 17 Jul 2012 14:42:59 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: References: <5005799D.20404@mozilla.com> <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> Message-ID: <5005DC63.2090209@mozilla.com> On 7/17/12 2:37 PM, Tim Chevalier wrote: > Likewise, I think that's a documentation issue. I don't think that's entirely true. Gecko is so large that nobody can hold all the names in their head. And the dependency graph of Gecko has rapidly approached a complete graph over time -- it's inevitable in large software projects -- so everyone encounters names of functions that they haven't seen before. Being able to guess at a glance what a function does is critical, and it's much easier to parse CreateOrRecycleThebesLayer() than, say, mk_tl(). Patrick From vladimir at slate-project.org Tue Jul 17 14:57:41 2012 From: vladimir at slate-project.org (Vladimir Lushnikov) Date: Tue, 17 Jul 2012 22:57:41 +0100 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: References: <5005799D.20404@mozilla.com> <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> Message-ID: English unabbreviated names seem like the way to go (they're not long if you're used to AbstractWidgetWithNetworkingConfigurationFactorySingleton or something like that from that Java world). I don't think it's about the number of keystrokes though - for two reasons: [1] Your editor (/IDE) should help you complete the keywords and type names [2] Code comprehension research so far shows it's about word count not character count - i.e. the more words of code you have to read, the longer it takes to comprehend I personally prefer to have an editor that can code complete as it both reduces the number of keystrokes and allows me to remember names of concepts rather than abbreviations or particular combinations of class names. I haven't written much Rust code because of a lack of good editor. When someone in your team asks you - hey, can you help me with this problem - I often find myself reading code that I've never seen and simulating what it's doing in my head. If I also had to learn a vocabulary or look at the documentation while standing at someone else's desk then debugging the code would take longer. Good code should be self-documenting - you read it once, and you can begin to understand what it's doing. Symbolic abbreviations (like @ or ~ are different because there are a fixed number of them with a fixed meaning) and you should be able to learn these when you've learnt the language. This is in contrast to abbreviations like 'ccx' or 'bcx' where the number of abbreviations is not fixed and differs from program to program. Obviously this is all just my opinion. Thanks, Vlad On Tue, Jul 17, 2012 at 10:37 PM, Tim Chevalier wrote: > On Tue, Jul 17, 2012 at 2:23 PM, Elliott Slaughter > wrote: >> Take, for example, trans/base.rs in the Rust code base. The code uses abbreviations fairly aggressively, including ccx, bcx, icx, ty, ti, insn, ptr, t, incr, sess, among others. None of these are especially difficult to figure out, but the time it takes to get used to the code is non-zero. >> > > This could be addressed by better documentation (inline comments or > something else). The advantage of that is that the documentation is > confined to one part of a particular module that no one needs to > re-read once they've learned what the abbreviations mean; in contrast, > everyone pays the cost of using (both typing and reading) long names > over and over. > > Also, since in Rust it's usually visually apparent what the type of a > variable is, at least if it's a function argument or a top-level > function, all you really need to do to figure out what "ccx" or "bcx" > means is figure out their types. The piece that's missing right now is > useful documentation for each type. > >> Now imagine that third-party Rust libraries follow this example. Now I have to learn abbreviations for every library I use in my application. If for any reason I need to modify a third party library for my own purposes, I'll need to learn its internal abbreviations as well. >> > > Likewise, I think that's a documentation issue. > >> Should we really be using short name everywhere? And if not, how do we encourage people to use readable names, given the example we are providing in the standard library? > > To me, short versus long names are a matter of taste and not something > we should dictate. Different contexts suggest different sorts of > naming conventions. I trust anyone who is sensible enough to choose > Rust to be sensible enough to choose those conventions for themselves > :-) > > Cheers, > Tim > > -- > Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt > "Debate is useless when one participant denies the full dignity of the > other." -- Eric Berndt > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pwalton at mozilla.com Tue Jul 17 15:04:41 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 17 Jul 2012 15:04:41 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005DB99.4060609@mozilla.com> References: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> <5005DB99.4060609@mozilla.com> Message-ID: <5005E179.5070806@mozilla.com> In short: "short unabbreviated names are fine, but abbreviations should be considered carefully and assumed bad unless proven otherwise". Patrick From niko at alum.mit.edu Tue Jul 17 21:03:10 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 17 Jul 2012 21:03:10 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005DB99.4060609@mozilla.com> References: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> <5005DB99.4060609@mozilla.com> Message-ID: <5006357E.30203@alum.mit.edu> This is interesting. When I first started working on the Rust compiler, I very much enjoyed the Unix-like, abbreviated names. However, I have to admit that reading Patrick's resolve3 code is making me ashamed of the code I've written lately. I plan to go back and "verbos-ify" some of my code. I do think it helps with readability overall, though it is definitely true that if names are unnecessarily long (e.g., `ty_param_bounds_and_ty` or `optional_interface`) they can become distracting. Also, our 78-character limit starts to become more of a burden. Niko On 7/17/12 2:39 PM, Patrick Walton wrote: > On 7/17/12 2:23 PM, Elliott Slaughter wrote: >> Now imagine that third-party Rust libraries follow this example. Now >> I have to learn abbreviations for every library I use in my >> application. If for any reason I need to modify a third party library >> for my own purposes, I'll need to learn its internal abbreviations as >> well. >> >> Should we really be using short name everywhere? And if not, how do >> we encourage people to use readable names, given the example we are >> providing in the standard library? > > Agreed. I personally prefer longer, unabbreviated names (and > camel-cased types) in user code for this reason. Keywords are a small > fixed set of things that all users of the language must know, while > user code contains an unbounded number of abbreviations in the limit. > See resolve3 for an example of this (although perhaps my names are > *too* long there...) > > In general I'm not a big fan of Unix-command-line-style abbreviation. > It works and is elegant when programs are kept very small, but as > programs grow larger and larger programmers have to page in and out > abbreviations too often for easy reading. Functions like > CreateOrRecycleThebesLayer() and UpdateDisplayItemDataForFrame() in > Gecko may be lengthy, but they sure make digging through MXR easier. > > Unix was forced to abbreviate for the 6 character limit, but that > doesn't exist anymore. In fact, modern Plan 9 code doesn't abbreviate > nearly as often as we do; they just pick short names. Take esc.c (just > as an example) from Go: > > http://code.google.com/p/go/source/browse/src/cmd/gc/esc.c > > We have escapes(), visit(), visitcodelist(), visitcode(), analyze(), > escfunc(), escloopdepthlist(), escloopdepth(), esclist(), esc(), > escassign(), esccall(), escflows(), escflood(), escwalk(), and > esctag(). If we assume that the "esc" prefix is just C namespacing, > then the only *abbreviation* there is "func". The rest are just short > names. The resulting code reads much nicer than the Rust code in our > compiler. Short names are fine and read well; abbreviations don't. > > (In fact, I prefer unabbreviated keywords in general; I'd prefer > "return", "module", and "match", but I'm happy to yield to the tastes > of the community and BDFL here, since I feel that abbreviated keywords > have a much smaller cost than abbreviated user code.) > > Patrick > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From hatahet at gmail.com Wed Jul 18 00:43:28 2012 From: hatahet at gmail.com (Ziad Hatahet) Date: Wed, 18 Jul 2012 00:43:28 -0700 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5006357E.30203@alum.mit.edu> References: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> <5005DB99.4060609@mozilla.com> <5006357E.30203@alum.mit.edu> Message-ID: Not to start a religious war, but maybe using camelCase instead of under_score would save even more space given the 78-character line limit? :) -- Ziad On Tue, Jul 17, 2012 at 9:03 PM, Niko Matsakis wrote: > This is interesting. When I first started working on the Rust compiler, I > very much enjoyed the Unix-like, abbreviated names. However, I have to > admit that reading Patrick's resolve3 code is making me ashamed of the code > I've written lately. I plan to go back and "verbos-ify" some of my code. > I do think it helps with readability overall, though it is definitely true > that if names are unnecessarily long (e.g., `ty_param_bounds_and_ty` or > `optional_interface`) they can become distracting. Also, our 78-character > limit starts to become more of a burden. > > > Niko > > > > On 7/17/12 2:39 PM, Patrick Walton wrote: > >> On 7/17/12 2:23 PM, Elliott Slaughter wrote: >> >>> Now imagine that third-party Rust libraries follow this example. Now >>> I have to learn abbreviations for every library I use in my >>> application. If for any reason I need to modify a third party library >>> for my own purposes, I'll need to learn its internal abbreviations as >>> well. >>> >>> Should we really be using short name everywhere? And if not, how do >>> we encourage people to use readable names, given the example we are >>> providing in the standard library? >>> >> >> Agreed. I personally prefer longer, unabbreviated names (and camel-cased >> types) in user code for this reason. Keywords are a small fixed set of >> things that all users of the language must know, while user code contains >> an unbounded number of abbreviations in the limit. See resolve3 for an >> example of this (although perhaps my names are *too* long there...) >> >> In general I'm not a big fan of Unix-command-line-style abbreviation. It >> works and is elegant when programs are kept very small, but as programs >> grow larger and larger programmers have to page in and out abbreviations >> too often for easy reading. Functions like CreateOrRecycleThebesLayer() and >> UpdateDisplayItemDataForFrame(**) in Gecko may be lengthy, but they sure >> make digging through MXR easier. >> >> Unix was forced to abbreviate for the 6 character limit, but that doesn't >> exist anymore. In fact, modern Plan 9 code doesn't abbreviate nearly as >> often as we do; they just pick short names. Take esc.c (just as an example) >> from Go: >> >> http://code.google.com/p/go/**source/browse/src/cmd/gc/esc.c >> >> We have escapes(), visit(), visitcodelist(), visitcode(), analyze(), >> escfunc(), escloopdepthlist(), escloopdepth(), esclist(), esc(), >> escassign(), esccall(), escflows(), escflood(), escwalk(), and esctag(). If >> we assume that the "esc" prefix is just C namespacing, then the only >> *abbreviation* there is "func". The rest are just short names. The >> resulting code reads much nicer than the Rust code in our compiler. Short >> names are fine and read well; abbreviations don't. >> >> (In fact, I prefer unabbreviated keywords in general; I'd prefer >> "return", "module", and "match", but I'm happy to yield to the tastes of >> the community and BDFL here, since I feel that abbreviated keywords have a >> much smaller cost than abbreviated user code.) >> >> Patrick >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tschneidereit at gmail.com Wed Jul 18 01:36:44 2012 From: tschneidereit at gmail.com (Till Schneidereit) Date: Wed, 18 Jul 2012 10:36:44 +0200 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5006357E.30203@alum.mit.edu> References: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> <5005DB99.4060609@mozilla.com> <5006357E.30203@alum.mit.edu> Message-ID: Having recently read a considerable amount of code in SpiderMonkey and quite a bit in various parts of the Rust compiler, I can attest to strong use of abbreviated names making things much harder to understand. While Tim is right about documentation helping with that, I agree with Patrick that that just doesn't scale indefinitely. Also, at least for me, the additional burden of keeping a translation table in my head makes a surprisingly big difference in my ability to parse code and figure out its semantics quickly. The bottom line is that I don't think it's just a matter of taste: it's a usability issue. Maybe not the biggest one, but certainly not a small one, either. On Wed, Jul 18, 2012 at 6:03 AM, Niko Matsakis wrote: > This is interesting. When I first started working on the Rust compiler, I > very much enjoyed the Unix-like, abbreviated names. However, I have to > admit that reading Patrick's resolve3 code is making me ashamed of the code > I've written lately. I plan to go back and "verbos-ify" some of my code. I > do think it helps with readability overall, though it is definitely true > that if names are unnecessarily long (e.g., `ty_param_bounds_and_ty` or > `optional_interface`) they can become distracting. Also, our 78-character > limit starts to become more of a burden. > > > Niko > > > > On 7/17/12 2:39 PM, Patrick Walton wrote: >> >> On 7/17/12 2:23 PM, Elliott Slaughter wrote: >>> >>> Now imagine that third-party Rust libraries follow this example. Now >>> I have to learn abbreviations for every library I use in my >>> application. If for any reason I need to modify a third party library >>> for my own purposes, I'll need to learn its internal abbreviations as >>> well. >>> >>> Should we really be using short name everywhere? And if not, how do >>> we encourage people to use readable names, given the example we are >>> providing in the standard library? >> >> >> Agreed. I personally prefer longer, unabbreviated names (and camel-cased >> types) in user code for this reason. Keywords are a small fixed set of >> things that all users of the language must know, while user code contains an >> unbounded number of abbreviations in the limit. See resolve3 for an example >> of this (although perhaps my names are *too* long there...) >> >> In general I'm not a big fan of Unix-command-line-style abbreviation. It >> works and is elegant when programs are kept very small, but as programs grow >> larger and larger programmers have to page in and out abbreviations too >> often for easy reading. Functions like CreateOrRecycleThebesLayer() and >> UpdateDisplayItemDataForFrame() in Gecko may be lengthy, but they sure make >> digging through MXR easier. >> >> Unix was forced to abbreviate for the 6 character limit, but that doesn't >> exist anymore. In fact, modern Plan 9 code doesn't abbreviate nearly as >> often as we do; they just pick short names. Take esc.c (just as an example) >> from Go: >> >> http://code.google.com/p/go/source/browse/src/cmd/gc/esc.c >> >> We have escapes(), visit(), visitcodelist(), visitcode(), analyze(), >> escfunc(), escloopdepthlist(), escloopdepth(), esclist(), esc(), >> escassign(), esccall(), escflows(), escflood(), escwalk(), and esctag(). If >> we assume that the "esc" prefix is just C namespacing, then the only >> *abbreviation* there is "func". The rest are just short names. The resulting >> code reads much nicer than the Rust code in our compiler. Short names are >> fine and read well; abbreviations don't. >> >> (In fact, I prefer unabbreviated keywords in general; I'd prefer "return", >> "module", and "match", but I'm happy to yield to the tastes of the community >> and BDFL here, since I feel that abbreviated keywords have a much smaller >> cost than abbreviated user code.) >> >> Patrick >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From itakingiteasy at gmail.com Wed Jul 18 04:52:33 2012 From: itakingiteasy at gmail.com (Alexander Tumin) Date: Wed, 18 Jul 2012 15:52:33 +0400 Subject: [rust-dev] [suggestion] Add ~[mut T].to_str() and @[mut T].to_str() to the core lib Message-ID: Hi, i am not aware of why similar implementations of to_str() for ~[mut T] and @[mut T] are missing and core lib, so i am suggesting to add them as follows (in rather naive manner, so any change should be an improvement): -->8-- import io::*; import to_str::*; impl of to_str for @[mut T] { fn to_str() -> ~str { (@self).map(|x| { x.to_str() }).to_str() } } impl of to_str for ~[mut T] { fn to_str() -> ~str { (~copy self).map(|x| { x.to_str() }).to_str() } } fn main() { println((~[mut 1, 2, 3]).to_str()); println((@[mut 1, 2, 3]).to_str()); } -->8-- Thanks. From ben.striegel at gmail.com Wed Jul 18 09:35:06 2012 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 18 Jul 2012 12:35:06 -0400 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005E179.5070806@mozilla.com> References: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> <5005DB99.4060609@mozilla.com> <5005E179.5070806@mozilla.com> Message-ID: I concur with Patrick. Short keywords: good Short identifiers for stdlib APIs: good Short identifiers for internal variables: bad (but excessively long ones are just as bad, for different reasons) On Tue, Jul 17, 2012 at 6:04 PM, Patrick Walton wrote: > In short: "short unabbreviated names are fine, but abbreviations should be > considered carefully and assumed bad unless proven otherwise". > > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dherman at mozilla.com Wed Jul 18 21:48:14 2012 From: dherman at mozilla.com (David Herman) Date: Wed, 18 Jul 2012 21:48:14 -0700 Subject: [rust-dev] rust to JavaScript In-Reply-To: <4FFEDBEA.6080003@alum.mit.edu> References: <4FFE7D79.9040802@gmail.com> <4FFEDBEA.6080003@alum.mit.edu> Message-ID: <63CA0DE3-F5D5-4B6C-B50E-5C6858F7CA0F@mozilla.com> On Jul 12, 2012, at 7:15 AM, Niko Matsakis wrote: > Certainly there is no pthread or stack-switching implementation for Javascript so I guess we'll have to rewrite at least the scheduler! We might end up having to model each Rust thread with a web worker or something like that, as a first attempt anyhow. That would result in a very different performance model, since Rust expects to be able to create several metric craptons [1] of concurrent tasks, whereas the number of workers you can create is much smaller. But who knows, it might still be interesting enough to be useful for some kinds of programs; ClojureScript is making progress as a single-threaded dialect of Clojure, after all. Dave [1] Give or take. From niko at alum.mit.edu Thu Jul 19 06:32:53 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 19 Jul 2012 06:32:53 -0700 Subject: [rust-dev] rust to JavaScript In-Reply-To: <63CA0DE3-F5D5-4B6C-B50E-5C6858F7CA0F@mozilla.com> References: <4FFE7D79.9040802@gmail.com> <4FFEDBEA.6080003@alum.mit.edu> <63CA0DE3-F5D5-4B6C-B50E-5C6858F7CA0F@mozilla.com> Message-ID: <50080C85.4090103@alum.mit.edu> On 7/18/12 9:48 PM, David Herman wrote: > That would result in a very different performance model, since Rust expects to be able to create several metric craptons [1] of concurrent tasks, whereas the number of workers you can create is much smaller. But who knows, it might still be interesting enough to be useful for some kinds of programs; ClojureScript is making progress as a single-threaded dialect of Clojure, after all. Not to mention that we would have to deep-copy all messages. Niko From pwalton at mozilla.com Thu Jul 19 07:52:11 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 19 Jul 2012 07:52:11 -0700 Subject: [rust-dev] Tree closed Message-ID: <50081F1B.9090005@mozilla.com> I've closed the tree due to massive breakage. Will reopen when we finally get a green test cycle on the bots. Patrick From pwalton at mozilla.com Thu Jul 19 08:59:16 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 19 Jul 2012 08:59:16 -0700 Subject: [rust-dev] Tree closed In-Reply-To: <50081F1B.9090005@mozilla.com> References: <50081F1B.9090005@mozilla.com> Message-ID: <50082ED4.4020303@mozilla.com> On 07/19/2012 07:52 AM, Patrick Walton wrote: > I've closed the tree due to massive breakage. Will reopen when we > finally get a green test cycle on the bots. Looks like it's OK now. Patrick From graydon at mozilla.com Fri Jul 20 19:03:10 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 20 Jul 2012 19:03:10 -0700 Subject: [rust-dev] Followup release: 0.3.1, mac only, very minor Message-ID: <500A0DDE.9040902@mozilla.com> Hi, There was a very minor makefile bug in 0.3 that affected the 'make install' target in the 0.3 release on macs, only. This was enough of an annoyance to people that I've updated the tarball to a 0.3.1 release. Users who had a successful 0.3 install experience (linux, other unixes) have no need to pick this one up. http://dl.rust-lang.org/dist/rust-0.3.1.tar.gz http://dl.rust-lang.org/dist/rust-0.3.1.tar.gz.asc sha256: eb99ff2e745ecb6eaf01d4caddebce397a2b4cda6836a051cb2d493b9cedd018 Everyone else who had a happy time with 0.3, please ignore this. -Graydon From zackcorr95 at gmail.com Sat Jul 21 00:59:15 2012 From: zackcorr95 at gmail.com (Zack Corr) Date: Sat, 21 Jul 2012 17:59:15 +1000 Subject: [rust-dev] Merge LLVM with the 3.1 release Message-ID: As mentioned on issue #2641 by jld: April 18th: 3.1 is branched. (llvm-mirror/clang at 103f41d) > April 26th: Rust grabs trunk. (llvm-mirror/clang at 9b94cd1) > April 30th: bug is fixed on trunk. (llvm-mirror/clang at b86b855) > May 8th: fix is crossported to 3.1. (llvm-mirror/clang at 82520fb) Rust's LLVM was merged with 3.1 before the fix for issue #2641 was merged into 3.1 for the official release. It'd be nice if someone could merge with the 3.1 release again so it can be fixed, because I have heard of this happening to a fair few people who living on rolling release 64-bit distros (such as Arch Linux and Debian Unstable) with GCC 4.7.1 on #rust. Merging might also fix something that was breaking my experimentations with JIT which seemed to work with Arch Linux's LLVM 3.1 package. -------------- next part -------------- An HTML attachment was scrubbed... URL: From bruant.d at gmail.com Sat Jul 21 11:54:31 2012 From: bruant.d at gmail.com (David Bruant) Date: Sat, 21 Jul 2012 20:54:31 +0200 Subject: [rust-dev] Getter and setters Message-ID: <500AFAE7.3020506@gmail.com> Hi, I was looking at the task.rs code [1] and I noticed the getter and setter for "opts" couldn't help thinking that it is boilerplate code. Comments removed, the incriminated code looks like this: enum builder { builder_({ mut opts: task_opts, mut gen_body: fn@(+fn~()) -> fn~(), can_not_copy: option> }) } fn builder() -> builder { let body_identity = fn@(+body: fn~()) -> fn~() { body }; builder_({ mut opts: default_task_opts(), mut gen_body: body_identity, can_not_copy: none }) } fn get_opts(builder: builder) -> task_opts { builder.opts } fn set_opts(builder: builder, opts: task_opts) { builder.opts = opts; } In order to interact with the 'opts' field of the builder, client code needs to go through get_opts and set_opts which, currently are only wrappers around "builder.opts" and "builder.opts = opts". This sounds like boilerplate... but I can hear the Java ghost whispering "but what if the implementation changes? If you want to add a logger?". The Java ghost would be right. Well... almost. If in object declaration it was possible to declare getters and setters, it would be possible for client code to write "builder.opts" and "builder.opts = opts" and for the implementor to change the implementation to getters/setters if necessary. Best of both worlds. There would be no overhead whatsoever; "builder.opts" and "builder.opts = opts" would just be syntactic sugar over the accessor, so it can be made at least as efficient by the compiler than get_opts and set_opts calls. What do you think? David [1] https://github.com/mozilla/rust/blob/f676547c9788b919762bfb379b1e26ebd94d3dc9/src/libcore/task.rs#L229 From dherman at mozilla.com Sat Jul 21 12:18:40 2012 From: dherman at mozilla.com (David Herman) Date: Sat, 21 Jul 2012 12:18:40 -0700 Subject: [rust-dev] rust to JavaScript In-Reply-To: <50080C85.4090103@alum.mit.edu> References: <4FFE7D79.9040802@gmail.com> <4FFEDBEA.6080003@alum.mit.edu> <63CA0DE3-F5D5-4B6C-B50E-5C6858F7CA0F@mozilla.com> <50080C85.4090103@alum.mit.edu> Message-ID: <434D654F-1EC6-4865-948A-EF20238FED11@mozilla.com> Oh, actually, I wonder if the "transfer" semantics of ArrayBuffers wouldn't give us the ability to emulate the exchange heap more accurately: http://www.khronos.org/registry/typedarray/specs/latest/#9.2 http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast Long story short: you can dynamically emulate unique ownership of binary data and transfer it between workers without copies. The sender's reference to the data becomes "neutered" so that it's unable to view the data after the send. Of course, Rust would guarantee it never even tried. Dave On Jul 19, 2012, at 6:32 AM, Niko Matsakis wrote: > On 7/18/12 9:48 PM, David Herman wrote: >> That would result in a very different performance model, since Rust expects to be able to create several metric craptons [1] of concurrent tasks, whereas the number of workers you can create is much smaller. But who knows, it might still be interesting enough to be useful for some kinds of programs; ClojureScript is making progress as a single-threaded dialect of Clojure, after all. > > Not to mention that we would have to deep-copy all messages. > > > > Niko From niko at alum.mit.edu Sat Jul 21 16:25:37 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Sat, 21 Jul 2012 16:25:37 -0700 Subject: [rust-dev] rust to JavaScript In-Reply-To: <434D654F-1EC6-4865-948A-EF20238FED11@mozilla.com> References: <4FFE7D79.9040802@gmail.com> <4FFEDBEA.6080003@alum.mit.edu> <63CA0DE3-F5D5-4B6C-B50E-5C6858F7CA0F@mozilla.com> <50080C85.4090103@alum.mit.edu> <434D654F-1EC6-4865-948A-EF20238FED11@mozilla.com> Message-ID: <500B3A71.8040405@alum.mit.edu> On 7/21/12 12:18 PM, David Herman wrote: > Oh, actually, I wonder if the "transfer" semantics of ArrayBuffers wouldn't give us the ability to emulate the exchange heap more accurately: > > http://www.khronos.org/registry/typedarray/specs/latest/#9.2 > http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast > > Long story short: you can dynamically emulate unique ownership of binary data and transfer it between workers without copies. The sender's reference to the data becomes "neutered" so that it's unable to view the data after the send. Of course, Rust would guarantee it never even tried. Ah, yes, I imagine that would help. Niko From ben.striegel at gmail.com Sat Jul 21 17:25:44 2012 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Sat, 21 Jul 2012 20:25:44 -0400 Subject: [rust-dev] A policy for impls Message-ID: When looking through libcore and libstd, there are some impl methods that simply delegate to functions elsewhere in the file, like so: impl extensions of unique_str for ~str { #[inline] fn trim() -> ~str { trim(self) } } Is this a pattern that all the impls in the standard libraries ought to follow? Is there some value to being able to always refer to module::function() rather than type.method()? Assuming that #[inline] or #[inline(always)] remove any overhead, I don't think there's any downside to it other than cluttered docs. -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Sun Jul 22 03:56:19 2012 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Sun, 22 Jul 2012 12:56:19 +0200 Subject: [rust-dev] Getter and setters In-Reply-To: <500AFAE7.3020506@gmail.com> References: <500AFAE7.3020506@gmail.com> Message-ID: Hi, It sounds to me like *properties* => http://en.wikipedia.org/wiki/Property_%28programming%29 *A property, in some object-oriented programming languages , is a special sort of class member, intermediate between a field (or data member ) and a method. Properties are read and written like fields, but property reads and writes are (usually) translated to get and set method calls.* Is this what you wanted to express ? -- Matthieu On Sat, Jul 21, 2012 at 8:54 PM, David Bruant wrote: > Hi, > > I was looking at the task.rs code [1] and I noticed the getter and > setter for "opts" couldn't help thinking that it is boilerplate code. > Comments removed, the incriminated code looks like this: > > enum builder { > builder_({ > mut opts: task_opts, > mut gen_body: fn@(+fn~()) -> fn~(), > can_not_copy: option> > }) > } > > fn builder() -> builder { > let body_identity = fn@(+body: fn~()) -> fn~() { body }; > > builder_({ > mut opts: default_task_opts(), > mut gen_body: body_identity, > can_not_copy: none > }) > } > > fn get_opts(builder: builder) -> task_opts { > builder.opts > } > > fn set_opts(builder: builder, opts: task_opts) { > builder.opts = opts; > } > > In order to interact with the 'opts' field of the builder, client code > needs to go through get_opts and set_opts which, currently are only > wrappers around "builder.opts" and "builder.opts = opts". This sounds > like boilerplate... but I can hear the Java ghost whispering "but what > if the implementation changes? If you want to add a logger?". The Java > ghost would be right. Well... almost. > If in object declaration it was possible to declare getters and setters, > it would be possible for client code to write "builder.opts" and > "builder.opts = opts" and for the implementor to change the > implementation to getters/setters if necessary. Best of both worlds. > There would be no overhead whatsoever; "builder.opts" and "builder.opts > = opts" would just be syntactic sugar over the accessor, so it can be > made at least as efficient by the compiler than get_opts and set_opts > calls. > > What do you think? > > David > > [1] > > https://github.com/mozilla/rust/blob/f676547c9788b919762bfb379b1e26ebd94d3dc9/src/libcore/task.rs#L229 > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bruant.d at gmail.com Sun Jul 22 04:15:25 2012 From: bruant.d at gmail.com (David Bruant) Date: Sun, 22 Jul 2012 13:15:25 +0200 Subject: [rust-dev] Getter and setters In-Reply-To: References: <500AFAE7.3020506@gmail.com> Message-ID: <500BE0CD.1050502@gmail.com> Le 22/07/2012 12:56, Matthieu Monrocq a ?crit : > Hi, > > It sounds to me like /properties/ => > http://en.wikipedia.org/wiki/Property_%28programming%29 > > /A *property*, in some object-oriented > programming > languages , is a > special sort of class > member, > intermediate between a field > (or data > member ) and a method > . > Properties are read and written like fields, but property reads and > writes are (usually) translated to get and set method calls./ > > Is this what you wanted to express ? The definition seems close to what I described indeed :-) Does Rust already have support for these? What's missing from the wikipedia page is a pro/con analysis. I've described pros in my initial message, I'm curious of arguments against properties. Thanks, David -------------- next part -------------- An HTML attachment was scrubbed... URL: From bklooste at gmail.com Sun Jul 22 05:20:30 2012 From: bklooste at gmail.com (Bennie Kloosteman) Date: Sun, 22 Jul 2012 20:20:30 +0800 Subject: [rust-dev] Getter and setters In-Reply-To: <500BE0CD.1050502@gmail.com> References: <500AFAE7.3020506@gmail.com> <500BE0CD.1050502@gmail.com> Message-ID: There are no real cons..it gets compiled out. The big pros to me are put a break point on them and access control ( which can be different between read and write) . However I'm not sure how to do private field / public property ( get function) in Rust . Ben On Sun, Jul 22, 2012 at 7:15 PM, David Bruant wrote: > Le 22/07/2012 12:56, Matthieu Monrocq a ?crit : > > Hi, > > It sounds to me like properties => > http://en.wikipedia.org/wiki/Property_%28programming%29 > > A property, in some object-oriented programming languages, is a special sort > of class member, intermediate between a field (or data member) and a method. > Properties are read and written like fields, but property reads and writes > are (usually) translated to get and set method calls. > > Is this what you wanted to express ? > > The definition seems close to what I described indeed :-) > Does Rust already have support for these? > > What's missing from the wikipedia page is a pro/con analysis. I've described > pros in my initial message, I'm curious of arguments against properties. > > Thanks, > > David > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From pwalton at mozilla.com Sun Jul 22 08:30:44 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 22 Jul 2012 08:30:44 -0700 Subject: [rust-dev] Getter and setters In-Reply-To: <500AFAE7.3020506@gmail.com> References: <500AFAE7.3020506@gmail.com> Message-ID: <500C1CA4.8070404@mozilla.com> On 7/21/12 11:54 AM, David Bruant wrote: > What do you think? First off, there are several problems with this code, the most obvious of which is that it's an awkwardly newtype'd record and not a struct. Fixing that should make the code look a lot less awkward. As for getters and setters, I've thought about them, but I'm really inclined to say YAGNI here. C# added them, and they actually accrued a lot of complexity over time (autogenerated getters and setters, etc). You can pretty easily make a function opts() and set_opts(). Our complexity budget is very strained as it is. Patrick From bklooste at gmail.com Sun Jul 22 09:52:44 2012 From: bklooste at gmail.com (Bennie Kloosteman) Date: Mon, 23 Jul 2012 00:52:44 +0800 Subject: [rust-dev] Getter and setters In-Reply-To: <500C1CA4.8070404@mozilla.com> References: <500AFAE7.3020506@gmail.com> <500C1CA4.8070404@mozilla.com> Message-ID: > > As for getters and setters, I've thought about them, but I'm really > inclined to say YAGNI here. C# added them, and they actually accrued a lot > of complexity over time (autogenerated getters and setters, etc). You can > pretty easily make a function opts() and set_opts(). Our complexity budget > is very strained as it is. > > Patrick > > > Yes you can easily make a function BUT - Your spending a lot of time making Rust brief yet hear you are writing a function for every field.. that's a lot of brain dead code.. When C# started , first they thought properties were a nice to have but later properties became a representation that means you want to export it . This allowed objects to control what was exported but without the internals being exported. So objects in the GUI bind to properties but not fields , likewise most serialization and ORMs used public properties to indicate the user wants to export this.. Since it became so common (and you would most certainly not write professional C# code without public properties and private fields , ) the new auto property was introduced to reduce it eg int field { get ; set; } ; OR int field { get ; private set; } ; Which as most of you know generates a hidden field wrapped by public properties succinctly. This covers 80% of cases but in the other cases where you need to manipulate it you still need the field and property That said personally I think there is no point having properties and prop functions unless you can have "private" fields which im not sure Rust can do as you need a "this" pointer which then makes you an OO language . You are then on the bitc path and you get into a lot of confusion in whether to use a trait or a class for polymorphism ... I do however like something like the HasField constraint so you can hide the datastructure but expose the fact it has a particular field eg a count on a collection but you can hide everything else. Anyway so what is Rusts position on data encapsulation , how do you simply hide some of the data without something nasty like hiding it behind a external lookup function ? Ben -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sun Jul 22 11:18:05 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 22 Jul 2012 11:18:05 -0700 Subject: [rust-dev] Getter and setters In-Reply-To: References: <500AFAE7.3020506@gmail.com> <500C1CA4.8070404@mozilla.com> Message-ID: <500C43DD.2050703@mozilla.com> On 7/22/12 9:52 AM, Bennie Kloosteman wrote: > - Your spending a lot of time making Rust brief yet hear you are writing > a function for every field.. that's a lot of brain dead code.. When C# > started , first they thought properties were a nice to have but later > properties became a representation that means you want to export it . > This allowed objects to control what was exported but without the > internals being exported. So objects in the GUI bind to properties but > not fields , likewise most serialization and ORMs used public > properties to indicate the user wants to export this.. Since it became > so common (and you would most certainly not write professional C# code > without public properties and private fields , ) the new auto property > was introduced to reduce it eg > int field { get ; set; } ; OR > int field { get ; private set; } ; > Which as most of you know generates a hidden field wrapped by public > properties succinctly. This covers 80% of cases but in the other cases > where you need to manipulate it you still need the field and property Yes, this is the complexity I was referring to. I'd like to try omitting it and seeing how painful it is. > That said personally I think there is no point having properties and > prop functions unless you can have "private" fields which im not sure > Rust can do as you need a "this" pointer which then makes you an OO > language . Classes (now structs) do have private fields. Methods have an implicit (soon to be explicit) "this" pointer. > You are then on the bitc path and you get into a lot of > confusion in whether to use a trait or a class for polymorphism ... In Rust, there is no class inheritance; your only choice for polymorphism is traits. > Anyway so what is Rusts position on data encapsulation , how do you > simply hide some of the data without something nasty like hiding it > behind a external lookup function ? Private fields. Patrick From pwalton at mozilla.com Sun Jul 22 11:29:16 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 22 Jul 2012 11:29:16 -0700 Subject: [rust-dev] A policy for impls In-Reply-To: References: Message-ID: <500C467C.2090204@mozilla.com> On 7/21/12 5:25 PM, Benjamin Striegel wrote: > Is this a pattern that all the impls in the standard libraries ought to > follow? Is there some value to being able to always refer to > module::function() rather than type.method()? Assuming that #[inline] or > #[inline(always)] remove any overhead, I don't think there's any > downside to it other than cluttered docs. I think it's mostly a backwards-compatibility thing. I'm in favor of having the non-method versions go away. Patrick From masklinn at masklinn.net Sun Jul 22 11:31:48 2012 From: masklinn at masklinn.net (Masklinn) Date: Sun, 22 Jul 2012 20:31:48 +0200 Subject: [rust-dev] Getter and setters In-Reply-To: <500C43DD.2050703@mozilla.com> References: <500AFAE7.3020506@gmail.com> <500C1CA4.8070404@mozilla.com> <500C43DD.2050703@mozilla.com> Message-ID: On 2012-07-22, at 20:18 , Patrick Walton wrote: >> That said personally I think there is no point having properties and >> prop functions unless you can have "private" fields which im not sure >> Rust can do as you need a "this" pointer which then makes you an OO >> language . > > Classes (now structs) do have private fields. Methods have an implicit (soon to be explicit) "this" pointer. > But do they have public fields, and if so why? That is what "properties" try to solve on two fronts: * public fields often can't be part of abstract types (e.g. interfaces) where methods can, in statically typed languages (or at least in C#) so can properties. * public fields and methods are not compatible, syntactically or binary-ly. In languages with public fields and methods, this often leads to syntactically noisy defensive code "just in case" (see: java's or C++'s getter/setter disease ? where IDEs even have support for generating these monsters) a field ever needs to be replaced by a less straightforward access handling. C# also has the issue with its properties (properties and fields are not compatible at the binary/bytecode level) but "autogenerated" properties provide a rather terse way to declare a "public" field. In dynamically typed languages (e.g. Python), properties can be added post-facto to replace a field by a computation (they are drop-in compatible in everything but reflective access) There is also the option of not allowing public fields at all, which solves the issue of transitioning a public field to private/computed, which is what e.g. Smalltalk used to do. Ruby does the same although they have added some sugar (method names ending with `=` will behave as writable attributes, and Object also has three methods autogenerating accessor methods: attr_writer, attr_reader and attr_accessor). Now as I noted above, I do not know if Rust has public fields. If it does, I think that's a mistake especially if the compiler is smart enough to inline "accessor methods", but in that case the discussion needs to happen now, it *will* be held against the language down the line. From pwalton at mozilla.com Sun Jul 22 11:55:00 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 22 Jul 2012 11:55:00 -0700 Subject: [rust-dev] Getter and setters In-Reply-To: References: <500AFAE7.3020506@gmail.com> <500C1CA4.8070404@mozilla.com> <500C43DD.2050703@mozilla.com> Message-ID: <500C4C84.6020409@mozilla.com> On 7/22/12 11:31 AM, Masklinn wrote: > On 2012-07-22, at 20:18 , Patrick Walton wrote: >>> That said personally I think there is no point having properties and >>> prop functions unless you can have "private" fields which im not sure >>> Rust can do as you need a "this" pointer which then makes you an OO >>> language . >> >> Classes (now structs) do have private fields. Methods have an implicit (soon to be explicit) "this" pointer. >> > > But do they have public fields, and if so why? They do, to achieve the FP separation of code and data. Max/min classes have very little magic; they're pretty much just newtyped records. > Now as I noted above, I do not know if Rust has public fields. If it > does, I think that's a mistake especially if the compiler is smart > enough to inline "accessor methods", but in that case the discussion > needs to happen now, it *will* be held against the language down the > line. I'm not sure. Is it a mistake in, say, Haskell or ML? Patrick From pwalton at mozilla.com Sun Jul 22 12:09:57 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 22 Jul 2012 12:09:57 -0700 Subject: [rust-dev] Getter and setters In-Reply-To: <500C4C84.6020409@mozilla.com> References: <500AFAE7.3020506@gmail.com> <500C1CA4.8070404@mozilla.com> <500C43DD.2050703@mozilla.com> <500C4C84.6020409@mozilla.com> Message-ID: <500C5005.4090408@mozilla.com> To follow up, in order to get rid of public fields, we'd have to require all field names to be module-private and have the automatic "public accessor and mutator" syntax generate "impl" declarations next to the class. If the field was immutable, it'd have to generate two implementations, one for &Foo and one for &mut Foo; if the field was mutable, it'd generate one for &Foo. Then we'd have to come up with some way to spell "this function is a getter" and "this function is a setter". Also keep in mind several caveats: * The field would not actually be private to the struct; it'd be private to the module containing the struct. * The field wouldn't really be private, as it could still be named by the outside world in the "Point { x: 1, y: 2 }"-style struct construction syntax. Changing this would require making the struct construction syntax module-private as well and forcing everyone to write constructors for the simplest of newtyped records. Right now you have to do this, and it's one of the major reasons why a lot of people don't use classes. All of this makes me think that removing public fields is not worth it. If we need to, we can make macros that generate accessor and mutator methods and see how that goes, for those who don't want to make their fields public. Honestly the issue just doesn't come up in Rust as often as it does in Java and C#; I suspect it has to do with the fact that we program in FP style in Rust, separating code and data, more than OO style. Of course there are benefits to OO style in many programs -- I'm a pluralist when it comes to programming style! -- but forbidding public fields just feels like it mandates a particular style too heavily. Patrick From pwalton at mozilla.com Sun Jul 22 12:17:28 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 22 Jul 2012 12:17:28 -0700 Subject: [rust-dev] Getter and setters In-Reply-To: <500C5005.4090408@mozilla.com> References: <500AFAE7.3020506@gmail.com> <500C1CA4.8070404@mozilla.com> <500C43DD.2050703@mozilla.com> <500C4C84.6020409@mozilla.com> <500C5005.4090408@mozilla.com> Message-ID: <500C51C8.7050808@mozilla.com> Oh, and also forbidding public fields would break pattern matching, unless we came up with some way to overload *that* a la Scala's "unapply". Patrick From jld at panix.com Sat Jul 21 12:04:35 2012 From: jld at panix.com (Jed Davis) Date: Sat, 21 Jul 2012 12:04:35 -0700 Subject: [rust-dev] Merge LLVM with the 3.1 release In-Reply-To: References: Message-ID: <20120721190435.GA19990@panix.com> On Sat, Jul 21, 2012 at 05:59:15PM +1000, Zack Corr wrote: > As mentioned on issue #2641 by > jld: > >> April 18th: 3.1 is branched. (llvm-mirror/clang at 103f41d) >> April 26th: Rust grabs trunk. (llvm-mirror/clang at 9b94cd1) >> April 30th: bug is fixed on trunk. (llvm-mirror/clang at b86b855) >> May 8th: fix is crossported to 3.1. (llvm-mirror/clang at 82520fb) > > Rust's LLVM was merged with 3.1 before the fix for issue #2641 was merged > into 3.1 for the official release. It's a little weirder than that, because Rust apparently grabbed LLVM and Clang from their respective trunks, rather than release_31, after the branch point. So there are a bunch of commits[*] that would be dropped if it switched to the 3.1 final version, but I don't know if those matter. The simple, low-impact alternative is to just pull up that one commit, thusly: https://github.com/jld/clang/tree/rust-2641 https://github.com/jld/llvm/tree/rust-2641 https://github.com/jld/rust/tree/rust-2641 > Merging might also fix something that was breaking my experimentations with > JIT which seemed to work with Arch Linux's LLVM 3.1 package. ...but that wouldn't fix anyone else's problems. --Jed [*] `git rev-list origin/release_31..9b94cd1 | wc -l` => 150 `git log origin/master..origin/release_31 | grep -c '^ *Merging r[0-9]*:$'` => 23 From dpreston at mozilla.com Mon Jul 23 09:23:33 2012 From: dpreston at mozilla.com (Donovan Preston) Date: Mon, 23 Jul 2012 12:23:33 -0400 Subject: [rust-dev] rust to JavaScript In-Reply-To: <434D654F-1EC6-4865-948A-EF20238FED11@mozilla.com> References: <4FFE7D79.9040802@gmail.com> <4FFEDBEA.6080003@alum.mit.edu> <63CA0DE3-F5D5-4B6C-B50E-5C6858F7CA0F@mozilla.com> <50080C85.4090103@alum.mit.edu> <434D654F-1EC6-4865-948A-EF20238FED11@mozilla.com> Message-ID: <500D7A85.20806@mozilla.com> Is this likely to get into firefox any time soon? I would be so, so happy. Donovan On 7/21/12 3:18 PM, David Herman wrote: > Oh, actually, I wonder if the "transfer" semantics of ArrayBuffers wouldn't give us the ability to emulate the exchange heap more accurately: > > http://www.khronos.org/registry/typedarray/specs/latest/#9.2 > http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast > > Long story short: you can dynamically emulate unique ownership of binary data and transfer it between workers without copies. The sender's reference to the data becomes "neutered" so that it's unable to view the data after the send. Of course, Rust would guarantee it never even tried. > > Dave > > On Jul 19, 2012, at 6:32 AM, Niko Matsakis wrote: > >> On 7/18/12 9:48 PM, David Herman wrote: >>> That would result in a very different performance model, since Rust expects to be able to create several metric craptons [1] of concurrent tasks, whereas the number of workers you can create is much smaller. But who knows, it might still be interesting enough to be useful for some kinds of programs; ClojureScript is making progress as a single-threaded dialect of Clojure, after all. >> Not to mention that we would have to deep-copy all messages. >> >> >> >> Niko > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From dherman at mozilla.com Mon Jul 23 15:18:25 2012 From: dherman at mozilla.com (David Herman) Date: Mon, 23 Jul 2012 15:18:25 -0700 Subject: [rust-dev] rust to JavaScript In-Reply-To: <500D7A85.20806@mozilla.com> References: <4FFE7D79.9040802@gmail.com> <4FFEDBEA.6080003@alum.mit.edu> <63CA0DE3-F5D5-4B6C-B50E-5C6858F7CA0F@mozilla.com> <50080C85.4090103@alum.mit.edu> <434D654F-1EC6-4865-948A-EF20238FED11@mozilla.com> <500D7A85.20806@mozilla.com> Message-ID: <389441E6-2395-450D-8F30-0C9AE3BBCA3D@mozilla.com> I don't know if anyone's assigned to it currently. Dave On Jul 23, 2012, at 9:23 AM, Donovan Preston wrote: > Is this likely to get into firefox any time soon? I would be so, so happy. > > Donovan > > On 7/21/12 3:18 PM, David Herman wrote: >> Oh, actually, I wonder if the "transfer" semantics of ArrayBuffers wouldn't give us the ability to emulate the exchange heap more accurately: >> >> http://www.khronos.org/registry/typedarray/specs/latest/#9.2 >> http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast >> >> Long story short: you can dynamically emulate unique ownership of binary data and transfer it between workers without copies. The sender's reference to the data becomes "neutered" so that it's unable to view the data after the send. Of course, Rust would guarantee it never even tried. >> >> Dave >> >> On Jul 19, 2012, at 6:32 AM, Niko Matsakis wrote: >> >>> On 7/18/12 9:48 PM, David Herman wrote: >>>> That would result in a very different performance model, since Rust expects to be able to create several metric craptons [1] of concurrent tasks, whereas the number of workers you can create is much smaller. But who knows, it might still be interesting enough to be useful for some kinds of programs; ClojureScript is making progress as a single-threaded dialect of Clojure, after all. >>> Not to mention that we would have to deep-copy all messages. >>> >>> >>> >>> Niko >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > From zackcorr95 at gmail.com Mon Jul 23 21:46:27 2012 From: zackcorr95 at gmail.com (Zack Corr) Date: Tue, 24 Jul 2012 14:46:27 +1000 Subject: [rust-dev] Merge LLVM with the 3.1 release In-Reply-To: <20120721190435.GA19990@panix.com> References: <20120721190435.GA19990@panix.com> Message-ID: On 7/22/12, Jed Davis wrote: > ...but that wouldn't fix anyone else's problems. Well, I'm writing the JIT compiler as a compiler target, not just for myself. There's really no reason not to merge with upstream 3.1 or 3.2 anyway, there's numerous fixes and improvements. I don't think it would be that hard to merge the Rust patches with it, but I'm not sure how fundamental the changes are. From ben.striegel at gmail.com Tue Jul 24 05:58:31 2012 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 24 Jul 2012 08:58:31 -0400 Subject: [rust-dev] Merge LLVM with the 3.1 release In-Reply-To: References: <20120721190435.GA19990@panix.com> Message-ID: I believe the upcoming LLVM changes can be found in pcwalton's LLVM repo, in the noteroots-ir branch: https://github.com/pcwalton/llvm/tree/noteroots-ir On Tue, Jul 24, 2012 at 12:46 AM, Zack Corr wrote: > On 7/22/12, Jed Davis wrote: > > ...but that wouldn't fix anyone else's problems. > > Well, I'm writing the JIT compiler as a compiler target, not just for > myself. There's really no reason not to merge with upstream 3.1 or 3.2 > anyway, there's numerous fixes and improvements. I don't think it > would be that hard to merge the Rust patches with it, but I'm not sure > how fundamental the changes are. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue Jul 24 08:51:36 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 24 Jul 2012 08:51:36 -0700 Subject: [rust-dev] Merge LLVM with the 3.1 release In-Reply-To: References: <20120721190435.GA19990@panix.com> Message-ID: <500EC488.1090206@mozilla.com> On 12-07-24 5:58 AM, Benjamin Striegel wrote: > I believe the upcoming LLVM changes can be found in pcwalton's LLVM > repo, in the noteroots-ir branch: > > https://github.com/pcwalton/llvm/tree/noteroots-ir Yeah. This is near the top of my list for the next couple days (catching LLVM up to closer-to-trunk). There's a pull req open I'll close when it's done. -Graydon From graydon at mozilla.com Tue Jul 24 08:59:05 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 24 Jul 2012 08:59:05 -0700 Subject: [rust-dev] Agenda Message-ID: <500EC649.5000003@mozilla.com> https://etherpad.mozilla.org/Meeting-weekly-2012-07-24 Starting now-ish. Sorry for late notice. From eslaughter at mozilla.com Tue Jul 24 09:22:45 2012 From: eslaughter at mozilla.com (Elliott Slaughter) Date: Tue, 24 Jul 2012 09:22:45 -0700 (PDT) Subject: [rust-dev] Merge LLVM with the 3.1 release In-Reply-To: Message-ID: <2125439973.774824.1343146965308.JavaMail.root@mozilla.com> ----- Original Message ----- > From: "Benjamin Striegel" > To: rust-dev at mozilla.org > Sent: Tuesday, July 24, 2012 5:58:31 AM > Subject: Re: [rust-dev] Merge LLVM with the 3.1 release > > > I believe the upcoming LLVM changes can be found in pcwalton's LLVM > repo, in the noteroots-ir branch: > > https://github.com/pcwalton/llvm/tree/noteroots-ir Please note, however, that this branch is currently unhappy with the code we generate in rustc. I'm about to fix this, but if you try it right now, you'll run into assertion failures in the liveness check. > > On Tue, Jul 24, 2012 at 12:46 AM, Zack Corr < zackcorr95 at gmail.com > > wrote: > > > > On 7/22/12, Jed Davis < jld at panix.com > wrote: > > ...but that wouldn't fix anyone else's problems. > > Well, I'm writing the JIT compiler as a compiler target, not just for > myself. There's really no reason not to merge with upstream 3.1 or > 3.2 > anyway, there's numerous fixes and improvements. I don't think it > would be that hard to merge the Rust patches with it, but I'm not > sure > how fundamental the changes are. It's mainly the GC branch of LLVM (see link to pcwalton's fork above), which we'll need to rebase when we update LLVM. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From graydon at mozilla.com Tue Jul 24 17:19:08 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 24 Jul 2012 17:19:08 -0700 Subject: [rust-dev] Merge LLVM with the 3.1 release In-Reply-To: <2125439973.774824.1343146965308.JavaMail.root@mozilla.com> References: <2125439973.774824.1343146965308.JavaMail.root@mozilla.com> Message-ID: <500F3B7C.8090506@mozilla.com> I've updated LLVM, clang and compiler-rt to SVN snaps within a few hours of one another, from today's LLVM trunk, and merged Elliott's LLVM GC work (which is the current continuation of pcwalton's GC work), and landed a little bit of configury and cleanup from Zack. Presumably I broke everything while doing this, though submodules are sufficiently stateful that I've also convinced myself that all's well due to my own workspace "seeming to work". I'll mop up as necessary tomorrow. Meanwhile please clear out and rebuild your llvm subdirs, they are probably not going to enjoy updating sideways. Sorry, (blame submodules!) -Graydon From niko at alum.mit.edu Tue Jul 24 18:50:55 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 24 Jul 2012 18:50:55 -0700 Subject: [rust-dev] exhaustiveness checking can fail due to confusion of identifier and variant Message-ID: <500F50FF.6010408@alum.mit.edu> I just uncovered a rather surprising "failure" of exhaustiveness checking. There was an enum defined like so in a module A: enum foo { a, b, c } and then, in another module B: import A::{foo, a, b}; // Note: no c! fn bar(f: foo) { alt f { a {"a"} b {"b"} c {"c"} } } Now this code worked fine, but there is a subtle bug: the value c here is not acting as a variant but rather a catch-all. So now when I added a new variant `d`, the code still compiled fine but just acted funny. I recall this sort of hazard was pointed out earlier (though in that case the example was of removing a variant, which can lead to a similar sort of catch-all). Also, fixing bug #941 (warn about unused bindings in patterns) would also have prevented this error. But still, nasty! Niko From niko at alum.mit.edu Tue Jul 24 18:55:00 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 24 Jul 2012 18:55:00 -0700 Subject: [rust-dev] exhaustiveness checking can fail due to confusion of identifier and variant In-Reply-To: <500F50FF.6010408@alum.mit.edu> References: <500F50FF.6010408@alum.mit.edu> Message-ID: <500F51F4.5090309@alum.mit.edu> Patrick, how hard would it be to allow something like: import A::foo::* to get all the variants of an enum into scope? Niko On 7/24/12 6:50 PM, Niko Matsakis wrote: > I just uncovered a rather surprising "failure" of exhaustiveness > checking. There was an enum defined like so in a module A: > > enum foo { a, b, c } > > and then, in another module B: > > import A::{foo, a, b}; // Note: no c! > > fn bar(f: foo) { > alt f { > a {"a"} > b {"b"} > c {"c"} > } > } > > Now this code worked fine, but there is a subtle bug: the value c here > is not acting as a variant but rather a catch-all. So now when I > added a new variant `d`, the code still compiled fine but just acted > funny. > > I recall this sort of hazard was pointed out earlier (though in that > case the example was of removing a variant, which can lead to a > similar sort of catch-all). Also, fixing bug #941 (warn about unused > bindings in patterns) would also have prevented this error. But still, > nasty! > > > Niko > > > > From catamorphism at gmail.com Tue Jul 24 18:56:28 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Tue, 24 Jul 2012 18:56:28 -0700 Subject: [rust-dev] exhaustiveness checking can fail due to confusion of identifier and variant In-Reply-To: <500F51F4.5090309@alum.mit.edu> References: <500F50FF.6010408@alum.mit.edu> <500F51F4.5090309@alum.mit.edu> Message-ID: On Tue, Jul 24, 2012 at 6:55 PM, Niko Matsakis wrote: > Patrick, how hard would it be to allow something like: > > import A::foo::* > > to get all the variants of an enum into scope? > It used to be that import A::foo; *would* get all the variants of an enum into scope, if foo was an enum. We got rid of this because Patrick said it was too hard to implement in the context of resolve3. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From niko at alum.mit.edu Tue Jul 24 19:29:54 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 24 Jul 2012 19:29:54 -0700 Subject: [rust-dev] exhaustiveness checking can fail due to confusion of identifier and variant In-Reply-To: References: <500F50FF.6010408@alum.mit.edu> <500F51F4.5090309@alum.mit.edu> Message-ID: <500F5A22.20107@alum.mit.edu> Yeah, thinking more on it I'm not sure I want it anyhow. It's kind of magical. Probably just fixing the bug about warning about unused bindings is the best thing. Niko On 7/24/12 6:56 PM, Tim Chevalier wrote: > On Tue, Jul 24, 2012 at 6:55 PM, Niko Matsakis wrote: >> Patrick, how hard would it be to allow something like: >> >> import A::foo::* >> >> to get all the variants of an enum into scope? >> > It used to be that import A::foo; *would* get all the variants of an > enum into scope, if foo was an enum. We got rid of this because > Patrick said it was too hard to implement in the context of resolve3. > > Cheers, > Tim > From pwalton at mozilla.com Tue Jul 24 19:53:35 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 24 Jul 2012 19:53:35 -0700 Subject: [rust-dev] exhaustiveness checking can fail due to confusion of identifier and variant In-Reply-To: <500F5A22.20107@alum.mit.edu> References: <500F50FF.6010408@alum.mit.edu> <500F51F4.5090309@alum.mit.edu> <500F5A22.20107@alum.mit.edu> Message-ID: <500F5FAF.6090405@mozilla.com> On 07/24/2012 07:29 PM, Niko Matsakis wrote: > Yeah, thinking more on it I'm not sure I want it anyhow. It's kind of > magical. > > Probably just fixing the bug about warning about unused bindings is the > best thing. In that example, if A::foo were a module in addition to an enum, would you import everything from the module in addition to all the variants? If so, resolve3 would have to resolve foo in the type namespace as well as the module namespace in order to resolve A::foo::*. This would make globs less likely to resolve (by how much, I don't know). The interaction with multiple namespaces and reexports was the reason why the original magic variant importing behavior was removed. Patrick From pwalton at mozilla.com Tue Jul 24 19:56:29 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 24 Jul 2012 19:56:29 -0700 Subject: [rust-dev] exhaustiveness checking can fail due to confusion of identifier and variant In-Reply-To: <500F5A22.20107@alum.mit.edu> References: <500F50FF.6010408@alum.mit.edu> <500F51F4.5090309@alum.mit.edu> <500F5A22.20107@alum.mit.edu> Message-ID: <500F605D.1050509@mozilla.com> On 07/24/2012 07:29 PM, Niko Matsakis wrote: > Yeah, thinking more on it I'm not sure I want it anyhow. It's kind of > magical. > > Probably just fixing the bug about warning about unused bindings is the > best thing. Another idea: If we camel-cased variants by convention, then we could issue a warning if a camel-cased identifier resolves to a variable binding. Patrick From niko at alum.mit.edu Tue Jul 24 20:34:44 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 24 Jul 2012 20:34:44 -0700 Subject: [rust-dev] exhaustiveness checking can fail due to confusion of identifier and variant In-Reply-To: <500F5FAF.6090405@mozilla.com> References: <500F50FF.6010408@alum.mit.edu> <500F51F4.5090309@alum.mit.edu> <500F5A22.20107@alum.mit.edu> <500F5FAF.6090405@mozilla.com> Message-ID: <500F6954.5060903@alum.mit.edu> On 7/24/12 7:53 PM, Patrick Walton wrote: > In that example, if A::foo were a module in addition to an enum, would > you import everything from the module in addition to all the variants? > If so, resolve3 would have to resolve foo in the type namespace as > well as the module namespace in order to resolve A::foo::*. This would > make globs less likely to resolve (by how much, I don't know). > > The interaction with multiple namespaces and reexports was the reason > why the original magic variant importing behavior was removed. I didn't realize we ever had that feature. I knew that if you *exported* an enum it exported the variants, didn't know the same worked for importing at one point. Niko From niko at alum.mit.edu Wed Jul 25 05:44:22 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 25 Jul 2012 05:44:22 -0700 Subject: [rust-dev] mode removal Message-ID: <500FEA26.8090108@alum.mit.edu> Here is my proposed plan for mode removal. The eventual goal is to pass all parameters by value. The idea is to proceed in two steps. In the first phase, we migrate the codebase over so that only two modes are in use: the default mode or the by-copy mode (+). By-copy will be used for unique pointers (including vecs, strs, fn~) which are expensive to copy and which the callee wishes to take ownership of. The default mode will be used for all other values. If you wish to borrow a unique pointer, then you use a borrowed pointer. This migration will be done piecemeal. There will be a lint mode (I am working on it now) which warns you about arguments that do not follow this convention. I'll send e-mail when it's ready. The idea will be to migrate modules or functions one at a time and then set the lint mode to prevent regression. Once the migration is complete, we can simply pass all arguments by value. There is one other factor, which is the changing of alt bindings to make by-ref explicit. I imagine this will proceed in a similar fashion. I will add an optional ref keyword that (currently) has no significance and a lint mode that warns if it is not used in the appropriate places. We can then switch over once refs are added where they need to be. Sound good? Niko From garethdanielsmith at gmail.com Wed Jul 25 12:57:37 2012 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Wed, 25 Jul 2012 20:57:37 +0100 Subject: [rust-dev] mode removal In-Reply-To: <500FEA26.8090108@alum.mit.edu> References: <500FEA26.8090108@alum.mit.edu> Message-ID: <50104FB1.8080800@gmail.com> On 25/07/12 13:44, Niko Matsakis wrote: > Sound good? Yes! I think modes are unintuitive and awkward, and that removing them is a good thing. To clarify how the migration will work, how will code like this look during a. the migration phase and b. after the migration? fn shizzle(x: {mut a: int}) { x.a = 2; } fn main() { let x = {mut a: 1}; shizzle(x); io::println(#fmt("x.a = %d", x.a)); // prints "x.a = 2" } Thanks Gareth From graydon at mozilla.com Wed Jul 25 13:11:00 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 25 Jul 2012 13:11:00 -0700 Subject: [rust-dev] mode removal In-Reply-To: <50104FB1.8080800@gmail.com> References: <500FEA26.8090108@alum.mit.edu> <50104FB1.8080800@gmail.com> Message-ID: <501052D4.2020606@mozilla.com> On 12-07-25 12:57 PM, Gareth Smith wrote: > On 25/07/12 13:44, Niko Matsakis wrote: > >> Sound good? > > Yes! I think modes are unintuitive and awkward, and that removing them > is a good thing. Yes. They exist for only two reasons: (1) we used to support type parameters via runtime dispatch, now we monomorphize, and are comfortable paying that cost. (2) we used to have no first-class borrowed pointers, but now we do. IOW they're entirely redundant now. We've just been postponing their removal until we're sure borrowed pointers work right. They seem to, or at least well enough, now. > To clarify how the migration will work, how will code like this look > during a. the migration phase and b. after the migration? > > fn shizzle(x: {mut a: int}) { > x.a = 2; > } > > fn main() { > let x = {mut a: 1}; > shizzle(x); > io::println(#fmt("x.a = %d", x.a)); // prints "x.a = 2" > } During and after migration -- indeed, you can write this today, and should be doing so in new code -- the borrowed-pointer-using code looks like so: fn shizzle(x: &{mut a: int}) { x.a = 2; } fn main() { let x = {mut a: 1}; // x is the record shizzle(&x); // &x is a pointer io::println(#fmt("x.a = %d", x.a)); } Or, alternatively, writing main as so: fn main() { let x = &{mut a: 1}; // x is a pointer shizzle(x); io::println(#fmt("x.a = %d", x.a)); } Both should work, just a matter of whether you want x to be a pointer, or the record itself. The "migration" is just a matter of going through all the existing code and rewriting it to use such newer idioms. -Graydon From garethdanielsmith at gmail.com Thu Jul 26 12:52:52 2012 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Thu, 26 Jul 2012 20:52:52 +0100 Subject: [rust-dev] mode removal In-Reply-To: <501052D4.2020606@mozilla.com> References: <500FEA26.8090108@alum.mit.edu> <50104FB1.8080800@gmail.com> <501052D4.2020606@mozilla.com> Message-ID: <5011A014.6050502@gmail.com> On 25/07/12 21:11, Graydon Hoare wrote: > ... the borrowed-pointer-using code looks like so: ... Thanks for the clarification. That makes sense. Can I have another clarification please. I have some rust code currently that looks like this: // a type that should not be copied implicitly because it is mutable class fat { let mut doughnuts: int; new(){ self.doughnuts = 99; } } trait fat_methods { fn shizzle(); } impl of fat_methods for fat { fn shizzle() { io::println("yo shizzlin"); } } fn main() { let x = fat(); x.shizzle(); } One way to change this code would be to make the impl for &fat rather than for fat, and change x's expression to &fat(). Luckily this also seems to allow calling methods on @fat and ~fat types. Is this a reasonable way to migrate the code? Are their alternatives? Thanks Gareth From graydon at mozilla.com Thu Jul 26 13:32:11 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 26 Jul 2012 13:32:11 -0700 Subject: [rust-dev] mode removal In-Reply-To: <5011A014.6050502@gmail.com> References: <500FEA26.8090108@alum.mit.edu> <50104FB1.8080800@gmail.com> <501052D4.2020606@mozilla.com> <5011A014.6050502@gmail.com> Message-ID: <5011A94B.3030400@mozilla.com> On 12-07-26 12:52 PM, Gareth Smith wrote: > One way to change this code would be to make the impl for &fat rather > than for fat, and change x's expression to &fat(). Luckily this also > seems to allow calling methods on @fat and ~fat types. Is this a > reasonable way to migrate the code? Are their alternatives? I'm not clear to me what the state of this machinery is. It sounds reasonable to me but I recall there being a bunch of subtle wrinkles to it, and it's possible that it will automatically borrow a &fat when presented with a @fat. I suspect one of Lindsey, Tim, Niko or Patrick can answer this better than me. -Graydon From niko at alum.mit.edu Thu Jul 26 13:54:23 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 26 Jul 2012 13:54:23 -0700 Subject: [rust-dev] mode removal In-Reply-To: <5011A014.6050502@gmail.com> References: <500FEA26.8090108@alum.mit.edu> <50104FB1.8080800@gmail.com> <501052D4.2020606@mozilla.com> <5011A014.6050502@gmail.com> Message-ID: <5011AE7F.3020101@alum.mit.edu> On 7/26/12 12:52 PM, Gareth Smith wrote: > One way to change this code would be to make the impl for &fat rather > than for fat, and change x's expression to &fat(). Luckily this also > seems to allow calling methods on @fat and ~fat types. Is this a > reasonable way to migrate the code? Are their alternatives? Summary: we plan to make it possible for you to call methods on a variable of type `fat` even if those methods are defined on `&fat`. But it doesn't work yet. Details: There is some debate about this. So, it seems that the best thing is to define your methods on &fat. However, this means (as you observed) that if you have a local variable `x` of type `fat` you can't call methods on it without something awkward like: (&x).fat(...) My original thought was that you would define the variable to be of type `&fat`, as you suggested. This seems to have a nice orthogonality to `@fat` and `~fat`. However, there is a downside: an `&fat` value is aliasable and hence less flexible. You can't, for example, send it to another task. So Patrick suggested that method call could "auto-deref" but also "auto-ref" . That is, if you write `x.y()`, where `x` has type `T`, we will take the address of `x` and call methods defined on `&T`. This is rather like C++, which defines methods on T but then the receiver has type T*. This would replace the current rule that will allow methods defined for `&T` to be called on `@T` or `~T`. That instead becomes a consequence of one auto-deref (to reach the receiver type of `T`) and one auto-ref from there (to `&T`). So the receiver effectively becomes `&*T`. In fact, this is the same as today, except that it occurs on one step: the type system allows `@T` to be converted to `&T`. Niko From garethdanielsmith at gmail.com Fri Jul 27 12:46:09 2012 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Fri, 27 Jul 2012 20:46:09 +0100 Subject: [rust-dev] mode removal In-Reply-To: <5011AE7F.3020101@alum.mit.edu> References: <500FEA26.8090108@alum.mit.edu> <50104FB1.8080800@gmail.com> <501052D4.2020606@mozilla.com> <5011A014.6050502@gmail.com> <5011AE7F.3020101@alum.mit.edu> Message-ID: <5012F001.3040906@gmail.com> On 26/07/12 21:54, Niko Matsakis wrote: > Summary: we plan to make it possible for you to call methods on a > variable of type `fat` even if those methods are defined on `&fat`. > But it doesn't work yet... Thats interesting. Thanks for the explanation. Gareth From fw at deneb.enyo.de Sat Jul 28 04:06:05 2012 From: fw at deneb.enyo.de (Florian Weimer) Date: Sat, 28 Jul 2012 13:06:05 +0200 Subject: [rust-dev] Tutorial issues Message-ID: <874nos402q.fsf@mid.deneb.enyo.de> I went over tutorial and spotted a few typos (see below). I think the SHA-1 example shouldn't use the static buffer because it is not task-safe. More significantly, the gettimeofday example still uses the wrong types for time_t and suseconds_t. time_t is usually signed and not always 64 bit (or the size of a machine word). suseconds_t can be a 32-bit type even on 64-bit machines, and the padding is in the wrong place on big-endian machines. Not sure if rustc already works on anything besides i386 and amd64 on GNU libc platforms. But even to support these two, you need this: type timeval = {mut tv_sec: c_long, mut tv_usec: c_long}; time_t and suseconds_t are two of the most problematic types for FFI. It's difficult to find structs in POSIX which are essentially fixed. struct pollfd appears to be one such type, but the example would have to be larger. diff --git a/doc/tutorial.md b/doc/tutorial.md index ed32100..78f41e3 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -350,7 +350,7 @@ more underscores. The double-colon (`::`) is used as a module separator, so `io::println` means 'the thing named `println` in the module -named `io`'. +named `io`. Rust will normally emit warnings about unused variables. These can be suppressed by using a variable name that starts with an underscore. @@ -1413,7 +1413,7 @@ let exchange_crayons: ~[crayon] = ~[banana_mania, beaver, bittersweet]; > but is deprecated. In the future it will probably represent some > "reasonable default" vector type. > -> Unique vectors are the currently-recomended vector type for general +> Unique vectors are the currently-recommended vector type for general > use as they are the most tested and well-supported by existing > libraries. There will be a gradual shift toward using more > stack and local vectors in the coming releases. @@ -2814,7 +2814,7 @@ C functions often take pointers to structs as arguments. Since Rust records are binary-compatible with C structs, Rust programs can call such functions directly. -This program uses the Posix function `gettimeofday` to get a +This program uses the POSIX function `gettimeofday` to get a microsecond-resolution timer. ~~~~ From pwalton at mozilla.com Sat Jul 28 19:38:57 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 28 Jul 2012 19:38:57 -0700 Subject: [rust-dev] RFC: string literals as &static.str Message-ID: <5014A241.70701@mozilla.com> Hi everyone, Currently, string literals have type str/_; e.g. "foo" has type str/3. This means that string literals are stored on the stack and are constructed anew for every function invocation with a series of mov instructions. While this is very occasionally useful, and it mirrors how vectors work, I suspect that 99% of string literals are actually intended to be stored in constant memory. The current behavior is a burden and an aesthetic problem, since in order to achieve the desired behavior, 99% of string literals will need to be prefixed with & or ~; e.g. println(&"Hello world!") I'd like to propose that unadorned string literals instead have the type &static.str, which mirrors how it (usually) works in C and C++. To get the current behavior one would write "Hello world"/_. This is slightly inconsistent with vectors, but string literals are special anyway in C and C++. This will make almost all the ~" punctuation-diphthongs that are peppered throughout Rust code go away. Thoughts? Patrick From erick.tryzelaar at gmail.com Sun Jul 29 11:43:46 2012 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Sun, 29 Jul 2012 11:43:46 -0700 Subject: [rust-dev] Ragel support for Rust Message-ID: Morning all, I just finished my initial support for a Rust backend for Ragel, which I describe on my blog: http://erickt.github.com/blog/2012/07/29/rust-for-ragel/ It could be pretty useful if we can solve the performance issues I mention. Inlined below: I've written a bunch of simple parsers for Rust, and it's starting to get a little obnoxious. So I added a Rust backend to the [Ragel State Machine Compiler](http://www.complang.org/ragel/). You can find my fork [here](https://github.com/erickt/ragel). I'm waiting for Rust to stablize before I try to push it upstream. Ragel is a rather neat way of writing simple parsers. In some ways it's pretty similar to Lex, but Ragel also allows you execute arbitrary code at any point in the state machine. Furthermore, this arbitrary code can manipulate the state machine itself, so it can be used in many places you'd traditionally need a full parser, such as properly handling parentheses. Here's an example of a `atoi` function: ``` %%{ machine atoi; action see_neg { neg = true; } action add_digit { res = res * 10 + (fc as int - '0' as int); } main := ( '-' @see_neg | '+' )? ( digit @add_digit )+ '\n'? ; write data; }%% fn atoi(data: ~str) -> option { let mut neg = false; let mut res = 0; // Ragel assumes that it will be iterating over a value called data, but we // need to tell ragel where to start (p) and end (pe) parsing. let mut p = 0; let mut pe = data.len(); // This is the current state in the state machine. let mut cs: int; write init; write exec; if neg { res = -1 * res; } // If we stopped before we hit one of the exit states, then there must have // been an error of some sort. if cs < atoi_first_final { none } else { some(res) } } ``` While this is probably a bit more verbose than writing `atoi` by hand, it does make the grammar pretty explicit, which can help keep it accurate. Unfortunately there are some pretty severe performance issues at the moment. Ragel supports two state machine styles, table-driven and goto-driven. My backend uses tables, but since Rust doesn't yet support global constant vectors, I need to malloc the state machine table on every function call. This results in the [ragel-based url parser](https://github.com/erickt/ragel/blob/rust/examples/rust/url.rl) being about 10 times slower than the equivalent table-based parser in OCaml. You can see the generated code [here](https://gist.github.com/3200980). The `goto` route could be promising to explore. We could simulate it using mutually recursive function calls. OCaml does this. But again, since Rust doesn't support tailcalls (and may [ever](https://github.com/mozilla/rust/issues/217)), we could run into a stack explosion. It may work well for small grammars though, and maybe LLVM could optimize calls into tailcalls. Unless I'm doing something glaringly wrong, it seems likely that we are going to need some compiler help before these performance issues get solved. From pwalton at mozilla.com Sun Jul 29 12:18:25 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 29 Jul 2012 12:18:25 -0700 Subject: [rust-dev] Ragel support for Rust In-Reply-To: References: Message-ID: <50158C81.60102@mozilla.com> On 07/29/2012 11:43 AM, Erick Tryzelaar wrote: > Morning all, > > I just finished my initial support for a Rust backend for Ragel, which > I describe on my blog: Awesome! > Unfortunately there are some pretty severe performance issues at the moment. > Ragel supports two state machine styles, table-driven and goto-driven. My > backend uses tables, but since Rust doesn't yet support global constant > vectors, I need to malloc the state machine table on every function call. This > results in the [ragel-based url > parser](https://github.com/erickt/ragel/blob/rust/examples/rust/url.rl) > being about > 10 times slower than the equivalent table-based parser in OCaml. You can see > the generated code [here](https://gist.github.com/3200980). Yeah, we definitely need global constant vectors. You can work around it to some degree by preallocating the constant vector and threading it around. > > The `goto` route could be promising to explore. We could simulate it using > mutually recursive function calls. OCaml does this. But again, since Rust > doesn't support tailcalls (and may > [ever](https://github.com/mozilla/rust/issues/217)), we could run into a stack > explosion. It may work well for small grammars though, and maybe LLVM could > optimize calls into tailcalls. There's a bug open on labeled break and continue -- this is needed for the HTML5 parser too. LLVM should do sibling call optimization. This means that, as long as the function you're tail calling has the same number of arguments, it should become a tail call. This may work for your use case. I personally think we should try guaranteed tail call optimization at some point and see whether it hurts performance. Note that this involves switching to Pascal-style calling conventions, which means that the runtime will need to change a bit. Patrick From catamorphism at gmail.com Sun Jul 29 12:20:56 2012 From: catamorphism at gmail.com (Tim Chevalier) Date: Sun, 29 Jul 2012 12:20:56 -0700 Subject: [rust-dev] Ragel support for Rust In-Reply-To: References: Message-ID: On Sun, Jul 29, 2012 at 11:43 AM, Erick Tryzelaar wrote: > Unfortunately there are some pretty severe performance issues at the moment. > Ragel supports two state machine styles, table-driven and goto-driven. My > backend uses tables, but since Rust doesn't yet support global constant > vectors, I need to malloc the state machine table on every function call. This > results in the [ragel-based url > parser](https://github.com/erickt/ragel/blob/rust/examples/rust/url.rl) > being about > 10 times slower than the equivalent table-based parser in OCaml. You can see > the generated code [here](https://gist.github.com/3200980). There's an open bug on vector constants: https://github.com/mozilla/rust/issues/571 It's assigned to me (though I haven't done anything on it yet), so feel free to bug me about it :-) > > The `goto` route could be promising to explore. We could simulate it using > mutually recursive function calls. OCaml does this. But again, since Rust > doesn't support tailcalls (and may > [ever](https://github.com/mozilla/rust/issues/217)), we could run into a stack > explosion. It may work well for small grammars though, and maybe LLVM could > optimize calls into tailcalls. This sounds like the open bug on labelled break and continue, as Patrick said: https://github.com/mozilla/rust/issues/2216 which is currently unassigned. As per #217, we decided not to support general tail calls, but that doesn't mean we can't support tail calls just for the special labelled break/continue form. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Debate is useless when one participant denies the full dignity of the other." -- Eric Berndt From pwalton at mozilla.com Sun Jul 29 12:51:08 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 29 Jul 2012 12:51:08 -0700 Subject: [rust-dev] Ragel support for Rust In-Reply-To: References: Message-ID: <5015942C.2050800@mozilla.com> On 07/29/2012 11:43 AM, Erick Tryzelaar wrote: > Unfortunately there are some pretty severe performance issues at the moment. > Ragel supports two state machine styles, table-driven and goto-driven. My > backend uses tables, but since Rust doesn't yet support global constant > vectors, I need to malloc the state machine table on every function call. This > results in the [ragel-based url > parser](https://github.com/erickt/ragel/blob/rust/examples/rust/url.rl) > being about > 10 times slower than the equivalent table-based parser in OCaml. You can see > the generated code [here](https://gist.github.com/3200980). Another thing you might try is using fixed-length vectors instead of heap-allocated vectors. Patrick From niko at alum.mit.edu Sun Jul 29 18:50:31 2012 From: niko at alum.mit.edu (Niko Matsakis) Date: Sun, 29 Jul 2012 18:50:31 -0700 Subject: [rust-dev] RFC: string literals as &static.str In-Reply-To: <5014A241.70701@mozilla.com> References: <5014A241.70701@mozilla.com> Message-ID: <5015E867.5010809@alum.mit.edu> On 7/28/12 7:38 PM, Patrick Walton wrote: > I'd like to propose that unadorned string literals instead have the > type &static.str, which mirrors how it (usually) works in C and C++. > To get the current behavior one would write "Hello world"/_. This is > slightly inconsistent with vectors, but string literals are special > anyway in C and C++. This will make almost all the ~" > punctuation-diphthongs that are peppered throughout Rust code go away. I'm not sure why this step alone would remove the ~"" strings, rather than (say) causing type errors for those cases where ~str is required but &str is supplied. It seems that the most important thing is to convert the various APIs that can take slices to do so. Or am I missing something? Niko From robert at ocallahan.org Sun Jul 29 20:15:41 2012 From: robert at ocallahan.org (Robert O'Callahan) Date: Mon, 30 Jul 2012 15:15:41 +1200 Subject: [rust-dev] Bikeshed proposal to simplify syntax In-Reply-To: <5005DB99.4060609@mozilla.com> References: <1217675229.16233569.1342560180613.JavaMail.root@mozilla.com> <5005DB99.4060609@mozilla.com> Message-ID: I strongly agree with everything you wrote here :-). I would add that abbreviated identifiers can be OK in local scopes, where it's easy to figure out the meaning of an identifier because all occurrences of it are "right there". Rob -- ?You have heard that it was said, ?Love your neighbor and hate your enemy.? But I tell you, love your enemies and pray for those who persecute you, that you may be children of your Father in heaven. ... If you love those who love you, what reward will you get? Are not even the tax collectors doing that? And if you greet only your own people, what are you doing more than others?" [Matthew 5:43-47] -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Mon Jul 30 10:58:25 2012 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 30 Jul 2012 10:58:25 -0700 Subject: [rust-dev] RFC: string literals as &static.str In-Reply-To: <5015E867.5010809@alum.mit.edu> References: <5014A241.70701@mozilla.com> <5015E867.5010809@alum.mit.edu> Message-ID: <5016CB41.2010104@mozilla.com> On 7/29/12 6:50 PM, Niko Matsakis wrote: > I'm not sure why this step alone would remove the ~"" strings, rather > than (say) causing type errors for those cases where ~str is required > but &str is supplied. It seems that the most important thing is to > convert the various APIs that can take slices to do so. Or am I missing > something? Yes, I was assuming we'd do that too. This is just about the language change. Patrick From graydon at mozilla.com Mon Jul 30 11:35:48 2012 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 30 Jul 2012 11:35:48 -0700 Subject: [rust-dev] RFC: string literals as &static.str In-Reply-To: <5014A241.70701@mozilla.com> References: <5014A241.70701@mozilla.com> Message-ID: <5016D404.9000400@mozilla.com> On 12-07-28 7:38 PM, Patrick Walton wrote: > I'd like to propose that unadorned string literals instead have the type > &static.str, which mirrors how it (usually) works in C and C++. To get > the current behavior one would write "Hello world"/_. This is slightly > inconsistent with vectors, but string literals are special anyway in C > and C++. This will make almost all the ~" punctuation-diphthongs that > are peppered throughout Rust code go away. > > Thoughts? A few: - "doh!" - "yes, of course" - so _that_ is why [] and "" should have type foo& not foo/_ - i.e. we should make [] evaluate to &[] too, and choose its lifetime by analysis of the arguments; this merges with the bug for constant vectors Good catch. -Graydon From banderson at mozilla.com Mon Jul 30 15:32:37 2012 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 30 Jul 2012 15:32:37 -0700 Subject: [rust-dev] Tutorial issues In-Reply-To: <874nos402q.fsf@mid.deneb.enyo.de> References: <874nos402q.fsf@mid.deneb.enyo.de> Message-ID: <50170B85.6040800@mozilla.com> On 07/28/2012 04:06 AM, Florian Weimer wrote: > I went over tutorial and spotted a few typos (see below). > Thanks! I committed the diff, and logged the larger FFI issues here: https://github.com/mozilla/rust/issues/3055