From asb at asbradbury.org Mon Apr 1 02:15:38 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Mon, 1 Apr 2013 10:15:38 +0100 Subject: [rust-dev] Rust per-process private memory overhead In-Reply-To: References: Message-ID: On 31 March 2013 22:21, Alex Bradbury wrote: > My test program simply prints "hello?" and sleeps for 60 seconds. I > run 5 of these processes, and then collect the memory usage. A full > log is below, but in summary my results for Rust (0.6RC), C (glibc 2.5 > and gcc 4.7.2) and Go (1.0.3) are as follows. Results are in format > Private + Shared = Total, see ps_mem.py for the memory accounting > methodology. I added Haskell (ghc 7.4.2) and Ocaml to the mix. Rust: 8.9 MiB + 785.0 KiB = 9.7 MiB hello (5) C: 452.0 KiB + 55.0 KiB = 507.0 KiB hello (5) Go: 1.9 MiB + 520.0 KiB = 2.4 MiB hello (5) Haskell: 1.6 MiB + 497.5 KiB = 2.1 MiB hello (5) Ocaml: 1.1 MiB + 237.5 KiB = 1.3 MiB hello (5) $ cat hello.hs import Control.Concurrent main = do putStrLn "hello?" threadDelay (60*1000000) $ ghc -O3 hello.hs $ for i in 1 2 3 4 5; do ./hello & done $ sudo python ~/ps_mem.py | grep -i hello 1.6 MiB + 497.5 KiB = 2.1 MiB hello (5) $ cat hello.ml print_endline "hello?";; Unix.sleep 60;; $ ocamlopt unix.cmxa hello.ml -o hello $ for i in 1 2 3 4 5; do ./hello & done $ sudo python ~/ps_mem.py | grep -i hello 1.1 MiB + 237.5 KiB = 1.3 MiB hello (5) From csp at csperkins.org Mon Apr 1 04:09:23 2013 From: csp at csperkins.org (Colin Perkins) Date: Mon, 1 Apr 2013 12:09:23 +0100 Subject: [rust-dev] 0.6 prerelease testing In-Reply-To: <5158CC57.60902@mozilla.com> References: <5157D711.2080205@mozilla.com> <5BC9FD56-E476-4ADD-8116-5D5C50791E5E@csperkins.org> <5158CC57.60902@mozilla.com> Message-ID: Thanks, that's the clue needed to track it down. It turns out I had the OS environment variable set, and this was overriding the assignment in libuv's build.mk due to the use of "OS ?= ..." rather than "OS = ..." there. Remove the environment variable, and it builds fine. Colin On 1 Apr 2013, at 00:52, Brian Anderson wrote: > Thanks. > > `OS` is set in libuv's [build.mk] with > > OS ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"') > > Perhaps it is failing somehow, though it seems unlikely. I've opened an [issue] and will try to reproduce it. > > [build.mk]: https://github.com/brson/libuv/blob/master/build.mk#L21 > [issue]: https://github.com/mozilla/rust/issues/5650 > > > On 03/31/2013 06:36 AM, Colin Perkins wrote: >> Hi, >> >> Trying to compile this on MacOS 10.7.5, I get the following build error in libuv: >> >> ... >> ar rcs libuv.a src/unix/async.o src/unix/core.o src/unix/dl.o src/unix/error.o src/unix/fs.o src/unix/getaddrinfo.o src/unix/loop.o src/unix/loop-watcher.o src/unix/pipe.o src/unix/poll.o src/unix/process.o src/unix/signal.o src/unix/stream.o src/unix/tcp.o src/unix/thread.o src/unix/threadpool.o src/unix/timer.o src/unix/tty.o src/unix/udp.o src/fs-poll.o src/uv-common.o src/inet.o >> link: rt/x86_64-apple-darwin/librustrt.dylib >> Undefined symbols for architecture x86_64: >> "_uv__hrtime", referenced from: >> _uv_hrtime in libuv.a(core.o) >> _uv__update_time in libuv.a(core.o) >> _uv__loop_init in libuv.a(loop.o) >> "_uv__fs_event_close", referenced from: >> _uv_close in libuv.a(core.o) >> "_uv__io_poll", referenced from: >> _uv_run in libuv.a(core.o) >> "_uv__platform_loop_init", referenced from: >> _uv__loop_init in libuv.a(loop.o) >> "_uv__platform_loop_delete", referenced from: >> _uv__loop_delete in libuv.a(loop.o) >> ld: symbol(s) not found for architecture x86_64 >> collect2: ld returned 1 exit status >> make: *** [rt/x86_64-apple-darwin/librustrt.dylib] Error 1 >> >> I can force it to build correctly by adding an "OS=darwin" around line 184 of mk/rt.mk, so it looks like the build system isn't passing the right parameters to the libuv build for some reason. >> >> I just tried with incoming from git, and get the same behaviour. >> >> Colin >> >> >> >> >> On 31 Mar 2013, at 07:26, Brian Anderson wrote: >>> Greetings, >>> >>> Here's a prerelease build of Rust 0.6: >>> >>> http://static.rust-lang.org/dist/rust-0.6.tar.gz >>> http://static.rust-lang.org/dist/rust-0.6-install.exe >>> >>> With sha256's: >>> >>> ebc7ff9dd1a72c9d23e3276c94c8d34b55ff622a0eb1aea4b61d78850e1c5b7e rust-0.6.tar.gz >>> 5ccfc062242562956f1fdfd252cf16744d704893799404774aa6a6a02065e7b0 rust-0.6-install.exe >>> >>> It's about time for 0.6, and it looks like all the critical features are in, so we've got a build ready for testing. This is _not_ a signed release, just a candidate. If you have some spare cycles please give this an install and report whether it does what you expect. If all goes well we will release 0.6 in the next few days. >>> >>> Our new integration process with bors has been keeping the tree consistently green so I feel much more confident in this release than previous ones. We mostly want to prove that the install works on platforms we tend to support (OS X 10.6+, various Linuxes, and Windows 7 & 2008) and the compiler generally behaves as expected, considering the various known issues. If you have fixes or features you are passionate about then now is the time to confirm they are working as intended. We are doing time based releases though, so there's no need to sweat the small things - there will be another one in a few months. >>> >>> -Brian >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev -- Colin Perkins http://csperkins.org/ From graydon at mozilla.com Mon Apr 1 11:21:41 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 01 Apr 2013 11:21:41 -0700 Subject: [rust-dev] Rust per-process private memory overhead In-Reply-To: References: Message-ID: <5159D035.5000708@mozilla.com> On 13-04-01 02:15 AM, Alex Bradbury wrote: > Rust: > 8.9 MiB + 785.0 KiB = 9.7 MiB hello (5) > C: > 452.0 KiB + 55.0 KiB = 507.0 KiB hello (5) > Go: > 1.9 MiB + 520.0 KiB = 2.4 MiB hello (5) > Haskell: > 1.6 MiB + 497.5 KiB = 2.1 MiB hello (5) > Ocaml: > 1.1 MiB + 237.5 KiB = 1.3 MiB hello (5) I don't know what's going on in your case. When I run this exercise on my machine I get the following: 1.5 MiB + 720.0 KiB = 2.2 MiB hello (5) which looks like about what I'd expect; rust's still a bit big there (some of the segments in libcore are probably still too big) but it is not miles off base. Further scrutiny of the /proc//maps and smaps file show similar numbers. Can you look in a little more detail and try to find where the numbers are coming from? -Graydon From asb at asbradbury.org Mon Apr 1 12:44:28 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Mon, 1 Apr 2013 20:44:28 +0100 Subject: [rust-dev] Rust per-process private memory overhead In-Reply-To: <5159D035.5000708@mozilla.com> References: <5159D035.5000708@mozilla.com> Message-ID: On 1 April 2013 19:21, Graydon Hoare wrote: > I don't know what's going on in your case. When I run this exercise on > my machine I get the following: > > 1.5 MiB + 720.0 KiB = 2.2 MiB hello (5) > > which looks like about what I'd expect; rust's still a bit big there > (some of the segments in libcore are probably still too big) but it is > not miles off base. Further scrutiny of the /proc//maps and smaps > file show similar numbers. Can you look in a little more detail and try > to find where the numbers are coming from? I've recompiled hellos.rs, re-run the test and get the same results. This is with the rust 0.6 rc tarball (from https://mail.mozilla.org/pipermail/rust-dev/2013-March/003402.html), compiled and installed with ./configure && make && make install. What would you recommend I use to investigate (may have a to wait a few days, as I'm going away tomorrow). massif? Thanks for taking a look, Alex From doy at tozt.net Mon Apr 1 13:04:55 2013 From: doy at tozt.net (Jesse Luehrs) Date: Mon, 1 Apr 2013 15:04:55 -0500 Subject: [rust-dev] Rust per-process private memory overhead In-Reply-To: References: <5159D035.5000708@mozilla.com> Message-ID: <20130401200455.GK26639@tozt.net> On Mon, Apr 01, 2013 at 08:44:28PM +0100, Alex Bradbury wrote: > On 1 April 2013 19:21, Graydon Hoare wrote: > > I don't know what's going on in your case. When I run this exercise on > > my machine I get the following: > > > > 1.5 MiB + 720.0 KiB = 2.2 MiB hello (5) > > > > which looks like about what I'd expect; rust's still a bit big there > > (some of the segments in libcore are probably still too big) but it is > > not miles off base. Further scrutiny of the /proc//maps and smaps > > file show similar numbers. Can you look in a little more detail and try > > to find where the numbers are coming from? > > I've recompiled hellos.rs, re-run the test and get the same results. > This is with the rust 0.6 rc tarball (from > https://mail.mozilla.org/pipermail/rust-dev/2013-March/003402.html), > compiled and installed with ./configure && make && make install. What > would you recommend I use to investigate (may have a to wait a few > days, as I'm going away tomorrow). massif? > > Thanks for taking a look, I can also reproduce this: rust single process: 2.3 MiB + 95.5 KiB = 2.4 MiB hello rust multiple processes: 8.8 MiB + 852.5 KiB = 9.6 MiB hello (5) c single process: 84.0 KiB + 11.0 KiB = 95.0 KiB hello c multiple processes: 400.0 KiB + 55.0 KiB = 455.0 KiB hello (5) go single process: 920.0 KiB + 4.0 KiB = 924.0 KiB hello go multiple processes: 2.0 MiB + 525.0 KiB = 2.5 MiB hello (5) I'll see if I can dig up some more information this evening. -doy From clements at brinckerhoff.org Mon Apr 1 14:51:54 2013 From: clements at brinckerhoff.org (John Clements) Date: Mon, 1 Apr 2013 14:51:54 -0700 Subject: [rust-dev] assuming this is a bug... Message-ID: In the parser, the function "parse_item_or_view_item" contains this code: if self.eat_keyword(&~"extern") { let opt_abis = self.parse_opt_abis(); if items_allowed && self.eat_keyword(&~"fn") { // EXTERN FUNCTION ITEM let abis = opt_abis.get_or_default(AbiSet::C()); let (ident, item_, extra_attrs) = self.parse_item_fn(extern_fn, abis); return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_, visibility, maybe_append(attrs, extra_attrs))); } if !foreign_items_allowed { // EXTERN MODULE ITEM return self.parse_item_foreign_mod(lo, opt_abis, visibility, attrs, items_allowed); } } Since "!foreign_items_allowed" is equivalent to "items_allowed", this will fall through if items_allowed is true. I'm assuming this is an accident, and that it should never be legal to write extern{ extern ? } ? at the module level. Let me know if this fall-through is deliberate! john From graydon at mozilla.com Mon Apr 1 15:00:31 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 01 Apr 2013 15:00:31 -0700 Subject: [rust-dev] Rust per-process private memory overhead In-Reply-To: References: <5159D035.5000708@mozilla.com> Message-ID: <515A037F.3070502@mozilla.com> On 13-04-01 12:44 PM, Alex Bradbury wrote: > I've recompiled hellos.rs, re-run the test and get the same results. > This is with the rust 0.6 rc tarball (from > https://mail.mozilla.org/pipermail/rust-dev/2013-March/003402.html), > compiled and installed with ./configure && make && make install. What > would you recommend I use to investigate (may have a to wait a few > days, as I'm going away tomorrow). massif? On some further reproduction-and-debugging, looks like this is due to segmented-stack growth grabbing a 2mb stack for running the C code for sleep(), which is neither a necessary nor permanent sort of behavior. If you read the smaps file for the pids in question, the difference is all in the stack segment. I am not sure why my machine isn't triggering the same condition, but it's ... not something I'd put down as intrinsic-to-the-language. Or at least not permanent; we're intending to do a lot of work tuning the stack-growth / switching machinery in the near future. IOW it's nothing deep, you just stumbled into a bug, one we'll fix at some point. I wouldn't worry about it in terms of "expensive heap" or such (we _do_ have a very high-overhead local heap presently, but that's a _different_ bug that's also WIP). If you don't hit this bug the memory usage is about what you'd expect. I wish I could say something more concrete today but we've got quite a number of bugs to fix and this one isn't as high on the list as others. -Graydon From pshagl007 at gmail.com Tue Apr 2 02:51:26 2013 From: pshagl007 at gmail.com (piyush agarwal) Date: Tue, 2 Apr 2013 15:21:26 +0530 Subject: [rust-dev] Error creating vector of vectors Message-ID: Hi all, I am finding errors while creating vector of vectors after updating my compiler to pre-release version of rust-0.6. let mut testStruct: @[~[int], ..4] = @[~[], ..4]; or let mut testStruct: ~[~[int], ..4] = ~[~[], ..4]; Thanks, Piyush -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Tue Apr 2 06:13:03 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 02 Apr 2013 06:13:03 -0700 Subject: [rust-dev] Error creating vector of vectors In-Reply-To: References: Message-ID: <515AD95F.8000702@alum.mit.edu> The meaning of `@[x, ..N]` and `~[x, ..N]` has changed. It used to mean a pointer to a fixed length struct, it now yields an `@[]` or `~[]` vector. Try: `let mut testStruct = @([~[], ..4])` etc. We should also not parse the types. Niko > piyush agarwal > April 2, 2013 2:51 AM > Hi all, > > I am finding errors while creating vector of vectors after updating my > compiler to pre-release version of rust-0.6. > > > let mut testStruct: @[~[int], ..4] = @[~[], ..4]; > > or > > let mut testStruct: ~[~[int], ..4] = ~[~[], ..4]; > > > Thanks, > Piyush > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: compose-unknown-contact.jpg Type: image/jpeg Size: 770 bytes Desc: not available URL: From hdd86 at qq.com Tue Apr 2 08:53:57 2013 From: hdd86 at qq.com (=?ISO-8859-1?B?aHVkbw==?=) Date: Tue, 2 Apr 2013 23:53:57 +0800 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration Message-ID: let x = get(x) / / immutable binding mut x = get(x) / / mutable binding, instead than modified I would have a clearer semantics and syntax of the simplified :) Thanks! hudo -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Tue Apr 2 09:21:14 2013 From: clements at brinckerhoff.org (John Clements) Date: Tue, 2 Apr 2013 09:21:14 -0700 Subject: [rust-dev] remove alt-type-simple.rs? Message-ID: In running parse tests, I discovered a file from 2010, alt-type-simple.rs, that is an (xfail'ed) test of a feature that would have allowed type dispatch. It looks to me like this is pretty deeply incompatible with the current approach to typing, so I'm removing this test. Lemme know if this is a mistake. Thanks! John From graydon at mozilla.com Tue Apr 2 09:33:47 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 02 Apr 2013 09:33:47 -0700 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: References: Message-ID: <515B086B.5050205@mozilla.com> On 02/04/2013 8:53 AM, hudo wrote: > let x = get(x) / / immutable binding > mut x = get(x) / / mutable binding, instead than modified > I would have a clearer semantics and syntax of the simplified :) There's an issue on file for this: https://github.com/mozilla/rust/issues/2643 though it started with var vs. let, it drifted into let vs. mut. I think at this stage we're unlikely to do this; it's late in the language design and the current syntax is symmetric with the other locations 'mut' can occur: after 'static' (for globals), or after & or @ for mutable referents of pointers. In all such places, you make something immutable by omitting the word 'mut', not changing it to something else. -Graydon From graydon at mozilla.com Tue Apr 2 09:47:28 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 02 Apr 2013 09:47:28 -0700 Subject: [rust-dev] remove alt-type-simple.rs? In-Reply-To: References: Message-ID: <515B0BA0.8020704@mozilla.com> On 02/04/2013 9:21 AM, John Clements wrote: > In running parse tests, I discovered a file from 2010, alt-type-simple.rs, that is an (xfail'ed) test of a feature that would have allowed type dispatch. It looks to me like this is pretty deeply incompatible with the current approach to typing, so I'm removing this test. Lemme know if this is a mistake. Yes. We were going to have an 'any' type and type-switch built in to the language. We decided against it and I've seen no plans to revive the concept as far as I know. Maybe for 2.0. -Graydon From pierrelouis.aublin at gmail.com Mon Apr 1 11:16:23 2013 From: pierrelouis.aublin at gmail.com (Pierre Louis Aublin) Date: Mon, 01 Apr 2013 20:16:23 +0200 Subject: [rust-dev] simple web server implementation Message-ID: <5159CEF7.7060401@gmail.com> Hello everybody I heard about Rust a few weeks ago and am very excited by this new language. To get a grip I have created a simple web server, with the v0.5 of the language: https://github.com/schaars/simple-web-server It is quite limited, as it handles only 1 client at a time and HTTP 1.0 GET request, but it was interesting to write. Feel free to make any comment :) I have a few questions about the language. I hope this mailing list is the right place to ask. 1) When I read a file, how can I make the difference between "file not found" and "not authorized to open file"? In my web server I cannot make it because in both cases the Result returned by io::read_whole_file() is Err(~"error opening file"). 2) I have not found how to use a single channel (pipes::stream) between 1 sender and n receivers. Is it possible? The solution I found (but not implemented because I had a vector size problem (https://github.com/mozilla/rust/pull/5112)), is to create several channels and write to them in a round-robin manner, but it's not ideal. 3) The different pointer types seem to be implicitly converted. What happens when a conversion occurs? For instance if I convert a managed box to an owned box, the pointed variable is moved from the private heap to the exchange heap? 4) I have found a prototype error in http://static.rust-lang.org/doc/core/files/str-rs.html#bytes : the name of the function is to_bytes() instead of bytes(). By the way, this page is very useful but hard to find: I have not found any link from www.rust-lang.org Best regards Pierre Louis Aublin From steve at steveklabnik.com Tue Apr 2 11:55:07 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Tue, 2 Apr 2013 11:55:07 -0700 Subject: [rust-dev] simple web server implementation In-Reply-To: <5159CEF7.7060401@gmail.com> References: <5159CEF7.7060401@gmail.com> Message-ID: Oh, you're awesome. I've been meaning to give this a shot for a few weeks, but was waiting for 0.6 to get released. -------------- next part -------------- An HTML attachment was scrubbed... URL: From garethdanielsmith at gmail.com Tue Apr 2 12:36:16 2013 From: garethdanielsmith at gmail.com (Gareth Smith) Date: Tue, 02 Apr 2013 20:36:16 +0100 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: References: Message-ID: <515B3330.7000305@gmail.com> My understanding is that there used to be a problem where using `mut` instead of `let mut` would introduce syntactic ambiguity. The ambiguity was caused by the presence of mutable fields and/or structural records, both of which I believe are now gone or going. There are other, very valid, arguments against making the change, as Graydon has pointed out, although personally I would like it to happen because I like how `mut` is more concise than `let mut`. Gareth On 02/04/13 16:53, hudo wrote: > let x = get(x) / / immutable binding > mut x = get(x) / / mutable binding, instead than modified > I would have a clearer semantics and syntax of the simplified :) > > > Thanks! > > hudo > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeaye at arrownext.com Tue Apr 2 13:40:08 2013 From: jeaye at arrownext.com (Jeaye Wilkerson) Date: Tue, 2 Apr 2013 13:40:08 -0700 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: <515B3330.7000305@gmail.com> References: <515B3330.7000305@gmail.com> Message-ID: `let mut` makes more sense to me than `mut` simply because `let` is already a declarator. mut, to me, is an attribute, not a declarator. I think we should keep the `let mut` syntax because it's still a `let` (with regard to scope), but it's mutable. Concise? Eh, it's consistent and predictable. Cheers, Jeaye On Apr 2, 2013, at 12:36 PM, Gareth Smith wrote: > My understanding is that there used to be a problem where using `mut` instead of `let mut` would introduce syntactic ambiguity. > > The ambiguity was caused by the presence of mutable fields and/or structural records, both of which I believe are now gone or going. > > There are other, very valid, arguments against making the change, as Graydon has pointed out, although personally I would like it to happen because I like how `mut` is more concise than `let mut`. > > Gareth > > On 02/04/13 16:53, hudo wrote: >> let x = get(x) / / immutable binding >> mut x = get(x) / / mutable binding, instead than modified >> I would have a clearer semantics and syntax of the simplified :) >> >> >> Thanks! >> >> hudo >> >> >> >> _______________________________________________ >> 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 pierrelouis.aublin at gmail.com Tue Apr 2 14:47:35 2013 From: pierrelouis.aublin at gmail.com (Pierre-Louis Aublin) Date: Tue, 2 Apr 2013 23:47:35 +0200 Subject: [rust-dev] simple web server implementation In-Reply-To: References: <5159CEF7.7060401@gmail.com> Message-ID: Thanks for your replies. I will continue my digging in the language. On Tue, Apr 2, 2013 at 10:26 PM, Daniel Micay wrote: > On Mon, Apr 1, 2013 at 2:16 PM, Pierre Louis Aublin > wrote: > > > > 3) The different pointer types seem to be implicitly converted. What > happens > > when a conversion occurs? For instance if I convert a managed box to an > > owned box, the pointed variable is moved from the private heap to the > > exchange heap? > > > > I don't think there's any implicit conversion between ~ and @. You can > move, copy or swap out of an owned box and either copy or swap out of > a managed box. There's no way to directly convert between them at a > language level. > > The documentation shouldn't be using the terms "exchange heap" and > "local heap" because it's not accurate. There's currently not really a > separate heap strategy at all, and when there is, owned pointers > containing managed boxes will be on the task-local heap. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Tue Apr 2 16:47:59 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 02 Apr 2013 16:47:59 -0700 Subject: [rust-dev] simple web server implementation In-Reply-To: <5159CEF7.7060401@gmail.com> References: <5159CEF7.7060401@gmail.com> Message-ID: <515B6E2F.1050903@mozilla.com> On 04/01/2013 11:16 AM, Pierre Louis Aublin wrote: > Hello everybody > > I heard about Rust a few weeks ago and am very excited by this new > language. > To get a grip I have created a simple web server, with the v0.5 of the > language: https://github.com/schaars/simple-web-server > It is quite limited, as it handles only 1 client at a time and HTTP > 1.0 GET request, but it was interesting to write. Feel free to make > any comment :) > > I have a few questions about the language. I hope this mailing list is > the right place to ask. > 1) When I read a file, how can I make the difference between "file not > found" and "not authorized to open file"? In my web server I cannot > make it because in both cases the Result returned by > io::read_whole_file() is Err(~"error opening file"). It's not possible at the moment. The I/O library just needs to be improved here. > > 2) I have not found how to use a single channel (pipes::stream) > between 1 sender and n receivers. Is it possible? > The solution I found (but not implemented because I had a vector size > problem (https://github.com/mozilla/rust/pull/5112)), is to create > several channels and write to them in a round-robin manner, but it's > not ideal. > Again, there is no abstraction for this in the libraries yet. > > 4) I have found a prototype error in > http://static.rust-lang.org/doc/core/files/str-rs.html#bytes : the > name of the function is to_bytes() instead of bytes(). By the way, > this page is very useful but hard to find: I have not found any link > from www.rust-lang.org Wow! I'm not sure how you found that file, but it is a remnant of the pre-0.1 Rust documentation. It should not exist on the server. > > Best regards > Pierre Louis Aublin > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From pshagl007 at gmail.com Tue Apr 2 23:13:49 2013 From: pshagl007 at gmail.com (piyush agarwal) Date: Wed, 3 Apr 2013 11:43:49 +0530 Subject: [rust-dev] Problem Understanding compiler errors Message-ID: Hi all, This code used to work in 0.5 version but wehn i updated my compiler to prerelease of 0.6 , these errors occurs which I am not able to understand. #[link(name = "testVector", vers = "1.0")]; #[crate_type = "lib"]; extern mod std; pub struct test { testStruct: @mut([~[int], ..4]) } impl test { pub fn print_lenght(&mut self) { io::println(uint::to_str(self.testStruct[2].len())); } } fn test() -> @mut test{ @mut test { testStruct: @mut([~[], ..4]) } } testVector.rs:12:27: 12:44 error: illegal borrow unless pure: unique value in aliasable, mutable location testVector.rs:12 io::println(uint::to_str(self.testStruct[2].len())); ^~~~~~~~~~~~~~~~~ testVector.rs:12:27: 12:52 note: impure due to access to impure function testVector.rs:12 io::println(uint::to_str(self.testStruct[2].len())); -------------- next part -------------- An HTML attachment was scrubbed... URL: From stefan.plantikow at gmail.com Wed Apr 3 00:53:29 2013 From: stefan.plantikow at gmail.com (Stefan Plantikow) Date: Wed, 3 Apr 2013 09:53:29 +0200 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: References: <515B3330.7000305@gmail.com> Message-ID: <3CC0F70F-B48A-4170-BF81-0A05DCC2E661@googlemail.com> Hi, Am 02.04.2013 um 22:40 schrieb Jeaye Wilkerson : > `let mut` makes more sense to me than `mut` simply because `let` is already a declarator. mut, to me, is an attribute, not a declarator. I think we should keep the `let mut` syntax because it's still a `let` (with regard to scope), but it's mutable. Concise? Eh, it's consistent and predictable. > I like the idea of having a short "let mut", it feels weird to need so many characters for that and it textually aligns badly. So why not go for something else, like "var" if we want that? Cheers, Stefan. From stefan.plantikow at gmail.com Wed Apr 3 05:10:51 2013 From: stefan.plantikow at gmail.com (Stefan Plantikow) Date: Wed, 3 Apr 2013 14:10:51 +0200 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: References: <515B3330.7000305@gmail.com> Message-ID: Hi, Am 02.04.2013 um 22:40 schrieb Jeaye Wilkerson : > `let mut` makes more sense to me than `mut` simply because `let` is already a declarator. mut, to me, is an attribute, not a declarator. I think we should keep the `let mut` syntax because it's still a `let` (with regard to scope), but it's mutable. Concise? Eh, it's consistent and predictable. > I like the idea of having a short "let mut", it feels weird to need so many characters for that and it textually aligns badly. So why not go for something else, like "var" if we want that? Cheers, Stefan. From banderson at mozilla.com Wed Apr 3 07:55:57 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 03 Apr 2013 07:55:57 -0700 Subject: [rust-dev] Rust 0.6 released Message-ID: <515C42FD.4070007@mozilla.com> Mozilla and the Rust community are pleased to announce version 0.6 of the Rust compiler and associated tools. Rust is a systems programming language with a focus on safety, performance and concurrency. This was our most active development cycle yet, with patches from many new contributors. This release continues our ongoing efforts to finalize the language syntax and semantics, removing many obsolete features. There has also been a lot of work to clean up and improve the core library. Finally, our friends at Samsung have contributed an experimental port to ARM and [Android]. The brief release notes are included in this announcement, and there is further explanation in the detailed release [notes] on the wiki. Documentation and all the links in this email are available on the [website]. As usual, version 0.6 should be considered an alpha release, suitable for early adopters and language enthusiasts. Please file [bugs]. [website]: http://www.rust-lang.org [notes]: https://github.com/mozilla/rust/wiki/Doc-detailed-release-notes [bugs]: https://github.com/mozilla/rust/issues [Android]: https://github.com/mozilla/rust/wiki/Doc-building-for-android This release is available as both a tarball and a Windows installer: * http://static.rust-lang.org/dist/rust-0.6.tar.gz http://static.rust-lang.org/dist/rust-0.6.tar.gz.asc SHA256 (of .tar.gz): e11cb529a1e20f27d99033181a9e0e131817136b46d2742f0fa1afa1210053e5 * http://static.rust-lang.org/dist/rust-0.6-install.exe http://static.rust-lang.org/dist/rust-0.6-install.exe.asc SHA256 (of .exe): 54d16fec24c512676bd8ef7117540c839a4e48e5f0e79a2dd3999633ef625ab3 Thanks to all [contributors]! Regards, The Rust Team Version 0.6 (April 2013) --------------------------- * ~2100 changes, numerous bugfixes * Syntax changes * The self type parameter in traits is now spelled `Self` * The `self` parameter in trait and impl methods must now be explicitly named (for example: `fn f(&self) { }`). Implicit self is deprecated. * Static methods no longer require the `static` keyword and instead are distinguished by the lack of a `self` parameter * Replaced the `Durable` trait with the `'static` lifetime * The old closure type syntax with the trailing sigil has been removed in favor of the more consistent leading sigil * `super` is a keyword, and may be prefixed to paths * Trait bounds are separated with `+` instead of whitespace * Traits are implemented with `impl Trait for Type` instead of `impl Type: Trait` * Lifetime syntax is now `&'l foo` instead of `&l/foo` * The `export` keyword has finally been removed * The `move` keyword has been removed (see "Semantic changes") * The interior mutability qualifier on vectors, `[mut T]`, has been removed. Use `&mut [T]`, etc. * `mut` is no longer valid in `~mut T`. Use inherited mutability * `fail` is no longer a keyword. Use `fail!()` * `assert` is no longer a keyword. Use `assert!()` * `log` is no longer a keyword. use `debug!`, etc. * 1-tuples may be represented as `(T,)` * Struct fields may no longer be `mut`. Use inherited mutability, `@mut T`, `core::mut` or `core::cell` * `extern mod { ... }` is no longer valid syntax for foreign function modules. Use extern blocks: `extern { ... }` * Newtype enums removed. Use tuple-structs. * Trait implementations no longer support visibility modifiers * Pattern matching over vectors improved and expanded * `const` renamed to `static` to correspond to lifetime name, and make room for future `static mut` unsafe mutable globals. * Replaced `#[deriving_eq]` with `#[deriving(Eq)]`, etc. * `Clone` implementations can be automatically generated with `#[deriving(Clone)]` * Casts to traits must use a pointer sigil, e.g. `@foo as @Bar` instead of `foo as Bar`. * Fixed length vector types are now written as `[int, .. 3]` instead of `[int * 3]`. * Fixed length vector types can express the length as a constant expression. (ex: `[int, .. GL_BUFFER_SIZE - 2]`) * Semantic changes * Types with owned pointers or custom destructors move by default, eliminating the `move` keyword * All foreign functions are considered unsafe * &mut is now unaliasable * Writes to borrowed @mut pointers are prevented dynamically * () has size 0 * The name of the main function can be customized using #[main] * The default type of an inferred closure is &fn instead of @fn * `use` statements may no longer be "chained" - they cannot import identifiers imported by previous `use` statements * `use` statements are crate relative, importing from the "top" of the crate by default. Paths may be prefixed with `super::` or `self::` to change the search behavior. * Method visibility is inherited from the implementation declaration * Structural records have been removed * Many more types can be used in static items, including enums 'static-lifetime pointers and vectors * Pattern matching over vectors improved and expanded * Typechecking of closure types has been overhauled to improve inference and eliminate unsoundness * Macros leave scope at the end of modules, unless that module is tagged with #[macro_escape] * Libraries * Added big integers to `std::bigint` * Removed `core::oldcomm` module * Added pipe-based `core::comm` module * Numeric traits have been reorganized under `core::num` * `vec::slice` finally returns a slice * `debug!` and friends don't require a format string, e.g. `debug!(Foo)` * Containers reorganized around traits in `core::container` * `core::dvec` removed, `~[T]` is a drop-in replacement * `core::send_map` renamed to `core::hashmap` * `std::map` removed; replaced with `core::hashmap` * `std::treemap` reimplemented as an owned balanced tree * `std::deque` and `std::smallintmap` reimplemented as owned containers * `core::trie` added as a fast ordered map for integer keys * Set types added to `core::hashmap`, `core::trie` and `std::treemap` * `Ord` split into `Ord` and `TotalOrd`. `Ord` is still used to overload the comparison operators, whereas `TotalOrd` is used by certain container types * Other * Replaced the 'cargo' package manager with 'rustpkg' * Added all-purpose 'rust' tool * `rustc --test` now supports benchmarks with the `#[bench]` attribute * rustc now *attempts* to offer spelling suggestions * Improved support for ARM and Android * Preliminary MIPS backend * Improved foreign function ABI implementation for x86, x86_64 * Various memory usage improvements * Rust code may be embedded in foreign code under limited circumstances * Inline assembler supported by new asm!() syntax extension. [contributors]: Contributors to Rust 0.6: Alex Crichton Andrew Paseltiner Armin Ronacher Ashok Gautham Aydin Kim Ben Alpert Ben Blum Benjamin Herr Ben Kelly Ben Striegel Brendan Zabarauskas Brian Anderson Brian Leibig Chris Peterson Cody Schroeder Daniel Micay Daniel Ursache Dogariu David Forsythe Dimitri Krassovski Eric J. Holmes Erick Tryzelaar Felix S. Klock II Franklin Chen gareth gifnksm Graydon Hoare hansjorg Huon Wilson ILyong Cho Jed Davis Jeff Olson Jens Nockert Jeong YunWon Jihyun Yu John Clements Josh Matthews Jyun-Yan You Kang Seonghoon kud1ing Kyeongwoon Lee Laurent Bonnans Lawrence Vela?zquez Lenny222 Lindsey Kuper Luca Bruno Luqman Aden Mark Lacey Mark Vian Martin DeMello Marvin L?bel Matthew McPherrin Matthijs Hofstra Michael Neumann Mikko Perttunen Nick Desaulniers Niko Matsakis Olivier Saut oncemoreification Patrick Walton Peter Williams Seo Sanghyeon Seth Pink sevrak Simon Sapin Stefan Plantikow Steve Klabnik Ted Horst Thad Guidry Tim Chevalier Tim Taubert Trinick Tycho Sci Tyler Bindon Viktor Dahl William Ting David Klein Young-il Choi Youngsoo Son Zack Corr From rust-dev at grant.x43.net Wed Apr 3 05:14:11 2013 From: rust-dev at grant.x43.net (Grant Husbands) Date: Wed, 3 Apr 2013 13:14:11 +0100 Subject: [rust-dev] Library Safety Message-ID: I've been following the Rust story with some interest and I'm excited about the opportunities Rust brings for sandbox-free, secure system software. However, there are some things that it lacks, that would otherwise make it the obvious choice. One that I feel is important that has been touched upon by others is having static assurances about code, especially imported libraries. If I use a jpg library, I want to be sure that it isn't going to do be able to do any unsafe operations, use GC or access the file-system or the network. That way, I don't have to trust the code and can instead be assured that it simply cannot perform any dangerous actions. Currently, to do that, I have to inspect the whole library. As a developer without the time to do that, I'd much prefer for the import to be annotated to indicate such things (or, ideally, to be annotated to indicate the allowed dangers). This could be seen, of course, as a precursor to capabilities - reducing ambient authority is a key first step in getting a capability-secure system - but it's also a simple way of getting assurances about code without having to inspect it. Does it seem like a reasonable thing to add? I may be able to find time to work on it, should it be acceptable. Regards, Grant Husbands. -------------- next part -------------- An HTML attachment was scrubbed... URL: From deansherthompson at gmail.com Wed Apr 3 08:26:34 2013 From: deansherthompson at gmail.com (Dean Thompson) Date: Wed, 03 Apr 2013 08:26:34 -0700 Subject: [rust-dev] Library Safety In-Reply-To: Message-ID: The Rust team refers to this as an "effect system". They originally had one, but that one proved unworkable and was deleted. They continue to regard it as desirable but difficult to get right, and as a potential future. Here's some history . They would certainly welcome serious proposals or demos, although almost certainly continuing to hold it out for post-1.0. They would think in terms of first researching the most successful effect systems in other languages. Dean From: Grant Husbands Date: Wednesday, April 3, 2013 5:14 AM To: Subject: [rust-dev] Library Safety I've been following the Rust story with some interest and I'm excited about the opportunities Rust brings for sandbox-free, secure system software. However, there are some things that it lacks, that would otherwise make it the obvious choice. One that I feel is important that has been touched upon by others is having static assurances about code, especially imported libraries. If I use a jpg library, I want to be sure that it isn't going to do be able to do any unsafe operations, use GC or access the file-system or the network. That way, I don't have to trust the code and can instead be assured that it simply cannot perform any dangerous actions. Currently, to do that, I have to inspect the whole library. As a developer without the time to do that, I'd much prefer for the import to be annotated to indicate such things (or, ideally, to be annotated to indicate the allowed dangers). This could be seen, of course, as a precursor to capabilities - reducing ambient authority is a key first step in getting a capability-secure system - but it's also a simple way of getting assurances about code without having to inspect it. Does it seem like a reasonable thing to add? I may be able to find time to work on it, should it be acceptable. Regards, Grant Husbands. _______________________________________________ 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 pohl.longsine at gmail.com Wed Apr 3 09:24:12 2013 From: pohl.longsine at gmail.com (pohl) Date: Wed, 3 Apr 2013 11:24:12 -0500 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration Message-ID: On Tue, 2 Apr 2013 Jeaye Wilkerson wrote: > > `let mut` makes more sense to me than `mut` simply because `let` is already a declarator. > mut, to me, is an attribute, not a declarator. I think we should keep the `let mut` syntax > because it's still a `let` (with regard to scope), but it's mutable. Concise? Eh, it's consistent > and predictable. Since this topic came up, I just wanted to throw out something that has been on my mind while lurking here: (Hi everybody!) I'm particularly fond of Scala's solution to this design challenge: they took the 'val' declarator from the ML family of languages and supplemented it with another declarator called 'var' with mutable semantics. val x = ... // immutable binding var y = ... // mutable binding This has nice properties when visually scanning code: if you have a block of bindings they're vertically aligned regardless of mutability. They're similar enough so that a casual glance identifies either as being a binding, but different enough to easily identify where your mutability is. It just seemed like an elegant touch to me. From pwalton at mozilla.com Wed Apr 3 09:28:48 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 03 Apr 2013 09:28:48 -0700 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: References: Message-ID: <515C58C0.900@mozilla.com> On 4/3/13 9:24 AM, pohl wrote: > I'm particularly fond of Scala's solution to this design challenge: > they took the 'val' declarator from > the ML family of languages and supplemented it with another > declarator called 'var' with mutable semantics. > > val x = ... // immutable binding > var y = ... // mutable binding This has been discussed several times in the past, with the same reasonable arguments on all sides of the issue. As Graydon said, I think the decision is already made at this point. Patrick From christian at siefkes.net Wed Apr 3 10:20:22 2013 From: christian at siefkes.net (Christian Siefkes) Date: Wed, 03 Apr 2013 19:20:22 +0200 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: (sfid-H20130403-182419-+074.75-1@spamfilter.osbf.lua) References: (sfid-H20130403-182419-+074.75-1@spamfilter.osbf.lua) Message-ID: <515C64D6.8070900@siefkes.net> Stefan Plantiko wrote: > I like the idea of having a short "let mut", it feels weird to need so many characters for that and it textually aligns badly. So why not go for something else, like "var" if we want that? I like the idea of encouraging immutable over mutable variables, so it feels right to be that mutability must be declared with an additional keyword. If mutable variables declarations were as short as immutable ones, people would tend to make variables mutable even when it's not needed. Hence I'm in favor of "let mut" since it means that people will think about whether or not they really need that "mut" modifier. 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 -- Institutions will try to preserve the problem to which they are the solution. -- The Shirky Principle (by Kevin Kelly) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 262 bytes Desc: OpenPGP digital signature URL: From clements at brinckerhoff.org Wed Apr 3 10:26:11 2013 From: clements at brinckerhoff.org (John Clements) Date: Wed, 3 Apr 2013 10:26:11 -0700 Subject: [rust-dev] heads-up on minor github error Message-ID: <61C2D179-CAC2-49A1-8E84-57F61325F1A0@brinckerhoff.org> GitHub seems to have a bug/misfeature where the commits in a sequential pull request are not presented in order, e.g.: https://github.com/mozilla/rust/pull/5559 ? where it appears that 2b07f0f is the tip of the pull request, but actually f2e47cd is. This means that an 'r+' placed on 2b07f0f won't actually spur @bors to action?. Anyhow, JFYI. John -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Wed Apr 3 10:44:37 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Wed, 3 Apr 2013 19:44:37 +0200 Subject: [rust-dev] Library Safety In-Reply-To: References: Message-ID: Well, a full effect system might not be necessary "just" for safe plugins. Since we have a way in Rust to indicate which version a "plugin" we want to link to, we could apply some restrictions there. For example, specifying that only a certain list of other libraries can be used by this "plugin" (and typically none with IO features) and that it cannot use unsafe code would guarantee some sandboxing already. Similarly, the GC restriction could be placed there. -- Matthieu On Wed, Apr 3, 2013 at 5:26 PM, Dean Thompson wrote: > The Rust team refers to this as an "effect system". They originally had > one, but that one proved unworkable and was deleted. They continue to > regard it as desirable but difficult to get right, and as a potential > future. Here's some history. > They would certainly welcome serious proposals or demos, although almost > certainly continuing to hold it out for post-1.0. They would think in terms > of first researching the most successful effect systems in other languages. > > Dean > > From: Grant Husbands > Date: Wednesday, April 3, 2013 5:14 AM > To: > Subject: [rust-dev] Library Safety > > I've been following the Rust story with some interest and I'm excited > about the opportunities Rust brings for sandbox-free, secure system > software. However, there are some things that it lacks, that would > otherwise make it the obvious choice. > > One that I feel is important that has been touched upon by others is > having static assurances about code, especially imported libraries. If I > use a jpg library, I want to be sure that it isn't going to do be able to > do any unsafe operations, use GC or access the file-system or the network. > That way, I don't have to trust the code and can instead be assured that it > simply cannot perform any dangerous actions. > > Currently, to do that, I have to inspect the whole library. As a developer > without the time to do that, I'd much prefer for the import to be annotated > to indicate such things (or, ideally, to be annotated to indicate the > allowed dangers). > > This could be seen, of course, as a precursor to capabilities - reducing > ambient authority is a key first step in getting a capability-secure system > - but it's also a simple way of getting assurances about code without > having to inspect it. > > Does it seem like a reasonable thing to add? I may be able to find time to > work on it, should it be acceptable. > > Regards, > Grant Husbands. > _______________________________________________ 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 thadguidry at gmail.com Wed Apr 3 11:22:12 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 3 Apr 2013 13:22:12 -0500 Subject: [rust-dev] Proposed : use ` mut ` as a binding declaration In-Reply-To: <515C58C0.900@mozilla.com> References: <515C58C0.900@mozilla.com> Message-ID: > This has been discussed several times in the past, with the same > reasonable arguments on all sides of the issue. As Graydon said, I think > the decision is already made at this point. > > Patrick > And Graydon and the general consensus (the majority voters and speakers within IRC and this list) have made that right decision. "let mut it=be" -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From rust-dev at grant.x43.net Wed Apr 3 13:22:56 2013 From: rust-dev at grant.x43.net (Grant Husbands) Date: Wed, 3 Apr 2013 21:22:56 +0100 Subject: [rust-dev] Library Safety In-Reply-To: References: Message-ID: I've now read through the mentions of effect systems and indeed I am talking about something simpler that doesn't require either function granularity or inference. As Matthieu Monrocq notes it mostly amounts to restrictions of imports and probably parse-time restriction of particular constructs over a whole module/plugin. I'm willing to create a demo/fork for it, but I wouldn't want to waste effort if it's something that wouldn't be accepted. If it's to be added at all, it might be best to add it for 1.0, so as to reduce the amount of code written without it in mind. On Wed, Apr 3, 2013 at 6:44 PM, Matthieu Monrocq wrote: > Well, a full effect system might not be necessary "just" for safe plugins. > > Since we have a way in Rust to indicate which version a "plugin" we want > to link to, we could apply some restrictions there. > > For example, specifying that only a certain list of other libraries can be > used by this "plugin" (and typically none with IO features) and that it > cannot use unsafe code would guarantee some sandboxing already. Similarly, > the GC restriction could be placed there. > > -- Matthieu > > > On Wed, Apr 3, 2013 at 5:26 PM, Dean Thompson wrote: > >> The Rust team refers to this as an "effect system". They originally had >> one, but that one proved unworkable and was deleted. They continue to >> regard it as desirable but difficult to get right, and as a potential >> future. Here's some history. >> They would certainly welcome serious proposals or demos, although almost >> certainly continuing to hold it out for post-1.0. They would think in terms >> of first researching the most successful effect systems in other languages. >> >> Dean >> >> From: Grant Husbands >> Date: Wednesday, April 3, 2013 5:14 AM >> To: >> Subject: [rust-dev] Library Safety >> >> I've been following the Rust story with some interest and I'm excited >> about the opportunities Rust brings for sandbox-free, secure system >> software. However, there are some things that it lacks, that would >> otherwise make it the obvious choice. >> >> One that I feel is important that has been touched upon by others is >> having static assurances about code, especially imported libraries. If I >> use a jpg library, I want to be sure that it isn't going to do be able to >> do any unsafe operations, use GC or access the file-system or the network. >> That way, I don't have to trust the code and can instead be assured that it >> simply cannot perform any dangerous actions. >> >> Currently, to do that, I have to inspect the whole library. As a >> developer without the time to do that, I'd much prefer for the import to be >> annotated to indicate such things (or, ideally, to be annotated to indicate >> the allowed dangers). >> >> This could be seen, of course, as a precursor to capabilities - reducing >> ambient authority is a key first step in getting a capability-secure system >> - but it's also a simple way of getting assurances about code without >> having to inspect it. >> >> Does it seem like a reasonable thing to add? I may be able to find time >> to work on it, should it be acceptable. >> >> Regards, >> Grant Husbands. >> _______________________________________________ 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 pierrelouis.aublin at gmail.com Wed Apr 3 12:45:47 2013 From: pierrelouis.aublin at gmail.com (Pierre Louis Aublin) Date: Wed, 03 Apr 2013 21:45:47 +0200 Subject: [rust-dev] simple web server implementation In-Reply-To: <515B6E2F.1050903@mozilla.com> References: <5159CEF7.7060401@gmail.com> <515B6E2F.1050903@mozilla.com> Message-ID: <515C86EB.1030402@gmail.com> On 04/03/2013 01:47 AM, Brian Anderson wrote: > On 04/01/2013 11:16 AM, Pierre Louis Aublin wrote: >> Hello everybody >> >> I heard about Rust a few weeks ago and am very excited by this new >> language. >> To get a grip I have created a simple web server, with the v0.5 of >> the language: https://github.com/schaars/simple-web-server >> It is quite limited, as it handles only 1 client at a time and HTTP >> 1.0 GET request, but it was interesting to write. Feel free to make >> any comment :) >> >> I have a few questions about the language. I hope this mailing list >> is the right place to ask. >> 1) When I read a file, how can I make the difference between "file >> not found" and "not authorized to open file"? In my web server I >> cannot make it because in both cases the Result returned by >> io::read_whole_file() is Err(~"error opening file"). > > It's not possible at the moment. The I/O library just needs to be > improved here. > >> >> 2) I have not found how to use a single channel (pipes::stream) >> between 1 sender and n receivers. Is it possible? >> The solution I found (but not implemented because I had a vector size >> problem (https://github.com/mozilla/rust/pull/5112)), is to create >> several channels and write to them in a round-robin manner, but it's >> not ideal. >> > > Again, there is no abstraction for this in the libraries yet. Thanks for your reply. I will continue to learn Rust in order to contribute soon. >> 4) I have found a prototype error in >> http://static.rust-lang.org/doc/core/files/str-rs.html#bytes : the >> name of the function is to_bytes() instead of bytes(). By the way, >> this page is very useful but hard to find: I have not found any link >> from www.rust-lang.org > > Wow! I'm not sure how you found that file, but it is a remnant of the > pre-0.1 Rust documentation. It should not exist on the server. :) I found it via google. It's the first result when I search for "rust convert str to bytes" (without quotes). >> >> Best regards >> Pierre Louis Aublin >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > From wilsonb at gmail.com Wed Apr 3 21:41:41 2013 From: wilsonb at gmail.com (Wilson Bilkovich) Date: Wed, 3 Apr 2013 21:41:41 -0700 Subject: [rust-dev] Library Safety In-Reply-To: References: Message-ID: > On Wed, Apr 3, 2013 at 6:44 PM, Matthieu Monrocq > wrote: > > Well, a full effect system might not be necessary "just" for safe plugins. > > Since we have a way in Rust to indicate which version a "plugin" we want > to link to, we could apply some restrictions there. > > For example, specifying that only a certain list of other libraries can be > used by this "plugin" (and typically none with IO features) and that it > cannot use unsafe code would guarantee some sandboxing already. Similarly, > the GC restriction could be placed there. > > On Wed, Apr 3, 2013 at 1:22 PM, Grant Husbands wrote: > I've now read through the mentions of effect systems and indeed I am talking > about something simpler that doesn't require either function granularity or > inference. As Matthieu Monrocq notes it mostly amounts to restrictions of > imports and probably parse-time restriction of particular constructs over a > whole module/plugin. > > I'm willing to create a demo/fork for it, but I wouldn't want to waste > effort if it's something that wouldn't be accepted. If it's to be added at > all, it might be best to add it for 1.0, so as to reduce the amount of code > written without it in mind. This seems like a great use-case for compiler plugins, which, unless I'm getting my languages mixed up, Rust has plans to support? I think people will have all sorts of ideas for static passes they want to perform during a build, and plugins would let them easily be tested (on travis-ci even, say) by the community without tracking an internal API. Re: safe libraries, I think even just a conventional manifest/description of some kind would be fine; if you mark your library as "safe, doesn't do X, Y, or Z" and you're wrong, well, the community will let you know. It doesn't have to necessarily be deep compiler / effect system magic, to me. --Wilson. From singpolyma at singpolyma.net Thu Apr 4 09:35:30 2013 From: singpolyma at singpolyma.net (Stephen Paul Weber) Date: Thu, 4 Apr 2013 11:35:30 -0500 Subject: [rust-dev] Some questions Message-ID: <20130404163530.GA1829@singpolyma-svelti> I've been watching rust with interest since 0.1, but finally installed the compiler yesterday and started looking through the standard libraries. I noted that Option has a procedure for it, called chain, which is a specialised version of monadic bind. Being a Haskeller, my immidiate thought was to try to write a trait for this: trait Monad { fn chain(self, f: &fn(t: T) -> Self) -> Self; } But apparently Self cannot be parameterised. Is there a way to write traits that model stuff like this? I then found that when writing the impl for a trait, I seem to be required to write type signatures for the arguments and return type of the method I'm implementing, even though such a type signature (a) already exists in the definition of the trait and (b) should be inferrable anyway. Is this a general limitation of the type checker when it comes to traits? -- Stephen Paul Weber, @singpolyma See for how I prefer to be contacted edition right joseph -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: From illissius at gmail.com Thu Apr 4 09:48:33 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Thu, 4 Apr 2013 18:48:33 +0200 Subject: [rust-dev] Library Safety In-Reply-To: References: Message-ID: On Wed, Apr 3, 2013 at 5:26 PM, Dean Thompson wrote: > The Rust team refers to this as an "effect system". They originally had > one, but that one proved unworkable and was deleted. They continue to > regard it as desirable but difficult to get right, and as a potential > future. Here's some history. > They would certainly welcome serious proposals or demos, although almost > certainly continuing to hold it out for post-1.0. They would think in terms > of first researching the most successful effect systems in other languages. > > Dean > Disciple is a strict-by-default Haskell dialect with region typing, mutability in the type system, and effect typing, so maybe it could be one place to look. http://disciple.ouroborus.net/ -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Thu Apr 4 10:21:40 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 04 Apr 2013 10:21:40 -0700 Subject: [rust-dev] Some questions In-Reply-To: <20130404163530.GA1829@singpolyma-svelti> References: <20130404163530.GA1829@singpolyma-svelti> Message-ID: <515DB6A4.9000107@mozilla.com> On 4/4/13 9:35 AM, Stephen Paul Weber wrote: > I've been watching rust with interest since 0.1, but finally installed > the compiler yesterday and started looking through the standard libraries. > > I noted that Option has a procedure for it, called chain, which is a > specialised version of monadic bind. Being a Haskeller, my immidiate > thought was to try to write a trait for this: > > trait Monad { > fn chain(self, f: &fn(t: T) -> Self) -> Self; > } > > But apparently Self cannot be parameterised. > > Is there a way to write traits that model stuff like this? We don't have higher-kinded type parameters. It's a common feature request. I would personally be in favor of taking a patch to add the feature. > I then found that when writing the impl for a trait, I seem to be > required to write type signatures for the arguments and return type of > the method I'm implementing, even though such a type signature (a) > already exists in the definition of the trait and (b) should be > inferrable anyway. Is this a general limitation of the type checker > when it comes to traits? In general we require type annotations for functions, both for separate compilation and for code clarity. Patrick From vadimcn at gmail.com Thu Apr 4 14:20:25 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 4 Apr 2013 14:20:25 -0700 Subject: [rust-dev] Not-quite-proposal about & sigils Message-ID: So I see all those borrow '&' sigils littering almost every function declaration in Rust source, and I think that this is major contributor to eye-soreness Rust syntax causes. Since '&' is so popular, couldn't Rust just make it a default? For instance, what if the following rule were be adopted: "All unadorned function parameters are implicitly assumed to be passed by borrow-reference"? Now, of course, this be inefficient for small types like int, but that could be dealt with by specifying that types less than N bytes in size (N perhaps being platform-dependent), are passed by-value, except if mutable, or if adorned by lifetime of another parameter. Ok, this is not a serious proposal, because I am probably missing a lot of corner cases, but I would like to hear why this wouldn't work. Vadim -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Thu Apr 4 14:24:51 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 04 Apr 2013 14:24:51 -0700 Subject: [rust-dev] Not-quite-proposal about & sigils In-Reply-To: References: Message-ID: <515DEFA3.2080701@mozilla.com> On 4/4/13 2:20 PM, Vadim wrote: > So I see all those borrow '&' sigils littering almost every function > declaration in Rust source, and I think that this is major contributor > to eye-soreness Rust syntax causes. Since '&' is so popular, couldn't > Rust just make it a default? > > For instance, what if the following rule were be adopted: "All unadorned > function parameters are implicitly assumed to be passed by > borrow-reference"? Now, of course, this be inefficient for small types > like int, but that could be dealt with by specifying that types less > than N bytes in size (N perhaps being platform-dependent), are passed > by-value, except if mutable, or if adorned by lifetime of another parameter. > > Ok, this is not a serious proposal, because I am probably missing a lot > of corner cases, but I would like to hear why this wouldn't work. We tried this once ("modes"), and it was very confusing, especially when generics were involved. Patrick From niko at alum.mit.edu Thu Apr 4 14:39:14 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 04 Apr 2013 17:39:14 -0400 Subject: [rust-dev] Library Safety In-Reply-To: References: Message-ID: <515DF302.3020702@alum.mit.edu> It sounds to me like you're talking about something similar to the current lint modes for GC etc? Niko > Grant Husbands > April 3, 2013 4:22 PM > I've now read through the mentions of effect systems and indeed I am > talking about something simpler that doesn't require either function > granularity or inference. As Matthieu Monrocq notes it mostly amounts > to restrictions of imports and probably parse-time restriction of > particular constructs over a whole module/plugin. > > I'm willing to create a demo/fork for it, but I wouldn't want to waste > effort if it's something that wouldn't be accepted. If it's to be > added at all, it might be best to add it for 1.0, so as to reduce the > amount of code written without it in mind. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > Matthieu Monrocq > April 3, 2013 1:44 PM > Well, a full effect system might not be necessary "just" for safe plugins. > > Since we have a way in Rust to indicate which version a "plugin" we > want to link to, we could apply some restrictions there. > > For example, specifying that only a certain list of other libraries > can be used by this "plugin" (and typically none with IO features) and > that it cannot use unsafe code would guarantee some sandboxing > already. Similarly, the GC restriction could be placed there. > > -- Matthieu > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > Dean Thompson > April 3, 2013 11:26 AM > The Rust team refers to this as an "effect system". They originally > had one, but that one proved unworkable and was deleted. They > continue to regard it as desirable but difficult to get right, and as > a potential future. Here's some history > . > They would certainly welcome serious proposals or demos, although > almost certainly continuing to hold it out for post-1.0. They would > think in terms of first researching the most successful effect systems > in other languages. > > Dean > > From: Grant Husbands > > Date: Wednesday, April 3, 2013 5:14 AM > To: > > Subject: [rust-dev] Library Safety > > I've been following the Rust story with some interest and I'm excited > about the opportunities Rust brings for sandbox-free, secure system > software. However, there are some things that it lacks, that would > otherwise make it the obvious choice. > > One that I feel is important that has been touched upon by others is > having static assurances about code, especially imported libraries. If > I use a jpg library, I want to be sure that it isn't going to do be > able to do any unsafe operations, use GC or access the file-system or > the network. That way, I don't have to trust the code and can instead > be assured that it simply cannot perform any dangerous actions. > > Currently, to do that, I have to inspect the whole library. As a > developer without the time to do that, I'd much prefer for the import > to be annotated to indicate such things (or, ideally, to be annotated > to indicate the allowed dangers). > > This could be seen, of course, as a precursor to capabilities - > reducing ambient authority is a key first step in getting a > capability-secure system - but it's also a simple way of getting > assurances about code without having to inspect it. > > Does it seem like a reasonable thing to add? I may be able to find > time to work on it, should it be acceptable. > > Regards, > Grant Husbands. > _______________________________________________ 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 > Grant Husbands > April 3, 2013 8:14 AM > I've been following the Rust story with some interest and I'm excited > about the opportunities Rust brings for sandbox-free, secure system > software. However, there are some things that it lacks, that would > otherwise make it the obvious choice. > > One that I feel is important that has been touched upon by others is > having static assurances about code, especially imported libraries. If > I use a jpg library, I want to be sure that it isn't going to do be > able to do any unsafe operations, use GC or access the file-system or > the network. That way, I don't have to trust the code and can instead > be assured that it simply cannot perform any dangerous actions. > > Currently, to do that, I have to inspect the whole library. As a > developer without the time to do that, I'd much prefer for the import > to be annotated to indicate such things (or, ideally, to be annotated > to indicate the allowed dangers). > > This could be seen, of course, as a precursor to capabilities - > reducing ambient authority is a key first step in getting a > capability-secure system - but it's also a simple way of getting > assurances about code without having to inspect it. > > Does it seem like a reasonable thing to add? I may be able to find > time to work on it, should it be acceptable. > > Regards, > Grant Husbands. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: compose-unknown-contact.jpg Type: image/jpeg Size: 770 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: postbox-contact.jpg Type: image/jpeg Size: 1185 bytes Desc: not available URL: From jeaye at arrownext.com Thu Apr 4 14:45:22 2013 From: jeaye at arrownext.com (Jeaye Wilkerson) Date: Thu, 4 Apr 2013 14:45:22 -0700 Subject: [rust-dev] Generics? Message-ID: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> Howdy, I've been tinkering with Rust generics lately and, unfortunately, they seem very limiting. Coming from C++, I expect from generics what templates provide: A plug-in-this-type-in-and-see-if-it-compiles ( http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error ) approach. It seems to me that trait-based generics are not really generic at all; they're polymorphic. Take the following: impl Foo { pub fn zero() -> Foo { Foo { bar: num::Zero::zero() } } } Often times in C++, a programmer will want to restrict the types that can go into a function. C++ traits make this kind of messy, so I appreciate the approach here. Still, getting zero from T uses a polymorphic num::Zero::zero(), instead of a generic T::zero(). Furthermore, what if one wanted to create also a "pub fn one() -> Foo" function; you then need "num::Zero::zero() + 1", but does that work as expected? Another problem that arises is the massive number of trait bounds that an arithmetic (or something else) function might need to simply work. Rust is doing an excellent job addressing a number of crucial problems of C++, but I feel it broke one thing C++ did pretty well. For the 0.6 release, it was said that there are no plans for major syntactic changes; are there no plans to cleanup Rust generics? Are there cleaner ways of approaching the problems I'm running into as I try to develop generic types in Rust? Perhaps this can be made sexier with macros? Cheers, Jeaye -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at steveklabnik.com Thu Apr 4 14:55:15 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Thu, 4 Apr 2013 16:55:15 -0500 Subject: [rust-dev] Generics? In-Reply-To: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> References: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> Message-ID: You should probably be using macros where you were using C++ templates, no? -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeaye at arrownext.com Thu Apr 4 15:01:48 2013 From: jeaye at arrownext.com (Jeaye Wilkerson) Date: Thu, 4 Apr 2013 15:01:48 -0700 Subject: [rust-dev] Generics? In-Reply-To: References: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> Message-ID: <3BB3EB4A-8F47-4305-B852-091770CCBCA1@arrownext.com> On Apr 4, 2013, at 2:55 PM, Steve Klabnik wrote: > You should probably be using macros where you were using C++ templates, no? Ahh, you're right. I see now that macros can essentially be C++ templates; plug in a type and see if it compiles! An epiphanic moment, indeed. Cheers, Jeaye From vadimcn at gmail.com Thu Apr 4 15:05:24 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 4 Apr 2013 15:05:24 -0700 Subject: [rust-dev] Not-quite-proposal about & sigils In-Reply-To: <515DEFA3.2080701@mozilla.com> References: <515DEFA3.2080701@mozilla.com> Message-ID: What's so confusing about this? I agree that parameter modes had too many options to think about, but this should be mostly transparent to the user. Perhaps to the programmer semantics should stay the same as if parameter was truly passed by value (i.e. no de-referencing needed). The difference would be on the calling convention level. I am thinking of how C++ fastcall calling convention handles function arguments: anything that fits in 4 bytes is passed in registers, otherwise it goes on stack. Also, in cdecl convention small return values go into EAX register, whereas large ones are copied directly into the caller's stack frame via a hidden pointer parameter. All this completely transparent to the programmer (unless cross-language libraries are involved, of course). It seems to me that most of the borrow pointer usage in Rust is for efficiency reasons, not because developer actually needs a pointer there. Such code would work fine with by-value parameters, only slower. BTW, it may also happen that the optimal value of the N threshold is different on different platforms, so "by-ref vs by-value" decision may be better left to whoever defines Rust ABI for that platform. Regarding generics: Rust generics are reified to concrete types before code is emitted, aren't they? After concrete parameter types are known, the same optimization rule could be applied. Finally, you might ask: "Why not just treat this as an optimization?". Well, if this optimization is not a part of the language spec, developers cannot rely on it, and will continue using &'s everywhere, just in case. Kind of like tail recursion optimization is pretty useless unless guaranteed by the language. Vadim On Thu, Apr 4, 2013 at 2:24 PM, Patrick Walton wrote: > On 4/4/13 2:20 PM, Vadim wrote: > >> So I see all those borrow '&' sigils littering almost every function >> declaration in Rust source, and I think that this is major contributor >> to eye-soreness Rust syntax causes. Since '&' is so popular, couldn't >> Rust just make it a default? >> >> For instance, what if the following rule were be adopted: "All unadorned >> function parameters are implicitly assumed to be passed by >> borrow-reference"? Now, of course, this be inefficient for small types >> like int, but that could be dealt with by specifying that types less >> than N bytes in size (N perhaps being platform-dependent), are passed >> by-value, except if mutable, or if adorned by lifetime of another >> parameter. >> >> Ok, this is not a serious proposal, because I am probably missing a lot >> of corner cases, but I would like to hear why this wouldn't work. >> > > We tried this once ("modes"), and it was very confusing, especially when > generics were involved. > > Patrick > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at steveklabnik.com Thu Apr 4 15:10:27 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Thu, 4 Apr 2013 17:10:27 -0500 Subject: [rust-dev] Generics? In-Reply-To: <3BB3EB4A-8F47-4305-B852-091770CCBCA1@arrownext.com> References: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> <3BB3EB4A-8F47-4305-B852-091770CCBCA1@arrownext.com> Message-ID: Any time. Moving to new languages is hard, especially when you've been doing one for a long time. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Thu Apr 4 15:30:41 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 04 Apr 2013 15:30:41 -0700 Subject: [rust-dev] Generics? In-Reply-To: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> References: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> Message-ID: <515DFF11.5000600@mozilla.com> On 4/4/13 2:45 PM, Jeaye Wilkerson wrote: > Howdy, > > I've been tinkering with Rust generics lately and, unfortunately, they > seem very limiting. Coming from C++, I expect from generics what > templates provide: A plug-in-this-type-in-and-see-if-it-compiles ( > http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error ) > approach. Rust generics are more like C++13 templates with concepts, not like the templates that exist today. This allows templates to be typechecked at the time you write them, not when you instantiate them. You can use macros for the more unstructured approach. It seems to me that trait-based generics are not really > generic at all; they're polymorphic. Take the following: > > impl Foo > { > pub fn zero() -> Foo > { > Foo { bar: num::Zero::zero() } > } > } > > > Often times in C++, a programmer will want to restrict the types that > can go into a function. C++ traits make this kind of messy, so I > appreciate the approach here. Still, getting zero from T uses a > polymorphic num::Zero::zero(), instead of a generic T::zero(). This is something that Niko addresses in these posts: http://smallcultfollowing.com/babysteps/blog/2013/04/02/associated-items/ http://smallcultfollowing.com/babysteps/blog/2013/04/03/associated-items-continued/ Allowing `T::zero()` could be done and has advantages and disadvantages, but I've shied away from it so far, because of the problems with types that aren't paths (`<~[int]>::empty()`) and ambiguities (what if there are two traits that define `zero()`?) > Furthermore, what if one wanted to create also a "pub fn one() -> > Foo" function; you then need "num::Zero::zero() + 1", but does that > work as expected? You would need another bound on the function. Or just use the Num trait, as below. > Another problem that arises is the massive number of > trait bounds that an arithmetic (or something else) function might need > to simply work. This is because trait inheritance is currently broken. Once it's fixed, you'll just be able to use the Num trait and you'll get all of the arithmetic with one short trait bound. Patrick From pwalton at mozilla.com Thu Apr 4 15:37:12 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 04 Apr 2013 15:37:12 -0700 Subject: [rust-dev] Not-quite-proposal about & sigils In-Reply-To: References: <515DEFA3.2080701@mozilla.com> Message-ID: <515E0098.7080501@mozilla.com> On 4/4/13 3:05 PM, Vadim wrote: > What's so confusing about this? I agree that parameter modes had too > many options to think about, but this should be mostly transparent to > the user. Perhaps to the programmer semantics should stay the same as > if parameter was truly passed by value (i.e. no de-referencing > needed). The difference would be on the calling convention level. > > I am thinking of how C++ fastcall calling convention handles function > arguments: anything that fits in 4 bytes is passed in registers, > otherwise it goes on stack. Also, in cdecl convention small return > values go into EAX register, whereas large ones are copied directly into > the caller's stack frame via a hidden pointer parameter. All this > completely transparent to the programmer (unless cross-language > libraries are involved, of course). This is already done. The Rust ABI specifies that when large structures are passed by move, a pointer is implicitly passed instead. Patrick From niko at alum.mit.edu Thu Apr 4 17:46:48 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 04 Apr 2013 20:46:48 -0400 Subject: [rust-dev] Not-quite-proposal about & sigils In-Reply-To: <515E0098.7080501@mozilla.com> References: <515DEFA3.2080701@mozilla.com> <515E0098.7080501@mozilla.com> Message-ID: <515E1EF8.40104@alum.mit.edu> Patrick Walton wrote: > This is already done. The Rust ABI specifies that when large > structures are passed by move, a pointer is implicitly passed instead. As an aside, I've been thinking that we can optimize the trans code further for non-drop types that are located in immutable variables which are not moved. In that case, we currently make a second copy, but there is no reason to do so. Niko From vadimcn at gmail.com Thu Apr 4 19:56:24 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 4 Apr 2013 19:56:24 -0700 Subject: [rust-dev] Not-quite-proposal about & sigils In-Reply-To: References: <515DEFA3.2080701@mozilla.com> Message-ID: Ahh, I guess I missed that rvalues of "moved" types are also moved when used as parameters. Yes, that throws a wrench into my reasoning. But this sucks! 95% of the time I don't want a function to take ownership of it's arguments. I understand that this was done for consistency with local assignments, but this adds so much line noise! On Thu, Apr 4, 2013 at 4:13 PM, Daniel Micay wrote: > On Thu, Apr 4, 2013 at 6:05 PM, Vadim wrote: > > What's so confusing about this? I agree that parameter modes had too > many > > options to think about, but this should be mostly transparent to the > user. > > Perhaps to the programmer semantics should stay the same as if parameter > was > > truly passed by value (i.e. no de-referencing needed). The difference > > would be on the calling convention level. > > > > The semantics between pass-by-value and pass-by-reference aren't the > same, because pass-by-value is a move of ownership for anything with a > destructor and borrowing a pointer has to freeze the object. > > For example, these function signatures on the Map trait express that > only insertion actually requires taking ownership of a value, which > allows to work with types that are non-cloneable/non-copyable: > > fn find(&self, key: &K) -> Option<&'self V>; > fn find_mut(&mut self, key: &K) -> Option<&'self mut V>; > fn insert(&mut self, key: K, value: V) -> bool; > fn remove(&mut self, key: &K) -> bool; > > In a lot of cases like this, & really means taking a parameter without > taking ownership and could in theory be optimized to a by-value > parameter for small objects. However, it would still need to act as an > immutable reference (freezing, inability to move out of it, lifetimes) > and it wouldn't have a semantic impact beyond adding complexity, just > a potential performance one for non-inlined functions. I don't think > it would really work out without adding a first-class > non-owning-immutable-thing-that-acts-like-a-pointer :P. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Thu Apr 4 20:23:36 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 4 Apr 2013 22:23:36 -0500 Subject: [rust-dev] Generics? In-Reply-To: <515DFF11.5000600@mozilla.com> References: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> <515DFF11.5000600@mozilla.com> Message-ID: Good points, Patrick. Added Generics to wiki page for Cxx programmers (probably could use more info there also) https://github.com/mozilla/rust/wiki/Rust-for-CXX-programmers On Thu, Apr 4, 2013 at 5:30 PM, Patrick Walton wrote: > On 4/4/13 2:45 PM, Jeaye Wilkerson wrote: > >> Howdy, >> >> I've been tinkering with Rust generics lately and, unfortunately, they >> seem very limiting. Coming from C++, I expect from generics what >> templates provide: A plug-in-this-type-in-and-see-**if-it-compiles ( >> http://en.wikipedia.org/wiki/**Substitution_failure_is_not_**an_error) >> approach. >> > > Rust generics are more like C++13 templates with concepts, not like the > templates that exist today. This allows templates to be typechecked at the > time you write them, not when you instantiate them. You can use macros for > the more unstructured approach. > > > It seems to me that trait-based generics are not really > >> generic at all; they're polymorphic. Take the following: >> >> impl Foo >> { >> pub fn zero() -> Foo >> { >> Foo { bar: num::Zero::zero() } >> } >> } >> >> >> Often times in C++, a programmer will want to restrict the types that >> can go into a function. C++ traits make this kind of messy, so I >> appreciate the approach here. Still, getting zero from T uses a >> polymorphic num::Zero::zero(), instead of a generic T::zero(). >> > > This is something that Niko addresses in these posts: > > http://smallcultfollowing.com/**babysteps/blog/2013/04/02/** > associated-items/ > > http://smallcultfollowing.com/**babysteps/blog/2013/04/03/** > associated-items-continued/ > > Allowing `T::zero()` could be done and has advantages and disadvantages, > but I've shied away from it so far, because of the problems with types that > aren't paths (`<~[int]>::empty()`) and ambiguities (what if there are two > traits that define `zero()`?) > > > Furthermore, what if one wanted to create also a "pub fn one() -> >> Foo" function; you then need "num::Zero::zero() + 1", but does that >> work as expected? >> > > You would need another bound on the function. Or just use the Num trait, > as below. > > > Another problem that arises is the massive number of >> trait bounds that an arithmetic (or something else) function might need >> to simply work. >> > > This is because trait inheritance is currently broken. Once it's fixed, > you'll just be able to use the Num trait and you'll get all of the > arithmetic with one short trait bound. > > Patrick > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeaye at arrownext.com Thu Apr 4 20:23:26 2013 From: jeaye at arrownext.com (Jeaye) Date: Thu, 04 Apr 2013 20:23:26 -0700 Subject: [rust-dev] Generics? In-Reply-To: References: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> <515DFF11.5000600@mozilla.com> Message-ID: <515E43AE.80301@arrownext.com> On 04/04/2013 08:23 PM, Thad Guidry wrote: > Good points, Patrick. Added Generics to wiki page for Cxx programmers > (probably could use more info there also) > https://github.com/mozilla/rust/wiki/Rust-for-CXX-programmers > Thanks for adding that! I'm sure it'll help the next me that runs into this situation. Cheers, Jeaye From graydon at mozilla.com Fri Apr 5 09:24:58 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 05 Apr 2013 09:24:58 -0700 Subject: [rust-dev] Generics? In-Reply-To: <3BB3EB4A-8F47-4305-B852-091770CCBCA1@arrownext.com> References: <9C425A62-C252-4CF5-9ADF-120947964BD1@arrownext.com> <3BB3EB4A-8F47-4305-B852-091770CCBCA1@arrownext.com> Message-ID: <515EFADA.1080801@mozilla.com> On 13-04-04 03:01 PM, Jeaye Wilkerson wrote: > > On Apr 4, 2013, at 2:55 PM, Steve Klabnik wrote: > >> You should probably be using macros where you were using C++ templates, no? > > > Ahh, you're right. I see now that macros can essentially be C++ templates; plug in a type and see if it compiles! An epiphanic moment, indeed. Not quite. It won't do SFINAE or backtracking. If the syntax fits, it'll expand, regardless of types. If the types don't fit, typechecking will fail-fail and the macro won't try some other pattern. So it's not quite the same as templates. As patrick said, it's more like templates-with-concepts (and without backtracking). I _believe_ the type system remains non-turing-complete. That's always been a goal for me anyway! (The macro system is turing complete, but apparently this is pretty much the norm in macro systems. It's not type-aware, which is what you were after.) -Graydon From steve at steveklabnik.com Fri Apr 5 11:44:40 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Fri, 5 Apr 2013 13:44:40 -0500 Subject: [rust-dev] I want to write more docs Message-ID: Now that the language has largely settled down, I'd like to start writing more docs. I've gotten a few patches in, but want to contribute more. Two things: 1. What needs documented the most? Where should I start to be most effective? 2. In Ruby-land, we have doc percentages published. Like this: http://documenting-ruby.org/assets/undocumented_core.txt Does this exist for Rust? -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Fri Apr 5 11:46:29 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Fri, 5 Apr 2013 11:46:29 -0700 Subject: [rust-dev] I want to write more docs In-Reply-To: References: Message-ID: On Fri, Apr 5, 2013 at 11:44 AM, Steve Klabnik wrote: > Now that the language has largely settled down, I'd like to start writing > more docs. I've gotten a few patches in, but want to contribute more. > > Two things: > > What needs documented the most? Where should I start to be most effective? > There's a bug open on documenting core::io; I think that would be good. Ask questions on IRC if there's stuff that's not clear; I'm sure there is stuff that's not clear! I think since core and std are so pervasive, starting by documenting them (in the way you've already done very well for some modules with one comment per function and examples where possible) would be useful. > In Ruby-land, we have doc percentages published. Like this: > http://documenting-ruby.org/assets/undocumented_core.txt Does this exist for > Rust? > It doesn't exist as far as I know, but would be great to have for Rust, and it probably wouldn't be hard to modify rustdoc to do it. Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Too much to carry, too much to let go Time goes fast, learning goes slow." -- Bruce Cockburn From jack at metajack.im Fri Apr 5 11:47:59 2013 From: jack at metajack.im (Jack Moffitt) Date: Fri, 5 Apr 2013 12:47:59 -0600 Subject: [rust-dev] I want to write more docs In-Reply-To: References: Message-ID: > What needs documented the most? Where should I start to be most effective? More on the ffi docs that specifically shows callback examples would be useful. I had a lot of questions about this while updating Servo, which defines callbacks for some HTML parsing stuff. I'm not sure what the best example would be. Cells and why you need them might be another good place. jack. From steve at steveklabnik.com Fri Apr 5 12:50:33 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Fri, 5 Apr 2013 14:50:33 -0500 Subject: [rust-dev] I want to write more docs In-Reply-To: References: Message-ID: > There's a bug open on documenting core::io; I think that would be good. Cool. I did a little bit of work there, I'll keep going through it. > I think since core and std are so > pervasive, starting by documenting them (in the way you've already > done very well for some modules with one comment per function and > examples where possible) would be useful. Seems legit. I'll get on it. One small issue about examples: I'm not sure what the best way is for providing examples for traits. Should I show usage of implementing the trait? Of using something that implements it? > It doesn't exist as far as I know, but would be great to have for > Rust, and it probably wouldn't be hard to modify rustdoc to do it. Cool. I'll consider checking that out, too. -------------- next part -------------- An HTML attachment was scrubbed... URL: From steve at steveklabnik.com Fri Apr 5 12:51:54 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Fri, 5 Apr 2013 14:51:54 -0500 Subject: [rust-dev] I want to write more docs In-Reply-To: References: Message-ID: > More on the ffi docs that specifically shows callback examples would > be useful. Seems good. I've been thinking about this from the Ruby perspective (and that recent blog post was great), so it's a natural fit for my interests. -------------- next part -------------- An HTML attachment was scrubbed... URL: From valentin.gosu at gmail.com Fri Apr 5 14:01:52 2013 From: valentin.gosu at gmail.com (Valentin Gosu) Date: Sat, 6 Apr 2013 00:01:52 +0300 Subject: [rust-dev] I want to write more docs In-Reply-To: References: Message-ID: On 5 April 2013 22:51, Steve Klabnik wrote: > > More on the ffi docs that specifically shows callback examples would > > be useful. > I think working examples for every function and structure described in the docs would be great for newbies. The server-client example I built 2 weeks ago isn't working any more, so it would be great to rebuild it with working snippets. Moreover, the examples could be actual tests, so when something changes, the examples will need to be updated. Thanks -------------- next part -------------- An HTML attachment was scrubbed... URL: From masklinn at masklinn.net Fri Apr 5 14:07:26 2013 From: masklinn at masklinn.net (Masklinn) Date: Fri, 5 Apr 2013 23:07:26 +0200 Subject: [rust-dev] I want to write more docs In-Reply-To: References: Message-ID: <8ED71BC8-A949-48F7-BB40-184CA23668B6@masklinn.net> On 2013-04-05, at 23:01 , Valentin Gosu wrote: > On 5 April 2013 22:51, Steve Klabnik wrote: > >>> More on the ffi docs that specifically shows callback examples would >>> be useful. >> > > I think working examples for every function and structure described in the > docs would be great for newbies. > The server-client example I built 2 weeks ago isn't working any more, so it > would be great to rebuild it with working snippets. For that, a gofix-type tool might be nice: although the dev team would like the language to be frozen, details may still change as needed and having a tool able to migrate Rust 0.6 code to 0.7 and 0.8 and? transparently would be neat. Event more so if it prints the changelog notes for the stuff it fixes, so the developer can learn what changed of what he knew/used. From banderson at mozilla.com Fri Apr 5 14:24:22 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 05 Apr 2013 14:24:22 -0700 Subject: [rust-dev] I want to write more docs In-Reply-To: <8ED71BC8-A949-48F7-BB40-184CA23668B6@masklinn.net> References: <8ED71BC8-A949-48F7-BB40-184CA23668B6@masklinn.net> Message-ID: <515F4106.8000506@mozilla.com> On 04/05/2013 02:07 PM, Masklinn wrote: > On 2013-04-05, at 23:01 , Valentin Gosu wrote: > >> On 5 April 2013 22:51, Steve Klabnik wrote: >> >>>> More on the ffi docs that specifically shows callback examples would >>>> be useful. >> I think working examples for every function and structure described in the >> docs would be great for newbies. >> The server-client example I built 2 weeks ago isn't working any more, so it >> would be great to rebuild it with working snippets. > For that, a gofix-type tool might be nice: although the dev team would > like the language to be frozen, details may still change as needed and > having a tool able to migrate Rust 0.6 code to 0.7 and 0.8 and? > transparently would be neat. > > Event more so if it prints the changelog notes for the stuff it fixes, > so the developer can learn what changed of what he knew/used. > rustfix is high on everybody's list of things we would like to have. it's a sizeable and difficult project though. From jack at metajack.im Fri Apr 5 14:32:53 2013 From: jack at metajack.im (Jack Moffitt) Date: Fri, 5 Apr 2013 15:32:53 -0600 Subject: [rust-dev] I want to write more docs In-Reply-To: <515F4106.8000506@mozilla.com> References: <8ED71BC8-A949-48F7-BB40-184CA23668B6@masklinn.net> <515F4106.8000506@mozilla.com> Message-ID: > rustfix is high on everybody's list of things we would like to have. it's a > sizeable and difficult project though. Since I don't think something that could have ported servo is likely to ever exist, perhaps a good first milestone is just something that can make the easy changes like removing `pub` from `pub impl X for Y` and s/const/static/. It seems like it needs a minimal amount of syntax awareness and would at least automate the main drudgery. Is the rust parser exposed as a library? jack. From banderson at mozilla.com Fri Apr 5 14:35:14 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 05 Apr 2013 14:35:14 -0700 Subject: [rust-dev] I want to write more docs In-Reply-To: References: <8ED71BC8-A949-48F7-BB40-184CA23668B6@masklinn.net> <515F4106.8000506@mozilla.com> Message-ID: <515F4392.30601@mozilla.com> On 04/05/2013 02:32 PM, Jack Moffitt wrote: >> rustfix is high on everybody's list of things we would like to have. it's a >> sizeable and difficult project though. > Since I don't think something that could have ported servo is likely > to ever exist, perhaps a good first milestone is just something that > can make the easy changes like removing `pub` from `pub impl X for Y` > and s/const/static/. It seems like it needs a minimal amount of syntax > awareness and would at least automate the main drudgery. Is the rust > parser exposed as a library? > > jack. The rust parser is available as a library, yes. From masklinn at masklinn.net Fri Apr 5 14:59:05 2013 From: masklinn at masklinn.net (Masklinn) Date: Fri, 5 Apr 2013 23:59:05 +0200 Subject: [rust-dev] I want to write more docs In-Reply-To: <515F4392.30601@mozilla.com> References: <8ED71BC8-A949-48F7-BB40-184CA23668B6@masklinn.net> <515F4106.8000506@mozilla.com> <515F4392.30601@mozilla.com> Message-ID: <8461BF9C-40D5-4410-ABAB-EFB339E982FA@masklinn.net> On 2013-04-05, at 23:35 , Brian Anderson wrote: > On 04/05/2013 02:32 PM, Jack Moffitt wrote: >>> rustfix is high on everybody's list of things we would like to have. it's a >>> sizeable and difficult project though. >> Since I don't think something that could have ported servo is likely >> to ever exist, perhaps a good first milestone is just something that >> can make the easy changes like removing `pub` from `pub impl X for Y` >> and s/const/static/. It seems like it needs a minimal amount of syntax >> awareness and would at least automate the main drudgery. Is the rust >> parser exposed as a library? >> >> jack. > > The rust parser is available as a library, yes. And does Rust support loading/using multiple versions of the same library? From rust-dev at grant.x43.net Fri Apr 5 16:14:09 2013 From: rust-dev at grant.x43.net (Grant Husbands) Date: Sat, 6 Apr 2013 00:14:09 +0100 Subject: [rust-dev] Library Safety In-Reply-To: <515DF302.3020702@alum.mit.edu> References: <515DF302.3020702@alum.mit.edu> Message-ID: To some extent, yes. I'm not familiar enough with Rust's lint modes to say much more than that. I'm going to try using Rust for a while before giving a more detailed proposal. However, I will give a more concrete example, now that I know slightly more. In servo.rc (in the servo project), there's a line like this: extern mod stb_image; I want to be able to write it something like this: extern mod rust-jpeg ( nogc, safe ); Doing so should ensure that the library cannot do GC or anything directly or indirectly unsafe (alternatively, it should import the version that was compiled that way). Then, the servo project can be sure that rust-jpeg cannot perform any unsafe operations (or GC), without manual audits of its imports or code. It essentially removes the JPEG library from the TCB (trusted computing base) of Servo. Carefully applied, it would make servo much more secure against maliciousness via supporting libraries. The important thing, to my mind, is that I don't have to audit the rust-jpeg library at all, and the worst it can do (probably) is a denial of service. If this became standard practice for Rust code, it would be a systems language in which it's feasible to easily include relatively untrusted third-party libraries, securely, and interact with them naturally. I think there's a lot of mileage in that. Grant. On Thu, Apr 4, 2013 at 10:39 PM, Niko Matsakis wrote: > It sounds to me like you're talking about something similar to the current > lint modes for GC etc? > > Niko > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri Apr 5 17:08:12 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 05 Apr 2013 17:08:12 -0700 Subject: [rust-dev] I want to write more docs In-Reply-To: References: Message-ID: <515F676C.5060701@mozilla.com> On 04/05/2013 11:44 AM, Steve Klabnik wrote: > > Now that the language has largely settled down, I'd like to start > writing more docs. I've gotten a few patches in, but want to > contribute more. > > Two things: > > 1. > > What needs documented the most? Where should I start to be most > effective? > > 2. > > In Ruby-land, we have doc percentages published. Like this: > http://documenting-ruby.org/assets/undocumented_core.txt Does this > exist for Rust? > A great thing would be to document Rust's coding standards, probably with an accompanying mailing list discussion to hash out the finer points. We do have some coding standards but they are not universally known since they are simply transmitted through received wisdom. There's a [wiki] page that is very sparse and very out of date. [wiki]: https://github.com/mozilla/rust/wiki/Note-style-guide -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri Apr 5 17:09:27 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 05 Apr 2013 17:09:27 -0700 Subject: [rust-dev] I want to write more docs In-Reply-To: <8461BF9C-40D5-4410-ABAB-EFB339E982FA@masklinn.net> References: <8ED71BC8-A949-48F7-BB40-184CA23668B6@masklinn.net> <515F4106.8000506@mozilla.com> <515F4392.30601@mozilla.com> <8461BF9C-40D5-4410-ABAB-EFB339E982FA@masklinn.net> Message-ID: <515F67B7.30602@mozilla.com> On 04/05/2013 02:59 PM, Masklinn wrote: > On 2013-04-05, at 23:35 , Brian Anderson wrote: > >> On 04/05/2013 02:32 PM, Jack Moffitt wrote: >>>> rustfix is high on everybody's list of things we would like to have. it's a >>>> sizeable and difficult project though. >>> Since I don't think something that could have ported servo is likely >>> to ever exist, perhaps a good first milestone is just something that >>> can make the easy changes like removing `pub` from `pub impl X for Y` >>> and s/const/static/. It seems like it needs a minimal amount of syntax >>> awareness and would at least automate the main drudgery. Is the rust >>> parser exposed as a library? >>> >>> jack. >> The rust parser is available as a library, yes. > And does Rust support loading/using multiple versions of the same > library? In theory, yes! From clements at brinckerhoff.org Fri Apr 5 18:50:02 2013 From: clements at brinckerhoff.org (John Clements) Date: Fri, 5 Apr 2013 18:50:02 -0700 Subject: [rust-dev] legality/utility of modules inside functions Message-ID: Our grammar currently parses modules inside functions just fine. However, it doesn't look like it's possible to call any functions defined in one. For instance: fn main () { use z; mod z { fn f () -> int { 19 } } z::f(); } Note that the "use" has to be at the beginning of the block--that's enforced. This gives the error: /tmp/foo.rs:2:8: 2:10 error: failed to resolve import: z /tmp/foo.rs:2 use z; ^~ error: failed to resolve imports error: aborting due to 2 previous errors It looks to me like modules are allowed here just because it's consistent with allowing other item types--struct and enum decls, for instance. Am I missing something obvious? In particular, I'm bad with the resolver; perhaps there's a way to write the "use" to make this work. If not, it would seem to me like removing them would be the sensible choice. Thoughts? John Clements From andres.osinski at gmail.com Fri Apr 5 19:13:04 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Fri, 5 Apr 2013 23:13:04 -0300 Subject: [rust-dev] FastCGI implementation Message-ID: Hi everyone, I've taken an interest in Rust as it fills a niche in programming that I've long been looking to fullfill. I'm primarily a Python web developer, so I wanted to start coding by implementing the FastCGI protocol for Rust. I know that its native task management and socket capabilities are very good, but you never know when it might be handy for someone. I just wanted to know if anyone was familiar with the FCGI protocol, and if there's any reference as to how to manage the packing and unpacking of C data structures, as well as if you know of any implementation for a similar protocol. One small question that I have is that FCGI protocol defines a struct with two char arrays whose length is defined by another field within the struct, and I was wondering how that would be modeled in Rust. Thanks -- Andr?s Osinski -------------- next part -------------- An HTML attachment was scrubbed... URL: From leebraid at gmail.com Fri Apr 5 19:25:21 2013 From: leebraid at gmail.com (Lee Braiden) Date: Sat, 06 Apr 2013 03:25:21 +0100 Subject: [rust-dev] FastCGI implementation In-Reply-To: References: Message-ID: <515F8791.2040208@gmail.com> On 06/04/13 03:13, Andres Osinski wrote: > I just wanted to know if anyone was familiar with the FCGI protocol, > and if there's any reference as to how to manage the packing and > unpacking of C data structures, as well as if you know of any > implementation for a similar protocol. > > One small question that I have is that FCGI protocol defines a struct > with two char arrays whose length is defined by another field within > the struct, and I was wondering how that would be modeled in Rust. It's my understanding that Rust structures are compatible with C structures. If so, you won't need to pack/unpack: just define a struct, read/write it, and access the elements. Data validation is still important, of course. http://static.rust-lang.org/doc/tutorial.html#data-structures -- Lee From pnkfelix at mozilla.com Sat Apr 6 03:35:11 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Sat, 06 Apr 2013 12:35:11 +0200 Subject: [rust-dev] legality/utility of modules inside functions In-Reply-To: References: Message-ID: <515FFA5F.9030808@mozilla.com> John (cc'ing rust-dev)- You can still use the module in other contexts. pub fn baz() { mod z { pub fn f () -> int { 19 } } fn g() -> int { use z; z::f() } g(); } Cheers, -Felix On 06/04/2013 03:50, John Clements wrote: > Our grammar currently parses modules inside functions just fine. However, it doesn't look like it's possible to call any functions defined in one. For instance: > > fn main () { > use z; > mod z { > fn f () -> int { 19 } > } > z::f(); > } > > Note that the "use" has to be at the beginning of the block--that's enforced. This gives the error: > > /tmp/foo.rs:2:8: 2:10 error: failed to resolve import: z > /tmp/foo.rs:2 use z; > ^~ > error: failed to resolve imports > error: aborting due to 2 previous errors > > It looks to me like modules are allowed here just because it's consistent with allowing other item types--struct and enum decls, for instance. Am I missing something obvious? In particular, I'm bad with the resolver; perhaps there's a way to write the "use" to make this work. If not, it would seem to me like removing them would be the sensible choice. > > Thoughts? > > John Clements > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.org From dherman at mozilla.com Sat Apr 6 07:56:01 2013 From: dherman at mozilla.com (David Herman) Date: Sat, 6 Apr 2013 07:56:01 -0700 Subject: [rust-dev] new benchmark Message-ID: This blog post showed up on HN: http://attractivechaos.wordpress.com/2013/04/06/performance-of-rust-and-dart-in-sudoku-solving/ The author's Rust implementation is here, and s/he invites pull requests if you can improve it: https://github.com/attractivechaos/plb/blob/master/sudoku/sudoku_v1.rs Enjoy, Dave From thadguidry at gmail.com Sat Apr 6 09:45:24 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sat, 6 Apr 2013 11:45:24 -0500 Subject: [rust-dev] FastCGI implementation In-Reply-To: References: Message-ID: Perhaps the Cherokee webserver might be useful for you to look at it's codebase... and it's implementation of fastcgi.h https://github.com/cherokee/webserver/tree/master/cherokee On Fri, Apr 5, 2013 at 9:13 PM, Andres Osinski wrote: > Hi everyone, I've taken an interest in Rust as it fills a niche in > programming that I've long been looking to fullfill. > > I'm primarily a Python web developer, so I wanted to start coding by > implementing the FastCGI protocol for Rust. I know that its native task > management and socket capabilities are very good, but you never know when > it might be handy for someone. > > I just wanted to know if anyone was familiar with the FCGI protocol, and > if there's any reference as to how to manage the packing and unpacking of C > data structures, as well as if you know of any implementation for a similar > protocol. > > One small question that I have is that FCGI protocol defines a struct with > two char arrays whose length is defined by another field within the struct, > and I was wondering how that would be modeled in Rust. > > Thanks > > -- > Andr?s Osinski > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Sat Apr 6 09:50:23 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Sat, 6 Apr 2013 11:50:23 -0500 Subject: [rust-dev] FastCGI implementation In-Reply-To: References: Message-ID: oops, that should have been the "handler portion" of Cherokee FastCGI ... https://github.com/cherokee/webserver/blob/master/cherokee/handler_fcgi.c more docs here: http://www.cherokee-project.com/doc/modules_handlers_fcgi.html On Sat, Apr 6, 2013 at 11:45 AM, Thad Guidry wrote: > Perhaps the Cherokee webserver might be useful for you to look at it's > codebase... and it's implementation of fastcgi.h > > https://github.com/cherokee/webserver/tree/master/cherokee > > > On Fri, Apr 5, 2013 at 9:13 PM, Andres Osinski wrote: > >> Hi everyone, I've taken an interest in Rust as it fills a niche in >> programming that I've long been looking to fullfill. >> >> I'm primarily a Python web developer, so I wanted to start coding by >> implementing the FastCGI protocol for Rust. I know that its native task >> management and socket capabilities are very good, but you never know when >> it might be handy for someone. >> >> I just wanted to know if anyone was familiar with the FCGI protocol, and >> if there's any reference as to how to manage the packing and unpacking of C >> data structures, as well as if you know of any implementation for a similar >> protocol. >> >> One small question that I have is that FCGI protocol defines a struct >> with two char arrays whose length is defined by another field within the >> struct, and I was wondering how that would be modeled in Rust. >> >> Thanks >> >> -- >> Andr?s Osinski >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From mcguire at crsr.net Sat Apr 6 13:57:58 2013 From: mcguire at crsr.net (Tommy M. McGuire) Date: Sat, 06 Apr 2013 15:57:58 -0500 Subject: [rust-dev] Difference between "mod foo" and "extern mod foo"? Message-ID: <51608C56.8000206@crsr.net> What is the difference between "mod misc;" and "extern mod misc;", other than the obvious linking with libmisc-...so? (Yeah, I'm a great namer.) I was moving a function from a program into a separate module, importing the module with "mod misc;", and my program went from taking ~6 seconds to ~32 seconds. After some experimentation, I discovered that using "extern mod misc;" and separately compiling misc.rs, the run time went back down to ~6 seconds. The weird part is that the function I moved contains the working loop of the program; it is called once by main. I compiled the original program with: rust build -O proggie.rs and the program with the separate, "mod misc;" imported module with: rust build -O proggie.rs and the third version with the separate crate misc with: rust build -O misc.rs rust build -L. -O proggie.rs I'm using rust 0.6. --- It occurs to me on second thought (since I can't get to the 'net to send this at the moment) that I've introduced another level of modules here, since the code was already calling functions from a third module. Originally, the function I moved, search, called a function from another module, combinations::each_combination, also imported with "mod". Following the move, main calls misc::search, which calls combinations::each_combination, and combinations was imported into misc via "mod" in addition to misc being imported into the main program via "mod". -- Tommy M. McGuire mcguire at crsr.net From ben at wanderview.com Sat Apr 6 20:14:31 2013 From: ben at wanderview.com (Ben Kelly) Date: Sat, 6 Apr 2013 23:14:31 -0400 Subject: [rust-dev] linking questions Message-ID: <42A0851F-311D-43B2-8BF8-46E760145B62@wanderview.com> Hello, I've been trying to see if a tool like tup [1] could be used to build rust crates and executables. In order for this to be useful I would like to compile .rs files individually to .o files and then link them together into their enclosing executable (or library). My initial (perhaps incorrect) impression is that currently rustc requires that all .rs files must be compiled in a single command. I've been able to generate the .o file using rustc -c, but I haven't been able to determine the correct link command. I ran into some symbol conflicts (I think related to more_stack) and also was unsure the correct libraries to use. Given that the library names are hashed, it seems difficult to build a traditional link rule. (rustc commands that produced library' with hashed names are also an issue for tup, but it may be possible to enhance it to support this case. Currently tup requires deterministic outputs from commands.) Can anyone give me any pointers where to look for linking information? Would it be possible/acceptable to add a --link option to rustc to perform the link or output correct link flags? One of my motivations for looking at this was the long build times required to compile larger crates. For example, if you touch a single file in libstd then rustc currently has to rebuild the entire crate which takes 45 seconds on my laptop: [xykon-2:~/devel/git/rust] bkelly% time x86_64-apple-darwin/stage2/bin/rustc --cfg stage2 -O --target=x86_64-apple-darwin -o x86_64-apple-darwin/stage2/lib/rustc/x86_64-apple-darwin/lib/libstd.dylib /Users/bkelly/devel/git/rust/src/libstd/std.rc && touch x86_64-apple-darwin/stage2/lib/rustc/x86_64-apple-darwin/lib/libstd.dylib warning: no debug symbols in executable (-arch x86_64) 43.953u 0.674s 0:45.82 97.3% 0+0k 0+8io 691pf+0w Thanks! Ben [1]: http://gittup.org/tup/ From pwalton at mozilla.com Sun Apr 7 00:30:53 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 07 Apr 2013 00:30:53 -0700 Subject: [rust-dev] linking questions In-Reply-To: <42A0851F-311D-43B2-8BF8-46E760145B62@wanderview.com> References: <42A0851F-311D-43B2-8BF8-46E760145B62@wanderview.com> Message-ID: <516120AD.40809@mozilla.com> On 4/6/13 8:14 PM, Ben Kelly wrote: > One of my motivations for looking at this was the long build times required to compile larger crates. For example, if you touch a single file in libstd then rustc currently has to rebuild the entire crate which takes 45 seconds on my laptop: Unfortunately, this isn't so straightforward. Crates can have mutually recursive definitions, so compiling one module requires at least scanning all the other modules for type and function definitions. Because of this, creating the dependency graph within a crate is rather difficult... I would recommend trying to break your crates up into smaller crates. Eventually it may be possible to recompile individual modules separately, but it will not be trivial. The good news is that we're focusing on improving raw compiler performance?the work that Graydon and I are doing should help with this. Patrick From ben at wanderview.com Sun Apr 7 19:47:32 2013 From: ben at wanderview.com (Ben Kelly) Date: Sun, 7 Apr 2013 22:47:32 -0400 Subject: [rust-dev] linking questions In-Reply-To: <516120AD.40809@mozilla.com> References: <42A0851F-311D-43B2-8BF8-46E760145B62@wanderview.com> <516120AD.40809@mozilla.com> Message-ID: On Apr 7, 2013, at 3:30 AM, Patrick Walton wrote: > On 4/6/13 8:14 PM, Ben Kelly wrote: >> One of my motivations for looking at this was the long build times > required to compile larger crates. For example, if you touch a single > file in libstd then rustc currently has to rebuild the entire crate > which takes 45 seconds on my laptop: > > Unfortunately, this isn't so straightforward. Crates can have mutually recursive definitions, so compiling one module requires at least scanning all the other modules for type and function definitions. Because of this, creating the dependency graph within a crate is rather difficult... So I guess this is where I was hoping tup might help a bit since it will automatically determine dependencies by monitoring file system reads and writes. And it seems while circular dependencies may exist in source files, the actual build graph could still be acyclic: foo.rs references bar.rs bar.rs references foo.rs foo.o depends on foo.rs and bar.rs bar.o depends on foo.rs and bar.rs This would result in the source files being scanned multiple times, of course. I guess its unclear to me if the penalty for this outweighs recompiling everything whenever there is a change. With javac the jvm startup speed tilts things towards just recompiling everything, but with a compiled binary like rustc it seems it might make sense to go the other direction. Of course, its likely I'm very confused here. :-) > I would recommend trying to break your crates up into smaller crates. Eventually it may be possible to recompile individual modules separately, but it will not be trivial. > > The good news is that we're focusing on improving raw compiler performance?the work that Graydon and I are doing should help with this. Awesome. Thanks! Ben From jpiatlicki at gmail.com Sun Apr 7 14:36:14 2013 From: jpiatlicki at gmail.com (Jauhien Piatlicki) Date: Sun, 07 Apr 2013 23:36:14 +0200 Subject: [rust-dev] rust-0.6 compilation with system LLVM fails Message-ID: <5161E6CE.50806@gmail.com> Hi all, sorry if this list is an inappropriate place for asking questions, feel free to point me to the right place or just ignore. ) I have a problem compiling rust with system llvm. I use Gentoo, llvm version 3.2 is installed in /usr. I configure rust like this: ./configure \ --prefix=/usr \ --enable-local-rust \ --local-rust-root="${WORKDIR}/rust-stage0" \ --llvm-root="/usr" where ${WORKDIR}/rust-stage0 points to the dir with stage0 snapshot. Here is configuration and compilation log: http://bpaste.net/show/89701/ As you can see linker fails with undefined references. What do I need beside passing --llvm-root="/usr" to configure to compile rust with system llvm. Thanks for answering, Jauhien Piatlicki -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 901 bytes Desc: OpenPGP digital signature URL: From mikhail.zabaluev at gmail.com Sun Apr 7 07:49:16 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Sun, 7 Apr 2013 17:49:16 +0300 Subject: [rust-dev] Importing foreign refcounted, non-threadsafe objects (GObject) Message-ID: Hi, I've started playing with Rust bindings to GObject: https://github.com/mzabaluev/grust The intent is to make any API that provides a GObject introspection safely usable in Rust. There are two important things about GLib objects: 1. The objects are reference counted in a thread-safe way. 2. The objects in general are not thread-safe: threads calling methods on one object need to be synchronized. In my proof-of-concept code, the Rust safe wrappers for the objects are intended to be cloneable and sendable by virtue of the GLib refcounting. But this may mean that an object may end up being used concurrently from multiple tasks. Are there any best practices for wrapping such objects? One solution I see is to dispatch all GObject calls through a dedicated ever-running task initialized on program startup (GObject needs an explicit init call anyway, so it's no big deal to add), but this grand central approach may not be optimal or flexible enough. Another topic of interest is casting. GObject provides runtime type information and supports dynamic type checks. This means we can safely down- and side-cast between traits representing GObject classes or interfaces, but we need a custom cast implementation. Is there any idiomatic trait to reuse? Best regards, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From heri16 at gmail.com Sun Apr 7 15:01:19 2013 From: heri16 at gmail.com (Heri Sim) Date: Mon, 8 Apr 2013 06:01:19 +0800 Subject: [rust-dev] 3 Gripes on Rust Message-ID: <7070576472340126500@unknownmsgid> Hi guys, I am new here. Just found out about this project today, and read up a lot on its history and purpose. There are 3 gripes I have about Rust, after comparing some good stuff in Go-lang. http://tour.golang.org 1st, dereferencing should be automatic everywhere. Running a pattern match on borrowed boxes should NOT require an asterisk (*). Passing in a stack-local variable to a function or closure (that requires arguments to be passed by reference), should not require the ampersand (&) in the caller. Why can't the compiler figure this out? In go-lang, all these things are just more invisible, which makes the learning curve so much easier. I understand people coming from C would prefer these memory-management signets explicit, but really they have little need to be so verbose in many cases, and should be optional or by-default instead, so that things just-work. (Just-like how custom borrow lifetimes are optional, and defaults well in most cases.) 2nd, there is a need for the concurrency mechanism similar to the concurrent "select" in go-lang. This is used to implement multiple patterns such as timeouts, and non-blocking channel receive, and many others. Errors in tasks would also be better handled/supervised this way. By the way, should rust errors be a trait like in go-lang? 3rd, while generics are great, there is a need for trait types or dynamic objects to be simpler to use in rust. Dynamic calls through interfaces in go-lang are simpler, while trading off performance. In rust, implementing draw_all on a vector of Drawable elements also have similar performance hit, but with a much uglier implementation requiring both @ and ~ signets and "as" syntax, which is confusing and too verbose. Also there seem to be a requirement for managed boxes in the shared heap for dynamic calls, which Erlang does not require. As such, recursion for some problem sets (like polymorphic binary trees) is not as clean in rust, compared to other languages. How can we improve this? Otherwise, Rust lang is really awesome. The documentation and syntax is easy to follow for the basics, but begin to feel "complex-for-complexity sake" in the advanced/modern language features. As such, the documentation feels schizophrenic as the language constructs begin to lose its delightful lean-opinionated design towards the end. Really beginning to like Rust a lot. Heri From steve at steveklabnik.com Sun Apr 7 20:03:17 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Sun, 7 Apr 2013 20:03:17 -0700 Subject: [rust-dev] rust-0.6 compilation with system LLVM fails In-Reply-To: <5161E6CE.50806@gmail.com> References: <5161E6CE.50806@gmail.com> Message-ID: Doesn't Rust still use custom patches to LLVM? Does your system LLVM have those patches? -------------- next part -------------- An HTML attachment was scrubbed... URL: From hatahet at gmail.com Sun Apr 7 20:21:00 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Sun, 7 Apr 2013 20:21:00 -0700 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: <7070576472340126500@unknownmsgid> References: <7070576472340126500@unknownmsgid> Message-ID: On Sun, Apr 7, 2013 at 3:01 PM, Heri Sim wrote: > > Passing in a stack-local variable to a function or closure (that > requires arguments to be passed by reference), should not require the > ampersand (&) in the caller. Why can't the compiler figure this out? > > This is one of the features I really like about Rust. C++ and D took the implicit approach to pass-by-reference, whereas languages like C# took the explicit approach. Not too long ago, there was a thread on the D forums arguing for making pass-by-reference explicit at the caller site. However, it was too late to make such a backward incompatible change since it would break a lot of code out there. There is no option of having pass-by-reference in Go. You pass a pointer to the struct, which also makes it explicit at the caller site. So in this case, Rust is not dissimilar from Go. -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From jarred at webkit.org Sun Apr 7 20:44:05 2013 From: jarred at webkit.org (Jarred Nicholls) Date: Sun, 7 Apr 2013 23:44:05 -0400 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: <7070576472340126500@unknownmsgid> References: <7070576472340126500@unknownmsgid> Message-ID: On Sun, Apr 7, 2013 at 6:01 PM, Heri Sim wrote: > Passing in a stack-local variable to a function or closure (that > requires arguments to be passed by reference), should not require the > ampersand (&) in the caller. Why can't the compiler figure this out? > I would attribute this as being a good language feature, in my opinion. I'd rather be explicit at the call site. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnathan at vandals.uidaho.edu Sun Apr 7 20:56:19 2013 From: pnathan at vandals.uidaho.edu (Paul Nathan) Date: Sun, 7 Apr 2013 20:56:19 -0700 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: <7070576472340126500@unknownmsgid> References: <7070576472340126500@unknownmsgid> Message-ID: <95EFB693-5108-46ED-8591-ECA1BB8C6133@vandals.uidaho.edu> Sir, Rust is not go. It addresses a different set of use cases, and, IMHO, is focused on a different audience. The sigils and their semantics are used for precision and control. Regards, Paul Nathan Sent from my iPhone On Apr 7, 2013, at 3:01 PM, Heri Sim wrote: > Hi guys, I am new here. Just found out about this project today, and > read up a lot on its history and purpose. > > > There are 3 gripes I have about Rust, after comparing some good stuff > in Go-lang. http://tour.golang.org > > > 1st, dereferencing should be automatic everywhere. > Running a pattern match on borrowed boxes should NOT require an asterisk (*). > Passing in a stack-local variable to a function or closure (that > requires arguments to be passed by reference), should not require the > ampersand (&) in the caller. Why can't the compiler figure this out? > > In go-lang, all these things are just more invisible, which makes the > learning curve so much easier. I understand people coming from C would > prefer these memory-management signets explicit, but really they have > little need to be so verbose in many cases, and should be optional or > by-default instead, so that things just-work. (Just-like how custom > borrow lifetimes are optional, and defaults well in most cases.) > > > 2nd, there is a need for the concurrency mechanism similar to the > concurrent "select" in go-lang. This is used to implement multiple > patterns such as timeouts, and non-blocking channel receive, and many > others. Errors in tasks would also be better handled/supervised this > way. By the way, should rust errors be a trait like in go-lang? > > > 3rd, while generics are great, there is a need for trait types or > dynamic objects to be simpler to use in rust. Dynamic calls through > interfaces in go-lang are simpler, while trading off performance. In > rust, implementing draw_all on a vector of Drawable elements also have > similar performance hit, but with a much uglier implementation > requiring both @ and ~ signets and "as" syntax, which is confusing and > too verbose. Also there seem to be a requirement for managed boxes in > the shared heap for dynamic calls, which Erlang does not require. As > such, recursion for some problem sets (like polymorphic binary trees) > is not as clean in rust, compared to other languages. How can we > improve this? > > > Otherwise, Rust lang is really awesome. > The documentation and syntax is easy to follow for the basics, but > begin to feel "complex-for-complexity sake" in the advanced/modern > language features. As such, the documentation feels schizophrenic as > the language constructs begin to lose its delightful lean-opinionated > design towards the end. > > Really beginning to like Rust a lot. > > Heri > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From catamorphism at gmail.com Sun Apr 7 20:58:01 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Sun, 7 Apr 2013 20:58:01 -0700 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: <7070576472340126500@unknownmsgid> References: <7070576472340126500@unknownmsgid> Message-ID: On Sun, Apr 7, 2013 at 3:01 PM, Heri Sim wrote: > Hi guys, I am new here. Just found out about this project today, and > read up a lot on its history and purpose. > > > There are 3 gripes I have about Rust, after comparing some good stuff > in Go-lang. http://tour.golang.org > > > 1st, dereferencing should be automatic everywhere. > Running a pattern match on borrowed boxes should NOT require an asterisk (*). > Passing in a stack-local variable to a function or closure (that > requires arguments to be passed by reference), should not require the > ampersand (&) in the caller. Why can't the compiler figure this out? We tried the second idea before Rust 0.4; it was called "modes". It was confusing and inconsistent. > > In go-lang, all these things are just more invisible, which makes the > learning curve so much easier. I understand people coming from C would > prefer these memory-management signets explicit, but really they have > little need to be so verbose in many cases, and should be optional or > by-default instead, so that things just-work. (Just-like how custom > borrow lifetimes are optional, and defaults well in most cases.) Feel free to fork Rust and implement the inference you're describing :-) This part of the language has been subject to a ton of work and length discussion. As with so many aspects of language design and implementation, it's more subtle than it seems. BTW, for harmonious discussions on this mailing list, it's best to indicate what is your opinion and what you believe is indisputable fact. The Rust code of conduct applies here: https://github.com/mozilla/rust/wiki/Note-development-policy -- specifically, "Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer." Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Too much to carry, too much to let go Time goes fast, learning goes slow." -- Bruce Cockburn From jack at metajack.im Sun Apr 7 22:05:37 2013 From: jack at metajack.im (Jack Moffitt) Date: Sun, 7 Apr 2013 23:05:37 -0600 Subject: [rust-dev] Importing foreign refcounted, non-threadsafe objects (GObject) In-Reply-To: References: Message-ID: > multiple tasks. Are there any best practices for wrapping such objects? One > solution I see is to dispatch all GObject calls through a dedicated > ever-running task initialized on program startup (GObject needs an explicit > init call anyway, so it's no big deal to add), but this grand central > approach may not be optimal or flexible enough. This is what tends to happen in Erlang, although in some cases multiple tasks would be available for dispatch (think SQL database connections where each task owns a single connection). It would probably work fine, and if it became a bottleneck you could have a task per object perhaps, or wherever the thread-safe boundary lies. jack. From pwalton at mozilla.com Sun Apr 7 22:26:01 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 07 Apr 2013 22:26:01 -0700 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: <7070576472340126500@unknownmsgid> References: <7070576472340126500@unknownmsgid> Message-ID: <1289d2ad-3920-492d-8b20-3520a8d59ea8@email.android.com> Apologies for the scattered responses; I'm on my phone. * I suppose we could implement automatic dereferencing in pattern matches, since we do require that types be fully resolved in match contexts, but it seems somewhat strange to me. Does any other language do automatic dereferencing in match or switch statements? There is precedent from D for automatic dereference for the '.' operator, but not switch. I suspect there might be nasty corner cases like: match @Some(3) { x @ Some(_) => { // is type of x @Option or // Option? } ... } I.e. where does the dereference happen? It's observable, as above. * Go requires you to use & and * to pass arguments by reference, just as Rust does. The difference is that Go's compiler chooses whether to allocate on the heap or the stack based on unspecified heuristics. This is a fine choice for Go, but it's contrary to the design goals of Rust. Rust programmers should be able to specify with precision whether data is allocated on the stack or the heap. * We tried to pass parameters by reference automatically based on heuristics in earlier versions of the language. These were called "modes". They made it hard to understand what data was being shared (when mutability is involved, this is not transparent!) and, moreover, interacted very badly with generics. Lesson learned: it's not worth it in a language with explicit memory management. * There is a select operation in the pipes module. * Making errors into a trait would require heap allocation for error types for no reason. The Result type is much more flexible, in any case, since it can store anything, not just a string. * I have a pull request to remove the necessity of "as @Trait". I would expect it to be removed in 0.7. You're right about it being too verbose. * You can use &Trait to avoid heap allocation. Patrick Heri Sim wrote: >Hi guys, I am new here. Just found out about this project today, and >read up a lot on its history and purpose. > > >There are 3 gripes I have about Rust, after comparing some good stuff >in Go-lang. http://tour.golang.org > > >1st, dereferencing should be automatic everywhere. >Running a pattern match on borrowed boxes should NOT require an >asterisk (*). >Passing in a stack-local variable to a function or closure (that >requires arguments to be passed by reference), should not require the >ampersand (&) in the caller. Why can't the compiler figure this out? > >In go-lang, all these things are just more invisible, which makes the >learning curve so much easier. I understand people coming from C would >prefer these memory-management signets explicit, but really they have >little need to be so verbose in many cases, and should be optional or >by-default instead, so that things just-work. (Just-like how custom >borrow lifetimes are optional, and defaults well in most cases.) > > >2nd, there is a need for the concurrency mechanism similar to the >concurrent "select" in go-lang. This is used to implement multiple >patterns such as timeouts, and non-blocking channel receive, and many >others. Errors in tasks would also be better handled/supervised this >way. By the way, should rust errors be a trait like in go-lang? > > >3rd, while generics are great, there is a need for trait types or >dynamic objects to be simpler to use in rust. Dynamic calls through >interfaces in go-lang are simpler, while trading off performance. In >rust, implementing draw_all on a vector of Drawable elements also have >similar performance hit, but with a much uglier implementation >requiring both @ and ~ signets and "as" syntax, which is confusing and >too verbose. Also there seem to be a requirement for managed boxes in >the shared heap for dynamic calls, which Erlang does not require. As >such, recursion for some problem sets (like polymorphic binary trees) >is not as clean in rust, compared to other languages. How can we >improve this? > > >Otherwise, Rust lang is really awesome. >The documentation and syntax is easy to follow for the basics, but >begin to feel "complex-for-complexity sake" in the advanced/modern >language features. As such, the documentation feels schizophrenic as >the language constructs begin to lose its delightful lean-opinionated >design towards the end. > >Really beginning to like Rust a lot. > >Heri >_______________________________________________ >Rust-dev mailing list >Rust-dev at mozilla.org >https://mail.mozilla.org/listinfo/rust-dev -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mikhail.zabaluev at gmail.com Sun Apr 7 23:03:54 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Mon, 8 Apr 2013 09:03:54 +0300 Subject: [rust-dev] Importing foreign refcounted, non-threadsafe objects (GObject) In-Reply-To: References: Message-ID: Hi Jack, 2013/4/8 Jack Moffitt > > One solution I see is to dispatch all GObject calls through a dedicated > > ever-running task initialized on program startup (GObject needs an > explicit > > init call anyway, so it's no big deal to add), but this grand central > > approach may not be optimal or flexible enough. > > This is what tends to happen in Erlang, although in some cases > multiple tasks would be available for dispatch (think SQL database > connections where each task owns a single connection). It would > probably work fine, and if it became a bottleneck you could have a > task per object perhaps, or wherever the thread-safe boundary lies. > Right; I don't think there is a general guarantee that any two GObjects can be concurrently used, as they may share data by implementation. So either it should be the grand central task, or maybe there is a way to weave a task context into every object wrapper. The latter looks difficult in the general case, as GObject does not maintain a concept of thread affinity or event loop affinity for the objects, the way Qt does. Best regards, Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From andres.osinski at gmail.com Sun Apr 7 23:14:17 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Mon, 8 Apr 2013 03:14:17 -0300 Subject: [rust-dev] FastCGI implementation In-Reply-To: References: Message-ID: Are the libUV bindings for the socket API the default canonical way in Rust for managing socket communications, or will there be a future implementation or binding to the standard POSIX socket library? On Sat, Apr 6, 2013 at 1:50 PM, Thad Guidry wrote: > oops, that should have been the "handler portion" of Cherokee FastCGI ... > https://github.com/cherokee/webserver/blob/master/cherokee/handler_fcgi.c > > more docs here: > http://www.cherokee-project.com/doc/modules_handlers_fcgi.html > > > On Sat, Apr 6, 2013 at 11:45 AM, Thad Guidry wrote: > >> Perhaps the Cherokee webserver might be useful for you to look at it's >> codebase... and it's implementation of fastcgi.h >> >> https://github.com/cherokee/webserver/tree/master/cherokee >> >> >> On Fri, Apr 5, 2013 at 9:13 PM, Andres Osinski wrote: >> >>> Hi everyone, I've taken an interest in Rust as it fills a niche in >>> programming that I've long been looking to fullfill. >>> >>> I'm primarily a Python web developer, so I wanted to start coding by >>> implementing the FastCGI protocol for Rust. I know that its native task >>> management and socket capabilities are very good, but you never know when >>> it might be handy for someone. >>> >>> I just wanted to know if anyone was familiar with the FCGI protocol, and >>> if there's any reference as to how to manage the packing and unpacking of C >>> data structures, as well as if you know of any implementation for a similar >>> protocol. >>> >>> One small question that I have is that FCGI protocol defines a struct >>> with two char arrays whose length is defined by another field within the >>> struct, and I was wondering how that would be modeled in Rust. >>> >>> Thanks >>> >>> -- >>> Andr?s Osinski >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >>> >> >> >> -- >> -Thad >> http://www.freebase.com/view/en/thad_guidry >> > > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From heri16 at gmail.com Mon Apr 8 00:05:28 2013 From: heri16 at gmail.com (Heri Sim) Date: Mon, 8 Apr 2013 15:05:28 +0800 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: References: <7070576472340126500@unknownmsgid> Message-ID: <8006176701478893209@unknownmsgid> Wow! the community here is more active than I had anticipated! I have read responses from you guys. The community's main concern is that pass-by-value should be the default desired behavior. Thus explicitness here helps in reasoning program flow. However, with deep-immutable variables, it should not matter. If so, we should require the ampersand sigil only for mutable stack variables. Also, I am not sure whether you guys have looked at Copy-On-Write implicit-shared mechanism of the core Qt classes. I think they are amazing and helps explain why immutable variables in practice can be passed as arguments without additional syntax. I think my first point is minor. If the language designer feels that we should keep the existing way of borrowing local stack variables at the caller site, then it shall be. A future IDE could hint the sigil during auto-completion. I see the merits of having the ampersand, but the tutorial should just explain this as "converting a stack-variable into a box that can be borrowed by others", rather than using the C paradigm of passing a pointer or address on the stack. This would make the idea of boxes consistent to beginners. Heri Sent from my iPhone On 8 Apr, 2013, at 11:58 AM, Tim Chevalier wrote: > On Sun, Apr 7, 2013 at 3:01 PM, Heri Sim wrote: >> Hi guys, I am new here. Just found out about this project today, and >> read up a lot on its history and purpose. >> >> >> There are 3 gripes I have about Rust, after comparing some good stuff >> in Go-lang. http://tour.golang.org >> >> >> 1st, dereferencing should be automatic everywhere. >> Running a pattern match on borrowed boxes should NOT require an asterisk (*). >> Passing in a stack-local variable to a function or closure (that >> requires arguments to be passed by reference), should not require the >> ampersand (&) in the caller. Why can't the compiler figure this out? > > We tried the second idea before Rust 0.4; it was called "modes". It > was confusing and inconsistent. > >> >> In go-lang, all these things are just more invisible, which makes the >> learning curve so much easier. I understand people coming from C would >> prefer these memory-management signets explicit, but really they have >> little need to be so verbose in many cases, and should be optional or >> by-default instead, so that things just-work. (Just-like how custom >> borrow lifetimes are optional, and defaults well in most cases.) > > Feel free to fork Rust and implement the inference you're describing > :-) This part of the language has been subject to a ton of work and > length discussion. As with so many aspects of language design and > implementation, it's more subtle than it seems. > > BTW, for harmonious discussions on this mailing list, it's best to > indicate what is your opinion and what you believe is indisputable > fact. The Rust code of conduct applies here: > https://github.com/mozilla/rust/wiki/Note-development-policy -- > specifically, "Respect that people have differences of opinion and > that every design or implementation choice carries a trade-off and > numerous costs. There is seldom a right answer." > > Cheers, > Tim > > -- > Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt > "Too much to carry, too much to let go > Time goes fast, learning goes slow." -- Bruce Cockburn From pwalton at mozilla.com Mon Apr 8 01:06:00 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 08 Apr 2013 01:06:00 -0700 Subject: [rust-dev] Importing foreign refcounted, non-threadsafe objects (GObject) In-Reply-To: References: Message-ID: <51627A68.5040400@mozilla.com> On 4/7/13 7:49 AM, Mikhail Zabaluev wrote: > Hi, > > I've started playing with Rust bindings to GObject: > https://github.com/mzabaluev/grust > > The intent is to make any API that provides a GObject introspection > safely usable in Rust. There are two important things about GLib objects: > 1. The objects are reference counted in a thread-safe way. > 2. The objects in general are not thread-safe: threads calling methods > on one object need to be synchronized. > > In my proof-of-concept code, the Rust safe wrappers for the objects are > intended to be cloneable and sendable by virtue of the GLib refcounting. > But this may mean that an object may end up being used concurrently from > multiple tasks. Are there any best practices for wrapping such objects? > One solution I see is to dispatch all GObject calls through a dedicated > ever-running task initialized on program startup (GObject needs an > explicit init call anyway, so it's no big deal to add), but this grand > central approach may not be optimal or flexible enough. This is a use case for the `#[nonsendable]` or `#[nonowned]` annotation on structs. This annotation isn't implemented yet, but it's a common feature request, as it will be needed for non-thread-safe reference-counted smart pointers too. With that attribute you could ensure that GObject values can only live in one thread at a time. > Another topic of interest is casting. GObject provides runtime type > information and supports dynamic type checks. This means we can safely > down- and side-cast between traits representing GObject classes or > interfaces, but we need a custom cast implementation. Is there any > idiomatic trait to reuse? There isn't anything in the standard library to do that, but the Rust Core Foundation bindings have a system similar to what you're proposing. (CF is a GObject-like system.) The trait definitions in `rust-core-foundation` are a little complex for my taste though--if you can come up with something simpler then I'm all for it. Patrick From danielmicay at gmail.com Mon Apr 8 03:34:29 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 8 Apr 2013 06:34:29 -0400 Subject: [rust-dev] Importing foreign refcounted, non-threadsafe objects (GObject) In-Reply-To: <51627A68.5040400@mozilla.com> References: <51627A68.5040400@mozilla.com> Message-ID: On Mon, Apr 8, 2013 at 4:06 AM, Patrick Walton wrote: > On 4/7/13 7:49 AM, Mikhail Zabaluev wrote: >> >> Hi, >> >> I've started playing with Rust bindings to GObject: >> https://github.com/mzabaluev/grust >> >> The intent is to make any API that provides a GObject introspection >> safely usable in Rust. There are two important things about GLib objects: >> 1. The objects are reference counted in a thread-safe way. >> 2. The objects in general are not thread-safe: threads calling methods >> on one object need to be synchronized. >> >> In my proof-of-concept code, the Rust safe wrappers for the objects are >> intended to be cloneable and sendable by virtue of the GLib refcounting. >> But this may mean that an object may end up being used concurrently from >> multiple tasks. Are there any best practices for wrapping such objects? >> One solution I see is to dispatch all GObject calls through a dedicated >> ever-running task initialized on program startup (GObject needs an >> explicit init call anyway, so it's no big deal to add), but this grand >> central approach may not be optimal or flexible enough. > > > This is a use case for the `#[nonsendable]` or `#[nonowned]` annotation on > structs. This annotation isn't implemented yet, but it's a common feature > request, as it will be needed for non-thread-safe reference-counted smart > pointers too. With that attribute you could ensure that GObject values can > only live in one thread at a time. Here's the issue request for #[non_owned] by the way: https://github.com/mozilla/rust/issues/5601 From heri16 at gmail.com Mon Apr 8 06:45:38 2013 From: heri16 at gmail.com (Heri Sim) Date: Mon, 8 Apr 2013 21:45:38 +0800 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: <1289d2ad-3920-492d-8b20-3520a8d59ea8@email.android.com> References: <7070576472340126500@unknownmsgid> <1289d2ad-3920-492d-8b20-3520a8d59ea8@email.android.com> Message-ID: <7034399688401886511@unknownmsgid> Thanks Patrick for the great explanation. Where can I find the typical usage examples of the select operation in the pipes module? I guess what remains is the inference for dynamic calls on polymorphic data structures. How would you implement a binary search tree cleanly, with types for empty, leaf, parent nodes? What is your team's approach to corner cases? Generic syntax must cater for corner cases? Or corner cases should have special syntax? Do more most of the time, or do more sometimes? Heri On 2013/04/08, at 13:25, Patrick Walton wrote: Apologies for the scattered responses; I'm on my phone. * I suppose we could implement automatic dereferencing in pattern matches, since we do require that types be fully resolved in match contexts, but it seems somewhat strange to me. Does any other language do automatic dereferencing in match or switch statements? There is precedent from D for automatic dereference for the '.' operator, but not switch. I suspect there might be nasty corner cases like: match @Some(3) { x @ Some(_) => { // is type of x @Option or // Option? } ... } I.e. where does the dereference happen? It's observable, as above. * Go requires you to use & and * to pass arguments by reference, just as Rust does. The difference is that Go's compiler chooses whether to allocate on the heap or the stack based on unspecified heuristics. This is a fine choice for Go, but it's contrary to the design goals of Rust. Rust programmers should be able to specify with precision whether data is allocated on the stack or the heap. * We tried to pass parameters by reference automatically based on heuristics in earlier versions of the language. These were called "modes". They made it hard to understand what data was being shared (when mutability is involved, this is not transparent!) and, moreover, interacted very badly with generics. Lesson learned: it's not worth it in a language with explicit memory management. * There is a select operation in the pipes module. * Making errors into a trait would require heap allocation for error types for no reason. The Result type is much more flexible, in any case, since it can store anything, not just a string. * I have a pull request to remove the necessity of "as @Trait". I would expect it to be removed in 0.7. You're right about it being too verbose. * You can use &Trait to avoid heap allocation. Patrick Heri Sim wrote: > > Hi guys, I am new here. Just found out about this project today, and > read up a lot on its history and purpose. > > > There are 3 gripes I have about Rust, after comparing some good stuff > in Go-lang. http://tour.golang.org > > > 1st, dereferencing should be automatic everywhere. > Running a pattern match on borrowed boxes should NOT require an asterisk (*). > Passing in a stack-local variable to a function or closure (that > requires arguments to be passed by reference), should not require the > ampersand (&) in the caller. Why can't the compiler figure this out? > > In go-lang, all these things are just more invisible, which makes the > learning curve so much easier. I understand people coming from C would > prefer these memory-management signets explicit, but really they have > l > ittle > need to be so verbose in many cases, and should be optional or > by-default instead, so that things just-work. (Just-like how custom > borrow lifetimes are optional, and defaults well in most cases.) > > > 2nd, there is a need for the concurrency mechanism similar to the > concurrent "select" in go-lang. This is used to implement multiple > patterns such as timeouts, and non-blocking channel receive, and many > others. Errors in tasks would also be better handled/supervised this > way. By the way, should rust errors be a trait like in go-lang? > > > 3rd, while generics are great, there is a need for trait types or > dynamic objects to be simpler to use in rust. Dynamic calls through > interfaces in go-lang are simpler, while trading off performance. In > rust, implementing draw_all on a vector of Drawable elements also have > similar performance hit, but with a much uglier implementation > requiring both @ and ~ signets a > nd "as" > syntax, which is confusing and > too verbose. Also there seem to be a requirement for managed boxes in > the shared heap for dynamic calls, which Erlang does not require. As > such, recursion for some problem sets (like polymorphic binary trees) > is not as clean in rust, compared to other languages. How can we > improve this? > > > Otherwise, Rust lang is really awesome. > The documentation and syntax is easy to follow for the basics, but > begin to feel "complex-for-complexity sake" in the advanced/modern > language features. As such, the documentation feels schizophrenic as > the language constructs begin to lose its delightful lean-opinionated > design towards the end. > > Really beginning to like Rust a lot. > > Heri > ------------------------------ > > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. -------------- next part -------------- An HTML attachment was scrubbed... URL: From asb at asbradbury.org Mon Apr 8 07:00:26 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Mon, 8 Apr 2013 15:00:26 +0100 Subject: [rust-dev] FastCGI implementation In-Reply-To: References: Message-ID: On 6 April 2013 03:13, Andres Osinski wrote: > I just wanted to know if anyone was familiar with the FCGI protocol, and if > there's any reference as to how to manage the packing and unpacking of C > data structures, as well as if you know of any implementation for a similar > protocol. I don't know what others think, but if I had to actually write the protocol implementation I'd be tempted to ignore FastCGI and go straight for SCGI. It is supported by Nginx, Apache and Lighttpd and seems much simpler to implement. Some public domain C code is here: http://www.xamuel.com/scgilib/ [I'll freely admit that for whatever reason, fastcgi seems more popular though] Alex From josh at joshmatthews.net Mon Apr 8 07:10:19 2013 From: josh at joshmatthews.net (Josh Matthews) Date: Mon, 8 Apr 2013 10:10:19 -0400 Subject: [rust-dev] FastCGI implementation In-Reply-To: References: Message-ID: There's a very basic POSIX socket binding at https://github.com/jdm/rust-socket. It's been neglected for a bit, I would quickly merge a PR to update it to 0.6. Cheers, Josh On 8 April 2013 02:14, Andres Osinski wrote: > Are the libUV bindings for the socket API the default canonical way in > Rust for managing socket communications, or will there be a future > implementation or binding to the standard POSIX socket library? > > > On Sat, Apr 6, 2013 at 1:50 PM, Thad Guidry wrote: > >> oops, that should have been the "handler portion" of Cherokee FastCGI ... >> https://github.com/cherokee/webserver/blob/master/cherokee/handler_fcgi.c >> >> more docs here: >> http://www.cherokee-project.com/doc/modules_handlers_fcgi.html >> >> >> On Sat, Apr 6, 2013 at 11:45 AM, Thad Guidry wrote: >> >>> Perhaps the Cherokee webserver might be useful for you to look at it's >>> codebase... and it's implementation of fastcgi.h >>> >>> https://github.com/cherokee/webserver/tree/master/cherokee >>> >>> >>> On Fri, Apr 5, 2013 at 9:13 PM, Andres Osinski >> > wrote: >>> >>>> Hi everyone, I've taken an interest in Rust as it fills a niche in >>>> programming that I've long been looking to fullfill. >>>> >>>> I'm primarily a Python web developer, so I wanted to start coding by >>>> implementing the FastCGI protocol for Rust. I know that its native task >>>> management and socket capabilities are very good, but you never know when >>>> it might be handy for someone. >>>> >>>> I just wanted to know if anyone was familiar with the FCGI protocol, >>>> and if there's any reference as to how to manage the packing and unpacking >>>> of C data structures, as well as if you know of any implementation for a >>>> similar protocol. >>>> >>>> One small question that I have is that FCGI protocol defines a struct >>>> with two char arrays whose length is defined by another field within the >>>> struct, and I was wondering how that would be modeled in Rust. >>>> >>>> Thanks >>>> >>>> -- >>>> Andr?s Osinski >>>> >>>> _______________________________________________ >>>> Rust-dev mailing list >>>> Rust-dev at mozilla.org >>>> https://mail.mozilla.org/listinfo/rust-dev >>>> >>>> >>> >>> >>> -- >>> -Thad >>> http://www.freebase.com/view/en/thad_guidry >>> >> >> >> >> -- >> -Thad >> http://www.freebase.com/view/en/thad_guidry >> > > > > -- > Andr?s Osinski > http://www.andresosinski.com.ar/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From o.renaud at gmx.fr Mon Apr 8 08:42:24 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Mon, 08 Apr 2013 17:42:24 +0200 Subject: [rust-dev] wanted libraries Message-ID: <20130408154224.114880@gmx.com> Hi, I saw the [wanted libraries]?page on the github wiki, and I'd like to submit some ideas there. The wiki page is read-only, so I fall back on submitting them on this list. I tried to confine myself to what would be useful to me, in a stdlib. * Internationalization : mechanisms for handling the internationalization of UI texts -> one aspect of i18n is to map a key to a text, based on the current locale (eg Java's [ResourceBundle]) -> another aspect is to format a string based on the current locale (eg Java's [MessageFormat]) * Libicu is already listed on the wiki, but there are no details of what is needed. Here are my suggestions : -> Convertions between text encodings. Ideally, with a customizable way of handling conversion errors. -> Unicode normalization (NFD, NFC, NFKD, NFKC) -> Collator (locale sensitive string comparison), with a configurable degree of strictness * Simple (yet powerful) search on a filesystem (eg Ruby's [glob]) * A simple tokenizer/file parser * Support to read/write zip and tar file formats (not only the gzip algorithm) Olivier Renaud ___ [wanted libraries]?https://github.com/mozilla/rust/wiki/Note-wanted-libraries [ResourceBundle] http://docs.oracle.com/javase/7/docs/api/java/util/ResourceBundle.html [MessageFormat] http://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html [glob] http://ruby-doc.org/core-2.0/Dir.html#method-c-glob From heri16 at gmail.com Mon Apr 8 09:47:21 2013 From: heri16 at gmail.com (Heri Sim) Date: Tue, 9 Apr 2013 00:47:21 +0800 Subject: [rust-dev] Rust Sudoku Performance Message-ID: <-7893937945089232072@unknownmsgid> Has anyone here taken a look at this yet? http://attractivechaos.wordpress.com/2013/04/06/performance-of-rust-and-dart-in-sudoku-solving/ Just came in on 6 April 2013 for rust 0.6 . Read it a few days back and it had instantly gotten me interested in Rust. Thought it would be good to share, even if it is just a specific CPU-bound test. Heri From steve at steveklabnik.com Mon Apr 8 10:00:39 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Mon, 8 Apr 2013 10:00:39 -0700 Subject: [rust-dev] Rust Sudoku Performance In-Reply-To: <-7893937945089232072@unknownmsgid> References: <-7893937945089232072@unknownmsgid> Message-ID: There's a thread called 'New Benchmark' that nobody replied to, but links to HN where most of the people replied. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Mon Apr 8 10:02:12 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 08 Apr 2013 10:02:12 -0700 Subject: [rust-dev] Rust Sudoku Performance In-Reply-To: <-7893937945089232072@unknownmsgid> References: <-7893937945089232072@unknownmsgid> Message-ID: <5162F814.4000509@mozilla.com> On 4/8/13 9:47 AM, Heri Sim wrote: > Has anyone here taken a look at this yet? > > http://attractivechaos.wordpress.com/2013/04/06/performance-of-rust-and-dart-in-sudoku-solving/ > > Just came in on 6 April 2013 for rust 0.6 . Read it a few days back > and it had instantly gotten me interested in Rust. Thought it would be > good to share, even if it is just a specific CPU-bound test. Removing I/O gets us within 10% of the C, in my tests. I expect the remaining 10% is bounds checks and some amount of LLVM/GCC backend differences. Patrick From jpiatlicki at gmail.com Mon Apr 8 11:14:31 2013 From: jpiatlicki at gmail.com (Jauhien Piatlicki) Date: Mon, 08 Apr 2013 20:14:31 +0200 Subject: [rust-dev] rust-0.6 compilation with system LLVM fails In-Reply-To: <5162A403.9060902@gmail.com> References: <5162A403.9060902@gmail.com> Message-ID: <51630907.3020305@gmail.com> -------- ????????? ???????????? -------- ????: Re: [rust-dev] rust-0.6 compilation with system LLVM fails ????: Mon, 08 Apr 2013 13:03:31 +0200 ???: Jauhien Piatlicki ????: Steve Klabnik As far as I can see Rust just provides another interface to LLVM that lives in src/rustllvm/RustWrapper.cpp. And linker complains about undefined references to functions that do not belong to RustWrapper.cpp, but as far as I understand to LLVM itself. So the problem may be with linker that does not pick static libs from /usr/lib/llvm. Hence my question is how can I pass to linker something like -L/usr/lib/llvm. Just exporting LDFLAGS before configuring and compiling does not work. 08.04.13 05:03, Steve Klabnik ???????(??): > Doesn't Rust still use custom patches to LLVM? Does your system LLVM > have those patches? -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 901 bytes Desc: OpenPGP digital signature URL: From banderson at mozilla.com Mon Apr 8 11:38:26 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 08 Apr 2013 11:38:26 -0700 Subject: [rust-dev] rust-0.6 compilation with system LLVM fails In-Reply-To: References: <5161E6CE.50806@gmail.com> Message-ID: <51630EA2.4010303@mozilla.com> On 04/07/2013 08:03 PM, Steve Klabnik wrote: > Doesn't Rust still use custom patches to LLVM? Does your system LLVM > have those patches? > Rust 0.6's patches are pretty minimal, so it *might* be possible to run something from upstream, though it would likely need to be whatever revision our branch is based off of instead of any released LLVM version. 0.7 will likely have new LLVM patches. --llvm-root is not known to work anymore though. From mikhail.zabaluev at gmail.com Mon Apr 8 11:41:34 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Mon, 8 Apr 2013 21:41:34 +0300 Subject: [rust-dev] Importing foreign refcounted, non-threadsafe objects (GObject) In-Reply-To: <51627A68.5040400@mozilla.com> References: <51627A68.5040400@mozilla.com> Message-ID: Hi Patrick, 2013/4/8 Patrick Walton > This is a use case for the `#[nonsendable]` or `#[nonowned]` annotation on > structs. This annotation isn't implemented yet, but it's a common feature > request, as it will be needed for non-thread-safe reference-counted smart > pointers too. With that attribute you could ensure that GObject values can > only live in one thread at a time. Good. Meanwhile, I've been looking at using lifetime-bound borrowed pointers to return wrapped objects. But I have no idea yet how to pass lifetime to constructors and other non-method functions returning objects. Also, this will probably not work well with managed boxes. > > Another topic of interest is casting. GObject provides runtime type >> information and supports dynamic type checks. This means we can safely >> down- and side-cast between traits representing GObject classes or >> interfaces, but we need a custom cast implementation. Is there any >> idiomatic trait to reuse? >> > > There isn't anything in the standard library to do that, but the Rust Core > Foundation bindings have a system similar to what you're proposing. (CF is > a GObject-like system.) The trait definitions in `rust-core-foundation` are > a little complex for my taste though--if you can come up with something > simpler then I'm all for it. > Thanks, I will look into that. Mikhail -------------- next part -------------- An HTML attachment was scrubbed... URL: From jpiatlicki at gmail.com Mon Apr 8 11:43:53 2013 From: jpiatlicki at gmail.com (Jauhien Piatlicki) Date: Mon, 08 Apr 2013 20:43:53 +0200 Subject: [rust-dev] rust-0.6 compilation with system LLVM fails In-Reply-To: <51630EA2.4010303@mozilla.com> References: <5161E6CE.50806@gmail.com> <51630EA2.4010303@mozilla.com> Message-ID: <51630FE9.7030100@gmail.com> 08.04.13 20:38, Brian Anderson ???????(??): > On 04/07/2013 08:03 PM, Steve Klabnik wrote: >> Doesn't Rust still use custom patches to LLVM? Does your system LLVM >> have those patches? >> > > Rust 0.6's patches are pretty minimal, so it *might* be possible to run > something from upstream, though it would likely need to be whatever > revision our branch is based off of instead of any released LLVM > version. 0.7 will likely have new LLVM patches. > > --llvm-root is not known to work anymore though. > _ Thank you for answering. ) May be it should be documented somewhere that --llvm-root does not work currently. I'll use bundled version. Thanks once again, best regards, Jauhien ______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 901 bytes Desc: OpenPGP digital signature URL: From ben.striegel at gmail.com Mon Apr 8 12:25:28 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Mon, 8 Apr 2013 15:25:28 -0400 Subject: [rust-dev] wanted libraries In-Reply-To: <20130408154224.114880@gmx.com> References: <20130408154224.114880@gmx.com> Message-ID: What do you mean when you say that the page is read-only? AFAIK all pages on the wiki are read+write, and I don't see any controls to change that. On Mon, Apr 8, 2013 at 11:42 AM, Olivier Renaud wrote: > Hi, > > I saw the [wanted libraries] page on the github wiki, and I'd like to > submit some ideas there. > The wiki page is read-only, so I fall back on submitting them on this list. > > I tried to confine myself to what would be useful to me, in a stdlib. > > * Internationalization : mechanisms for handling the internationalization > of UI texts > -> one aspect of i18n is to map a key to a text, based on the current > locale (eg Java's [ResourceBundle]) > -> another aspect is to format a string based on the current locale (eg > Java's [MessageFormat]) > > * Libicu is already listed on the wiki, but there are no details of what > is needed. Here are my suggestions : > -> Convertions between text encodings. Ideally, with a customizable way > of handling conversion errors. > -> Unicode normalization (NFD, NFC, NFKD, NFKC) > -> Collator (locale sensitive string comparison), with a configurable > degree of strictness > > * Simple (yet powerful) search on a filesystem (eg Ruby's [glob]) > > * A simple tokenizer/file parser > > * Support to read/write zip and tar file formats (not only the gzip > algorithm) > > > Olivier Renaud > ___ > > [wanted libraries] > https://github.com/mozilla/rust/wiki/Note-wanted-libraries > [ResourceBundle] > http://docs.oracle.com/javase/7/docs/api/java/util/ResourceBundle.html > [MessageFormat] > http://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html > [glob] http://ruby-doc.org/core-2.0/Dir.html#method-c-glob > _______________________________________________ > 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 giles at thaumas.net Mon Apr 8 12:30:55 2013 From: giles at thaumas.net (Ralph Giles) Date: Mon, 08 Apr 2013 12:30:55 -0700 Subject: [rust-dev] wanted libraries In-Reply-To: References: <20130408154224.114880@gmx.com> Message-ID: <51631AEF.7080002@thaumas.net> On 13-04-08 12:25 PM, Benjamin Striegel wrote: > What do you mean when you say that the page is read-only? AFAIK all > pages on the wiki are read+write, and I don't see any controls to change > that. At the very least, one must be logged in with a github account to edit anything. -r From o.renaud at gmx.fr Mon Apr 8 13:50:44 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Mon, 08 Apr 2013 22:50:44 +0200 Subject: [rust-dev] Re : Re: wanted libraries Message-ID: <20130408205044.114890@gmx.com> >> What do you mean when you say that the page is read-only? AFAIK all >> pages on the wiki are read+write, and I don't see any controls to change >> that. > >At the very least, one must be logged in with a github account to edit >anything. > > -r Oh you are right, the page is writeable. Actually, I was seeing all pages as writeable except this one. Certainly a mistake on my part. Sorry about that, I'll edit the wiki directly, then. Cheers, Olivier Renaud From andres.osinski at gmail.com Mon Apr 8 14:01:14 2013 From: andres.osinski at gmail.com (andres.osinski at gmail.com) Date: Mon, 8 Apr 2013 21:01:14 +0000 Subject: [rust-dev] wanted libraries In-Reply-To: <20130408154224.114880@gmx.com> References: <20130408154224.114880@gmx.com> Message-ID: <1127528972-1365454872-cardhu_decombobulator_blackberry.rim.net-638423182-@b3.c24.bise6.blackberry> Would making idiomatic bindings to gettext on Unix platforms qualify for transaltions, or is the core team more interested in cross-platform Rust libraries from the start? Enviado desde mi BlackBerry de Movistar (http://www.movistar.com.ar) -----Original Message----- From: "Olivier Renaud" Sender: rust-dev-bounces at mozilla.orgDate: Mon, 08 Apr 2013 17:42:24 To: Subject: [rust-dev] wanted libraries Hi, I saw the [wanted libraries]?page on the github wiki, and I'd like to submit some ideas there. The wiki page is read-only, so I fall back on submitting them on this list. I tried to confine myself to what would be useful to me, in a stdlib. * Internationalization : mechanisms for handling the internationalization of UI texts -> one aspect of i18n is to map a key to a text, based on the current locale (eg Java's [ResourceBundle]) -> another aspect is to format a string based on the current locale (eg Java's [MessageFormat]) * Libicu is already listed on the wiki, but there are no details of what is needed. Here are my suggestions : -> Convertions between text encodings. Ideally, with a customizable way of handling conversion errors. -> Unicode normalization (NFD, NFC, NFKD, NFKC) -> Collator (locale sensitive string comparison), with a configurable degree of strictness * Simple (yet powerful) search on a filesystem (eg Ruby's [glob]) * A simple tokenizer/file parser * Support to read/write zip and tar file formats (not only the gzip algorithm) Olivier Renaud ___ [wanted libraries]?https://github.com/mozilla/rust/wiki/Note-wanted-libraries [ResourceBundle] http://docs.oracle.com/javase/7/docs/api/java/util/ResourceBundle.html [MessageFormat] http://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html [glob] http://ruby-doc.org/core-2.0/Dir.html#method-c-glob _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From artella.coding at googlemail.com Mon Apr 8 11:55:13 2013 From: artella.coding at googlemail.com (Artella Coding) Date: Mon, 8 Apr 2013 19:55:13 +0100 Subject: [rust-dev] Debugging in Ubuntu via GDB or related tools Message-ID: Hi, I know that if I have the following basic program : *********** ///hello.rs fn main(){ io::println("Hello"); } *********** then the command : >rustc hello.rs produces an executable called hello which I can then run in ubuntu, How would I compile it so that I can then use gdb to debug, for example to set a breakpoint on println? So far I have only found the following as an example of someone using GDB to debug Rust : https://github.com/mozilla/rust/issues/1174 . Thanks. -------------- next part -------------- An HTML attachment was scrubbed... URL: From catamorphism at gmail.com Mon Apr 8 14:45:02 2013 From: catamorphism at gmail.com (Tim Chevalier) Date: Mon, 8 Apr 2013 14:45:02 -0700 Subject: [rust-dev] Debugging in Ubuntu via GDB or related tools In-Reply-To: References: Message-ID: On Mon, Apr 8, 2013 at 11:55 AM, Artella Coding wrote: > Hi, I know that if I have the following basic program : > > > *********** > ///hello.rs > fn main(){ > io::println("Hello"); > } > *********** > > then the command : > >>rustc hello.rs > > produces an executable called hello which I can then run in ubuntu, > > How would I compile it so that I can then use gdb to debug, for example to > set a breakpoint on println? So far I have only found the following as an > example of someone using GDB to debug Rust : > https://github.com/mozilla/rust/issues/1174 . Thanks. First, you need to run rustc -g hello.rs -- the -g flag tells rustc to generate debuginfo. After that, you can use gdb on the resulting executable and set breakpoints, get a stack trace (with bt), and possibly some of the other things you usually do with gdb. It's useful to know that if you set a break on upcall_fail , then you'll break at any point where your program calls the fail!() macro or has an assertion failure arising from assert!(). Cheers, Tim -- Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt "Too much to carry, too much to let go Time goes fast, learning goes slow." -- Bruce Cockburn From pnkfelix at mozilla.com Mon Apr 8 14:54:21 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Mon, 08 Apr 2013 14:54:21 -0700 Subject: [rust-dev] Debugging in Ubuntu via GDB or related tools In-Reply-To: References: Message-ID: <51633C8D.2050501@mozilla.com> Artelia (cc'ing rust-dev)- FYI: There is no '-g' flag, at least not in Rust 0.6. According to the #rust IRC channel, the correct flag is now "-Z debug-info" From the #rust IRC channel: http://irclog.gr/#show/irc.mozilla.org/rust/444262 Cheers, -Felix On 08/04/2013 14:45, Tim Chevalier wrote: > On Mon, Apr 8, 2013 at 11:55 AM, Artella Coding > wrote: >> Hi, I know that if I have the following basic program : >> >> >> *********** >> ///hello.rs >> fn main(){ >> io::println("Hello"); >> } >> *********** >> >> then the command : >> >>> rustc hello.rs >> produces an executable called hello which I can then run in ubuntu, >> >> How would I compile it so that I can then use gdb to debug, for example to >> set a breakpoint on println? So far I have only found the following as an >> example of someone using GDB to debug Rust : >> https://github.com/mozilla/rust/issues/1174 . Thanks. > First, you need to run rustc -g hello.rs -- the -g flag tells rustc to > generate debuginfo. > > After that, you can use gdb on the resulting executable and set > breakpoints, get a stack trace (with bt), and possibly some of the > other things you usually do with gdb. It's useful to know that if you > set a break on upcall_fail , then you'll break at any point where your > program calls the fail!() macro or has an assertion failure arising > from assert!(). > > Cheers, > Tim > > -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.org From singpolyma at singpolyma.net Mon Apr 8 19:14:57 2013 From: singpolyma at singpolyma.net (Stephen Paul Weber) Date: Tue, 9 Apr 2013 02:14:57 +0000 Subject: [rust-dev] Higher-kinded type parameters In-Reply-To: <515DB6A4.9000107@mozilla.com> Message-ID: <20130409021457.GA16641@singpolyma.net> > We don't have higher-kinded type parameters. It's a common feature > request. I would personally be in favor of taking a patch to add the > feature. Have there been many discussions about this on the mailing list about this feature? Is it lack of interest by the language designedrs, lack of manpower, or other impediments that keeps it out so far? I'm not sure if I myself have the chops to add this (I would need to learn a lot more rust and dig into the rust compiler quite a bit, I imagine!), but would very much be willing to participate in a bounty to see this feature implemented, if manpower is all that stands in the way. -- Stephen Paul Weber, @singpolyma See for how I prefer to be contacted edition right joseph From andres.osinski at gmail.com Mon Apr 8 23:25:00 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Tue, 9 Apr 2013 03:25:00 -0300 Subject: [rust-dev] PEP8-like document? Message-ID: This may have been answered elsewhere, but I was wondering if the Rust community has developed anything similar to Python's PEP8 for an idiomatic convention for structuring code? The examples of both Python and Go seem to indicate that there's great benefit in having a normalized coding style for code in the wild. -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From mozilla at mcpherrin.ca Tue Apr 9 00:37:27 2013 From: mozilla at mcpherrin.ca (Matthew McPherrin) Date: Tue, 9 Apr 2013 03:37:27 -0400 Subject: [rust-dev] PEP8-like document? In-Reply-To: References: Message-ID: For a start, you can look at how rustc --pretty prints out source code On Tue, Apr 9, 2013 at 2:25 AM, Andres Osinski wrote: > This may have been answered elsewhere, but I was wondering if the Rust > community has developed anything similar to Python's PEP8 for an idiomatic > convention for structuring code? > > The examples of both Python and Go seem to indicate that there's great > benefit in having a normalized coding style for code in the wild. > > -- > Andr?s Osinski > http://www.andresosinski.com.ar/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sh4.seo at samsung.com Tue Apr 9 02:17:33 2013 From: sh4.seo at samsung.com (Sanghyeon Seo) Date: Tue, 09 Apr 2013 09:17:33 +0000 (GMT) Subject: [rust-dev] LLVM versions Message-ID: <15654084.67371365499053217.JavaMail.weblogic@epml03> Rust 0.6's configure script claims Rust needs >=3.0svn. (Search for "bad LLVM version" for this.) In truth, Rust 0.6 includes inline assembly functionality https://github.com/mozilla/rust/pull/5317 which needs llvm::InlineAsm::AsmDialect enum type. This enum type was added to LLVM in September 2012. http://llvm.org/viewvc/llvm-project?view=revision&revision=163231 Looking at http://llvm.org/releases/ only LLVM 3.2 provides this type, so 3.0 and 3.1 can't be used. LLVM is known to make no promise of API stability between versions, so if Rust in the future is to support compilation with system LLVM (which it doesn't at the moment), it should be wary of these problems. Although some LLVM users try to suppot multiple versions of LLVM, I am not sure whether Rust should do so. If Rust is to support multiple versions of LLVM, we should learn from Pure, which with some remarkable efforts, supports LLVM versions 2.5 thru 3.2. Look for "#if LLVMXY" preprocessors in the following file for how this is done. https://bitbucket.org/purelang/pure-lang/src/tip/pure/interpreter.cc From asb at asbradbury.org Tue Apr 9 03:27:49 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Tue, 9 Apr 2013 11:27:49 +0100 Subject: [rust-dev] Debugging in Ubuntu via GDB or related tools In-Reply-To: <51633C8D.2050501@mozilla.com> References: <51633C8D.2050501@mozilla.com> Message-ID: On 8 April 2013 22:54, Felix S. Klock II wrote: > Artelia (cc'ing rust-dev)- > > FYI: There is no '-g' flag, at least not in Rust 0.6. According to the > #rust IRC channel, the correct flag is now "-Z debug-info" There is also a proposed GSoC project to improve debugging support: https://wiki.mozilla.org/Community:SummerOfCode13#Rust Alex From ben.striegel at gmail.com Tue Apr 9 05:11:09 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 9 Apr 2013 08:11:09 -0400 Subject: [rust-dev] PEP8-like document? In-Reply-To: References: Message-ID: The general guidelines appear to be: * put opening braces at the end of the line * indent by four spaces * restrict lines to 100 characters or less In the future, the pretty printer may be improved such that it's suitable for automatically applying these rules, as per gofmt. On Tue, Apr 9, 2013 at 2:25 AM, Andres Osinski wrote: > This may have been answered elsewhere, but I was wondering if the Rust > community has developed anything similar to Python's PEP8 for an idiomatic > convention for structuring code? > > The examples of both Python and Go seem to indicate that there's great > benefit in having a normalized coding style for code in the wild. > > -- > Andr?s Osinski > http://www.andresosinski.com.ar/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Tue Apr 9 10:02:02 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 09 Apr 2013 10:02:02 -0700 Subject: [rust-dev] PEP8-like document? In-Reply-To: References: Message-ID: <5164498A.3010304@mozilla.com> On 04/08/2013 11:25 PM, Andres Osinski wrote: > This may have been answered elsewhere, but I was wondering if the Rust > community has developed anything similar to Python's PEP8 for an > idiomatic convention for structuring code? > > The examples of both Python and Go seem to indicate that there's great > benefit in having a normalized coding style for code in the wild. This would be very welcome, and I would be happy to help if somebody wanted to take the lead on this. From clements at brinckerhoff.org Tue Apr 9 10:04:28 2013 From: clements at brinckerhoff.org (John Clements) Date: Tue, 9 Apr 2013 10:04:28 -0700 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) Message-ID: I've recently become aware of the existence of a comma-separated local-variable declaration in Rust. Would people object strongly to the removal of this form? John From jon.mb at proinbox.com Tue Apr 9 10:13:02 2013 From: jon.mb at proinbox.com (John Mija) Date: Tue, 09 Apr 2013 18:13:02 +0100 Subject: [rust-dev] PEP8-like document? In-Reply-To: <5164498A.3010304@mozilla.com> References: <5164498A.3010304@mozilla.com> Message-ID: <51644C1E.4080707@proinbox.com> Go has not anything like Python's PEP8, but a tool which formats code and it is being used widely by the projects. I prefer that Rust would have such tool, replacing the usual compendium of do's and don'ts that allows interpretation: http://golang.org/doc/faq#Is_there_a_Go_programming_style_guide El 09/04/13 18:02, Brian Anderson escribi?: > On 04/08/2013 11:25 PM, Andres Osinski wrote: >> This may have been answered elsewhere, but I was wondering if the Rust >> community has developed anything similar to Python's PEP8 for an >> idiomatic convention for structuring code? >> >> The examples of both Python and Go seem to indicate that there's great >> benefit in having a normalized coding style for code in the wild. > > This would be very welcome, and I would be happy to help if somebody > wanted to take the lead on this. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > From pnathan at vandals.uidaho.edu Tue Apr 9 10:13:24 2013 From: pnathan at vandals.uidaho.edu (Paul Nathan) Date: Tue, 9 Apr 2013 10:13:24 -0700 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: I think it's handy and concise. Regards, Paul Nathan Sent from my iPhone On Apr 9, 2013, at 10:04 AM, John Clements wrote: > I've recently become aware of the existence of a comma-separated local-variable declaration in Rust. Would people object strongly to the removal of this form? > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From thadguidry at gmail.com Tue Apr 9 10:16:24 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Tue, 9 Apr 2013 12:16:24 -0500 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: What's the problem that develops with that form for you John ? -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From jack at metajack.im Tue Apr 9 10:16:51 2013 From: jack at metajack.im (Jack Moffitt) Date: Tue, 9 Apr 2013 11:16:51 -0600 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: > I've recently become aware of the existence of a comma-separated local-variable declaration in Rust. Would people object strongly to the removal of this form? I wouldn't miss it. jack. From andres.osinski at gmail.com Tue Apr 9 10:25:03 2013 From: andres.osinski at gmail.com (andres.osinski at gmail.com) Date: Tue, 9 Apr 2013 17:25:03 +0000 Subject: [rust-dev] PEP8-like document? Message-ID: <1445541237-1365528301-cardhu_decombobulator_blackberry.rim.net-1680636232-@b3.c24.bise6.blackberry> I would be happy to document this based on the existing Rust codebase and generally asking around. ------Mensaje original------ De: Brian Anderson Remitente: rust-dev-bounces at mozilla.org Para: rust-dev at mozilla.org Asunto: Re: [rust-dev] PEP8-like document? Enviado: 9 de abr de 2013 14:02 On 04/08/2013 11:25 PM, Andres Osinski wrote: > This may have been answered elsewhere, but I was wondering if the Rust > community has developed anything similar to Python's PEP8 for an > idiomatic convention for structuring code? > > The examples of both Python and Go seem to indicate that there's great > benefit in having a normalized coding style for code in the wild. This would be very welcome, and I would be happy to help if somebody wanted to take the lead on this. _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev Enviado desde mi BlackBerry de Movistar (http://www.movistar.com.ar) From ben.striegel at gmail.com Tue Apr 9 10:30:58 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 9 Apr 2013 13:30:58 -0400 Subject: [rust-dev] PEP8-like document? In-Reply-To: <51644C1E.4080707@proinbox.com> References: <5164498A.3010304@mozilla.com> <51644C1E.4080707@proinbox.com> Message-ID: > Go has not anything like Python's PEP8, but a tool which formats code and it is being used widely by the projects. > I prefer that Rust would have such tool, replacing the usual compendium of do's and don'ts that allows interpretation: I agree that such a tool would be wonderful. However, there are some guidelines that are only *suggestions*, and cannot be enforced automatically. For example, Rust encourages you to use lower_case_with_underscores for function names and CapitalCaseWithoutUnderscores for type names, but sometimes there are good reasons for violating these (e.g. providing a Rust wrapper for a library in a language with different naming conventions). Even Go has a styleguide containing many things that are not enforced automatically: http://golang.org/doc/effective_go.html On Tue, Apr 9, 2013 at 1:13 PM, John Mija wrote: > Go has not anything like Python's PEP8, but a tool which formats code and > it is being used widely by the projects. > > I prefer that Rust would have such tool, replacing the usual compendium of > do's and don'ts that allows interpretation: > > http://golang.org/doc/faq#Is_**there_a_Go_programming_style_**guide > > > El 09/04/13 18:02, Brian Anderson escribi?: > > On 04/08/2013 11:25 PM, Andres Osinski wrote: >> >>> This may have been answered elsewhere, but I was wondering if the Rust >>> community has developed anything similar to Python's PEP8 for an >>> idiomatic convention for structuring code? >>> >>> The examples of both Python and Go seem to indicate that there's great >>> benefit in having a normalized coding style for code in the wild. >>> >> >> This would be very welcome, and I would be happy to help if somebody >> wanted to take the lead on this. >> ______________________________**_________________ >> 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 andres.osinski at gmail.com Tue Apr 9 10:31:44 2013 From: andres.osinski at gmail.com (andres.osinski at gmail.com) Date: Tue, 9 Apr 2013 17:31:44 +0000 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: <609623101-1365528706-cardhu_decombobulator_blackberry.rim.net-1327623515-@b3.c24.bise6.blackberry> This for is useful in algorithmically-intensive code where a lot of variables are declared at the top level. Matrix algorithms come to mind. I don't think it's a frequent use case but it's very useful when it arises. Enviado desde mi BlackBerry de Movistar (http://www.movistar.com.ar) -----Original Message----- From: Jack Moffitt Sender: rust-dev-bounces at mozilla.orgDate: Tue, 9 Apr 2013 11:16:51 To: John Clements Cc: rust-dev at mozilla.org Subject: Re: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) > I've recently become aware of the existence of a comma-separated local-variable declaration in Rust. Would people object strongly to the removal of this form? I wouldn't miss it. jack. _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From pwalton at mozilla.com Tue Apr 9 10:33:50 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 09 Apr 2013 10:33:50 -0700 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: <609623101-1365528706-cardhu_decombobulator_blackberry.rim.net-1327623515-@b3.c24.bise6.blackberry> References: <609623101-1365528706-cardhu_decombobulator_blackberry.rim.net-1327623515-@b3.c24.bise6.blackberry> Message-ID: <516450FE.6040902@mozilla.com> On 4/9/13 10:31 AM, andres.osinski at gmail.com wrote: > This for is useful in algorithmically-intensive code where a lot of > variables are declared at the top level. Matrix algorithms come to > mind. I don't think it's a frequent use case but it's very useful > when it arises. Keep in mind that you can use destructuring tuples: let (x, y) = (1, 2); Patrick From ben.striegel at gmail.com Tue Apr 9 10:34:10 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 9 Apr 2013 13:34:10 -0400 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: I use it frequently enough for conciseness. I'm having a hard time thinking of a language that *doesn't* support a construction. Does it cause a problem with formalizing the grammar? On Tue, Apr 9, 2013 at 1:04 PM, John Clements wrote: > I've recently become aware of the existence of a comma-separated > local-variable declaration in Rust. Would people object strongly to the > removal of this form? > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jon.mb at proinbox.com Tue Apr 9 10:54:18 2013 From: jon.mb at proinbox.com (John Mija) Date: Tue, 09 Apr 2013 18:54:18 +0100 Subject: [rust-dev] wanted libraries In-Reply-To: <20130408154224.114880@gmx.com> References: <20130408154224.114880@gmx.com> Message-ID: <516455CA.1050304@proinbox.com> +1 for internationalization/localization; it's complex and the solution should be designed by the Rust team. +1 for tokenizer, parser, just like Go has: http://golang.org/pkg/go/ This will allow to build tools like "gofmt" (to format Rust code) -1 for protobuf and thrift since they are not "standard". Instead, I prefer "csv" in the standard library * The library "math" should be in the library since it's something basic to create things related to image and audio. In addition a language like JavaScript comes with that library included: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math El 08/04/13 16:42, Olivier Renaud escribi?: > Hi, > > I saw the [wanted libraries] page on the github wiki, and I'd like to submit some ideas there. > The wiki page is read-only, so I fall back on submitting them on this list. > > I tried to confine myself to what would be useful to me, in a stdlib. > > * Internationalization : mechanisms for handling the internationalization of UI texts > -> one aspect of i18n is to map a key to a text, based on the current locale (eg Java's [ResourceBundle]) > -> another aspect is to format a string based on the current locale (eg Java's [MessageFormat]) > > * Libicu is already listed on the wiki, but there are no details of what is needed. Here are my suggestions : > -> Convertions between text encodings. Ideally, with a customizable way of handling conversion errors. > -> Unicode normalization (NFD, NFC, NFKD, NFKC) > -> Collator (locale sensitive string comparison), with a configurable degree of strictness > > * Simple (yet powerful) search on a filesystem (eg Ruby's [glob]) > > * A simple tokenizer/file parser > > * Support to read/write zip and tar file formats (not only the gzip algorithm) > > > Olivier Renaud > ___ > > [wanted libraries] https://github.com/mozilla/rust/wiki/Note-wanted-libraries > [ResourceBundle] http://docs.oracle.com/javase/7/docs/api/java/util/ResourceBundle.html > [MessageFormat] http://docs.oracle.com/javase/7/docs/api/java/text/MessageFormat.html > [glob] http://ruby-doc.org/core-2.0/Dir.html#method-c-glob > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From andres.osinski at gmail.com Tue Apr 9 11:14:03 2013 From: andres.osinski at gmail.com (andres.osinski at gmail.com) Date: Tue, 9 Apr 2013 18:14:03 +0000 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) Message-ID: <713459496-1365531246-cardhu_decombobulator_blackberry.rim.net-1763292463-@b3.c24.bise6.blackberry> Patrick, would destructured tuples show the intent of code adequately? If i saw a destructured tuple at the top level my first impression of that code would be that the author wants to work with tuples and just wants to keep around the internal values as a convenience. Keep in my mind that I've only started coding Rust code a week ago, but it I see it as "slightly confusing". ------Mensaje original------ De: Patrick Walton Remitente: rust-dev-bounces at mozilla.org Para: rust-dev at mozilla.org Asunto: Re: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) Enviado: 9 de abr de 2013 14:33 On 4/9/13 10:31 AM, andres.osinski at gmail.com wrote: > This for is useful in algorithmically-intensive code where a lot of > variables are declared at the top level. Matrix algorithms come to > mind. I don't think it's a frequent use case but it's very useful > when it arises. Keep in mind that you can use destructuring tuples: let (x, y) = (1, 2); Patrick _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev Enviado desde mi BlackBerry de Movistar (http://www.movistar.com.ar) From thadguidry at gmail.com Tue Apr 9 11:30:22 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Tue, 9 Apr 2013 13:30:22 -0500 Subject: [rust-dev] wanted libraries In-Reply-To: <516455CA.1050304@proinbox.com> References: <20130408154224.114880@gmx.com> <516455CA.1050304@proinbox.com> Message-ID: Approximate String Matching routines would be nice, if not already available... Perhaps performing similar functions such as Second String http://secondstring.sourceforge.net/ On Tue, Apr 9, 2013 at 12:54 PM, John Mija wrote: > +1 for internationalization/**localization; it's complex and the solution > should be designed by the Rust team. > > +1 for tokenizer, parser, just like Go has: > http://golang.org/pkg/go/ > > This will allow to build tools like "gofmt" (to format Rust code) > > -1 for protobuf and thrift since they are not "standard". Instead, I > prefer "csv" in the standard library > > * The library "math" should be in the library since it's something basic > to create things related to image and audio. > In addition a language like JavaScript comes with that library included: > > https://developer.mozilla.org/**en-US/docs/JavaScript/** > Reference/Global_Objects/Math > > > El 08/04/13 16:42, Olivier Renaud escribi?: > > Hi, >> >> I saw the [wanted libraries] page on the github wiki, and I'd like to >> submit some ideas there. >> The wiki page is read-only, so I fall back on submitting them on this >> list. >> >> I tried to confine myself to what would be useful to me, in a stdlib. >> >> * Internationalization : mechanisms for handling the internationalization >> of UI texts >> -> one aspect of i18n is to map a key to a text, based on the current >> locale (eg Java's [ResourceBundle]) >> -> another aspect is to format a string based on the current locale (eg >> Java's [MessageFormat]) >> >> * Libicu is already listed on the wiki, but there are no details of what >> is needed. Here are my suggestions : >> -> Convertions between text encodings. Ideally, with a customizable way >> of handling conversion errors. >> -> Unicode normalization (NFD, NFC, NFKD, NFKC) >> -> Collator (locale sensitive string comparison), with a configurable >> degree of strictness >> >> * Simple (yet powerful) search on a filesystem (eg Ruby's [glob]) >> >> * A simple tokenizer/file parser >> >> * Support to read/write zip and tar file formats (not only the gzip >> algorithm) >> >> >> Olivier Renaud >> ___ >> >> [wanted libraries] https://github.com/mozilla/**rust/wiki/Note-wanted-** >> libraries >> [ResourceBundle] http://docs.oracle.com/javase/**7/docs/api/java/util/** >> ResourceBundle.html >> [MessageFormat] http://docs.oracle.com/javase/**7/docs/api/java/text/** >> MessageFormat.html >> [glob] http://ruby-doc.org/core-2.0/**Dir.html#method-c-glob >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> >> ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From fredrik at haard.se Tue Apr 9 12:09:59 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Tue, 9 Apr 2013 21:09:59 +0200 Subject: [rust-dev] String encode/decode Message-ID: Hi all, is anyone working on generic (i.e. iso-*, cp*) string encoding/decoding? I googled and looked through the wiki, but apart from the from/to_bytes and from_to utf-16 I came up with nothing. Are there plans for what it should look like? Also, how come utf-16 has special treatment? -- /fredrik I reject your reality and substitute my own. http://courteous.ly/yp3Zgd -------------- next part -------------- An HTML attachment was scrubbed... URL: From giles at thaumas.net Tue Apr 9 12:15:40 2013 From: giles at thaumas.net (Ralph Giles) Date: Tue, 09 Apr 2013 12:15:40 -0700 Subject: [rust-dev] String encode/decode In-Reply-To: References: Message-ID: <516468DC.7010602@thaumas.net> On 13-04-09 12:09 PM, Fredrik H??rd wrote: > Also, how come utf-16 has special treatment? I expect it's needed for servo and the js engine bindings. Javascript uses utf-16 internally, like its namesake. -r From graydon at mozilla.com Tue Apr 9 12:20:59 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 09 Apr 2013 12:20:59 -0700 Subject: [rust-dev] String encode/decode In-Reply-To: <516468DC.7010602@thaumas.net> References: <516468DC.7010602@thaumas.net> Message-ID: <51646A1B.8060309@mozilla.com> On 09/04/2013 12:15 PM, Ralph Giles wrote: > On 13-04-09 12:09 PM, Fredrik H??rd wrote: > >> Also, how come utf-16 has special treatment? > > I expect it's needed for servo and the js engine bindings. Javascript > uses utf-16 internally, like its namesake. I added it for interop with win32, which takes UTF-16 in its unicode-aware APIs. -Graydon From pwalton at mozilla.com Tue Apr 9 14:03:42 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 09 Apr 2013 14:03:42 -0700 Subject: [rust-dev] 3 Gripes on Rust In-Reply-To: <7034399688401886511@unknownmsgid> References: <7070576472340126500@unknownmsgid> <1289d2ad-3920-492d-8b20-3520a8d59ea8@email.android.com> <7034399688401886511@unknownmsgid> Message-ID: <5164822E.5070804@mozilla.com> On 4/8/13 6:45 AM, Heri Sim wrote: > Thanks Patrick for the great explanation. > > Where can I find the typical usage examples of the select operation in > the pipes module? http://static.rust-lang.org/doc/core/pipes.html#function-select2 > I guess what remains is the inference for dynamic calls on polymorphic > data structures. How would you implement a binary search tree cleanly, > with types for empty, leaf, parent nodes? Not quite sure what you're asking, but the data type definition looks like this: enum Node { Empty, Leaf(T), Parent(@Node, @Node), } This would be the typical definition. This gives you something similar to the data model in Erlang or ML: the garbage collector is used to collect nodes, and sending such a binary search tree from task to task would require a deep copy (via serialization). You can also use ~ pointers, and avoid the garbage collector and the deep copy on sending. This is how strcat's treemap library in core works. But this requires explicit use of lifetimes. > What is your team's approach to corner cases? Generic syntax must cater > for corner cases? Or corner cases should have special syntax? Do more > most of the time, or do more sometimes? There's no hard and fast rule in language design for corner cases, but we try to minimize corner cases that violate the principle of least surprise. Patrick From ben.striegel at gmail.com Tue Apr 9 14:16:04 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 9 Apr 2013 17:16:04 -0400 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: One argument in favor of John's proposal is that: let mut foo = 1, bar = 2; somewhat deceptively declares bar as mutable. However, a lint pass for never-mutated mutable variables (which we'd want anyway) would catch this. It's still a rather convenient form, though. On Tue, Apr 9, 2013 at 1:34 PM, Benjamin Striegel wrote: > I use it frequently enough for conciseness. I'm having a hard time > thinking of a language that *doesn't* support a construction. Does it cause > a problem with formalizing the grammar? > > > On Tue, Apr 9, 2013 at 1:04 PM, John Clements wrote: > >> I've recently become aware of the existence of a comma-separated >> local-variable declaration in Rust. Would people object strongly to the >> removal of this form? >> >> John >> >> _______________________________________________ >> 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 mrhandle at outlook.com Tue Apr 9 14:23:17 2013 From: mrhandle at outlook.com (mrhandle) Date: Wed, 10 Apr 2013 00:23:17 +0300 Subject: [rust-dev] How to move data to closures? Message-ID: An HTML attachment was scrubbed... URL: From stefan.plantikow at gmail.com Tue Apr 9 14:56:30 2013 From: stefan.plantikow at gmail.com (Stefan Plantikow) Date: Tue, 9 Apr 2013 23:56:30 +0200 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: <950EFC0A-18F0-40BB-AFDC-669D7472EF70@googlemail.com> Am 09.04.2013 um 23:16 schrieb Benjamin Striegel : > One argument in favor of John's proposal is that: > > let mut foo = 1, > bar = 2; > maybe that should change then in favor of let mut foo = 1, mut bar = 2; ? Cheers, Stefan PLantikow From David.Klein at baesystemsdetica.com Tue Apr 9 16:30:30 2013 From: David.Klein at baesystemsdetica.com (David.Klein at baesystemsdetica.com) Date: Wed, 10 Apr 2013 09:30:30 +1000 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: <94B03B5BBF9A1E408916A8E2A499FD1B12C4D5180A@SSCBREX01.stratsec.local> Why not let a,b = 3, 4 -----Original Message----- From: rust-dev-bounces at mozilla.org [mailto:rust-dev-bounces at mozilla.org] On Behalf Of Jack Moffitt Sent: Wednesday, 10 April 2013 3:17 AM To: John Clements Cc: rust-dev at mozilla.org Subject: Re: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) > I've recently become aware of the existence of a comma-separated local-variable declaration in Rust. Would people object strongly to the removal of this form? I wouldn't miss it. jack. _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4826 bytes Desc: not available URL: From graydon at mozilla.com Tue Apr 9 16:48:07 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 09 Apr 2013 16:48:07 -0700 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: <94B03B5BBF9A1E408916A8E2A499FD1B12C4D5180A@SSCBREX01.stratsec.local> References: <94B03B5BBF9A1E408916A8E2A499FD1B12C4D5180A@SSCBREX01.stratsec.local> Message-ID: <5164A8B7.6010808@mozilla.com> I think the answer to this bikeshed's impressive shower of sparks is "no". We'll leave things as they are. -Graydon From graydon at mozilla.com Tue Apr 9 18:06:33 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 09 Apr 2013 18:06:33 -0700 Subject: [rust-dev] wanted libraries In-Reply-To: <1127528972-1365454872-cardhu_decombobulator_blackberry.rim.net-638423182-@b3.c24.bise6.blackberry> References: <20130408154224.114880@gmx.com> <1127528972-1365454872-cardhu_decombobulator_blackberry.rim.net-638423182-@b3.c24.bise6.blackberry> Message-ID: <5164BB19.3080108@mozilla.com> On 08/04/2013 2:01 PM, andres.osinski at gmail.com wrote: > Would making idiomatic bindings to gettext on Unix platforms qualify for transaltions, or is the core team more interested in cross-platform Rust libraries from the start? I'm not aware of a lot of good alternatives to gettext, tbh. I think it might be the best we can aim for here. I'd be happy to be proven wrong. -Graydon From marcianx at gmail.com Tue Apr 9 19:07:36 2013 From: marcianx at gmail.com (Ashish Myles) Date: Tue, 9 Apr 2013 22:07:36 -0400 Subject: [rust-dev] Macro bugs or misunderstanding of use? Message-ID: Hi, I am running the rust compiler from trunk. My macro usage seems to be a ---- macro_rules! my_print( ($a:expr, $b:expr) => ( io::println(fmt!("%d", a)); io::println(fmt!("%d", b)); ); ) fn main() { let a : int = 1; let b : int = 2; my_print!(a, b); } ---- Compiling with "rustc tmp.rs" gives the following suspicious warning ---- tmp.rs:10:8: 10:11 warning: unused variable: `b` tmp.rs:10 let b : int = 2; ---- and ./tmp prints only "1". Running "rustc tmp.rs --pretty expanded" shows below that the second line "io::println(fmt!("%d", b));" was ignored. ---- fn main() { let a: int = 1; let b: int = 2; io::println({ let mut __fmtbuf = ~""; ::unstable::extfmt::rt::conv_int(::unstable::extfmt::rt::Conv{flags: ::unstable::extfmt::rt::flag_none, width: ::unstable::extfmt::rt::CountImplied, precision: ::unstable::extfmt::rt::CountImplied, ty: ::unstable::extfmt::rt::TyDefault,}, a, &mut __fmtbuf); __fmtbuf }); } ---- Can someone point me in the right direction here? Also, can someone provide examples of how exactly log_syntax!() and trace_macros!(true) work? Ashish From doy at tozt.net Tue Apr 9 19:12:26 2013 From: doy at tozt.net (Jesse Luehrs) Date: Tue, 9 Apr 2013 21:12:26 -0500 Subject: [rust-dev] Macro bugs or misunderstanding of use? In-Reply-To: References: Message-ID: <20130410021226.GT26639@tozt.net> On Tue, Apr 09, 2013 at 10:07:36PM -0400, Ashish Myles wrote: > Hi, > > I am running the rust compiler from trunk. My macro usage seems to be a > > ---- > macro_rules! my_print( > ($a:expr, $b:expr) => ( > io::println(fmt!("%d", a)); > io::println(fmt!("%d", b)); > ); > ) > > fn main() { > let a : int = 1; > let b : int = 2; > my_print!(a, b); > } > ---- > > Compiling with "rustc tmp.rs" gives the following suspicious warning > > ---- > tmp.rs:10:8: 10:11 warning: unused variable: `b` > tmp.rs:10 let b : int = 2; > ---- > > and ./tmp prints only "1". Running "rustc tmp.rs --pretty expanded" > shows below that the second line "io::println(fmt!("%d", b));" was > ignored. > > ---- > fn main() { > let a: int = 1; > let b: int = 2; > io::println({ > let mut __fmtbuf = ~""; > > ::unstable::extfmt::rt::conv_int(::unstable::extfmt::rt::Conv{flags: > > ::unstable::extfmt::rt::flag_none, > > width: > > ::unstable::extfmt::rt::CountImplied, > > precision: > > ::unstable::extfmt::rt::CountImplied, > > ty: > > ::unstable::extfmt::rt::TyDefault,}, > a, &mut __fmtbuf); > __fmtbuf > }); > } > ---- > > Can someone point me in the right direction here? Currently, macros can only expand to a single item. See https://github.com/mozilla/rust/issues/4375 for more details. -doy From jeaye at arrownext.com Tue Apr 9 19:45:26 2013 From: jeaye at arrownext.com (Jeaye Wilkerson) Date: Tue, 9 Apr 2013 19:45:26 -0700 Subject: [rust-dev] Macro bugs or misunderstanding of use? In-Reply-To: <20130410021226.GT26639@tozt.net> References: <20130410021226.GT26639@tozt.net> Message-ID: <8615DDC1-7362-4EDC-BC56-90C73B8A61FB@arrownext.com> In other words, try putting those two prints (in the macro) inside of a { } block. Cheers, Jeaye On Apr 9, 2013, at 7:12 PM, Jesse Luehrs wrote: > On Tue, Apr 09, 2013 at 10:07:36PM -0400, Ashish Myles wrote: >> Hi, >> >> I am running the rust compiler from trunk. My macro usage seems to be a >> >> ---- >> macro_rules! my_print( >> ($a:expr, $b:expr) => ( >> io::println(fmt!("%d", a)); >> io::println(fmt!("%d", b)); >> ); >> ) >> >> fn main() { >> let a : int = 1; >> let b : int = 2; >> my_print!(a, b); >> } >> ---- >> >> Compiling with "rustc tmp.rs" gives the following suspicious warning >> >> ---- >> tmp.rs:10:8: 10:11 warning: unused variable: `b` >> tmp.rs:10 let b : int = 2; >> ---- >> >> and ./tmp prints only "1". Running "rustc tmp.rs --pretty expanded" >> shows below that the second line "io::println(fmt!("%d", b));" was >> ignored. >> >> ---- >> fn main() { >> let a: int = 1; >> let b: int = 2; >> io::println({ >> let mut __fmtbuf = ~""; >> >> ::unstable::extfmt::rt::conv_int(::unstable::extfmt::rt::Conv{flags: >> >> ::unstable::extfmt::rt::flag_none, >> >> width: >> >> ::unstable::extfmt::rt::CountImplied, >> >> precision: >> >> ::unstable::extfmt::rt::CountImplied, >> >> ty: >> >> ::unstable::extfmt::rt::TyDefault,}, >> a, &mut __fmtbuf); >> __fmtbuf >> }); >> } >> ---- >> >> Can someone point me in the right direction here? > > Currently, macros can only expand to a single item. See > https://github.com/mozilla/rust/issues/4375 for more details. > > -doy > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From jeaye at arrownext.com Tue Apr 9 22:28:37 2013 From: jeaye at arrownext.com (Jeaye) Date: Tue, 09 Apr 2013 22:28:37 -0700 Subject: [rust-dev] Macro bugs or misunderstanding of use? In-Reply-To: References: <20130410021226.GT26639@tozt.net> <8615DDC1-7362-4EDC-BC56-90C73B8A61FB@arrownext.com> Message-ID: <5164F885.7030904@arrownext.com> > Ah, thank you both for that. That limitation on code generation > currently puts a damper on my attempt at a semi-convenient work-around > for the template system's lack of support for integer parameters. I > don't seem to be able to define structs and trait implementations > within the {...} and have them be accessible to the outer scope. Any > other possibly hacks around this? If not, I suppose I will wait for > rust to add support for what I would like to do (either in the > template system or the macro system). > You can put a module inside of the macro and the `pub use` that module to bring it into scope. For example: ```rust pub use self::macro::Vec3f; macro_rules! declare ( ($Type:ident, $Component:ty) => ( mod macro { pub struct $Type { x: $Component, y: $Component, z: $Component } impl $Type { pub fn new(nx: $Component, ny: $Component, nz: $Component) -> $Type { $Type{ x: nx, y: ny, z: nz } } } } ); ) declare!(Vec3f, f32) ``` Cheers, Jeaye From alexander.kjeldaas at gmail.com Tue Apr 9 23:11:05 2013 From: alexander.kjeldaas at gmail.com (Alexander Kjeldaas) Date: Wed, 10 Apr 2013 08:11:05 +0200 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: On Tue, Apr 9, 2013 at 11:16 PM, Benjamin Striegel wrote: > One argument in favor of John's proposal is that: > > let mut foo = 1, > bar = 2; > > somewhat deceptively declares bar as mutable. However, a lint pass for > never-mutated mutable variables (which we'd want anyway) would catch this. > > Ouch! I think the semantics of the above is far from obvious and slightly dangerous. Alexander > It's still a rather convenient form, though. > > > On Tue, Apr 9, 2013 at 1:34 PM, Benjamin Striegel wrote: > >> I use it frequently enough for conciseness. I'm having a hard time >> thinking of a language that *doesn't* support a construction. Does it cause >> a problem with formalizing the grammar? >> >> >> On Tue, Apr 9, 2013 at 1:04 PM, John Clements wrote: >> >>> I've recently become aware of the existence of a comma-separated >>> local-variable declaration in Rust. Would people object strongly to the >>> removal of this form? >>> >>> John >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Tue Apr 9 23:28:16 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 09 Apr 2013 23:28:16 -0700 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: <51650680.5010401@alum.mit.edu> For what it's worth, when I was implementing `let mut` I did a straw poll at the time whether let mut a = 1, b = 2; should declare both a and b as mutable or only a, and the response at the time was uniformly in favor of "both a and b" (which surprised me, since I had intended to do the opposite). Niko > Alexander Kjeldaas > April 9, 2013 11:11 PM > > > > On Tue, Apr 9, 2013 at 11:16 PM, Benjamin Striegel > > wrote: > > One argument in favor of John's proposal is that: > > let mut foo = 1, > bar = 2; > > somewhat deceptively declares bar as mutable. However, a lint pass > for never-mutated mutable variables (which we'd want anyway) would > catch this. > > > Ouch! I think the semantics of the above is far from obvious and > slightly dangerous. > > Alexander > > It's still a rather convenient form, though. > > > On Tue, Apr 9, 2013 at 1:34 PM, Benjamin Striegel > > wrote: > > I use it frequently enough for conciseness. I'm having a hard > time thinking of a language that *doesn't* support a > construction. Does it cause a problem with formalizing the > grammar? > > > On Tue, Apr 9, 2013 at 1:04 PM, John Clements > > > wrote: > > I've recently become aware of the existence of a > comma-separated local-variable declaration in Rust. Would > people object strongly to the removal of this form? > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > Benjamin Striegel > April 9, 2013 2:16 PM > One argument in favor of John's proposal is that: > > let mut foo = 1, > bar = 2; > > somewhat deceptively declares bar as mutable. However, a lint pass for > never-mutated mutable variables (which we'd want anyway) would catch this. > > It's still a rather convenient form, though. > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > Benjamin Striegel > April 9, 2013 10:34 AM > I use it frequently enough for conciseness. I'm having a hard time > thinking of a language that *doesn't* support a construction. Does it > cause a problem with formalizing the grammar? > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > John Clements > April 9, 2013 10:04 AM > I've recently become aware of the existence of a comma-separated > local-variable declaration in Rust. Would people object strongly to > the removal of this form? > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: compose-unknown-contact.jpg Type: image/jpeg Size: 770 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: postbox-contact.jpg Type: image/jpeg Size: 1106 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: postbox-contact.jpg Type: image/jpeg Size: 1360 bytes Desc: not available URL: From mrhandle at outlook.com Wed Apr 10 02:10:36 2013 From: mrhandle at outlook.com (mrhandle) Date: Wed, 10 Apr 2013 12:10:36 +0300 Subject: [rust-dev] How to move data to closures? In-Reply-To: References: Message-ID: I just realized my message was sent as an HTML attachment and was scrubbed from the email. Here is the email again in text format (hopefully): On 2013-04-10 12:23 AM, mrhandle wrote: > Hi all, > > I am trying to write a generator function that returns a struct > containing some value and an owned closure computing the next value. > > fn generate_something() -> gen_res { ...blah... } > > struct gen_res { > val : T, > next : ~fn() -> gen_res, > } > > For every closure I create I need to append some computation data in a > Cons like fashion (I don't mutate old data). Is that possible without > cloning data? > > (In my specific case I want to write a prime number generator that > computes one prime at a time and keeps track of discovered prime > numbers. I know there are other C-like ways to do it but I want to > play around with closures). > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From artella.coding at googlemail.com Wed Apr 10 05:43:33 2013 From: artella.coding at googlemail.com (Artella Coding) Date: Wed, 10 Apr 2013 13:43:33 +0100 Subject: [rust-dev] Tail call optimization Message-ID: Hi does rust do tail call optimization? The reason I am asking is that the following tail call recursive implementation results in a stack overflow. Thanks. ********************************************************************************* //In this program we check (via a tail recursive function) //whether 200003 (which is a prime number) has any divisors. //Clearly the answer is negative, but the aim is to illustrate //the stack overflowing. /* Starting with a maximum value of I-1, J is decreased and tested to see if it is a divisor of I. If I has a divisor, then the function returns true, otherwise it returns false. */ fn divisibleRec(I: int, J:int) -> bool { if J==1 { false } else{ if I%J==0 { true } else{ divisibleRec(I,J-1) } } } //Checks whether I is divisible by any number below it. fn divisible(I: int) -> bool { divisibleRec(I, I-1) } fn main() { let number = 200003;//200003 is a prime number let result_isNumDivisible = divisible(number); io::println(bool::to_str(result_isNumDivisible)); } ********************************************************************************* -------------- next part -------------- An HTML attachment was scrubbed... URL: From chadz.ski at gmail.com Wed Apr 10 06:37:24 2013 From: chadz.ski at gmail.com (Chad Zawistowski) Date: Wed, 10 Apr 2013 09:37:24 -0400 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) Message-ID: > > One argument in favor of John's proposal is that: >> >> let mut foo = 1, >> bar = 2; >> >> somewhat deceptively declares bar as mutable. However, a lint pass for >> never-mutated mutable variables (which we'd want anyway) would catch this. >> > > For what it's worth, when I was implementing `let mut` I did a straw > poll at the time whether > > let mut a = 1, b = 2; > > should declare both a and b as mutable or only a, and the response at > the time was uniformly in favor of "both a and b" (which surprised me, > since I had intended to do the opposite). > > Niko It seems to me that if you're going to spread the declaration across two lines, you might as well make it two statements, which would remove ambiguity here. let mut foo = 1; let bar = 2; In the case where both declarations are on the same line, I agree with the results of Niko's straw poll. let mut foo = 1, bar = 2; This should make both foo and bar be mut, in my opinion. Chad -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Wed Apr 10 09:32:03 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 10 Apr 2013 09:32:03 -0700 Subject: [rust-dev] Tail call optimization In-Reply-To: References: Message-ID: <51659403.8070204@mozilla.com> On 4/10/13 5:43 AM, Artella Coding wrote: > Hi does rust do tail call optimization? The reason I am asking is that > the following tail call recursive implementation results in a stack > overflow. Thanks. Not in the general case. But the WIP patch I have to use the machine return value may allow LLVM to optimize that function into a loop. Patrick From lucian.branescu at gmail.com Wed Apr 10 09:34:31 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Wed, 10 Apr 2013 17:34:31 +0100 Subject: [rust-dev] Tail call optimization In-Reply-To: <51659403.8070204@mozilla.com> References: <51659403.8070204@mozilla.com> Message-ID: It would be nice if there was an attribute for expressing the wish that a function be tail call optimised (like Scala), It's otherwise hard to rely on tail calls if they don't work in the general case (and I'm assuming LLVM doesn't support general tail calls). On 10 April 2013 17:32, Patrick Walton wrote: > On 4/10/13 5:43 AM, Artella Coding wrote: > >> Hi does rust do tail call optimization? The reason I am asking is that >> the following tail call recursive implementation results in a stack >> overflow. Thanks. >> > > Not in the general case. But the WIP patch I have to use the machine > return value may allow LLVM to optimize that function into a loop. > > Patrick > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed Apr 10 09:39:22 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 10 Apr 2013 12:39:22 -0400 Subject: [rust-dev] Tail call optimization In-Reply-To: References: <51659403.8070204@mozilla.com> Message-ID: On Wed, Apr 10, 2013 at 12:34 PM, Lucian Branescu wrote: > It would be nice if there was an attribute for expressing the wish that a > function be tail call optimised (like Scala), It's otherwise hard to rely on > tail calls if they don't work in the general case (and I'm assuming LLVM > doesn't support general tail calls). > > > On 10 April 2013 17:32, Patrick Walton wrote: >> >> On 4/10/13 5:43 AM, Artella Coding wrote: >>> >>> Hi does rust do tail call optimization? The reason I am asking is that >>> the following tail call recursive implementation results in a stack >>> overflow. Thanks. >> >> >> Not in the general case. But the WIP patch I have to use the machine >> return value may allow LLVM to optimize that function into a loop. >> >> 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 > LLVM does support tail call optimization, but it requires using a different calling convention than C and slowing down all function calls.[1] If Rust was actually using the return value it could do sibling call optimization (same function signature in the tail call) in many cases, but destructors will often stop functions from actually being a tail call. [1] http://llvm.org/docs/CodeGenerator.html#tail-call-optimization From graydon at mozilla.com Wed Apr 10 10:21:23 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 10 Apr 2013 10:21:23 -0700 Subject: [rust-dev] Tail call optimization In-Reply-To: References: Message-ID: <51659F93.6090007@mozilla.com> On 10/04/2013 5:43 AM, Artella Coding wrote: > Hi does rust do tail call optimization? The reason I am asking is that > the following tail call recursive implementation results in a stack > overflow. Thanks. No, and it very likely won't. We have a longstanding bug on this: https://github.com/mozilla/rust/issues/217 as well as a wiki page and several mailing list threads: https://github.com/mozilla/rust/wiki/Bikeshed-tailcall https://mail.mozilla.org/pipermail/rust-dev/2011-August/000689.html https://mail.mozilla.org/pipermail/rust-dev/2012-January/001280.html ... The summary of all this is: - We all know that tail calls are a virtuous language feature. Further elaboration of their virtues is not required. Many of us have lisp and ML backgrounds and would quite like them. Their absence is heartache and sadness, not arrived-at lightly. - Tail calls "play badly" with deterministic destruction. Including deterministic drop of ~ boxes. Not to say that they're not composable, but the options for composing them are UI-awkward, performance-penalizing, semantics-complicating or all of the above. - Tail calls also "play badly" with assumptions in C tools, including platform ABIs and dynamic linking. - Tail calls require a calling convention that is a performance hit relative to the C convention. - We find most cases of tail _recursion_ convert reasonably well to loops, and most cases of non-recursive tail calls encode state machines that convert reasonably well to loops wrapped around enums. Neither of these are _quite_ as pretty as the tail-call-using variants, but they do work and are "as fast"*, as well as idiomatic for C and C++ programmers (who are our primary audience). I'm sorry to be saying all this, and it is with a heavy heart, but we tried and did not find a way to make the tradeoffs associated with them sum up to an argument for inclusion in rust. -Graydon * speed-wise, a switch-in-a-loop state machine is indirect dispatch so will likely run slower than a state machine encoded by tail calls from state to state; on the other hand if the way to get this performance "back" is to turn on tail calls everywhere, we'd be trading one isolated suboptimal-perf case for a cross-all-programs suboptimal-perf tax. We don't find this trade acceptable. From illissius at gmail.com Wed Apr 10 11:30:12 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Wed, 10 Apr 2013 20:30:12 +0200 Subject: [rust-dev] getting rid of let a=3, b=4? (bikeshed alert) In-Reply-To: References: Message-ID: On Wed, Apr 10, 2013 at 3:37 PM, Chad Zawistowski wrote: > In the case where both declarations are on the same line, I agree with the > results of Niko's straw poll. > > let mut foo = 1, bar = 2; > > This should make both foo and bar be mut, in my opinion. > > Chad > The question is whether mut applies to let or to foo: (let mut) foo, bar vs. let (mut foo, bar). Is there any other place left in the language besides let, @, and & where mut is allowed? The latter cases seem to support (let mut): if you have &mut foo, it's a pointer through which mutation is allowed, named foo, in other words (&mut) foo, while the other way, &(mut foo), doesn't make any sense: it's not foo that's mutable! Similarly for @. So yeah, +1 for existing interpretation. -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Wed Apr 10 15:57:45 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 10 Apr 2013 15:57:45 -0700 Subject: [rust-dev] Some work on Rust coding standards Message-ID: <5165EE69.4000109@mozilla.com> There have been a few mentions recently about writing up the Rust coding standards. Several of us sat in a room and tried to identify and agree on some that we thought were important. I've pasted the resulting notes into the wiki: https://github.com/mozilla/rust/wiki/Note-style-guide These are very, very rough but cover a number of topics. Comments and suggestions are welcome. These need to be cleaned up into readable prose, with decent examples, and moved from the 'Notes' section of the wiki to the 'Docs' section where users will find them. Help is definitely appreciated. -Brian From erick.tryzelaar at gmail.com Wed Apr 10 17:25:53 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Wed, 10 Apr 2013 17:25:53 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: <5165EE69.4000109@mozilla.com> References: <5165EE69.4000109@mozilla.com> Message-ID: Great! We've needed something like this. I worry a little bit about the function declaration style though. I could see it being difficult to implement this format in the pretty printer, which would make it hard to write something like gofix. Here's the longest function declaration I could find in our codebase, this one in src/librustc/middle/typeck/infer/unify.rs: fn simple_vars>>(&mut self, +a_is_expected: bool, +a_id: V, +b_id: V) -> ures { Assuming we extended the rule to the typarams, we'd have: fn simple_vars>>(&mut self, +a_is_expected: bool, +a_id: V, +b_id: V) -> ures { Which in my opinion is hard to read. Then there's the question of what happens if even after wrapping the line pushes us past the 100 character limit? For my bikeshed, I have started using the basic rule that if I can't fit a statement on one line, I wrap and indent 4 spaces after a '<', '(', or '{': fn simple_vars< T:Copy + Eq + InferStr + SimplyUnifiable, V:Copy + Eq + Vid + ToStr + UnifyVid> >( &mut self, +a_is_expected: bool, +a_id: V, +b_id: V ) -> ures { Another option is to do what Go does, and say there's no limit in the line length, but if the user wants to wrap, just add a tab to the start of the next line. So it could look something like this fn simple_vars< T:Copy + Eq + InferStr + SimplyUnifiable, V:Copy + Eq + Vid + ToStr + UnifyVid>>(&mut self, +a_is_expected: bool, +a_id: V, +b_id: V) -> ures { It's a little ugly, but it's consistent, and really easy to implement with a pretty printer. Here are the Go rules: http://golang.org/doc/effective_go.html#formatting I personally don't care what style we use, I just want to make sure we choose a style that's easy to automate so we can move on with our lives. On Wed, Apr 10, 2013 at 3:57 PM, Brian Anderson wrote: > There have been a few mentions recently about writing up the Rust coding > standards. Several of us sat in a room and tried to identify and agree on > some that we thought were important. I've pasted the resulting notes into > the wiki: > > https://github.com/mozilla/**rust/wiki/Note-style-guide > > These are very, very rough but cover a number of topics. Comments and > suggestions are welcome. These need to be cleaned up into readable prose, > with decent examples, and moved from the 'Notes' section of the wiki to the > 'Docs' section where users will find them. Help is definitely appreciated. > > -Brian > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Wed Apr 10 17:37:42 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 10 Apr 2013 17:37:42 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: <5165EE69.4000109@mozilla.com> References: <5165EE69.4000109@mozilla.com> Message-ID: <516605D6.209@alum.mit.edu> Hi guys, I guess it is time to adopt some consistent standards. Since I wasn't in the room, here are my two cents. # Function docs I prefer putting the function comment *inside* the fn rather than in front. However, I am probably alone on this point, so I'm prepared to lose this fight. Anyhow, if we are going to place comments in front of the function, I think we should encourage `///` comments in favor of the `/**..*/`. That is, prefer this: /// Function comment /// More function comment fn foo() { ... } To this: /** * Function comment * More function comment */ fn foo() { ... } My reasons: 1. No wasted lines (unlike /** ... */ which wastes two lines). 2. If you include a code example inside the `///` comment, you can use `/* ... */` within the comment without triggering errors. 3. It just looks better to my eyes ;) # Module docs I like to make long comments on modules sometimes. I've decided these "book chapter"-like comments ought to be put into a `doc.rs` module, since it's a pain to scroll down through them. # Long function signatures and the opening brace Also, we should give more guidance in the event of long function signatures. Personally, if the first parameter will not fit on the same line as the function names, I favor moving the opening brace to its own line, like this: fn some_really_long_name( a: T1, b: T2) -> RT { ... } The idea is to use the brace at the start of a line to separate code and signature when they have the same indentation. Another relevant example would be what to do if you have a lot of type parameters and traits. I typically do this: fn some_really_long_name( a: T1, b: T2) -> RT { ... } I think similar rules apply to if statements and so forth: #Pattern syntax I don't like the `|` in front of the patterns. Things don't line up. When using `|` to combine patterns together, and things don't fit on one line, my own personal inclination is to follow a style like this: match foo { pat1 | pat2 => { ... } pat3 | pat4 => { ... } } Here the indentation separates the patterns from everything else. In cases like this, I never use the non-brace form, since otherwise the indentation doesn't work. I also find I prefer using `{...}` form in cases where the body does not produce a value, such as: match foo { Some(v) => { return v; } None => {} } not match foo { Some(v) => return v, None => {} }; Somehow, the `,` strongly suggests a value is being produced to me. # "Ternary operator" If else expressions For cases where you would use the ternary operator in C, such as `(foo ? bar : zed)` I tend to nestle the braces up with the expressions, like so `if foo {bar} else {zed}`. I find this reads better than `if foo { bar } else { zed }`. If others disagree, let me know so I can stop doing it. Niko > Brian Anderson > April 10, 2013 3:57 PM > There have been a few mentions recently about writing up the Rust > coding standards. Several of us sat in a room and tried to identify > and agree on some that we thought were important. I've pasted the > resulting notes into the wiki: > > https://github.com/mozilla/rust/wiki/Note-style-guide > > These are very, very rough but cover a number of topics. Comments and > suggestions are welcome. These need to be cleaned up into readable > prose, with decent examples, and moved from the 'Notes' section of the > wiki to the 'Docs' section where users will find them. Help is > definitely appreciated. > > -Brian > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: compose-unknown-contact.jpg Type: image/jpeg Size: 770 bytes Desc: not available URL: From doy at tozt.net Wed Apr 10 17:46:29 2013 From: doy at tozt.net (Jesse Luehrs) Date: Wed, 10 Apr 2013 19:46:29 -0500 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: References: <5165EE69.4000109@mozilla.com> Message-ID: <20130411004628.GU26639@tozt.net> On Wed, Apr 10, 2013 at 05:25:53PM -0700, Erick Tryzelaar wrote: > Great! We've needed something like this. I worry a little bit about the > function declaration style though. I could see it being difficult to > implement this format in the pretty printer, which would make it hard to > write something like gofix. Here's the longest function declaration I could > find in our codebase, this one in src/librustc/middle/typeck/infer/unify.rs: > > fn simple_vars Vid + ToStr + UnifyVid>>(&mut self, +a_is_expected: bool, +a_id: > V, +b_id: V) -> ures { > > Assuming we extended the rule to the typarams, we'd have: > > fn simple_vars V:Copy + Eq + Vid + ToStr + UnifyVid>>(&mut > self, > > +a_is_expected: bool, > +a_id: > V, > +b_id: > V) > -> ures > { > > Which in my opinion is hard to read. Then there's the question of what > happens if even after wrapping the line pushes us past the 100 character > limit? > > For my bikeshed, I have started using the basic rule that if I can't fit a > statement on one line, I wrap and indent 4 spaces after a '<', '(', or '{': > > fn simple_vars< > T:Copy + Eq + InferStr + SimplyUnifiable, > V:Copy + Eq + Vid + ToStr + UnifyVid> > >( > &mut self, > +a_is_expected: bool, > +a_id: V, > +b_id: V > ) -> ures { I prefer this style as well, although in my experience it doesn't seem to be very common among C/C++ programmers for whatever reason. The benefit here over just indenting the next line without putting the closing brace on its own line (like the next example) is that the signature doesn't visually run into the body of the function. > Another option is to do what Go does, and say there's no limit in the line > length, but if the user wants to wrap, just add a tab to the start of the > next line. So it could look something like this > > fn simple_vars< > T:Copy + Eq + InferStr + SimplyUnifiable, > V:Copy + Eq + Vid + ToStr + UnifyVid>>(&mut self, > +a_is_expected: bool, +a_id: V, +b_id: V) > -> ures { > > It's a little ugly, but it's consistent, and really easy to implement with > a pretty printer. Here are the Go rules: > > http://golang.org/doc/effective_go.html#formatting > > I personally don't care what style we use, I just want to make sure we > choose a style that's easy to automate so we can move on with our lives. -doy From niko at alum.mit.edu Wed Apr 10 17:52:07 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Wed, 10 Apr 2013 17:52:07 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: <516605D6.209@alum.mit.edu> References: <5165EE69.4000109@mozilla.com> <516605D6.209@alum.mit.edu> Message-ID: <51660937.1070606@alum.mit.edu> Niko Matsakis wrote: > Anyhow, if we are going to place comments in front of the function, I > think we should encourage `///` comments in favor of the `/**..*/`. It's been pointed out to me that this is what the style guide already said. Okay then. Niko From ncm at cantrip.org Wed Apr 10 18:29:17 2013 From: ncm at cantrip.org (Nathan Myers) Date: Wed, 10 Apr 2013 18:29:17 -0700 Subject: [rust-dev] Fwd: Re: Some work on Rust coding standards In-Reply-To: <5166116F.6020108@cantrip.org> References: <5166116F.6020108@cantrip.org> Message-ID: <516611ED.8090706@cantrip.org> On 04/10/2013 03:57 PM, Brian Anderson wrote: > There have been a few mentions recently about writing up the Rust > coding standards. Several of us sat in a room and tried to identify > and agree on some that we thought were important. I've pasted the > resulting notes into the wiki: > > https://github.com/mozilla/rust/wiki/Note-style-guide > > These are very, very rough but cover a number of topics. Comments and > suggestions are welcome. These need to be cleaned up into readable > prose, with decent examples, and moved from the 'Notes' section of the > wiki to the 'Docs' section where users will find them. Help is > definitely appreciated. Is it permitted to recoil in horror? No? OK. Before commenting on individual items, it seems better to start by identifying what conventions can achieve, and what they shouldn't try: 1. The overarching goal is interoperability. Codify conventions to ease mixing libraries from diverse sources. Only codify what actually matters. Different people make different esthetic choices, and a style guide cannot change that. So, don't publish a style guide, publish coding guidelines. Leave superficialities for the the superficial to quarrel over. 2. Some resources will always be scarce: conscious attention, screen space, editing time, short-term memory. Sacrifice anything, even consistency, to favor those. (E.g., start long text strings at the left margin, ignoring current indentation level.) 3. Rules should favor needs of coders reading or writing the most difficult code. That means, in particular, don't ask coders to waste scarce screen space calling attention to details that are not important. Don't demand fussy aligning. Extra whitespace should be reserved to the coder to enable signaling something important, e.g. early function return. Deep indentation usually wastes whitespace on incidentals. Non-coding vertical whitespace could better be used in the next window over. 4. Some rules may have a purely operational purpose. E.g. two potential breakpoint sites that would be usefully distinct should be on different lines, such as conditional predicate and consequent, so that debugging is easier. 5. As the language definition solidifies, it gets harder to make unwise design choices actually illegal, and the coding guide must take up the slack. It took a long time to realize that C++ virtual functions shouldn't be public. 6. Layout recommendations should be representable as code, so an editor can re-flow code automatically as the window is narrowed, or as the indentation of blocks of code changes. Nathan Myers ncm at cantrip.org From someone at mearie.org Wed Apr 10 19:22:50 2013 From: someone at mearie.org (Kang Seonghoon) Date: Thu, 11 Apr 2013 11:22:50 +0900 Subject: [rust-dev] Some work on Rust coding standards Message-ID: I mostly agree to Niko's comments, but I'd like to point out one issue with function docs. Given the following code: ~~~~ /// This is a doc comment with two paragraphs. /// /// Not actually. pub fn a() { } /** * This is a doc comment with two paragraphs. * * Really. */ pub fn b() { } ~~~~ ...rustdoc produces two paragraphs for `b` but one paragraph for `a` (behaves as if there are no empty lines). I was assumed that it was by design until now, but it now feels like a bug. (I'll open an issue if it is indeed considered a bug.) Niko Matsakis wrote: > # Function docs > > I prefer putting the function comment *inside* the fn rather than in > front. However, I am probably alone on this point, so I'm prepared to > lose this fight. Anyhow, if we are going to place comments in front of > the function, I think we should encourage `///` comments in favor of the > `/**..*/`. That is, prefer this: > > /// Function comment > /// More function comment > fn foo() { ... } > > To this: > > /** > * Function comment > * More function comment > */ > fn foo() { ... } > > My reasons: > > 1. No wasted lines (unlike /** ... */ which wastes two lines). > 2. If you include a code example inside the `///` comment, you can use > `/* ... */` within the comment without triggering errors. > 3. It just looks better to my eyes ;) -- -- Kang Seonghoon | Software Engineer, iPlateia Inc. | http://mearie.org/ -- Opinions expressed in this email do not necessarily represent the views of my employer. -- From steve at steveklabnik.com Wed Apr 10 20:02:50 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Wed, 10 Apr 2013 20:02:50 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: References: Message-ID: I want my coding standards to be blue! I think this is a damn fine guide. Strong conventions are one of the things I love most about Ruby, so I'd love to see strong conventions in Rust, too, no matter what they are. From banderson at mozilla.com Wed Apr 10 22:53:15 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 10 Apr 2013 22:53:15 -0700 Subject: [rust-dev] LLVM upgraded on incoming Message-ID: <51664FCB.8090902@mozilla.com> Hi Rusties, I've pushed an LLVM upgrade to incoming. This version of LLVM is from LLVM trunk in March plus Rust patches for segmented stacks and ARM. For the sake of improving compilation speed I've also dropped the clang and compiler-rt submodules since we've never used them for anything. The old files for these submodules will not be removed automatically. I *think* this will not cause you a build problem but you may want to manually delete src/llvm/projects/compiler-rt and src/llvm/tools/clang. If you run into problems with LLVM then consider running `make clean-llvm` or simply deleting your build directory. Some of the bots are throwing fits and I've already heard that this breaks the build on Arch, and also breaks the debug-info tests. I'll have all this sorted out tomorrow. Thanks for your patience. -Brian From banderson at mozilla.com Wed Apr 10 23:20:41 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 10 Apr 2013 23:20:41 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: References: <5165EE69.4000109@mozilla.com> Message-ID: <51665639.7010805@mozilla.com> On 04/10/2013 05:25 PM, Erick Tryzelaar wrote: > Great! We've needed something like this. I worry a little bit about > the function declaration style though. I could see it being difficult > to implement this format in the pretty printer, which would make it > hard to write something like gofix. Here's the longest function > declaration I could find in our codebase, this one in > src/librustc/middle/typeck/infer/unify.rs : > > fn simple_vars Eq + Vid + ToStr + UnifyVid>>(&mut self, +a_is_expected: > bool, +a_id: V, +b_id: V) -> ures { > > Assuming we extended the rule to the typarams, we'd have: > > fn simple_vars V:Copy + Eq + Vid + ToStr + > UnifyVid>>(&mut self, > +a_is_expected: bool, > +a_id: V, > +b_id: V) > -> ures { This indentation looks pretty crazy here because I see a non-monospace font, but your point about type parameters is well-taken. We were not considering them. > > Which in my opinion is hard to read. Then there's the question of what > happens if even after wrapping the line pushes us past the 100 > character limit? > > For my bikeshed, I have started using the basic rule that if I can't > fit a statement on one line, I wrap and indent 4 spaces after a '<', > '(', or '{': > > fn simple_vars< > T:Copy + Eq + InferStr + SimplyUnifiable, > V:Copy + Eq + Vid + ToStr + UnifyVid> > >( > &mut self, > +a_is_expected: bool, > +a_id: V, > +b_id: V > ) -> ures { I like this style as well. It wasn't so popular in a straw vote. > Another option is to do what Go does, and say there's no limit in the > line length, but if the user wants to wrap, just add a tab to the > start of the next line. So it could look something like this > > fn simple_vars< > T:Copy + Eq + InferStr + SimplyUnifiable, > V:Copy + Eq + Vid + ToStr + UnifyVid>>(&mut self, > +a_is_expected: bool, +a_id: V, +b_id: V) > -> ures { > > It's a little ugly, but it's consistent, and really easy to implement > with a pretty printer. Here are the Go rules: > > http://golang.org/doc/effective_go.html#formatting > > I personally don't care what style we use, I just want to make sure we > choose a style that's easy to automate so we can move on with our lives. > > > > On Wed, Apr 10, 2013 at 3:57 PM, Brian Anderson > wrote: > > There have been a few mentions recently about writing up the Rust > coding standards. Several of us sat in a room and tried to > identify and agree on some that we thought were important. I've > pasted the resulting notes into the wiki: > > https://github.com/mozilla/rust/wiki/Note-style-guide > > These are very, very rough but cover a number of topics. Comments > and suggestions are welcome. These need to be cleaned up into > readable prose, with decent examples, and moved from the 'Notes' > section of the wiki to the 'Docs' section where users will find > them. Help is definitely appreciated. > > -Brian > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Wed Apr 10 23:28:07 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 10 Apr 2013 23:28:07 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: <516605D6.209@alum.mit.edu> References: <5165EE69.4000109@mozilla.com> <516605D6.209@alum.mit.edu> Message-ID: <516657F7.7020905@mozilla.com> On 04/10/2013 05:37 PM, Niko Matsakis wrote: > Hi guys, > > I guess it is time to adopt some consistent standards. > > Since I wasn't in the room, here are my two cents. > > # Function docs > > I prefer putting the function comment *inside* the fn rather than in > front. However, I am probably alone on this point, so I'm prepared to > lose this fight. Anyhow, if we are going to place comments in front > of the function, I think we should encourage `///` comments in favor > of the `/**..*/`. That is, prefer this: > > /// Function comment > /// More function comment > fn foo() { ... } > > To this: > > /** > * Function comment > * More function comment > */ > fn foo() { ... } > > My reasons: > > 1. No wasted lines (unlike /** ... */ which wastes two lines). > 2. If you include a code example inside the `///` comment, you can use > `/* ... */` within the comment without triggering errors. > 3. It just looks better to my eyes ;) I too like the idea of using inner doc comments on functions, though I haven't seen any code that uses them to good effect. We did say to always use line-comments instead of block comments. > > # Module docs > > I like to make long comments on modules sometimes. I've decided these > "book chapter"-like comments ought to be put into a `doc.rs` module, > since it's a pain to scroll down through them. > > # Long function signatures and the opening brace > > Also, we should give more guidance in the event of long function > signatures. Personally, if the first parameter will not fit on the > same line as the function names, I favor moving the opening brace to > its own line, like this: > > fn some_really_long_name( > a: T1, > b: T2) > -> RT > { > ... > } > > The idea is to use the brace at the start of a line to separate code > and signature when they have the same indentation. > > Another relevant example would be what to do if you have a lot of type > parameters and traits. I typically do this: > > fn some_really_long_name V: Another+Set+Of+Traits>( > a: T1, > b: T2) > -> RT > { > ... > } > It sounds like this requires further discussion since the recommended format on the wiki doesn't work well with type parameters as erickt pointed out and you don't like it. > I think similar rules apply to if statements and so forth: > > #Pattern syntax > > I don't like the `|` in front of the patterns. Things don't line up. > When using `|` to combine patterns together, and things don't fit on > one line, my own personal inclination is to follow a style like this: > > match foo { > pat1 | > pat2 => { > ... > } > pat3 | > pat4 => { > ... > } > } > > Here the indentation separates the patterns from everything else. In > cases like this, I never use the non-brace form, since otherwise the > indentation doesn't work. > > I also find I prefer using `{...}` form in cases where the body does > not produce a value, such as: > > match foo { > Some(v) => { return v; } > None => {} > } > > not > > match foo { > Some(v) => return v, > None => {} > }; > > Somehow, the `,` strongly suggests a value is being produced to me. I agree that match arms without braces should only be used with expressiony forms, not statementy. > > # "Ternary operator" If else expressions > > For cases where you would use the ternary operator in C, such as `(foo > ? bar : zed)` I tend to nestle the braces up with the expressions, > like so `if foo {bar} else {zed}`. I find this reads better than `if > foo { bar } else { zed }`. If others disagree, let me know so I can > stop doing it. I'm not a fan of the inconsistency. > > Niko > >> Brian Anderson >> April 10, 2013 3:57 PM >> There have been a few mentions recently about writing up the Rust >> coding standards. Several of us sat in a room and tried to identify >> and agree on some that we thought were important. I've pasted the >> resulting notes into the wiki: >> >> https://github.com/mozilla/rust/wiki/Note-style-guide >> >> These are very, very rough but cover a number of topics. Comments and >> suggestions are welcome. These need to be cleaned up into readable >> prose, with decent examples, and moved from the 'Notes' section of >> the wiki to the 'Docs' section where users will find them. Help is >> definitely appreciated. >> >> -Brian >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: compose-unknown-contact.jpg Type: image/jpeg Size: 770 bytes Desc: not available URL: From banderson at mozilla.com Wed Apr 10 23:32:58 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 10 Apr 2013 23:32:58 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: References: Message-ID: <5166591A.4060802@mozilla.com> On 04/10/2013 07:22 PM, Kang Seonghoon wrote: > I mostly agree to Niko's comments, but I'd like to point out one issue > with function docs. Given the following code: > > ~~~~ > /// This is a doc comment with two paragraphs. > /// > /// Not actually. > pub fn a() { > } > > /** > * This is a doc comment with two paragraphs. > * > * Really. > */ > pub fn b() { > } > ~~~~ > > ...rustdoc produces two paragraphs for `b` but one paragraph for `a` > (behaves as if there are no empty lines). I was assumed that it was by > design until now, but it now feels like a bug. (I'll open an issue if > it is indeed considered a bug.) I consider this a bug. > > Niko Matsakis wrote: >> # Function docs >> >> I prefer putting the function comment *inside* the fn rather than in >> front. However, I am probably alone on this point, so I'm prepared to >> lose this fight. Anyhow, if we are going to place comments in front of >> the function, I think we should encourage `///` comments in favor of the >> `/**..*/`. That is, prefer this: >> >> /// Function comment >> /// More function comment >> fn foo() { ... } >> >> To this: >> >> /** >> * Function comment >> * More function comment >> */ >> fn foo() { ... } >> >> My reasons: >> >> 1. No wasted lines (unlike /** ... */ which wastes two lines). >> 2. If you include a code example inside the `///` comment, you can use >> `/* ... */` within the comment without triggering errors. >> 3. It just looks better to my eyes ;) > -- > -- Kang Seonghoon | Software Engineer, iPlateia Inc. | http://mearie.org/ > -- Opinions expressed in this email do not necessarily represent the > views of my employer. > -- > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From brandon at mintern.net Wed Apr 10 23:33:40 2013 From: brandon at mintern.net (Brandon Mintern) Date: Wed, 10 Apr 2013 23:33:40 -0700 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: <51665639.7010805@mozilla.com> References: <5165EE69.4000109@mozilla.com> <51665639.7010805@mozilla.com> Message-ID: On Wed, Apr 10, 2013 at 11:20 PM, Brian Anderson wrote: > On 04/10/2013 05:25 PM, Erick Tryzelaar wrote: > > Which in my opinion is hard to read. Then there's the question of what > happens if even after wrapping the line pushes us past the 100 character > limit? > > For my bikeshed, I have started using the basic rule that if I can't fit > a statement on one line, I wrap and indent 4 spaces after a '<', '(', or > '{': > > fn simple_vars< > T:Copy + Eq + InferStr + SimplyUnifiable, > V:Copy + Eq + Vid + ToStr + UnifyVid> > >( > &mut self, > +a_is_expected: bool, > +a_id: V, > +b_id: V > ) -> ures { > > > I like this style as well. It wasn't so popular in a straw vote. > > Java style in these situations (function parameters, if/while conditions, etc.) is to indent 8 spaces. I think it actually works pretty well in that it makes it clear that it's a continuation of the previous line while also setting it apart from the lines inside the block. -------------- next part -------------- An HTML attachment was scrubbed... URL: From andres.osinski at gmail.com Wed Apr 10 23:39:46 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Thu, 11 Apr 2013 03:39:46 -0300 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: References: <5165EE69.4000109@mozilla.com> <51665639.7010805@mozilla.com> Message-ID: It's also the same in Python. On Thu, Apr 11, 2013 at 3:33 AM, Brandon Mintern wrote: > On Wed, Apr 10, 2013 at 11:20 PM, Brian Anderson wrote: > >> On 04/10/2013 05:25 PM, Erick Tryzelaar wrote: >> > > >> Which in my opinion is hard to read. Then there's the question of what >> happens if even after wrapping the line pushes us past the 100 character >> limit? >> >> For my bikeshed, I have started using the basic rule that if I can't >> fit a statement on one line, I wrap and indent 4 spaces after a '<', '(', >> or '{': >> >> fn simple_vars< >> T:Copy + Eq + InferStr + SimplyUnifiable, >> V:Copy + Eq + Vid + ToStr + UnifyVid> >> >( >> &mut self, >> +a_is_expected: bool, >> +a_id: V, >> +b_id: V >> ) -> ures { >> >> >> I like this style as well. It wasn't so popular in a straw vote. >> >> > Java style in these situations (function parameters, if/while conditions, > etc.) is to indent 8 spaces. I think it actually works pretty well in that > it makes it clear that it's a continuation of the previous line while also > setting it apart from the lines inside the block. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From fredrik at haard.se Thu Apr 11 07:30:23 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Thu, 11 Apr 2013 16:30:23 +0200 Subject: [rust-dev] String encode/decode In-Reply-To: References: Message-ID: So, I take it no-one is working on codecs, is anyone interested in codecs? I've started prototyping a solution patterned on Python (i.e. a tool to generate specific codec modules from the specs). /fredrik 2013/4/9 Fredrik H??rd > Hi all, > > is anyone working on generic (i.e. iso-*, cp*) string encoding/decoding? > > I googled and looked through the wiki, but apart from the from/to_bytes > and from_to utf-16 I came up with nothing. Are there plans for what it > should look like? > > Also, how come utf-16 has special treatment? > -- > /fredrik > > I reject your reality and substitute my own. > http://courteous.ly/yp3Zgd > -- /f I reject your reality and substitute my own. http://courteous.ly/yp3Zgd -------------- next part -------------- An HTML attachment was scrubbed... URL: From someone at mearie.org Thu Apr 11 08:09:56 2013 From: someone at mearie.org (Kang Seonghoon) Date: Fri, 12 Apr 2013 00:09:56 +0900 Subject: [rust-dev] String encode/decode In-Reply-To: References: Message-ID: I do. See also the issue #4837 for my initial ad-hoc attempt. The inevitable problem here is, of course, whether we should reuse the existing iconv library or make our own. This is also deeply connected to the assumption that `str` only contains a valid UTF-8 string (which some standard modules break, `ReaderUtil::each_line` for instance). Maybe we should start making an wiki page for entire character encoding issues? Note: If you copy Python's design (which is actually quite good compared to many others but not without caveats), try not to copy `Stream{Reader,Writer}` at least. These are mostly replaced by newer `Incremental{Reader,Writer}` which doesn't require streams at all. 2013/4/11 Fredrik H??rd : > So, I take it no-one is working on codecs, is anyone interested in codecs? > I've started prototyping a solution patterned on Python (i.e. a tool to > generate specific codec modules from the specs). > > /fredrik > > > 2013/4/9 Fredrik H??rd >> >> Hi all, >> >> is anyone working on generic (i.e. iso-*, cp*) string encoding/decoding? >> >> I googled and looked through the wiki, but apart from the from/to_bytes >> and from_to utf-16 I came up with nothing. Are there plans for what it >> should look like? >> >> Also, how come utf-16 has special treatment? >> -- >> /fredrik >> >> I reject your reality and substitute my own. >> http://courteous.ly/yp3Zgd > > > > > -- > /f > > I reject your reality and substitute my own. > http://courteous.ly/yp3Zgd > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -- Kang Seonghoon | Software Engineer, iPlateia Inc. | http://mearie.org/ -- Opinions expressed in this email do not necessarily represent the views of my employer. -- From simon.sapin at exyr.org Thu Apr 11 08:24:59 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Thu, 11 Apr 2013 17:24:59 +0200 Subject: [rust-dev] String encode/decode In-Reply-To: References: Message-ID: <5166D5CB.3050203@exyr.org> Le 11/04/2013 16:30, Fredrik H??rd a ?crit : > So, I take it no-one is working on codecs, is anyone interested in codecs? Hi, A while ago I started implementing in Rust the WHATWG Encoding specification: http://encoding.spec.whatwg.org/ In addition to the actual algorithms (and precise error handling), the spec defines a set of labels that should be used for legacy web content. For example, when getting 'Content-Type: text/html;charset=ISO-8859-1', it?s the Windows-1252 encoding that should actually be used. It?s also important that labels *not* on the list are not supported. UTF-7 for example has known security issues. Servo will need this eventually. A general-purpose library might want to support encodings that are not supported on the web, such as UTF-32. One should be careful to provide a separate API, so as not to expose these encodings to the web. My implementation is very much incomplete and kind of abandoned at the moment. I expect to start working on it again in the next few months. If someone wants to take it up in the meantime, feel free to do so. Or start from scratch, there really isn?t much there. https://github.com/SimonSapin/rust-webencodings > I've started prototyping a solution patterned on Python (i.e. a tool to > generate specific codec modules from the specs). What does "patterned on Python" mean? -- Simon Sapin From a.stavonin at gmail.com Thu Apr 11 11:58:38 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Thu, 11 Apr 2013 22:58:38 +0400 Subject: [rust-dev] Crossplatform compatibility Message-ID: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> Hi! I'm going to create Rust installation package for Mac OS X. Right now you can find the installer there: http://www.sysdev.me/public/RustInstaller.pkg.zip But... I've build the installer on 10.8 and when I'm running it on 10.7 result is: Segmentation fault: 11 Is it possible to build Rust on 10.8 and run it on other 10.x systems? Regards, Alexander From steve at steveklabnik.com Thu Apr 11 12:04:12 2013 From: steve at steveklabnik.com (Steve Klabnik) Date: Thu, 11 Apr 2013 12:04:12 -0700 Subject: [rust-dev] Crossplatform compatibility In-Reply-To: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> References: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> Message-ID: > Is it possible to build Rust on 10.8 and run it on other 10.x systems? OSX :( I don't know about Rust's specifics, but I have dealt with this kind of thing before, and it's safest to do the builds on the oldest version of OSX you support and then share upwards, rather than downwards... it's possible you built in with something that's optional and 10.8 only. Again, unsure about Rust, just what I've seen with some other projects. From fredrik at haard.se Thu Apr 11 13:31:50 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Thu, 11 Apr 2013 22:31:50 +0200 Subject: [rust-dev] String encode/decode In-Reply-To: References: Message-ID: 2013/4/11 Kang Seonghoon > I do. See also the issue #4837 for my initial ad-hoc attempt. > > The inevitable problem here is, of course, whether we should reuse the > existing iconv library or make our own. iconv is dependent on locales on Unix / mingw on Windows I believe? This is also deeply connected > to the assumption that `str` only contains a valid UTF-8 string (which > some standard modules break, `ReaderUtil::each_line` for instance). > That str only contains valid UTF-8 is good assumption (and rule) I believe; to me it seems Python 3 got that right and Rust could use the same pattern of str vs [u8]. I'm not sure that I see the problem here. > Maybe we should start making an wiki page for entire character > encoding issues? > +1 > Note: If you copy Python's design (which is actually quite good > compared to many others but not without caveats), try not to copy > `Stream{Reader,Writer}` at least. These are mostly replaced by newer > `Incremental{Reader,Writer}` which doesn't require streams at all. > Right now my goal is just to create a charmap from the specification, and start with creating a codec that can handle u8<->char. I need to get a much better feel for Rust/stdlib before I have a solid opinion on high-level design choices. /fredrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From fredrik at haard.se Thu Apr 11 13:35:57 2013 From: fredrik at haard.se (=?UTF-8?B?RnJlZHJpayBIw6XDpXJk?=) Date: Thu, 11 Apr 2013 22:35:57 +0200 Subject: [rust-dev] String encode/decode In-Reply-To: <5166D5CB.3050203@exyr.org> References: <5166D5CB.3050203@exyr.org> Message-ID: 2013/4/11 Simon Sapin > Le 11/04/2013 16:30, Fredrik H??rd a ?crit : > > So, I take it no-one is working on codecs, is anyone interested in codecs? >> > > Hi, > > A while ago I started implementing in Rust the WHATWG Encoding > specification: > > http://encoding.spec.whatwg.**org/ > Sorry if I was unclear; I meant a general-purpose codec for handling ftp://ftp.unicode.org/Public/MAPPINGS/** more or less. Web stuff is out of scope for what I intend here (Although my 'penultimate' goal is to be able to implement MIME so that email handling can be implemented). I've started prototyping a solution patterned on Python (i.e. a tool to > generate specific codec modules from the specs). > What does "patterned on Python" mean? > I meant 'following the same pattern as Python'. Might mean something else or nothing at all though, I'm not a native English speaker =) /fredrik -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeremy at jeremyhuffman.com Thu Apr 11 14:36:48 2013 From: jeremy at jeremyhuffman.com (Jeremy Huffman) Date: Thu, 11 Apr 2013 17:36:48 -0400 Subject: [rust-dev] Scheduling for blocking foreign calls Message-ID: Hi, I am considering Rust for a particular use case in which I would be doing lots of concurrent requests that would spend most of their time blocked on network I/O in foreign C calls. I may be mistaken but I think a task that blocks like this would block any other tasks on the same scheduler - is that correct? What would perhaps be a good solution would be something like a task pool in which each task runs in a separate OS thread - is there a straightforward way to achieve this? Thanks, Jeremy -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Thu Apr 11 14:38:43 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 11 Apr 2013 14:38:43 -0700 Subject: [rust-dev] Scheduling for blocking foreign calls In-Reply-To: References: Message-ID: <51672D63.9010908@mozilla.com> On 4/11/13 2:36 PM, Jeremy Huffman wrote: > Hi, > > I am considering Rust for a particular use case in which I would be > doing lots of concurrent requests that would spend most of their time > blocked on network I/O in foreign C calls. I may be mistaken but I > think a task that blocks like this would block any other tasks on the > same scheduler - is that correct? What would perhaps be a good solution > would be something like a task pool in which each task runs in a > separate OS thread - is there a straightforward way to achieve this? There is `std::task_pool` for this purpose. There is an example of this use case in the test case in that file. Patrick From jarred at webkit.org Thu Apr 11 18:51:54 2013 From: jarred at webkit.org (Jarred Nicholls) Date: Thu, 11 Apr 2013 21:51:54 -0400 Subject: [rust-dev] Crossplatform compatibility In-Reply-To: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> References: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> Message-ID: On Thu, Apr 11, 2013 at 2:58 PM, Alexander Stavonin wrote: > Hi! > I'm going to create Rust installation package for Mac OS X. Right now you > can find the installer there: > http://www.sysdev.me/public/RustInstaller.pkg.zip > But... I've build the installer on 10.8 and when I'm running it on 10.7 > result is: > > Segmentation fault: 11 > > Is it possible to build Rust on 10.8 and run it on other 10.x systems? > That's a fair question. A Mach-O binary has a load command that specifies the minimum version of OS X it supports, and is settable by Apple's gcc/clang front end by passing the flag -mmacosx-version-min. I don't know what level of control we are given by rustc for such things, so I'm interested in the answer to this as well. > > Regards, > Alexander > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Apr 11 22:51:35 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 11 Apr 2013 22:51:35 -0700 Subject: [rust-dev] Crossplatform compatibility In-Reply-To: References: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> Message-ID: <5167A0E7.4000109@mozilla.com> On 04/11/2013 06:51 PM, Jarred Nicholls wrote: > On Thu, Apr 11, 2013 at 2:58 PM, Alexander Stavonin > > wrote: > > Hi! > I'm going to create Rust installation package for Mac OS X. Right > now you can find the installer there: > http://www.sysdev.me/public/RustInstaller.pkg.zip > But... I've build the installer on 10.8 and when I'm running it on > 10.7 result is: > > Segmentation fault: 11 > > Is it possible to build Rust on 10.8 and run it on other 10.x systems? > > > That's a fair question. A Mach-O binary has a load command that > specifies the minimum version of OS X it supports, and is settable by > Apple's gcc/clang front end by passing the flag -mmacosx-version-min. > I don't know what level of control we are given by rustc for such > things, so I'm interested in the answer to this as well. > I don't know exactly how this works, but rustc currently uses gcc or clang to link crates so conceivably this flag could usefully be added to the linking command line. Unfortunately I can't think of a way off hand to thread custom linker flags through the entire build. It would require first adding a command line switch to rustc to pass arbitrary flags to the 'linker', then modifying the Makefiles to pass custom flags to all the build steps. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Fri Apr 12 07:48:56 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Fri, 12 Apr 2013 10:48:56 -0400 Subject: [rust-dev] Another language that's implementing a custom GC strategy on top of LLVM Message-ID: Browsing the web today I found this short article on the Epoch programming language: https://code.google.com/p/epoch-language/wiki/GarbageCollectionScheme I'm not a GC expert so I'm not sure if it has any applicability to Rust, but perhaps someone will find it interesting. -------------- next part -------------- An HTML attachment was scrubbed... URL: From a.stavonin at gmail.com Fri Apr 12 08:13:50 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Fri, 12 Apr 2013 19:13:50 +0400 Subject: [rust-dev] Crossplatform compatibility In-Reply-To: References: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> Message-ID: Looks like same flag (if the reason if missed flag) also have to be passed in case of Rust developed programs compilation. I've made simple test: fn main() { io::println("Hellow world") } Compiled it on 10.8 and runed on 10.7. The result is: Illegal instruction: 4 2013/4/12 Jarred Nicholls > On Thu, Apr 11, 2013 at 2:58 PM, Alexander Stavonin wrote: > >> Hi! >> I'm going to create Rust installation package for Mac OS X. Right now you >> can find the installer there: >> http://www.sysdev.me/public/RustInstaller.pkg.zip >> But... I've build the installer on 10.8 and when I'm running it on 10.7 >> result is: >> >> Segmentation fault: 11 >> >> Is it possible to build Rust on 10.8 and run it on other 10.x systems? >> > > That's a fair question. A Mach-O binary has a load command that specifies > the minimum version of OS X it supports, and is settable by Apple's > gcc/clang front end by passing the flag -mmacosx-version-min. I don't know > what level of control we are given by rustc for such things, so I'm > interested in the answer to this as well. > > >> >> Regards, >> Alexander >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Fri Apr 12 08:25:57 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 12 Apr 2013 08:25:57 -0700 Subject: [rust-dev] Another language that's implementing a custom GC strategy on top of LLVM In-Reply-To: References: Message-ID: <51682785.6050308@mozilla.com> On 4/12/13 7:48 AM, Benjamin Striegel wrote: > Browsing the web today I found this short article on the Epoch > programming language: > > https://code.google.com/p/epoch-language/wiki/GarbageCollectionScheme > > I'm not a GC expert so I'm not sure if it has any applicability to Rust, > but perhaps someone will find it interesting. It's using register spilling (a.k.a. the llvm.gcroot intrinsics). We considered this, but it would impose a significant cost on runtime performance over the conservative GC or a precise GC that allows roots to live in registers (e.g. OCaml, V8, SpiderMonkey, .NET, Java). I think that, before we consider precise-on-the-stack GC, we should fix this problem at the LLVM level. Patrick From jarred at webkit.org Fri Apr 12 08:26:19 2013 From: jarred at webkit.org (Jarred Nicholls) Date: Fri, 12 Apr 2013 11:26:19 -0400 Subject: [rust-dev] Crossplatform compatibility In-Reply-To: References: <1EE473D6-0CF5-4448-903C-613AE8C54F1F@gmail.com> Message-ID: On Fri, Apr 12, 2013 at 11:13 AM, Alexander Stavonin wrote: > Looks like same flag (if the reason if missed flag) also have to be passed in > case of Rust developed programs compilation. I've made simple test: > > fn main() { > io::println("Hellow world") > } > > Compiled it on 10.8 and runed on 10.7. The result is: > > Illegal instruction: 4 > In (Obj-)C(++) world, the flag is passed to the compiler for every object file compilation, in addition to the final link. I do believe if the target min version is inconsistent during any part of the process, the result will be these types of load errors. > > > 2013/4/12 Jarred Nicholls > >> On Thu, Apr 11, 2013 at 2:58 PM, Alexander Stavonin > > wrote: >> >>> Hi! >>> I'm going to create Rust installation package for Mac OS X. Right now >>> you can find the installer there: >>> http://www.sysdev.me/public/RustInstaller.pkg.zip >>> But... I've build the installer on 10.8 and when I'm running it on 10.7 >>> result is: >>> >>> Segmentation fault: 11 >>> >>> Is it possible to build Rust on 10.8 and run it on other 10.x systems? >>> >> >> That's a fair question. A Mach-O binary has a load command that >> specifies the minimum version of OS X it supports, and is settable by >> Apple's gcc/clang front end by passing the flag -mmacosx-version-min. I >> don't know what level of control we are given by rustc for such things, so >> I'm interested in the answer to this as well. >> >> >>> >>> Regards, >>> Alexander >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at dhardy.name Fri Apr 12 07:47:32 2013 From: lists at dhardy.name (Diggory Hardy) Date: Fri, 12 Apr 2013 16:47:32 +0200 Subject: [rust-dev] automatic dereferences and semicolons Message-ID: <1447610.FFiMCI3ifm@l10036> Hello list (new here), May I comment on a post from this Monday? Heri Sim posted: > 1st, dereferencing should be automatic everywhere. > Running a pattern match on borrowed boxes should NOT require an asterisk > (*). > Passing in a stack-local variable to a function or closure (that > requires arguments to be passed by reference), should not require the > ampersand (&) in the caller. Why can't the compiler figure this out? I agree with the majority on the list that requiring use of the ampersand when calling is a useful feature, but why not automatic dereferencing everywhere? There are two problems with this, namely comparison and assignment. For the former, I think D really got it right with `x is y` to compare references and `x == y` to compare objects/boxes. In the case of references to references (e.g. ~@int) it would have to be decided which references were compared by "is", but in any case "&" can be used to get a reference to compare. Assignment could similarly be done with a new syntax to *assign to the box referenced by* a pointer, e.g. x <- y. Unfortunately that doesn't cover multiple levels of boxing. An alternative might be not auto-dereferencing assignment targets or use of `&x` to "undo" a level of dereferencing (instead of merely take the address of): let mut a : ~int = ~1 a = 2 // assign to box &a = ~3 // assign to reference I'm not quite sure about assignments but for other cases this seems beneficial to me (especially since it avoids most of the syntax changes involved in replacing an unboxed parameter with a boxed parameter). Second thing: why are semicolons required at the end of lines at all? Go, Scala etc. manage fine without. Diggory From hatahet at gmail.com Fri Apr 12 15:13:58 2013 From: hatahet at gmail.com (Ziad Hatahet) Date: Fri, 12 Apr 2013 15:13:58 -0700 Subject: [rust-dev] automatic dereferences and semicolons In-Reply-To: <1447610.FFiMCI3ifm@l10036> References: <1447610.FFiMCI3ifm@l10036> Message-ID: Second thing: why are semicolons required at the end of lines at all? Go, > Scala etc. manage fine without. > > Go has some weird edge cases due to semi-colon insertion. I don't know if Scala managed to prevent those though. -- Ziad -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Apr 12 16:55:27 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 12 Apr 2013 16:55:27 -0700 Subject: [rust-dev] automatic dereferences and semicolons In-Reply-To: <1447610.FFiMCI3ifm@l10036> References: <1447610.FFiMCI3ifm@l10036> Message-ID: <51689EEF.80508@mozilla.com> On 13-04-12 07:47 AM, Diggory Hardy wrote: > Hello list (new here), > > May I comment on a post from this Monday? Sure. But I ought to point out: we're in a "stabilizing and finalizing" phase with the language now -- picking through corner cases and remaining internal contradictions. Broad reorganization of assignment, equality and argument-passing is out of scope at this point. These ships sailed a year or two ago. > I agree with the majority on the list that requiring use of the ampersand when > calling is a useful feature, but why not automatic dereferencing everywhere? > There are two problems with this, namely comparison and assignment. We auto-dereference on . (dot) already since it can't be overridden; most other operators we allow overriding, and those have the option of dereferencing when applied to pointers. Many do. > For the former, I think D really got it right with `x is y` to compare > references and `x == y` to compare objects/boxes. In the case of references to > references (e.g. ~@int) it would have to be decided which references were > compared by "is", but in any case "&" can be used to get a reference to > compare. There are plenty of strategies for comparing. We permit overriding operator == for this reason. Adding another operator like 'is' doesn't seem like it'll make things more clear (memories of eq? eqv? and equal? from lisp). I'd prefer adding a PtrEq trait with .ptr_eq() for @, ~ and & types. > Second thing: why are semicolons required at the end of lines at all? Go, > Scala etc. manage fine without. Most such rules wind up either whitespace sensitive or requiring a bunch of lookahead. We don't want either of those. This is a major bikeshed that _everyone_ has an opinion on; absent a syntactic ambiguity or error in our existing rules, we're going to leave it alone. -Graydon From lists at dhardy.name Mon Apr 15 01:53:42 2013 From: lists at dhardy.name (Diggory Hardy) Date: Mon, 15 Apr 2013 10:53:42 +0200 Subject: [rust-dev] automatic dereferences and semicolons In-Reply-To: <51689EEF.80508@mozilla.com> References: <1447610.FFiMCI3ifm@l10036> <51689EEF.80508@mozilla.com> Message-ID: <1670159.t98T4AN7C8@l10036> On Friday 12 April 2013 16:55:27 Graydon Hoare wrote: > On 13-04-12 07:47 AM, Diggory Hardy wrote: > > Hello list (new here), > > > > May I comment on a post from this Monday? > > Sure. But I ought to point out: we're in a "stabilizing and finalizing" > phase with the language now -- picking through corner cases and > remaining internal contradictions. Broad reorganization of assignment, > equality and argument-passing is out of scope at this point. These ships > sailed a year or two ago. I expected that. Guess I am mostly just curious. You're right to point out that both issues are "bike sheds" with no clear best. (The semi-colon thing can be solved without syntactic ambiguity, e.g. closer to how shells work: require escapes or wrapping with an extra set of parenthesis when statements do not finish at the end of the line. But I am not suggesting you change this now.) -Diggory From a.stavonin at gmail.com Mon Apr 15 02:46:28 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Mon, 15 Apr 2013 13:46:28 +0400 Subject: [rust-dev] Range vector initialization Message-ID: I always thought that it is possible to write next code: let box_box = ~[1 .. 5]; And obtain the vector with [1, 2, 3, 4, 5], but it doesn't works. What is the simplest way to do it? -------------- next part -------------- An HTML attachment was scrubbed... URL: From someone at mearie.org Mon Apr 15 03:22:22 2013 From: someone at mearie.org (Kang Seonghoon) Date: Mon, 15 Apr 2013 19:22:22 +0900 Subject: [rust-dev] Range vector initialization In-Reply-To: References: Message-ID: There are several possible ways to do that. For example, using `vec::from_fn`: ~~~~ // prints `~[1, 2, 3, 4, 5]` io::println(fmt!("%?", vec::from_fn(5, |x| x+1))) ~~~~ This has a caveat that you should cast to the target type if your vector is not `~[uint]`. In that case, you can also use `vec::build` and `::range`: ~~~~ // prints `~[1, 2, 3, 4, 5]` let v = do vec::build |push| { for int::range(1, 6) |i| { push(i); } }; ~~~~ ...which can be a bit annoying if you need more of them. Ideally we may be able to use `vec::range::(1, 6)` which is exactly equivalent to that, but it is not yet there. 2013/4/15 Alexander Stavonin : > I always thought that it is possible to write next code: > > let box_box = ~[1 .. 5]; > > And obtain the vector with [1, 2, 3, 4, 5], but it doesn't works. What is > the simplest way to do it? > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -- Kang Seonghoon | Software Engineer, iPlateia Inc. | http://mearie.org/ -- Opinions expressed in this email do not necessarily represent the views of my employer. -- From danielmicay at gmail.com Mon Apr 15 03:33:59 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Mon, 15 Apr 2013 06:33:59 -0400 Subject: [rust-dev] Range vector initialization In-Reply-To: References: Message-ID: On Mon, Apr 15, 2013 at 6:22 AM, Kang Seonghoon wrote: > > ...which can be a bit annoying if you need more of them. Ideally we > may be able to use `vec::range::(1, 6)` which is exactly > equivalent to that, but it is not yet there. Containers should implement a way to constructor them from iterator objects, which range would be. From graydon at mozilla.com Mon Apr 15 07:55:19 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 15 Apr 2013 07:55:19 -0700 Subject: [rust-dev] automatic dereferences and semicolons In-Reply-To: <1670159.t98T4AN7C8@l10036> References: <1447610.FFiMCI3ifm@l10036> <51689EEF.80508@mozilla.com> <1670159.t98T4AN7C8@l10036> Message-ID: <516C14D7.2070808@mozilla.com> On 15/04/2013 1:53 AM, Diggory Hardy wrote: > The semi-colon thing > can be solved without syntactic ambiguity, e.g. closer to how shells work: > require escapes or wrapping with an extra set of parenthesis when statements > do not finish at the end of the line. Yeah. We've been over (and over and over and over) the way these rules work in other languages. As I said, the variant you're describing introduces whitespace sensitivity to the grammar (newline is whitespace); we'd prefer not to do that. -Graydon From artella.coding at googlemail.com Sun Apr 14 10:06:56 2013 From: artella.coding at googlemail.com (Artella Coding) Date: Sun, 14 Apr 2013 18:06:56 +0100 Subject: [rust-dev] Non additive execution time scaling Message-ID: Hi, suppose I have : 1)first.rs calls function "first" 2)second.rs calls function "second" 3)firstAndSecond.rs calls function "first" followed by function "second" Then I would expect (ignoring "startup" times) that: TimeToRun( firstAndSecond.rs) = TimeToRun( first.rs) + TimeToRun( second.rs) However instead I find that : TimeToRun( firstAndSecond.rs) > TimeToRun( first.rs) + TimeToRun( second.rs) Specifically : TimeToRun( first.rs) = real 0m2.631s TimeToRun( second.rs) = real 0m5.739s TimeToRun( firstAndSecond.rs) = real 0m23.856s I cannot quite work out why this might be the case (and I dont think it is to do with startup times). Note I compile the programs as follows : rustc first.rs rustc second.rs rustc firstAndSecond.rs Note that when you profile the programs, "firstAndSecond" looks a bit strange in that there are library calls which are absent when one profiles first or second. The programs are given below : ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** //first.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn first(n: i64, x0 : float, r: float) -> float { let mut x = x0; let mut i = 0i64; loop { x = r*x*(1.-x); i += 1; if i == n { break } } x } fn second(n: i64, x0 : float, r: float) -> float { fn calc(x : float, r: float) -> float { let mut xm = x; xm = r*xm*(1.-xm); xm } let mut x = x0; let mut i = 0i64; loop { x = calc(x,r); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = first(l,g_x0,g_r); io::println(float::to_str(result)); } ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** //second.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn first(n: i64, x0 : float, r: float) -> float { let mut x = x0; let mut i = 0i64; loop { x = r*x*(1.-x); i += 1; if i == n { break } } x } fn second(n: i64, x0 : float, r: float) -> float { fn calc(x : float, r: float) -> float { let mut xm = x; xm = r*xm*(1.-xm); xm } let mut x = x0; let mut i = 0i64; loop { x = calc(x,r); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = second(l,g_x0,g_r); io::println(float::to_str(result)); } ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** //firstAndSecond.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn first(n: i64, x0 : float, r: float) -> float { let mut x = x0; let mut i = 0i64; loop { x = r*x*(1.-x); i += 1; if i == n { break } } x } fn second(n: i64, x0 : float, r: float) -> float { fn calc(x : float, r: float) -> float { let mut xm = x; xm = r*xm*(1.-xm); xm } let mut x = x0; let mut i = 0i64; loop { x = calc(x,r); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = first(l,g_x0,g_r); io::println(float::to_str(result)); let result = second(l,g_x0,g_r); io::println(float::to_str(result)); } ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Mon Apr 15 15:50:17 2013 From: pnkfelix at mozilla.com (Felix Klock) Date: Mon, 15 Apr 2013 15:50:17 -0700 (PDT) Subject: [rust-dev] Non additive execution time scaling In-Reply-To: Message-ID: <116848820.10333451.1366066217403.JavaMail.root@mozilla.com> Artella (cc'ing rust-dev)- It is an interesting phenomenon that you note. I think it is arising from the fact that you have *two* expressions of the form io::println(float::to_str(...)) in the main fn from firstAndSecond.rs, while each of the other two rs files have only one expression of the form io::println(float::to_str(..)). In fact, when I revised your fn main from firstAndSecond.rs to look like this: fn main(){ let l = 400000000i64; let result = first(l,g_x0,g_r); // io::println(float::to_str(result)); let result2 = second(l,g_x0,g_r); // io::println(float::to_str(result2)); io::println(fmt!("%s\n%s", float::to_str(result), float::to_str(result2))); } then the running time dropped back down to something more closely approximating the sum of first and second: % time ./first 0.507920831295682972950089606456458568572998046875 real 0m1.795s user 0m1.791s sys 0m0.003s % time ./second 0.507920831295682972950089606456458568572998046875 real 0m5.150s user 0m5.144s sys 0m0.005s % time ./firstAndSecond 0.507920831295682972950089606456458568572998046875 0.507920831295682972950089606456458568572998046875 real 0m6.941s user 0m6.933s sys 0m0.007s Of course, this is not what you wrote, since presumably the user would like to get feed back about the first step completing without waiting for the longer second step. I am not sure why fusing your two io::println calls into one seems to resolve this issue. (There are many potential places to look, though; such as how expensive flushing the port might be? Or whether there is some state that needs to be cleaned up on the second call to io::println? But really, I am just guessing.) Anyway, I just thought I'd share what little I had discovered after playing with your code. Cheers, -Felix ----- Original Message ----- From: "Artella Coding" To: rust-dev at mozilla.org Sent: Sunday, April 14, 2013 7:06:56 PM Subject: [rust-dev] Non additive execution time scaling Hi, suppose I have : 1) first.rs calls function "first" 2) second.rs calls function "second" 3)firstAndSecond.rs calls function "first" followed by function "second" Then I would expect (ignoring "startup" times) that: TimeToRun( firstAndSecond.rs) = TimeToRun( first.rs ) + TimeToRun( second.rs ) However instead I find that : TimeToRun( firstAndSecond.rs) > TimeToRun( first.rs ) + TimeToRun( second.rs ) Specifically : TimeToRun( first.rs ) = real 0m2.631s TimeToRun( second.rs ) = real 0m5.739s TimeToRun( firstAndSecond.rs) = real 0m23.856s I cannot quite work out why this might be the case (and I dont think it is to do with startup times). Note I compile the programs as follows : rustc first.rs rustc second.rs rustc firstAndSecond.rs Note that when you profile the programs, "firstAndSecond" looks a bit strange in that there are library calls which are absent when one profiles first or second. The programs are given below : ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** // first.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn first(n: i64, x0 : float, r: float) -> float { let mut x = x0; let mut i = 0i64; loop { x = r*x*(1.-x); i += 1; if i == n { break } } x } fn second(n: i64, x0 : float, r: float) -> float { fn calc(x : float, r: float) -> float { let mut xm = x; xm = r*xm*(1.-xm); xm } let mut x = x0; let mut i = 0i64; loop { x = calc(x,r); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = first(l,g_x0,g_r); io::println(float::to_str(result)); } ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** // second.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn first(n: i64, x0 : float, r: float) -> float { let mut x = x0; let mut i = 0i64; loop { x = r*x*(1.-x); i += 1; if i == n { break } } x } fn second(n: i64, x0 : float, r: float) -> float { fn calc(x : float, r: float) -> float { let mut xm = x; xm = r*xm*(1.-xm); xm } let mut x = x0; let mut i = 0i64; loop { x = calc(x,r); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = second(l,g_x0,g_r); io::println(float::to_str(result)); } ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** //firstAndSecond.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn first(n: i64, x0 : float, r: float) -> float { let mut x = x0; let mut i = 0i64; loop { x = r*x*(1.-x); i += 1; if i == n { break } } x } fn second(n: i64, x0 : float, r: float) -> float { fn calc(x : float, r: float) -> float { let mut xm = x; xm = r*xm*(1.-xm); xm } let mut x = x0; let mut i = 0i64; loop { x = calc(x,r); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = first(l,g_x0,g_r); io::println(float::to_str(result)); let result = second(l,g_x0,g_r); io::println(float::to_str(result)); } ******************************************************************************** ******************************************************************************** ******************************************************************************** ******************************************************************************** _______________________________________________ Rust-dev mailing list Rust-dev at mozilla.org https://mail.mozilla.org/listinfo/rust-dev From artella.coding at googlemail.com Mon Apr 15 16:45:19 2013 From: artella.coding at googlemail.com (Artella Coding) Date: Tue, 16 Apr 2013 00:45:19 +0100 Subject: [rust-dev] Non additive execution time scaling In-Reply-To: <968717829.10332252.1366065318616.JavaMail.root@mozilla.com> References: <968717829.10332252.1366065318616.JavaMail.root@mozilla.com> Message-ID: Hi Felix, Thanks for your response. That is an interest observation you made about the println functon. Upon playing with the code a bit more, I noticed that the strange behaviour seems to be limited to the function "second". The distinguishing feature of this function is that it involves a nested function. I have rewritten the codes to only involve a single function in each source file (in order to illustrate this better) & the source and results are below (to call the functions twice just uncomment the last few lines I have commented out in each program) : firstAndFirst.rs 1)Call "first" once : 4.5s 2)Call "first" twice : 9.4s secondAndSecond.rs (nested function call_ 1)Call "second" once : 9.5s 2)Call "second" twice : 43.8s (--> I would have expected this to be 19s <--) ********************************************************************************* ********************************************************************************* //firstAndFirst.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn first(n: i64, x0 : float, r: float) -> float { let mut x = x0; let mut i = 0i64; loop { x = r*x*(1.-x); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = first(l,g_x0,g_r); io::println(float::to_str(result)); //let result2 = first(l,g_x0,g_r); //io::println(float::to_str(result2)); } ********************************************************************************* ********************************************************************************* //secondAndSecond.rs static g_r: float = 3.569956; static g_x0:float = 0.53; fn second(n: i64, x0 : float, r: float) -> float { fn calc(x : float, r: float) -> float { let mut xm = x; xm = r*xm*(1.-xm); xm } let mut x = x0; let mut i = 0i64; loop { x = calc(x,r); i += 1; if i == n { break } } x } fn main(){ let l = 400000000i64; let result = second(l,g_x0,g_r); io::println(float::to_str(result)); //let result2 = second(l,g_x0,g_r); //io::println(float::to_str(result2)); } ********************************************************************************* ********************************************************************************* -------------- next part -------------- An HTML attachment was scrubbed... URL: From pshagl007 at gmail.com Tue Apr 16 02:27:42 2013 From: pshagl007 at gmail.com (piyush agarwal) Date: Tue, 16 Apr 2013 14:57:42 +0530 Subject: [rust-dev] core dumped in rust Message-ID: Hi all, I encountered the following error during execution of my code: : exchange heap not empty on on exit10 dangling allocations Aborted (core dumped) what could be the possible causes?? Please don?t print this e-mail unless you really need to! -------------- next part -------------- An HTML attachment was scrubbed... URL: From eddycizeron at gmail.com Tue Apr 16 02:53:05 2013 From: eddycizeron at gmail.com (Eddy Cizeron) Date: Tue, 16 Apr 2013 11:53:05 +0200 Subject: [rust-dev] About a "protected" visibility modifier Message-ID: Hi everyone I was thinking: wouldn't it be useful if rust also had a "protected" visibility modifier for struct fields with the following meaning: A protected field in a structure type T is accessible wherever a private one would be as well as in any implementation of a trait for type T. Just an idea. -- Eddy Cizeron -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Tue Apr 16 03:08:44 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 16 Apr 2013 06:08:44 -0400 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: On Tue, Apr 16, 2013 at 5:53 AM, Eddy Cizeron wrote: > > Hi everyone > > I was thinking: wouldn't it be useful if rust also had a "protected" > visibility modifier for struct fields with the following meaning: > A protected field in a structure type T is accessible wherever a private one > would be as well as in any implementation of a trait for type T. > > Just an idea. > > -- > Eddy Cizeron What use case do you have in mind for using a protected field instead of a public one? The use case for a private field is separating implementation details from the external API and upholding invariants. Although it's *possible* to safely access them in an external module by using an unsafe block, if you took into account all of the implementation details and invariants of the type. From jon.mb at proinbox.com Tue Apr 16 03:28:38 2013 From: jon.mb at proinbox.com (John Mija) Date: Tue, 16 Apr 2013 11:28:38 +0100 Subject: [rust-dev] Grouping declarations In-Reply-To: <1670159.t98T4AN7C8@l10036> References: <1447610.FFiMCI3ifm@l10036> <51689EEF.80508@mozilla.com> <1670159.t98T4AN7C8@l10036> Message-ID: <516D27D6.4070206@proinbox.com> Since the low level libraries usually have many constants, it would be great whether multiple constants and variables could be grouped using parenthesis. Now: static a = 1; static b = 35; static c = 120; Using parenthesis: static ( a = 1; b = 35; c = 120; ) From asb at asbradbury.org Tue Apr 16 03:33:31 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Tue, 16 Apr 2013 11:33:31 +0100 Subject: [rust-dev] Grouping declarations In-Reply-To: <516D27D6.4070206@proinbox.com> References: <1447610.FFiMCI3ifm@l10036> <51689EEF.80508@mozilla.com> <1670159.t98T4AN7C8@l10036> <516D27D6.4070206@proinbox.com> Message-ID: On 16 April 2013 11:28, John Mija wrote: > Since the low level libraries usually have many constants, it would be great > whether multiple constants and variables could be grouped using parenthesis. > > Now: > > static a = 1; > static b = 35; > static c = 120; > > Using parenthesis: > > static ( > a = 1; > b = 35; > c = 120; > ) Wouldn't `static a=1, b=35, c=120;` make more sense and match `let a=1, b=25, c=120;'? Alex From jon.mb at proinbox.com Tue Apr 16 03:40:33 2013 From: jon.mb at proinbox.com (John Mija) Date: Tue, 16 Apr 2013 11:40:33 +0100 Subject: [rust-dev] Grouping declarations In-Reply-To: References: <1447610.FFiMCI3ifm@l10036> <51689EEF.80508@mozilla.com> <1670159.t98T4AN7C8@l10036> <516D27D6.4070206@proinbox.com> Message-ID: <516D2AA1.4090009@proinbox.com> That way (a) does not allow comment out a declaration *easily* and (b) it is not useful for more than 10 or 20 multiple declarations. static ( a = 1; //b = 35; c = 120; ) so the code will always be clearer vs static a=1, /*b=35,*/ c=120; El 16/04/13 11:33, Alex Bradbury escribi?: > On 16 April 2013 11:28, John Mija wrote: >> Since the low level libraries usually have many constants, it would be great >> whether multiple constants and variables could be grouped using parenthesis. >> >> Now: >> >> static a = 1; >> static b = 35; >> static c = 120; >> >> Using parenthesis: >> >> static ( >> a = 1; >> b = 35; >> c = 120; >> ) > > Wouldn't `static a=1, b=35, c=120;` make more sense and match `let > a=1, b=25, c=120;'? > > Alex > > From danielmicay at gmail.com Tue Apr 16 03:50:20 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 16 Apr 2013 06:50:20 -0400 Subject: [rust-dev] Grouping declarations In-Reply-To: <516D2AA1.4090009@proinbox.com> References: <1447610.FFiMCI3ifm@l10036> <51689EEF.80508@mozilla.com> <1670159.t98T4AN7C8@l10036> <516D27D6.4070206@proinbox.com> <516D2AA1.4090009@proinbox.com> Message-ID: On Tue, Apr 16, 2013 at 6:40 AM, John Mija wrote: > That way (a) does not allow comment out a declaration *easily* and (b) it is > not useful for more than 10 or 20 multiple declarations. > > static ( > a = 1; > //b = 35; > c = 120; > ) > > so the code will always be clearer > > vs > > static a=1, /*b=35,*/ c=120; > > El 16/04/13 11:33, Alex Bradbury escribi?: >> >> On 16 April 2013 11:28, John Mija wrote: >>> >>> Since the low level libraries usually have many constants, it would be >>> great >>> whether multiple constants and variables could be grouped using >>> parenthesis. >>> >>> Now: >>> >>> static a = 1; >>> static b = 35; >>> static c = 120; >>> >>> Using parenthesis: >>> >>> static ( >>> a = 1; >>> b = 35; >>> c = 120; >>> ) >> >> >> Wouldn't `static a=1, b=35, c=120;` make more sense and match `let >> a=1, b=25, c=120;'? >> >> Alex It would be simpler and clearer to just have `let x = 5;` and `static x: int = 5`. Adding special cases to the syntax makes it more complex, so the question is whether the added sugar outweighs the complexity. In this case, I have a strong opinion that the simple `let pattern = expression;` syntax is more than enough. I don't think the comma-separated syntax should exist at all when there's already `let (x, y) = (a, b);`. From clements at brinckerhoff.org Tue Apr 16 08:51:28 2013 From: clements at brinckerhoff.org (John Clements) Date: Tue, 16 Apr 2013 08:51:28 -0700 Subject: [rust-dev] core dumped in rust In-Reply-To: References: Message-ID: <337C6FFC-96C2-41C4-9332-56EB35E454EF@brinckerhoff.org> On Apr 16, 2013, at 2:27 AM, piyush agarwal wrote: > Hi all, > > I encountered the following error during execution of my code: > > : exchange heap not empty on on exit10 dangling allocations Aborted (core dumped) > > what could be the possible causes?? First things first: that shouldn't happen, and almost certainly indicates a bug in the Rust compiler. More to the point: Do you have a program that reliably causes this crash? Is it small :) ? What version of the rust compiler are you using? Basically, it looks to me like it would be hard to diagnose this error without knowing more about your program. Thanks for your time! John Clements From james at aatch.net Mon Apr 15 18:37:58 2013 From: james at aatch.net (James Miller) Date: Tue, 16 Apr 2013 13:37:58 +1200 Subject: [rust-dev] Non additive execution time scaling In-Reply-To: References: <968717829.10332252.1366065318616.JavaMail.root@mozilla.com> Message-ID: <20130416013758.GE4212@tyr.home.aatch.net> On 2013-04-16 00:45:19, Artella Coding wrote: > Hi Felix, > > Thanks for your response. That is an interest observation you made about > the println functon. > > Upon playing with the code a bit more, I noticed that the strange behaviour > seems to be limited to the function "second". The distinguishing feature of > this function is that it involves a nested function. > > I have rewritten the codes to only involve a single function in each source > file (in order to illustrate this better) & the source and results are > below (to call the functions twice just uncomment the last few lines I have > commented out in each program) : > > firstAndFirst.rs > 1)Call "first" once : 4.5s > 2)Call "first" twice : 9.4s > > secondAndSecond.rs (nested function call_ > 1)Call "second" once : 9.5s > 2)Call "second" twice : 43.8s (--> I would have expected this to be 19s <--) > > ********************************************************************************* > ********************************************************************************* > //firstAndFirst.rs > static g_r: float = 3.569956; > static g_x0:float = 0.53; > > fn first(n: i64, x0 : float, r: float) -> float { > let mut x = x0; > let mut i = 0i64; > loop { > x = r*x*(1.-x); > i += 1; > if i == n { break } > } > x > } > > fn main(){ > let l = 400000000i64; > > let result = first(l,g_x0,g_r); > io::println(float::to_str(result)); > > //let result2 = first(l,g_x0,g_r); > //io::println(float::to_str(result2)); > } > ********************************************************************************* > ********************************************************************************* > //secondAndSecond.rs > static g_r: float = 3.569956; > static g_x0:float = 0.53; > > fn second(n: i64, x0 : float, r: float) -> float { > > fn calc(x : float, r: float) -> float { > let mut xm = x; > xm = r*xm*(1.-xm); > xm > } > > let mut x = x0; > let mut i = 0i64; > loop { > x = calc(x,r); > i += 1; > if i == n { break } > } > x > > } > > fn main(){ > let l = 400000000i64; > > let result = second(l,g_x0,g_r); > io::println(float::to_str(result)); > > //let result2 = second(l,g_x0,g_r); > //io::println(float::to_str(result2)); > } > ********************************************************************************* > ********************************************************************************* Hi Artella, I was curious about this and did some investigation. There are a few things that are causing the issues you are seeing. rustc doesn't produce particularly good LLVM IR. There is nothing technically wrong with it, it is just very bloated. This is fine because the LLVM optimizer is pretty good at taking that code down to a reasonable level. I did some tests compiling with all 4 levels of optimization: Level 0: (default) Time: 10.0s Binary Size: 118k LLVM IR Size: 16512 lines Level 1: Time: 1.38s Binary Size: 62k LLVM IR Size: 6902 lines Level 2: (default level with -O) Time: 1.37s Binary Size: 22k LLVM IR Size: 1949 lines Level 3: Time: 1.37s Binary Size: 22k LLVM IR Size: 1949 lines The jump from 0 to 1 is the biggest. In fact calling second twice produces a difference of 50s vs 2.7 for level 0 vs level 1 optimization. As to why it produces so much code, well for one, all the intrinsics and a few other things are included, even at opt-level 1 they are removed as being unused. That doesn't explain the speed of the code though. That is likely to do with the fact that the call to the inner function isn't inlined, and therefore you are paying for that function call. While normally function calls are fast, when you are calling it 400,000,000 times, it adds up. As for the exponetial slow-down, it's related to the fact that io is asynchronous and handled by the scheduler task, but tasks are scheduled co-operative meaning a CPU-intensive task can block other tasks in the same thread. I haven't yet figured out the specific reasons, but wrapping each call to `second` in it's own task causes the time to drop from ~1 minute to 7 seconds. If you account for parallelism from running in multiple threads, then `time` reports ~15 seconds. Which is double. Again, I am unclear on the exact reason why this happens, but it is fairly clear that it is the IO that is causing the issue. Fortunately there is a new scheduler on the way that will hopefully sort some of these issues. -- James Miller From clements at brinckerhoff.org Tue Apr 16 09:02:26 2013 From: clements at brinckerhoff.org (John Clements) Date: Tue, 16 Apr 2013 09:02:26 -0700 Subject: [rust-dev] Grouping declarations In-Reply-To: <516D27D6.4070206@proinbox.com> References: <1447610.FFiMCI3ifm@l10036> <51689EEF.80508@mozilla.com> <1670159.t98T4AN7C8@l10036> <516D27D6.4070206@proinbox.com> Message-ID: <8ADFC2B4-66D9-477F-9C48-4ED0A61ACD40@brinckerhoff.org> On Apr 16, 2013, at 3:28 AM, John Mija wrote: > Since the low level libraries usually have many constants, it would be great whether multiple constants and variables could be grouped using parenthesis. > > Now: > > static a = 1; > static b = 35; > static c = 120; > > Using parenthesis: > > static ( > a = 1; > b = 35; > c = 120; > ) The macro system should be able to handle this. I'm not saying it can, just that it should. More generally, I think I would offer you this RnRS quote: "Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary." John From brandon at mintern.net Tue Apr 16 09:23:34 2013 From: brandon at mintern.net (Brandon Mintern) Date: Tue, 16 Apr 2013 09:23:34 -0700 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: I was about to write how I can understand the use case. That often for efficiency (runtime, memory, or concision) reasons, it's helpful to program to an API other than the public one. That in the process of implementing an interface on some existing type, it often needs to be reworked a bit to make it more flexible and extensible. That not having protected might result in a lot of unsafe declarations sprinkled around. And then I thought about it a little more and realized that this is precisely something that's unsafe. Most of my protected fields and methods in Java are accompanied by comments like, "Important note: don't frobnicate a foo without also twiddling a bar." I think you're right, Daniel, that having a layer between public API and present implementation is probably not worth the cognitive overhead. It seems like it would be Rust best practice when implementing an interface to use the public API of the type to the extent possible, and when necessary for efficiency or other reasons, to use unsafe and fiddle with the private API. On Tue, Apr 16, 2013 at 3:08 AM, Daniel Micay wrote: > On Tue, Apr 16, 2013 at 5:53 AM, Eddy Cizeron > wrote: > > > > Hi everyone > > > > I was thinking: wouldn't it be useful if rust also had a "protected" > > visibility modifier for struct fields with the following meaning: > > A protected field in a structure type T is accessible wherever a private > one > > would be as well as in any implementation of a trait for type T. > > > > Just an idea. > > > > -- > > Eddy Cizeron > > What use case do you have in mind for using a protected field instead > of a public one? > > The use case for a private field is separating implementation details > from the external API and upholding invariants. Although it's *possible* > to safely access them in an external module by using an unsafe block, > if you took into account all of the implementation details and > invariants of the type. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Tue Apr 16 10:11:00 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Tue, 16 Apr 2013 19:11:00 +0200 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: I would also had that before jumping straight to direct access, one should carefully measure. With inlining and constant propagation I would not be surprised if the optimizer could not turn an access via the public API into as efficient code as a direct access to the field in the trait method implementation. And if you really need another access method, then maybe it should be added to the type directly ? On Tue, Apr 16, 2013 at 6:23 PM, Brandon Mintern wrote: > I was about to write how I can understand the use case. That often for > efficiency (runtime, memory, or concision) reasons, it's helpful to program > to an API other than the public one. That in the process of implementing an > interface on some existing type, it often needs to be reworked a bit to > make it more flexible and extensible. That not having protected might > result in a lot of unsafe declarations sprinkled around. > > And then I thought about it a little more and realized that this is > precisely something that's unsafe. Most of my protected fields and methods > in Java are accompanied by comments like, "Important note: don't frobnicate > a foo without also twiddling a bar." > > I think you're right, Daniel, that having a layer between public API and > present implementation is probably not worth the cognitive overhead. It > seems like it would be Rust best practice when implementing an interface to > use the public API of the type to the extent possible, and when necessary > for efficiency or other reasons, to use unsafe and fiddle with the private > API. > > > On Tue, Apr 16, 2013 at 3:08 AM, Daniel Micay wrote: > >> On Tue, Apr 16, 2013 at 5:53 AM, Eddy Cizeron >> wrote: >> > >> > Hi everyone >> > >> > I was thinking: wouldn't it be useful if rust also had a "protected" >> > visibility modifier for struct fields with the following meaning: >> > A protected field in a structure type T is accessible wherever a >> private one >> > would be as well as in any implementation of a trait for type T. >> > >> > Just an idea. >> > >> > -- >> > Eddy Cizeron >> >> What use case do you have in mind for using a protected field instead >> of a public one? >> >> The use case for a private field is separating implementation details >> from the external API and upholding invariants. Although it's *possible* >> to safely access them in an external module by using an unsafe block, >> if you took into account all of the implementation details and >> invariants of the type. >> _______________________________________________ >> 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 brandon at mintern.net Tue Apr 16 10:36:49 2013 From: brandon at mintern.net (Brandon Mintern) Date: Tue, 16 Apr 2013 10:36:49 -0700 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: I agree with you completely, Matthieu, but that's not the kind of thing I had in mind. Consider a LinkedList implementation. Its nodes and their pointers would be private to the LinkedList, but when implementing an Iterator for that list, you would need to use that private information to avoid n^2 performance. On Tue, Apr 16, 2013 at 10:11 AM, Matthieu Monrocq < matthieu.monrocq at gmail.com> wrote: > I would also had that before jumping straight to direct access, one should > carefully measure. With inlining and constant propagation I would not be > surprised if the optimizer could not turn an access via the public API into > as efficient code as a direct access to the field in the trait method > implementation. > > And if you really need another access method, then maybe it should be > added to the type directly ? > > > On Tue, Apr 16, 2013 at 6:23 PM, Brandon Mintern wrote: > >> I was about to write how I can understand the use case. That often for >> efficiency (runtime, memory, or concision) reasons, it's helpful to program >> to an API other than the public one. That in the process of implementing an >> interface on some existing type, it often needs to be reworked a bit to >> make it more flexible and extensible. That not having protected might >> result in a lot of unsafe declarations sprinkled around. >> >> And then I thought about it a little more and realized that this is >> precisely something that's unsafe. Most of my protected fields and methods >> in Java are accompanied by comments like, "Important note: don't frobnicate >> a foo without also twiddling a bar." >> >> I think you're right, Daniel, that having a layer between public API and >> present implementation is probably not worth the cognitive overhead. It >> seems like it would be Rust best practice when implementing an interface to >> use the public API of the type to the extent possible, and when necessary >> for efficiency or other reasons, to use unsafe and fiddle with the private >> API. >> >> >> On Tue, Apr 16, 2013 at 3:08 AM, Daniel Micay wrote: >> >>> On Tue, Apr 16, 2013 at 5:53 AM, Eddy Cizeron >>> wrote: >>> > >>> > Hi everyone >>> > >>> > I was thinking: wouldn't it be useful if rust also had a "protected" >>> > visibility modifier for struct fields with the following meaning: >>> > A protected field in a structure type T is accessible wherever a >>> private one >>> > would be as well as in any implementation of a trait for type T. >>> > >>> > Just an idea. >>> > >>> > -- >>> > Eddy Cizeron >>> >>> What use case do you have in mind for using a protected field instead >>> of a public one? >>> >>> The use case for a private field is separating implementation details >>> from the external API and upholding invariants. Although it's *possible* >>> to safely access them in an external module by using an unsafe block, >>> if you took into account all of the implementation details and >>> invariants of the type. >>> _______________________________________________ >>> 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 graydon at mozilla.com Tue Apr 16 11:07:40 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 16 Apr 2013 11:07:40 -0700 Subject: [rust-dev] String encode/decode In-Reply-To: References: <5166D5CB.3050203@exyr.org> Message-ID: <516D936C.300@mozilla.com> On 11/04/2013 1:35 PM, Fredrik H??rd wrote: > Sorry if I was unclear; I meant a general-purpose codec for handling > ftp://ftp.unicode.org/Public/MAPPINGS/** more or less. Web stuff is out > of scope for what I intend here (Although my 'penultimate' goal is to be > able to implement MIME so that email handling can be implemented). I believe we'll wind up taking a dependency either on libICU or "things provided by the OS" in cases where OS services are adequate (for example it seems win32 has some conversion services built in). This topic intersects pretty much every other thing provided by ICU and/or i18n / l10n APIs, and will take a while to work out a reasonable strategy. I'll post more on this soon. -Graydon From tschneidereit at gmail.com Tue Apr 16 11:11:29 2013 From: tschneidereit at gmail.com (Till Schneidereit) Date: Tue, 16 Apr 2013 11:11:29 -0700 Subject: [rust-dev] String encode/decode In-Reply-To: <516D936C.300@mozilla.com> References: <5166D5CB.3050203@exyr.org> <516D936C.300@mozilla.com> Message-ID: For what it's worth, SpiderMonkey has just added a dependency on ICU, so it might make sense to align with that. At least for Servo, if not for Rust itself. On Tue, Apr 16, 2013 at 11:07 AM, Graydon Hoare wrote: > On 11/04/2013 1:35 PM, Fredrik H??rd wrote: > > Sorry if I was unclear; I meant a general-purpose codec for handling >> ftp://ftp.unicode.org/Public/**MAPPINGS/**more or less. Web stuff is out >> of scope for what I intend here (Although my 'penultimate' goal is to be >> able to implement MIME so that email handling can be implemented). >> > > I believe we'll wind up taking a dependency either on libICU or "things > provided by the OS" in cases where OS services are adequate (for example it > seems win32 has some conversion services built in). This topic intersects > pretty much every other thing provided by ICU and/or i18n / l10n APIs, and > will take a while to work out a reasonable strategy. I'll post more on this > soon. > > -Graydon > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue Apr 16 11:35:21 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 16 Apr 2013 11:35:21 -0700 Subject: [rust-dev] LLVM versions In-Reply-To: <15654084.67371365499053217.JavaMail.weblogic@epml03> References: <15654084.67371365499053217.JavaMail.weblogic@epml03> Message-ID: <516D99E9.6000804@mozilla.com> On 09/04/2013 2:17 AM, Sanghyeon Seo wrote: > LLVM is known to make no promise of API stability between versions, > so if Rust in the future is to support compilation with system LLVM > (which it doesn't at the moment), it should be wary of these problems. > Although some LLVM users try to suppot multiple versions of LLVM, > I am not sure whether Rust should do so. I would not spend a lot of energy supporting multiple versions. "As many versions as are easy" is fine by me. LLVM is big but not impossibly big, and if we wind up needing a different-than-trunk version on a given system, I think it will not be the end of the world. -Graydon From graydon at mozilla.com Tue Apr 16 11:52:22 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 16 Apr 2013 11:52:22 -0700 Subject: [rust-dev] Library Safety In-Reply-To: References: <515DF302.3020702@alum.mit.edu> Message-ID: <516D9DE6.8090003@mozilla.com> On 05/04/2013 4:14 PM, Grant Husbands wrote: > The important thing, to my mind, is that I don't have to audit the > rust-jpeg library at all, and the worst it can do (probably) is a denial > of service. If this became standard practice for Rust code, it would be > a systems language in which it's feasible to easily include relatively > untrusted third-party libraries, securely, and interact with them > naturally. I think there's a lot of mileage in that. Yeah. It'd involve reifying ... probably just the 'forbid()' lint flags used at crate top level as linkage metadata so we can specify it as a linkage criterion. It's possible but I am not sure how common or likely it'll be. It's also possible to just make this a criterion you enforce as part of coding standards, or a thing to inspect when checking dependencies manually. At some point, tooling interfaces with human choice. -Graydon From thadguidry at gmail.com Tue Apr 16 11:54:41 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Tue, 16 Apr 2013 13:54:41 -0500 Subject: [rust-dev] LLVM versions In-Reply-To: <516D99E9.6000804@mozilla.com> References: <15654084.67371365499053217.JavaMail.weblogic@epml03> <516D99E9.6000804@mozilla.com> Message-ID: > I would not spend a lot of energy supporting multiple versions. "As many > versions as are easy" is fine by me. LLVM is big but not impossibly big, > and if we wind up needing a different-than-trunk version on a given system, > I think it will not be the end of the world. > > -Graydon > > +1 not the end of the world. -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Tue Apr 16 14:32:15 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Tue, 16 Apr 2013 23:32:15 +0200 Subject: [rust-dev] Library Safety In-Reply-To: References: <515DF302.3020702@alum.mit.edu> Message-ID: On Sat, Apr 6, 2013 at 1:14 AM, Grant Husbands wrote: > To some extent, yes. I'm not familiar enough with Rust's lint modes to say > much more than that. I'm going to try using Rust for a while before giving > a more detailed proposal. > > However, I will give a more concrete example, now that I know slightly > more. In servo.rc (in the servo project), there's a line like this: > extern mod stb_image; > > I want to be able to write it something like this: > extern mod rust-jpeg ( nogc, safe ); > > Doing so should ensure that the library cannot do GC or anything directly > or indirectly unsafe (alternatively, it should import the version that was > compiled that way). Then, the servo project can be sure that rust-jpeg > cannot perform any unsafe operations (or GC), without manual audits of its > imports or code. It essentially removes the JPEG library from the TCB > (trusted computing base) of Servo. Carefully applied, it would make servo > much more secure against maliciousness via supporting libraries. > > The important thing, to my mind, is that I don't have to audit the > rust-jpeg library at all, and the worst it can do (probably) is a denial of > service. If this became standard practice for Rust code, it would be a > systems language in which it's feasible to easily include relatively > untrusted third-party libraries, securely, and interact with them > naturally. I think there's a lot of mileage in that. > > Grant. > > SafeHaskell might be a relevant example of prior art here (at least regarding the nothing-unsafe half of the above). Much like Rust, Haskell has a strong static type system, but with escape hatches (unsafePerformIO, unsafeCoerce, most things involving the FFI) which can subvert it if used improperly or maliciously, as with unsafe { } in Rust. The approach SafeHaskell takes is that safety is tracked at the module level, with three classifications: Unsafe, meaning that the module exposes an interface which can violate safety; Trustworthy, meaning that the module imports Unsafe modules, but the author of the module asserts that they are only used in ways that are safe, and that the module does not outwardly expose any way to violate safety; and Safe, meaning that the module transitively imports only Safe and Trustworthy modules. These can either be declared by the module author, where in the case of Safe the compiler will verify that it's true, or otherwise the compiler will infer Safe or Unsafe. It's up to the system administrator to set policy regarding trusted packages. Essentially, if a package is marked as trusted, Trustworthy modules in the package will be treated as being Safe, otherwise they will be treated as being Unsafe. If you try to compile something while requiring it to be safe, and it imports Trustworthy modules from untrusted packages (or of course actual Unsafe modules), the compiler will complain and refuse to compile it. Basically, using the term from your email, the "trusted computing base" requiring human inspection would consist of the modules marked Trustworthy. > > > On Thu, Apr 4, 2013 at 10:39 PM, Niko Matsakis wrote: > >> It sounds to me like you're talking about something similar to the >> current lint modes for GC etc? >> >> Niko >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From artella.coding at googlemail.com Tue Apr 16 14:58:24 2013 From: artella.coding at googlemail.com (Artella Coding) Date: Tue, 16 Apr 2013 22:58:24 +0100 Subject: [rust-dev] Non additive execution time scaling In-Reply-To: <20130416013758.GE4212@tyr.home.aatch.net> References: <968717829.10332252.1366065318616.JavaMail.root@mozilla.com> <20130416013758.GE4212@tyr.home.aatch.net> Message-ID: Hi James, Thanks for the response. I have a few questions below : >As for the exponetial slow-down, it's related to the fact that io is asynchronous and >handled by the scheduler task, but tasks are scheduled co-operative meaning >a CPU-intensive task can block other tasks in the same thread. But why is it the case that calling "first" twice results in the twice the execution time as compared to calling "first" once, whereas calling "second" twice results in much more than doubling of execution time as compared to a call of "second" once. I did realise that "second" would be slower as no inlining would be performed, but what was more important to me was the way the program scales with function calls. In particular what is it about calling a nested function (as compared to calling a non-nested function) that results in the io behaving in an unexpected way? >I haven't yet figured out >the specific reasons, but wrapping each call to `second` in it's own task causes the time >to drop from ~1 minute to 7 seconds. If you account for parallelism from running in >multiple threads, then `time` reports ~15 seconds. Which is double. How can I wrap each "second" call in its own task? Thanks On Tue, Apr 16, 2013 at 2:37 AM, James Miller wrote: > As for the exponetial slow-down, it's related to the fact that io is > asynchronous and > handled by the scheduler task, but tasks are scheduled co-operative meaning > a CPU-intensive task can block other tasks in the same thread. I haven't > yet figured out > the specific reasons, but wrapping each call to `second` in it's own task > causes the time > to drop from ~1 minute to 7 seconds. If you account for parallelism from > running in > multiple threads, then `time` reports ~15 seconds. Which is double. > 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 aatch at aatch.net Tue Apr 16 17:41:06 2013 From: aatch at aatch.net (James Miller) Date: Wed, 17 Apr 2013 12:41:06 +1200 Subject: [rust-dev] Non additive execution time scaling In-Reply-To: References: <968717829.10332252.1366065318616.JavaMail.root@mozilla.com> <20130416013758.GE4212@tyr.home.aatch.net> Message-ID: <20130417004106.GA14912@tyr.home.aatch.net> On 2013-04-16 22:58:24, Artella Coding wrote: > Hi James, > > Thanks for the response. I have a few questions below : > > >As for the exponetial slow-down, it's related to the fact that io is > asynchronous and > >handled by the scheduler task, but tasks are scheduled co-operative meaning > >a CPU-intensive task can block other tasks in the same thread. > > But why is it the case that calling "first" twice results in the twice the > execution time as compared to calling "first" once, whereas calling > "second" twice results in much more than doubling of execution time as > compared to a call of "second" once. I did realise that "second" would be > slower as no inlining would be performed, but what was more important to me > was the way the program scales with function calls. > > In particular what is it about calling a nested function (as compared to > calling a non-nested function) that results in the io behaving in an > unexpected way? > > >I haven't yet figured out > >the specific reasons, but wrapping each call to `second` in it's own task > causes the time > >to drop from ~1 minute to 7 seconds. If you account for parallelism from > running in > >multiple threads, then `time` reports ~15 seconds. Which is double. > > How can I wrap each "second" call in its own task? Thanks > > On Tue, Apr 16, 2013 at 2:37 AM, James Miller wrote: > > > As for the exponetial slow-down, it's related to the fact that io is > > asynchronous and > > handled by the scheduler task, but tasks are scheduled co-operative meaning > > a CPU-intensive task can block other tasks in the same thread. I haven't > > yet figured out > > the specific reasons, but wrapping each call to `second` in it's own task > > causes the time > > to drop from ~1 minute to 7 seconds. If you account for parallelism from > > running in > > multiple threads, then `time` reports ~15 seconds. Which is double. > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > > I'm not entirely familiar on the inner workings of the scheduler. It's a little bit magic to me still. However, I did find that by moving the IO out of the way, so all the calculation happened then the output, the scaling was linear as you'd expect. If I had to guess, then I would say that the increased memory usage of calling an inner function tips some internal limit over and makes the scheduler thrash for a while. IIRC rust functions are passed an environment pointer, and I think that the environment pointer for a top-level function is NULL, whereas it is not for closures and inner functions (internally Rust makes no significant distinction between the different "types" of functions, they are all more or less the same by the time it gets to code gen). It would explain why even level 1 optimization fixed it, since I think LLVM would optimize out the unused environment as a dead store. However I am just guessing about that. At any rate Patrick Walton (@pcwalton) is working on a new scheduler that fixed many of the issues with the current one. So it is possible that this issue will be solved by 0.7/8. As for tasks, http://static.rust-lang.org/docs/0.6/core/task.html is where you want to look. The most basic version is `task::spawn` which takes a closure. this means that you write do task::spawn { /* my code here */ } to spawn a task. Simple. Thanks -- James Miller From ysoo.son at samsung.com Tue Apr 16 18:55:15 2013 From: ysoo.son at samsung.com (=?euc-kr?B?vNW/tbz2?=) Date: Wed, 17 Apr 2013 01:55:15 +0000 (GMT) Subject: [rust-dev] ICE with using a condition from another crate Message-ID: <1D.A2.24454.3010E615@epcpsbgx4.samsung.com> An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: 201304171055805_44YDXKW4.gif Type: image/gif Size: 14036 bytes Desc: not available URL: From eddycizeron at gmail.com Wed Apr 17 00:24:58 2013 From: eddycizeron at gmail.com (Eddy Cizeron) Date: Wed, 17 Apr 2013 09:24:58 +0200 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: 2013/4/16 Brandon Mintern > I agree with you completely, Matthieu, but that's not the kind of thing I > had in mind. Consider a LinkedList implementation. Its nodes and their > pointers would be private to the LinkedList, but when implementing an > Iterator for that list, you would need to use that private information to > avoid n^2 performance. > That's a typical case I had in mind. > And then I thought about it a little more and realized that this is >>> precisely something that's unsafe. Most of my protected fields and methods >>> in Java are accompanied by comments like, "Important note: don't frobnicate >>> a foo without also twiddling a bar." >>> >>> I think you're right, Daniel, that having a layer between public API and >>> present implementation is probably not worth the cognitive overhead. >>> >> I understand your point Brandon. But I could say sometime protected information is not so sensitive. When it is immutable for example. So why not declaring it public? Not to pollute the public interface with data unrelated with the common use (Yes I agree the argument is not very strong) > It seems like it would be Rust best practice when implementing an >>> interface to use the public API of the type to the extent possible, and >>> when necessary for efficiency or other reasons, to use unsafe and fiddle >>> with the private API. >>> >> It could be. But if I'm allowed to play the Devil's advocate this implies that any implentation detail must be thought as potentially accessible (and then as necessarily understandable / documented) from outside (what you call "private API"). This is not the typical approach when considering private data. -------------- next part -------------- An HTML attachment was scrubbed... URL: From a.stavonin at gmail.com Wed Apr 17 07:05:57 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Wed, 17 Apr 2013 18:05:57 +0400 Subject: [rust-dev] Cloning RWARC Message-ID: Hi, I'd like to clone RWARC object. For example: let data = arc::RWARC(get_data()); How can I do it? I tried next: let read_data = arc::clone(&data); But looks like I have to write something different: error: mismatched types: expected `&std::arc::ARC<>` but found `&std::arc::RWARC<~[uint]>` Next forme doesn't work too: let read_data = arc::RWARC::clone(&data); -------------- next part -------------- An HTML attachment was scrubbed... URL: From abhijeet.gaiha at gmail.com Wed Apr 17 07:10:58 2013 From: abhijeet.gaiha at gmail.com (Abhijeet Gaiha) Date: Wed, 17 Apr 2013 19:40:58 +0530 Subject: [rust-dev] Cloning RWARC In-Reply-To: References: Message-ID: Try data.clone() instead. On Wednesday, April 17, 2013, Alexander Stavonin wrote: > Hi, > > I'd like to clone RWARC object. For example: > > let data = arc::RWARC(get_data()); > > How can I do it? I tried next: > > let read_data = arc::clone(&data); > > But looks like I have to write something different: > > error: mismatched types: expected `&std::arc::ARC<>` but found > `&std::arc::RWARC<~[uint]>` > > Next forme doesn't work too: > > let read_data = arc::RWARC::clone(&data); > -- http://about.me/abhijeet.gaiha -------------- next part -------------- An HTML attachment was scrubbed... URL: From hsivonen at iki.fi Wed Apr 17 07:51:08 2013 From: hsivonen at iki.fi (Henri Sivonen) Date: Wed, 17 Apr 2013 17:51:08 +0300 Subject: [rust-dev] String encode/decode In-Reply-To: <516D936C.300@mozilla.com> References: <5166D5CB.3050203@exyr.org> <516D936C.300@mozilla.com> Message-ID: On Tue, Apr 16, 2013 at 9:07 PM, Graydon Hoare wrote: > On 11/04/2013 1:35 PM, Fredrik H??rd wrote: > >> Sorry if I was unclear; I meant a general-purpose codec for handling >> ftp://ftp.unicode.org/Public/MAPPINGS/** more or less. Web stuff is out >> of scope for what I intend here (Although my 'penultimate' goal is to be >> able to implement MIME so that email handling can be implemented). Does email really need the ftp.unicode.org / IANA understanding of encodings instead of the Web-compatible understanding of encodings? > I believe we'll wind up taking a dependency either on libICU ICU's label handling and converters aren't Encoding Standard-compliant. For Servo, we should do the right thing straight away and implement the Encoding Standard. Having another set of converters seems like an opportunity for people to use the wrong (as in Web-incompatible) thing. -- Henri Sivonen hsivonen at iki.fi http://hsivonen.iki.fi/ From matthieu.monrocq at gmail.com Wed Apr 17 10:59:08 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Wed, 17 Apr 2013 19:59:08 +0200 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: On Wed, Apr 17, 2013 at 9:24 AM, Eddy Cizeron wrote: > > 2013/4/16 Brandon Mintern > >> I agree with you completely, Matthieu, but that's not the kind of thing I >> had in mind. Consider a LinkedList implementation. Its nodes and their >> pointers would be private to the LinkedList, but when implementing an >> Iterator for that list, you would need to use that private information to >> avoid n^2 performance. >> > > That's a typical case I had in mind. > I am not sure. Whilst the head of the list will be private to the list, there is no reason that the *node type* be private. Expose the node, built iterators that take a reference to a node in their constructor, and have the list build the begin/end iterators (I guess). All iterations can be done safely... Of course, it does mean that you have an issue whenever you wish to "erase" an item by passing its position (unless you use unsafe code to make the reference mutable again). But that is, I think, a wrong example. Iterators are unsafe. You can easily keep dangling iterators aside and having them blow up in your hands. On the other, if we shunt external iterators and implement iteration with a "foreach" method accepting a predicate, then we do not need to expose the list internals. Give the predicate the ability to "influence" the list it is running on (returning an enum "Stop/Remove/...") and you are on. I am not saying that there is absolutely no reason it will ever be needed, but I am challenging the needs exposed so far :) -- Matthieu > > >> And then I thought about it a little more and realized that this is >>>> precisely something that's unsafe. Most of my protected fields and methods >>>> in Java are accompanied by comments like, "Important note: don't frobnicate >>>> a foo without also twiddling a bar." >>>> >>>> I think you're right, Daniel, that having a layer between public API >>>> and present implementation is probably not worth the cognitive overhead. >>>> >>> > I understand your point Brandon. But I could say sometime protected > information is not so sensitive. When it is immutable for example. So why > not declaring it public? Not to pollute the public interface with data > unrelated with the common use (Yes I agree the argument is not very strong) > > >> It seems like it would be Rust best practice when implementing an >>>> interface to use the public API of the type to the extent possible, and >>>> when necessary for efficiency or other reasons, to use unsafe and fiddle >>>> with the private API. >>>> >>> > It could be. But if I'm allowed to play the Devil's advocate this implies > that any implentation detail must be thought as potentially accessible (and > then as necessarily understandable / documented) from outside (what you > call "private API"). This is not the typical approach when considering > private data. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Wed Apr 17 11:39:00 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Wed, 17 Apr 2013 14:39:00 -0400 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: On Wed, Apr 17, 2013 at 1:59 PM, Matthieu Monrocq wrote: > > > > On Wed, Apr 17, 2013 at 9:24 AM, Eddy Cizeron wrote: >> >> >> 2013/4/16 Brandon Mintern >>> >>> I agree with you completely, Matthieu, but that's not the kind of thing I >>> had in mind. Consider a LinkedList implementation. Its nodes and their >>> pointers would be private to the LinkedList, but when implementing an >>> Iterator for that list, you would need to use that private information to >>> avoid n^2 performance. >> >> >> That's a typical case I had in mind. > > > I am not sure. > > Whilst the head of the list will be private to the list, there is no reason > that the *node type* be private. Expose the node, built iterators that take > a reference to a node in their constructor, and have the list build the > begin/end iterators (I guess). All iterations can be done safely... > > Of course, it does mean that you have an issue whenever you wish to "erase" > an item by passing its position (unless you use unsafe code to make the > reference mutable again). > > > But that is, I think, a wrong example. Iterators are unsafe. You can easily > keep dangling iterators aside and having them blow up in your hands. > > > On the other, if we shunt external iterators and implement iteration with a > "foreach" method accepting a predicate, then we do not need to expose the > list internals. Give the predicate the ability to "influence" the list it is > running on (returning an enum "Stop/Remove/...") and you are on. > > > I am not saying that there is absolutely no reason it will ever be needed, > but I am challenging the needs exposed so far :) > > -- Matthieu > >> >> >>>>> >>>>> And then I thought about it a little more and realized that this is >>>>> precisely something that's unsafe. Most of my protected fields and methods >>>>> in Java are accompanied by comments like, "Important note: don't frobnicate >>>>> a foo without also twiddling a bar." >>>>> >>>>> I think you're right, Daniel, that having a layer between public API >>>>> and present implementation is probably not worth the cognitive overhead. >> >> >> I understand your point Brandon. But I could say sometime protected >> information is not so sensitive. When it is immutable for example. So why >> not declaring it public? Not to pollute the public interface with data >> unrelated with the common use (Yes I agree the argument is not very strong) >> >>>>> >>>>> It seems like it would be Rust best practice when implementing an >>>>> interface to use the public API of the type to the extent possible, and when >>>>> necessary for efficiency or other reasons, to use unsafe and fiddle with the >>>>> private API. >> >> >> It could be. But if I'm allowed to play the Devil's advocate this implies >> that any implentation detail must be thought as potentially accessible (and >> then as necessarily understandable / documented) from outside (what you call >> "private API"). This is not the typical approach when considering private >> data. >> >> _______________________________________________ >> 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 > You can write safe external iterators by using lifetimes. The compiler will enforce that the list is frozen while you have iterators - completely statically for all owned types, and dynamically for @mut boxes. From brandon at mintern.net Wed Apr 17 11:58:35 2013 From: brandon at mintern.net (Brandon Mintern) Date: Wed, 17 Apr 2013 11:58:35 -0700 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: Please let's not get derailed here. I wasn't bemoaning the difficulty of implementing list iterators. I was trying to offer a simple example everyone could understand to show when protected might be useful. There are definitely times when implementing an interface that it's more convenient or efficient to use an object's non-public API. This discussion is not about list iterators, it's about whether it makes sense to have any visibility other than public and private. I argued that protected doesn't buy much over using unsafe private. Another unmentioned approach is to build classes as a composition of traits. Most callers will not be concerned with the internal traits, but users implementing a new trait for a class would use them. Both of those approaches get most of the way to protected without adding the cognitive overhead. So that's my suggestion. On Apr 17, 2013 11:39 AM, "Daniel Micay" wrote: > On Wed, Apr 17, 2013 at 1:59 PM, Matthieu Monrocq > wrote: > > > > > > > > On Wed, Apr 17, 2013 at 9:24 AM, Eddy Cizeron > wrote: > >> > >> > >> 2013/4/16 Brandon Mintern > >>> > >>> I agree with you completely, Matthieu, but that's not the kind of > thing I > >>> had in mind. Consider a LinkedList implementation. Its nodes and their > >>> pointers would be private to the LinkedList, but when implementing an > >>> Iterator for that list, you would need to use that private information > to > >>> avoid n^2 performance. > >> > >> > >> That's a typical case I had in mind. > > > > > > I am not sure. > > > > Whilst the head of the list will be private to the list, there is no > reason > > that the *node type* be private. Expose the node, built iterators that > take > > a reference to a node in their constructor, and have the list build the > > begin/end iterators (I guess). All iterations can be done safely... > > > > Of course, it does mean that you have an issue whenever you wish to > "erase" > > an item by passing its position (unless you use unsafe code to make the > > reference mutable again). > > > > > > But that is, I think, a wrong example. Iterators are unsafe. You can > easily > > keep dangling iterators aside and having them blow up in your hands. > > > > > > On the other, if we shunt external iterators and implement iteration > with a > > "foreach" method accepting a predicate, then we do not need to expose the > > list internals. Give the predicate the ability to "influence" the list > it is > > running on (returning an enum "Stop/Remove/...") and you are on. > > > > > > I am not saying that there is absolutely no reason it will ever be > needed, > > but I am challenging the needs exposed so far :) > > > > -- Matthieu > > > >> > >> > >>>>> > >>>>> And then I thought about it a little more and realized that this is > >>>>> precisely something that's unsafe. Most of my protected fields and > methods > >>>>> in Java are accompanied by comments like, "Important note: don't > frobnicate > >>>>> a foo without also twiddling a bar." > >>>>> > >>>>> I think you're right, Daniel, that having a layer between public API > >>>>> and present implementation is probably not worth the cognitive > overhead. > >> > >> > >> I understand your point Brandon. But I could say sometime protected > >> information is not so sensitive. When it is immutable for example. So > why > >> not declaring it public? Not to pollute the public interface with data > >> unrelated with the common use (Yes I agree the argument is not very > strong) > >> > >>>>> > >>>>> It seems like it would be Rust best practice when implementing an > >>>>> interface to use the public API of the type to the extent possible, > and when > >>>>> necessary for efficiency or other reasons, to use unsafe and fiddle > with the > >>>>> private API. > >> > >> > >> It could be. But if I'm allowed to play the Devil's advocate this > implies > >> that any implentation detail must be thought as potentially accessible > (and > >> then as necessarily understandable / documented) from outside (what you > call > >> "private API"). This is not the typical approach when considering > private > >> data. > >> > >> _______________________________________________ > >> 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 > > > > You can write safe external iterators by using lifetimes. The compiler > will enforce that the list is frozen while you have iterators - > completely statically for all owned types, and dynamically for @mut > boxes. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Wed Apr 17 14:26:32 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 17 Apr 2013 14:26:32 -0700 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: <516F1388.5070100@mozilla.com> On 17/04/2013 11:58 AM, Brandon Mintern wrote: > Please let's not get derailed here. I wasn't bemoaning the difficulty of > implementing list iterators. I was trying to offer a simple example > everyone could understand to show when protected might be useful. There > are definitely times when implementing an interface that it's more > convenient or efficient to use an object's non-public API. > > This discussion is not about list iterators, it's about whether it makes > sense to have any visibility other than public and private. I argued > that protected doesn't buy much over using unsafe private. Yes. Our concept of visibility is a fair bit different from the way it works in other OO languages. Rust's visibility modifiers control whether one bit of code can see across a module boundary, no more. Fields of a struct are always visible to anyone who can see the struct definition. And anyone can add methods to a struct, even outside the module it was defined in. So the whole conversation feels a bit off to me. There's no place for the concept of "protected" in the semantics at all, that I can see. It assumes a privilege-relation between certain methods and structs that doesn't exist. -Graydon From niko at alum.mit.edu Thu Apr 18 10:01:42 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Thu, 18 Apr 2013 13:01:42 -0400 Subject: [rust-dev] Some work on Rust coding standards In-Reply-To: <5165EE69.4000109@mozilla.com> References: <5165EE69.4000109@mozilla.com> Message-ID: <517026F6.4080408@alum.mit.edu> One other thing which I have noticed. The suggested form for a function declaration is difficult to maintain in light of refactorings and in particular search-and-replace commands. That is, if you place each argument on a separate line and line that line up with the opening parenthesis, as suggested: fn foo(p1: P1, p2: P2) { } Then if I rename `foo()` to `foo_bar()` via search-and-replace, I wind up with the following: fn foo_bar(p1: P1, p2: P2) { } I find this happens...semi-regularly and it's annoying. Perhaps it would be better to format functions as follows: fn foo( p1: P1, p2: P2) { code } or as follows: fn foo( p1: P1, p2: P2) { code // double indent distinguish parameters from code } Any of those options neatly avoids this problem, and also scales better to long type names. Niko > Brian Anderson > April 10, 2013 6:57 PM > There have been a few mentions recently about writing up the Rust > coding standards. Several of us sat in a room and tried to identify > and agree on some that we thought were important. I've pasted the > resulting notes into the wiki: > > https://github.com/mozilla/rust/wiki/Note-style-guide > > These are very, very rough but cover a number of topics. Comments and > suggestions are welcome. These need to be cleaned up into readable > prose, with decent examples, and moved from the 'Notes' section of the > wiki to the 'Docs' section where users will find them. Help is > definitely appreciated. > > -Brian > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: compose-unknown-contact.jpg Type: image/jpeg Size: 770 bytes Desc: not available URL: From bmintern at gmail.com Wed Apr 17 11:56:46 2013 From: bmintern at gmail.com (Brandon Mintern) Date: Wed, 17 Apr 2013 11:56:46 -0700 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: References: Message-ID: Please let's not get derailed here. I wasn't bemoaning the difficulty of implementing list iterators. I was trying to offer a simple example everyone could understand to show when protected might be useful. There are definitely times when implementing an interface that it's more convenient or efficient to use an object's non-public API. This discussion is not about list iterators, it's about whether it makes sense to have any visibility other than public and private. I argued that protected doesn't buy much over using unsafe private. Another unmentioned approach is to build classes as a composition of traits. Most callers will not be concerned with the internal traits, but users implementing a new trait for a class would use them. Both of those approaches get most of the way to protected without adding the cognitive overhead. So that's my suggestion. On Apr 17, 2013 11:39 AM, "Daniel Micay" wrote: > On Wed, Apr 17, 2013 at 1:59 PM, Matthieu Monrocq > wrote: > > > > > > > > On Wed, Apr 17, 2013 at 9:24 AM, Eddy Cizeron > wrote: > >> > >> > >> 2013/4/16 Brandon Mintern > >>> > >>> I agree with you completely, Matthieu, but that's not the kind of > thing I > >>> had in mind. Consider a LinkedList implementation. Its nodes and their > >>> pointers would be private to the LinkedList, but when implementing an > >>> Iterator for that list, you would need to use that private information > to > >>> avoid n^2 performance. > >> > >> > >> That's a typical case I had in mind. > > > > > > I am not sure. > > > > Whilst the head of the list will be private to the list, there is no > reason > > that the *node type* be private. Expose the node, built iterators that > take > > a reference to a node in their constructor, and have the list build the > > begin/end iterators (I guess). All iterations can be done safely... > > > > Of course, it does mean that you have an issue whenever you wish to > "erase" > > an item by passing its position (unless you use unsafe code to make the > > reference mutable again). > > > > > > But that is, I think, a wrong example. Iterators are unsafe. You can > easily > > keep dangling iterators aside and having them blow up in your hands. > > > > > > On the other, if we shunt external iterators and implement iteration > with a > > "foreach" method accepting a predicate, then we do not need to expose the > > list internals. Give the predicate the ability to "influence" the list > it is > > running on (returning an enum "Stop/Remove/...") and you are on. > > > > > > I am not saying that there is absolutely no reason it will ever be > needed, > > but I am challenging the needs exposed so far :) > > > > -- Matthieu > > > >> > >> > >>>>> > >>>>> And then I thought about it a little more and realized that this is > >>>>> precisely something that's unsafe. Most of my protected fields and > methods > >>>>> in Java are accompanied by comments like, "Important note: don't > frobnicate > >>>>> a foo without also twiddling a bar." > >>>>> > >>>>> I think you're right, Daniel, that having a layer between public API > >>>>> and present implementation is probably not worth the cognitive > overhead. > >> > >> > >> I understand your point Brandon. But I could say sometime protected > >> information is not so sensitive. When it is immutable for example. So > why > >> not declaring it public? Not to pollute the public interface with data > >> unrelated with the common use (Yes I agree the argument is not very > strong) > >> > >>>>> > >>>>> It seems like it would be Rust best practice when implementing an > >>>>> interface to use the public API of the type to the extent possible, > and when > >>>>> necessary for efficiency or other reasons, to use unsafe and fiddle > with the > >>>>> private API. > >> > >> > >> It could be. But if I'm allowed to play the Devil's advocate this > implies > >> that any implentation detail must be thought as potentially accessible > (and > >> then as necessarily understandable / documented) from outside (what you > call > >> "private API"). This is not the typical approach when considering > private > >> data. > >> > >> _______________________________________________ > >> 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 > > > > You can write safe external iterators by using lifetimes. The compiler > will enforce that the list is frozen while you have iterators - > completely statically for all owned types, and dynamically for @mut > boxes. > _______________________________________________ > 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 clements at brinckerhoff.org Thu Apr 18 15:30:20 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 18 Apr 2013 15:30:20 -0700 Subject: [rust-dev] eliminate issue-2185.rs test? Message-ID: <28DF308D-B9BF-40BC-ABE5-E37870C9324C@brinckerhoff.org> the "issue-2185.rs" test was xfailed with a ref to #2263. Issue #2263 is now fixed, so I tried it again, and after adding some &self parameters, I got this error: Running /usr/local/bin/rustc: issue-2185.rs:24:0: 26:1 error: conflicting implementations for a trait issue-2185.rs:24 impl iterable for @fn(&fn(uint)) { issue-2185.rs:25 fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) ) } issue-2185.rs:26 } issue-2185.rs:20:0: 22:1 note: note conflicting implementation here issue-2185.rs:20 impl iterable for @fn(&fn(A)) { issue-2185.rs:21 fn iter(&self, blk: &fn(A)) { self(blk); } issue-2185.rs:22 } ? so it looks like it's just not possible to implement both the generic iterable and iterable for the type iterable. Is it okay if I just remove this test? John (text of slightly-patched issue-2185.rs follows:) // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // xfail-fast // This test had to do with an outdated version of the iterable trait. // However, the condition it was testing seemed complex enough to // warrant still having a test, so I inlined the old definitions. trait iterable { fn iter(&self, blk: &fn(A)); } impl iterable for @fn(&fn(A)) { fn iter(&self, blk: &fn(A)) { self(blk); } } impl iterable for @fn(&fn(uint)) { fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) ) } } fn filter>(self: IA, prd: @fn(A) -> bool, blk: &fn(A)) { do self.iter |a| { if prd(a) { blk(a) } } } fn foldl>(self: IA, b0: B, blk: &fn(B, A) -> B) -> B { let mut b = b0; do self.iter |a| { b = blk(b, a); } b } fn range(lo: uint, hi: uint, it: &fn(uint)) { let mut i = lo; while i < hi { it(i); i += 1u; } } pub fn main() { let range: @fn(&fn(uint)) = |a| range(0u, 1000u, a); let filt: @fn(&fn(v: uint)) = |a| filter( range, |&&n: uint| n % 3u != 0u && n % 5u != 0u, a); let sum = foldl(filt, 0u, |accum, &&n: uint| accum + n ); io::println(fmt!("%u", sum)); } From graydon at mozilla.com Thu Apr 18 15:34:51 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 18 Apr 2013 15:34:51 -0700 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: <516F1388.5070100@mozilla.com> References: <516F1388.5070100@mozilla.com> Message-ID: <5170750B.2040103@mozilla.com> On 13-04-17 02:26 PM, Graydon Hoare wrote: > On 17/04/2013 11:58 AM, Brandon Mintern wrote: >> Please let's not get derailed here. I wasn't bemoaning the difficulty of >> implementing list iterators. I was trying to offer a simple example >> everyone could understand to show when protected might be useful. There >> are definitely times when implementing an interface that it's more >> convenient or efficient to use an object's non-public API. >> >> This discussion is not about list iterators, it's about whether it makes >> sense to have any visibility other than public and private. I argued >> that protected doesn't buy much over using unsafe private. > > Yes. Our concept of visibility is a fair bit different from the way it > works in other OO languages. Rust's visibility modifiers control whether > one bit of code can see across a module boundary, no more. > > Fields of a struct are always visible to anyone who can see the struct > definition. Ah, of course, this is wrong; I forget people do sometimes set per-field visibility and it refines the concept of type visibility. I never use the per-field part. I guess all I was getting at is that pub and priv currently only relate to the module structure, not the impl structure. I think! And I think that makes them cognitively pretty straightforward, so I am generally against trying to entangle them with other concepts. You can see priv definitions when you're inside a module with it, otherwise not. That's an easy rule to explain and it seems to compose well given how powerful the module system is. (Moreover, I think the proposed form of "protected" would not really buy much protection anyway, since you could always make up a trait and implement it if you wanted access to such a field.) -Graydon From brandon at mintern.net Thu Apr 18 17:17:37 2013 From: brandon at mintern.net (Brandon Mintern) Date: Thu, 18 Apr 2013 17:17:37 -0700 Subject: [rust-dev] About a "protected" visibility modifier In-Reply-To: <5170750B.2040103@mozilla.com> References: <516F1388.5070100@mozilla.com> <5170750B.2040103@mozilla.com> Message-ID: On Thu, Apr 18, 2013 at 3:34 PM, Graydon Hoare wrote: > (Moreover, I think the proposed form of "protected" would not really buy > much protection anyway, since you could always make up a trait and > implement it if you wanted access to such a field.) > This is the approach that I agree with, as well. If there is a "protected" API, it is often better off being a trait that is only used by trait implementers. For example, a LinkedList might implement: trait QueueInternal { fn head<'r>(&'r self) -> Option<&'r DoublyLinkedNode>; fn tail<'r>(&'r self) -> Option<&'r DoublyLinkedNode>; } trait DoublyLinkedNode { fn next<'r>(&'r self) -> Option<&'r DoublyLinkedNode>; fn prev<'r>(&'r self) -> Option<&'r DoublyLinkedNode>; fn data(&self) -> T; } -------------- next part -------------- An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Fri Apr 19 03:49:44 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 19 Apr 2013 06:49:44 -0400 Subject: [rust-dev] eliminate issue-2185.rs test? In-Reply-To: <28DF308D-B9BF-40BC-ABE5-E37870C9324C@brinckerhoff.org> References: <28DF308D-B9BF-40BC-ABE5-E37870C9324C@brinckerhoff.org> Message-ID: I think it's fine to remove this test, just because it's old and cruft and not hard to reproduce. *However* it should eventually be possible to implement the same interface for the same type multiple times with different type parameters, it's just that our current trait implementation has accidental limitations. On Thu, Apr 18, 2013 at 6:30 PM, John Clements wrote: > the "issue-2185.rs" test was xfailed with a ref to #2263. Issue #2263 is > now fixed, so I tried it again, and after adding some &self parameters, I > got this error: > > Running /usr/local/bin/rustc: > issue-2185.rs:24:0: 26:1 error: conflicting implementations for a trait > issue-2185.rs:24 impl iterable for @fn(&fn(uint)) { > issue-2185.rs:25 fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) > ) } > issue-2185.rs:26 } > issue-2185.rs:20:0: 22:1 note: note conflicting implementation here > issue-2185.rs:20 impl iterable for @fn(&fn(A)) { > issue-2185.rs:21 fn iter(&self, blk: &fn(A)) { self(blk); } > issue-2185.rs:22 } > > ? so it looks like it's just not possible to implement both the generic > iterable and iterable for the type iterable. Is it okay if I > just remove this test? > > John > > (text of slightly-patched issue-2185.rs follows:) > > // Copyright 2012 The Rust Project Developers. See the COPYRIGHT > // file at the top-level directory of this distribution and at > // http://rust-lang.org/COPYRIGHT. > // > // Licensed under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license > // , at your > // option. This file may not be copied, modified, or distributed > // except according to those terms. > > // xfail-fast > // This test had to do with an outdated version of the iterable trait. > // However, the condition it was testing seemed complex enough to > // warrant still having a test, so I inlined the old definitions. > > trait iterable { > fn iter(&self, blk: &fn(A)); > } > > impl iterable for @fn(&fn(A)) { > fn iter(&self, blk: &fn(A)) { self(blk); } > } > > impl iterable for @fn(&fn(uint)) { > fn iter(&self, blk: &fn(v: uint)) { self( |i| blk(i) ) } > } > > fn filter>(self: IA, prd: @fn(A) -> bool, blk: &fn(A)) { > do self.iter |a| { > if prd(a) { blk(a) } > } > } > > fn foldl>(self: IA, b0: B, blk: &fn(B, A) -> B) -> B { > let mut b = b0; > do self.iter |a| { > b = blk(b, a); > } > b > } > > fn range(lo: uint, hi: uint, it: &fn(uint)) { > let mut i = lo; > while i < hi { > it(i); > i += 1u; > } > } > > pub fn main() { > let range: @fn(&fn(uint)) = |a| range(0u, 1000u, a); > let filt: @fn(&fn(v: uint)) = |a| filter( > range, > |&&n: uint| n % 3u != 0u && n % 5u != 0u, > a); > let sum = foldl(filt, 0u, |accum, &&n: uint| accum + n ); > > io::println(fmt!("%u", sum)); > } > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From a.stavonin at gmail.com Fri Apr 19 07:44:35 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Fri, 19 Apr 2013 18:44:35 +0400 Subject: [rust-dev] Passing managed value to task Message-ID: Do we have any possibility to do something like this or only owned values can be send? 11 fn task_with_shared_pointers() { 12 let value = @[1, 2, 3, 4, 5]; 13 let (server_chan, server_port) = stream(); 14 15 do task::spawn { 16 let val: @[uint] = server_chan.recv(); 17 io::println(fmt!("Value: %?", val)); 18 } 19 server_port.send(copy value); 20 } -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Apr 19 08:19:54 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 19 Apr 2013 08:19:54 -0700 Subject: [rust-dev] Passing managed value to task In-Reply-To: References: Message-ID: <5171609A.3060904@mozilla.com> On 13-04-19 07:44 AM, Alexander Stavonin wrote: > Do we have any possibility to do something like this or only owned > values can be send? Only owned values. -Graydon From danielmicay at gmail.com Fri Apr 19 08:31:53 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Fri, 19 Apr 2013 11:31:53 -0400 Subject: [rust-dev] Passing managed value to task In-Reply-To: References: Message-ID: On Fri, Apr 19, 2013 at 10:44 AM, Alexander Stavonin wrote: > Do we have any possibility to do something like this or only owned values > can be send? > > 11 fn task_with_shared_pointers() { > 12 let value = @[1, 2, 3, 4, 5]; > 13 let (server_chan, server_port) = stream(); > 14 > 15 do task::spawn { > 16 let val: @[uint] = server_chan.recv(); > 17 io::println(fmt!("Value: %?", val)); > 18 } > 19 server_port.send(copy value); > 20 } If you have @T where T is Owned, you have to explicitly copy the inner part with (*foo).clone() and send that. From pwalton at mozilla.com Fri Apr 19 08:50:25 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 19 Apr 2013 08:50:25 -0700 Subject: [rust-dev] Passing managed value to task In-Reply-To: References: Message-ID: <517167C1.3030808@mozilla.com> On 4/19/13 7:44 AM, Alexander Stavonin wrote: > Do we have any possibility to do something like this or only owned > values can be send? You can mark your data as serializable and use flatpipes. This gives you the ability to send managed values, at the cost of a copy on send. Essentially it's the Erlang model. I'd like to write a tutorial on this someday. Patrick From erick.tryzelaar at gmail.com Fri Apr 19 09:01:46 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Fri, 19 Apr 2013 09:01:46 -0700 Subject: [rust-dev] Passing managed value to task In-Reply-To: <517167C1.3030808@mozilla.com> References: <517167C1.3030808@mozilla.com> Message-ID: Here's a demonstration using flatpipes: extern mod std; use std::flatpipes; fn main() { let (server_chan, server_port) = flatpipes::serial::pipe_stream(); do task::spawn { let val: @[int] = server_chan.recv(); io::println(fmt!("Value: %?", val)); } let value = @[1, 2, 3, 4, 5]; server_port.send(value); } On Fri, Apr 19, 2013 at 8:50 AM, Patrick Walton wrote: > On 4/19/13 7:44 AM, Alexander Stavonin wrote: > >> Do we have any possibility to do something like this or only owned >> values can be send? >> > > You can mark your data as serializable and use flatpipes. This gives you > the ability to send managed values, at the cost of a copy on send. > Essentially it's the Erlang model. > > I'd like to write a tutorial on this someday. > > 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 clements at brinckerhoff.org Fri Apr 19 11:57:40 2013 From: clements at brinckerhoff.org (John Clements) Date: Fri, 19 Apr 2013 11:57:40 -0700 Subject: [rust-dev] trailing comma inconsistency between tuple-enum-variants and tuple-structs Message-ID: This program illustrates a small but irritating inconsistency between tuple-shaped enum variants and tuple-shaped structs: // trailing comma allowed here: struct F1(int,int,); struct F2(int,int); // trailing comma disallowed here: /*enum G1 { H1(int,int,) }*/ enum G2 { H2(int,int) } In structs, there can be a trailing comma after the types. In enums, there cannot be. I feel strongly that these should be the same, though I don't care which one it is. Anyone? John From banderson at mozilla.com Fri Apr 19 12:03:32 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 19 Apr 2013 12:03:32 -0700 Subject: [rust-dev] trailing comma inconsistency between tuple-enum-variants and tuple-structs In-Reply-To: References: Message-ID: <51719504.3010009@mozilla.com> On 04/19/2013 11:57 AM, John Clements wrote: > This program illustrates a small but irritating inconsistency between tuple-shaped enum variants and tuple-shaped structs: > > // trailing comma allowed here: > struct F1(int,int,); > struct F2(int,int); > // trailing comma disallowed here: > /*enum G1 { > H1(int,int,) > }*/ > enum G2 { > H2(int,int) > } > > In structs, there can be a trailing comma after the types. In enums, there cannot be. I feel strongly that these should be the same, though I don't care which one it is. > > Anyone? > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev I guess the comma should be allowed to be consistent with tuples and vectors. From jack at metajack.im Fri Apr 19 12:20:44 2013 From: jack at metajack.im (Jack Moffitt) Date: Fri, 19 Apr 2013 13:20:44 -0600 Subject: [rust-dev] trailing comma inconsistency between tuple-enum-variants and tuple-structs In-Reply-To: <51719504.3010009@mozilla.com> References: <51719504.3010009@mozilla.com> Message-ID: > I guess the comma should be allowed to be consistent with tuples and > vectors. +1 jack. From andres.osinski at gmail.com Sat Apr 20 00:56:26 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Sat, 20 Apr 2013 04:56:26 -0300 Subject: [rust-dev] What is the difference between cell and Option? Message-ID: Reading through the docs it seems as though cell contains an Option, and Option just contains the value or None, much like Haskell Maybe monad. I fail to see what use cell has that cannot be done with Option. -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sat Apr 20 00:59:50 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 20 Apr 2013 00:59:50 -0700 Subject: [rust-dev] What is the difference between cell and Option? In-Reply-To: References: Message-ID: <51724AF6.9090007@mozilla.com> On 4/20/13 12:56 AM, Andres Osinski wrote: > Reading through the docs it seems as though cell contains an Option, and > Option just contains the value or None, much like Haskell Maybe monad. I > fail to see what use cell has that cannot be done with Option. Cell allows you to more clearly specify your intent. You can do everything with Cell with Option--it's called the "option dance"--but it can be harder to read. In particular, Cell is preferred over Option when working around the current lack of one-shot closures (i.e. when you want to move out of a closure). Patrick From andres.osinski at gmail.com Sat Apr 20 02:43:04 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Sat, 20 Apr 2013 06:43:04 -0300 Subject: [rust-dev] Mutable struct member destructuring Message-ID: I was in a situation where I'd like to modify multiple attributes in a struct at once. Knowing that Rust theoretically supports tuple destructuring I attempted the following: let (hints.ai_family, hints.ai_socktype) = (AF_INET, SOCK_STREAM); where hints is the struct in question, yet that threw a syntax error. Removing the let keyword did not work. I know that this is not specified in the language, but coming from other languages where destructuring can be done for anything that's an lvalue, it seems as though it would be intuitive and practical to have struct member destructuring, or support just any kind of lvalue assignment; it seems highly declarative of intent, and frankly looks very readable and a nice way to structure assigment visually. I'm stretching the analogy a bit but it would make it slightly closer to a LISP let-block. -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From andres.osinski at gmail.com Sat Apr 20 03:33:52 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Sat, 20 Apr 2013 07:33:52 -0300 Subject: [rust-dev] Unix socket lib bindings Message-ID: Hi everyone, this is just to let you guys know that I've updated a piece of older C socket library bindings to Rust 0.6. I understand Rust intends to go with native libuv bindings for handling sockets, but I'm much more familiar with BSD sockets and having native bindings won't be hurting anyone. If anyone wishes to take a look you can check it out at https://github.com/AndresOsinski/rust-socket . Kudos to the original author who wrote the first implementation at https://github.com/jdm/rust-socket; I've only made it compile on the latest version of the language. I've taken a very big interest in the language and I'd like to contribute as an end user to see how the language features work out in practice for library code. Thanks -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From zack at z0w0.me Sat Apr 20 05:03:49 2013 From: zack at z0w0.me (Zack Corr) Date: Sat, 20 Apr 2013 22:03:49 +1000 Subject: [rust-dev] Unix socket lib bindings In-Reply-To: References: Message-ID: You should make a pull request to include this under libc. I think its a fitting place for it. On 20 Apr 2013 20:34, "Andres Osinski" wrote: > Hi everyone, this is just to let you guys know that I've updated a piece > of older C socket library bindings to Rust 0.6. I understand Rust intends > to go with native libuv bindings for handling sockets, but I'm much more > familiar with BSD sockets and having native bindings won't be hurting > anyone. > > If anyone wishes to take a look you can check it out at > https://github.com/AndresOsinski/rust-socket . Kudos to the original > author who wrote the first implementation at > https://github.com/jdm/rust-socket; I've only made it compile on the > latest version of the language. I've taken a very big interest in the > language and I'd like to contribute as an end user to see how the language > features work out in practice for library code. > > Thanks > > -- > Andr?s Osinski > http://www.andresosinski.com.ar/ > > _______________________________________________ > 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 walter_bz at hotmail.com Sat Apr 20 06:07:40 2013 From: walter_bz at hotmail.com (walter lynsdale) Date: Sat, 20 Apr 2013 13:07:40 +0000 Subject: [rust-dev] rust->ARM asm -> iphone attempt Message-ID: perhaps naievely i thought i could generate source from rust that i couuld compile into an iOS project; i'm flailing around with minimal knowledge of the toolchain here. (originally i hoped i could go rust->LLVM IR->C but thats no longer available ) my current attempt is to use generated ARM assembly source, rustc -S main.rs -o main.s -Z no-asm-comment If i include this resulting source in an iOS project i run into what appears to be unsupported directives - eg .save, .setfp ; also __aeabi_fadd(PLT) i'm told some of these are "metadata for exception handling", and the (PLT) can just be removed. Other than more hacks (like trying to strip various directives with regex :) ) - does anyone have any further ideas on what I could try - maybe there are more optiona on what rust is trying to generate .eabi_attribute 6, 2 .eabi_attribute 8, 1 .eabi_attribute 9, 1 .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .file "main.rc" .text .globl _ZN14__extensions__9meth_24273add17_7a292226f3cda72f3_00E .align 2 .type _ZN14__extensions__9meth_24273add17_7a292226f3cda72f3_00E,%function _ZN14__extensions__9meth_24273add17_7a292226f3cda72f3_00E: .fnstart .Leh_func_begin0: .save {r11, lr} <<<<<<<<<<<<<<<<<< push {r11, lr} .setfp r11, sp <<<<<<<<<<< mov r11, sp .pad #24 sub sp, sp, #24 ldr r3, [r1] ldr r12, [r2] ldr r3, [r3] str r0, [r11, #-4] mov r0, r3 str r1, [r11, #-8] mov r1, r12 str r2, [sp, #12] bl __aeabi_fadd(PLT) <<<<<<<<<<<<<<<< ldr r1, [r11, #-4] str r0, [r1] ldr r0, [r11, #-8] ldr r2, [r0] ldr r3, [sp, #12] -------------- next part -------------- An HTML attachment was scrubbed... URL: From a.stavonin at gmail.com Sat Apr 20 10:44:06 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Sat, 20 Apr 2013 21:44:06 +0400 Subject: [rust-dev] Passing managed value to task In-Reply-To: References: Message-ID: Unfortunately, my value is not Owned but Shared. So, what is the cheapest way for making conversion between Owned -> Shared and Shared -> Owned? On Apr 19, 2013, at 7:31 PM, Daniel Micay wrote: > On Fri, Apr 19, 2013 at 10:44 AM, Alexander Stavonin > wrote: >> Do we have any possibility to do something like this or only owned values >> can be send? >> >> 11 fn task_with_shared_pointers() { >> 12 let value = @[1, 2, 3, 4, 5]; >> 13 let (server_chan, server_port) = stream(); >> 14 >> 15 do task::spawn { >> 16 let val: @[uint] = server_chan.recv(); >> 17 io::println(fmt!("Value: %?", val)); >> 18 } >> 19 server_port.send(copy value); >> 20 } > > If you have @T where T is Owned, you have to explicitly copy the inner > part with (*foo).clone() and send that. From a.stavonin at gmail.com Sun Apr 21 05:17:35 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Sun, 21 Apr 2013 16:17:35 +0400 Subject: [rust-dev] Main idea of DuplexStream Message-ID: I'm trying to understand the idea of DuplexStream. First of all, it can't be used for cross-task communications: 13 let value = gen_data(); 14 let (server, client) = DuplexStream(); 15 16 do task::spawn { 17 let val: ~[uint] = server.recv(); 18 io::println(fmt!("Value: %?", val)); 19 let res = val.map(|v| {v+1}); 20 client.send(res) 21 } 22 23 server.send(value); 24 io::println(fmt!("Resilt: %?", client.recv())); because of error: "21:5 note: `server` moved into closure environment here because its type is moved by default". In library sources I found example which passes messages inside one task, what IMHO is not too useful. Would you please provide a brief explanation of DuplexStream usage scenario? From dbau.pp at gmail.com Mon Apr 22 05:54:13 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Mon, 22 Apr 2013 22:54:13 +1000 Subject: [rust-dev] Traits and @ boxes in stdlib/rustc Message-ID: <517532F5.9070701@gmail.com> Hi all, I've got a few questions: There are many instances of functions returning and taking dynamic trait objects in @ boxes (e.g. all of the io functions, things dealing with core::rand::Rng, core::run::Program) rather than a plain type (for return values) or a generic (for arguments), this seems a little peculiar given it (probably?) has a runtime cost due to the vtables and the extra GC required. Is this legacy code that hasn't been updated yet? And, is there a reason for it remain in the dynamic objects form? (I know there's no point touching the io stuff since it is all being redone.) To give an example, I'm talking about converting items like (all from core::rand) fn Rng() -> @Rng fn rand(rng: @rand::Rng) -> Self impl RngUtil for @Rng to fn Rng() -> RandRes fn rand(rng: &R) -> Self impl RngUtil for R On a similar note, there are multiple instances in syntax and rustc where there is trait defined, impl'd for a single type and used as a @trait dynamic object, rather than just putting the functions on an impl for the type and using the type without the dynamic indirection (e.g. in libsyntax/ext/base.rs, the trait ext_ctxt and the struct CtxtRepr). Would doing a similar transformation to remove the indirection be desired? I'm asking because there is quite a few occurrences of these patterns through out the rust repo so there is quite probably something non-obvious about them. Huon From niko at alum.mit.edu Mon Apr 22 07:30:10 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Mon, 22 Apr 2013 10:30:10 -0400 Subject: [rust-dev] Traits and @ boxes in stdlib/rustc In-Reply-To: <517532F5.9070701@gmail.com> References: <517532F5.9070701@gmail.com> Message-ID: Generally speaking this is legacy code that has not yet been updated. On Mon, Apr 22, 2013 at 8:54 AM, Huon Wilson wrote: > Hi all, > > I've got a few questions: > > There are many instances of functions returning and taking dynamic > trait objects in @ boxes (e.g. all of the io functions, things dealing > with core::rand::Rng, core::run::Program) rather than a plain type > (for return values) or a generic (for arguments), this seems a little > peculiar given it (probably?) has a runtime cost due to the vtables > and the extra GC required. Is this legacy code that hasn't been > updated yet? And, is there a reason for it remain in the dynamic > objects form? (I know there's no point touching the io stuff since it > is all being redone.) > > To give an example, I'm talking about converting items like (all > from core::rand) > > fn Rng() -> @Rng > fn rand(rng: @rand::Rng) -> Self > impl RngUtil for @Rng > > to > > fn Rng() -> RandRes > fn rand(rng: &R) -> Self > impl RngUtil for R > > > On a similar note, there are multiple instances in syntax and rustc > where there is trait defined, impl'd for a single type and used as a > @trait dynamic object, rather than just putting the functions on an > impl for the type and using the type without the dynamic indirection > (e.g. in libsyntax/ext/base.rs, the trait ext_ctxt and the struct > CtxtRepr). Would doing a similar transformation to remove the > indirection be desired? > > > I'm asking because there is quite a few occurrences of these patterns > through out the rust repo so there is quite probably something > non-obvious about them. > > > Huon > > ______________________________**_________________ > 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 adaszko at gmail.com Sat Apr 20 16:15:02 2013 From: adaszko at gmail.com (Adam Szkoda) Date: Sun, 21 Apr 2013 01:15:02 +0200 Subject: [rust-dev] Code hot-swapping Message-ID: <20130420231502.GA63794@grom.local> Hello, First of all, let me just say that Rust is quite a beauty and I look forward to how it will develop. Discovering that there?s an interactive interpreter (rusti) was a very pleasant surprise. Taking this a step further, I would like to ask what?s the language designers? stance on hot code swapping a la Erlang or Common Lisp. Thanks ? Adam From tsam at tormail.org Sun Apr 21 00:09:08 2013 From: tsam at tormail.org (tsam at tormail.org) Date: Sun, 21 Apr 2013 07:09:08 -0000 Subject: [rust-dev] No range integer type? Saftey beyond memory? Message-ID: <1UToOa-000PkW-TJ@internal.tormail.org> I am very excited to hear about Rust because the world is greatly in need of a language which increases safety and expressiveness without compromising performance and this seems to be one of the motivations behind Rust. But I am concerned that ranged types are not a core part of the language, or even overflow-checked machine types. Our profession should be embarrassed that memory safety is still but it looks like Rust has a chance of finally solving it. But memory safety is only one part of creating reliable software. Java has substantial memory safety, although not as much as Rust, and still java software is full of bugs... perhaps a higher defect rate than common C code once you correct for java's verbosity. I worry that once Rust fixes memory safety it will quickly be time to replace Rust to correct all the other programmer-traps. On example is overflow. This is a common source of flaws in C/C++ software. Instrumenting to detect overflow is difficult, and it is difficult or impossible to determine the permitted ranges output from library functions in order to by-hand statically certify software against overflow. Tools like valgrind make memory safety often fairly painless but overflow and other kinds of logic flaws cannot be easily statically or dynamically detected because the languages (and machine code) do not express enough for the machine to tell when the behavior is wrong. In Rust (like C) there doesn't appear to be any way to access the processor flags to cheaply detect overflow on machine types, so writing your "safe integer objects" will likely have poor performance and of course not work with the standard libraries. Integrated ranged types would also be synergistic with memory safety since a function which takes limited-range inputs can sometimes be statically proven memory-safe when it couldn't otherwise be, allowing the boundary check to be hoisted out of functions entirely even across closed-source-library boundaries when their interfaces are range constrained. Some C compilers now offer an int128 type that uses the fast hardware carry support, which makes certain kinds of overflow safety easier (for example 64bit x 64bit cannot overflow int128) as long as you don't mind non-portable code, but it doesn't appear that Rust has this either. Overflow is something that ada seems to handle well, but ada doesn't really seem to be in the running for a wide spread next language outside of certain niches. I hope some thought has been given to how greater safety could be added later without making an inconsistent mess of the language. In any case, thank you for the exciting new language! From snowmantw at gmail.com Mon Apr 22 01:22:29 2013 From: snowmantw at gmail.com (Greg Weng) Date: Mon, 22 Apr 2013 16:22:29 +0800 Subject: [rust-dev] [GSoC 2013] May I ask some questions about the Rust debugging symbols idea ? Message-ID: Sorry if I seemed too rude to ask these questions here... 1. The `debuginfo.rs` seems already implemented some LLVM debugging symbols outputting functions, like `create_vec` or `create_local_var`. But currently I can only find `create_local_var` already been used in other components, and others are missing. So, should the first step be generating LLVM debugging information in every language unit while compiling them ? 2. The Rust compiler owns the `-Z extra-debug-info` option, but it didn't work and seems related to the not yet implemented debugging symbol feature. Is this option created for outputting all language units' LLVM debugging information ? Or it's expected to do more things than this ? 3. I've did some researching works on Rustc and LLVM debugging symbol features, and will start to try to add those outputting function in other components. Is any other step should I take to prepare the project ? Greg Weng snowmantw at gamil.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Mon Apr 22 09:01:53 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Mon, 22 Apr 2013 09:01:53 -0700 Subject: [rust-dev] Traits and @ boxes in stdlib/rustc In-Reply-To: <517532F5.9070701@gmail.com> References: <517532F5.9070701@gmail.com> Message-ID: <51755EF1.6080302@mozilla.com> On 4/22/13 5:54 AM, Huon Wilson wrote: > Hi all, > > I've got a few questions: > > There are many instances of functions returning and taking dynamic > trait objects in @ boxes (e.g. all of the io functions, things dealing > with core::rand::Rng, core::run::Program) rather than a plain type > (for return values) or a generic (for arguments), this seems a little > peculiar given it (probably?) has a runtime cost due to the vtables > and the extra GC required. Is this legacy code that hasn't been > updated yet? And, is there a reason for it remain in the dynamic > objects form? (I know there's no point touching the io stuff since it > is all being redone.) You're correct. The `@` smart pointers in `io` are currently the #1 performance problem with Rust in benchmarks that people write. (They're also responsible for a lot of unsafe code in the benchmarks-game benchmarks that could otherwise be fully safe.) The new `rt::io` module [1] is being designed to avoid this. That module will replace `io` when it's ready. > To give an example, I'm talking about converting items like (all > from core::rand) > > fn Rng() -> @Rng > fn rand(rng: @rand::Rng) -> Self > impl RngUtil for @Rng > > to > > fn Rng() -> RandRes > fn rand(rng: &R) -> Self > impl RngUtil for R Yes, I wanted to do just that at some point. Patches welcome :) Patrick [1]: https://github.com/brson/rust/tree/io From graydon at mozilla.com Mon Apr 22 09:04:29 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 22 Apr 2013 09:04:29 -0700 Subject: [rust-dev] Code hot-swapping In-Reply-To: <20130420231502.GA63794@grom.local> References: <20130420231502.GA63794@grom.local> Message-ID: <51755F8D.1080704@mozilla.com> On 20/04/2013 4:15 PM, Adam Szkoda wrote: > First of all, let me just say that Rust is quite a beauty and I look > forward to how it will develop. Thanks! > Discovering that there?s an interactive interpreter (rusti) was a very > pleasant surprise. Taking this a step further, I would like to ask > what?s the language designers? stance on hot code swapping a la Erlang > or Common Lisp. That it's incompatible with the way PLTs currently work on various operating systems, so out of scope. Sorry. When we were doing our own runtime linking (yes, really) this was more possible. Now that we're trying to integrate with the native C toolchains (including runtime linker), it's not, and won't be. -Graydon From graydon at mozilla.com Mon Apr 22 09:06:16 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 22 Apr 2013 09:06:16 -0700 Subject: [rust-dev] Traits and @ boxes in stdlib/rustc In-Reply-To: <517532F5.9070701@gmail.com> References: <517532F5.9070701@gmail.com> Message-ID: <51755FF8.7060409@mozilla.com> On 22/04/2013 5:54 AM, Huon Wilson wrote: > I'm asking because there is quite a few occurrences of these patterns > through out the rust repo so there is quite probably something > non-obvious about them. Pure legacy code from when we had no better solutions for abstraction. The older the code in stdlibs, the more likely it doesn't use traits at all, and/or uses @-boxed objects or similar slower abstractions. Patches to fix all this stuff very much welcome. It's on our list! -Graydon From graydon at mozilla.com Mon Apr 22 09:18:54 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 22 Apr 2013 09:18:54 -0700 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <1UToOa-000PkW-TJ@internal.tormail.org> References: <1UToOa-000PkW-TJ@internal.tormail.org> Message-ID: <517562EE.4000303@mozilla.com> On 21/04/2013 12:09 AM, tsam at tormail.org wrote: > I worry that once Rust fixes memory safety it will quickly be > time to replace Rust to correct all the other programmer-traps. Yeah. There are unfortunately always limits and compromises when making a real language. Rust is attacking a very difficult niche so we have to spend a lot of energy on things that are not strictly about safety. But I appreciate your concern. > In Rust (like C) there doesn't appear to be any way to access the > processor flags to cheaply detect overflow on machine types It would be done with some per-platform inline asm (which we support now), or intrinsics, or an attribute on (say) newtyped integral types. Any of these would probably be ok. The attribute form would make it part of the type, so you'd wind up with checks performed on cast boundaries as well as any non-approximated operations. > your "safe integer objects" will likely have poor performance and of > course not work with the standard libraries. I believe any such integration -- inline asm, intrinsics or attribute -- would be similar, performance-wise. Maybe LLVM's scheduler could do a better job with them if it knows more about the instruction (an argument for intrinsics), and if it knows about the type range itself it may eliminate certain branches as dead code, but otherwise inlining should boil off most of the abstractions equivalently. > Integrated ranged types would > also be synergistic with memory safety since a function which takes > limited-range inputs can sometimes be statically proven memory-safe when > it couldn't otherwise be, allowing the boundary check to be hoisted out of > functions entirely even across closed-source-library boundaries when their > interfaces are range constrained. Not entirely. There are always limited approximations at work in these things; range checks can only be statically eliminated in some cases when the approximation is tight, otherwise it has to be repeated on each potentially range-violating arithmetic operation. LLVM does expose range-limited types and, presumably, does some such check-elimination. I'd not be opposed to absorbing this via a well-integrated attribute on integer types. We've also had some requests for a mechanism to enable overflow checking on _all_ integer types within a given static or dynamic program extent, using attributes. And similar things are going to be desirable wrt. the floating point environment, which is trickier since it's latent in the CPU state rather than the (static) operations performed. Again, I'd be happy to work through developing patches for this and exploring the problem space. It's a set of bugs usually swept under the rug in C. > Overflow is something that ada seems to handle well, but ada doesn't > really seem to be in the running for a wide spread next language outside > of certain niches. Agreed. -Graydon From psa at di.uminho.pt Mon Apr 22 09:21:38 2013 From: psa at di.uminho.pt (=?UTF-8?B?UGF1bG8gU8OpcmdpbyBBbG1laWRh?=) Date: Mon, 22 Apr 2013 17:21:38 +0100 Subject: [rust-dev] Simplifying lifetime expression Message-ID: <51756392.5050202@di.uminho.pt> Hi all, (My first post here.) First, congrats for what you are trying to achieve with Rust. I arrived very late to the party, and so I am not sure that what I will say can be of use. But as I understand, lifetimes is one of those things that are not completely solidified, and anyway, better late than never. Looking at some code, expressing lifetimes of borrowed references is one of those things that is somewhat bewildering, making the code somewhat noisy. I think it can be improved through a better choice of defaults and a slight change in explicit lifetimes. The main thing I think is "wrong" is the defaults for function parameters. From the tutorial: "the compiler simply creates a fresh name for the lifetime automatically: that is, the lifetime name is guaranteed to refer to a distinct lifetime from the lifetimes of all other parameters." This default is not very useful. For example, it is wrong basically everytime we want to return a borrowed pointer (unless, for a global variable?). The more common case is returning something with the same lifetime as some parameter. In many cases we don't need to distinguish parameters, and specify which we are returning, in others we want to split parameters in two equivalence classes, the one from which we are returning, and everything else. When type parameters are involved, a return type typically says where the result comes from most of the times. Again, the default should be different. E.g., when we are returning a borrowed reference to a "key" of type parameter K, the default should be "other things also of type K in parameters". Finally, with better defaults, in the remaining cases where we need to explicitly express lifetimes, having to "invent" identifiers is a nuisance. Also the space which must be used between the lifetime identifier and the type is too distracting and makes it cumbersome (for humans) to "parse" the type of some identifier. I have been thinking about this and have the following proposal. (Of course there may be inumerous things that must have escaped me, but here it goes anyway.) --- Regarding types for borrowed references in function parameters or result, and type parameters: 1) each type-parameter has an associated implicit lifetime, which by default is different from the lifetimes of other type-parameters or normal function parameter types, but it can be qualified in each declaration or use with an explicit lifetime; 2) function parameter types or return type that are not type parameters have all the same implicit lifetime by default, but they can be qualified explicitly with some lifetime. 3) explicit lifetimes are written identifier' instead of 'identifier; a null identifier is allowed, as in &'T, to qualify a reference &T with lifetime '. --- (Another useful possibility would be allowing several ' at the end, allowing e.g., &T, &'T, &''T as borrowed references to the same type but with different lifetimes. In practice, a single ' plus 1) and 2) will cover "99%" of cases. We could even get rid of using identifiers, using only several '. But this is not relevant for the main proposal.) 1) and 2) are about defaults for implicit lifetimes, which currently are "fresh lifetime for each parameter", and 3) is about simplifying the remaining cases of explicit expression. The motivation for 3) is to remove both the need of a space separating lifetime from type and also the need to "invent" lifetime identifiers. Rewriting examples from the tutorial and elsewhere, under this proposal, would make code more legible and standard, reducing a lot the need for explicit lifetime expression. Things would "just work" as wanted most times. -------------------------------------------------------------------------------- From the Rust Borrowed Pointers Tutorial --- fn get_x<'r>(p: &'r Point) -> &'r float { &p.x } becomes fn get_x(p: &Point) -> &float { &p.x } --- fn select<'r, T>(shape: &'r Shape, threshold: float, a: &'r T, b: &'r T) -> &'r T { if compute_area(shape) > threshold {a} else {b} } becomes fn select<'T>(shape: &'Shape, threshold: float, a: &'T, b: &'T) -> &'T { if compute_area(shape) > threshold {a} else {b} } (not very useful case) --- fn select<'r, T>(shape: &Shape, threshold: float, a: &'r T, b: &'r T) -> &'r T { if compute_area(shape) > threshold {a} else {b} } becomes fn select(shape: &Shape, threshold: float, a: &T, b: &T) -> &T { if compute_area(shape) > threshold {a} else {b} } -------------------------------------------------------------------------------- Other examples: --- struct Iterator<'lt, T> { source: &'lt [T], index: uint } fn has_next<'a, 'b, T>(iter: &'a Iterator<'b, T>) -> bool { iter.index + 1 < iter.source.len() } fn next<'a, 'b, T>(iter: &'a mut Iterator<'b, T>) -> Option<&'b T> { iter.index += 1; if iter.index < iter.source.len() { Some(&iter.source[iter.index]) } else { None } } becomes: struct Iterator<'T> { source: &'[T], index: uint } fn has_next(iter: &Iterator) -> bool { iter.index + 1 < iter.source.len() } fn next(iter: &mut Iterator) -> Option<&T> { iter.index += 1; if iter.index < iter.source.len() { Some(&iter.source[iter.index]) } else { None } } --- impl<'b, T> Iterator<'b, T> { fn has_next(&self) { /* same as before */ } fn next(&mut self) -> Option<&'b T> { /* same as before */ } } becomes impl Iterator { fn has_next(&self) { /* same as before */ } fn next(&mut self) -> Option<&T> { /* same as before */ } } --- Regards, Paulo -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at dhardy.name Mon Apr 22 09:48:58 2013 From: lists at dhardy.name (Diggory Hardy) Date: Mon, 22 Apr 2013 18:48:58 +0200 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: <51756392.5050202@di.uminho.pt> References: <51756392.5050202@di.uminho.pt> Message-ID: <4158220.SHD5kegRtM@l10036> Please don't use HTML when posting to lists. > 2) function parameter types or return type that are not type parameters have > all the same implicit lifetime by default, but they can be qualified > explicitly with some lifetime. That would mean that a function with default-lifetime parameters taking two borrowing references could not be called when the two parameters have different lifetime, if I understand correctly (though I am not aware of the whole situation). Example: fn f<'l>(x : & 'l int, y : & 'l int) -> & 'l int { x } fn caller<'l>(x : & 'l int) -> & 'l int { let y = 2; f(x, &y) } fn main() { let x = 5; io::println(fmt!("%i", *caller(&x))); } (This fails, but giving parameter y an independent lifetime makes it succeed.) From josh at joshmatthews.net Mon Apr 22 09:58:42 2013 From: josh at joshmatthews.net (Josh Matthews) Date: Mon, 22 Apr 2013 18:58:42 +0200 Subject: [rust-dev] [GSoC 2013] May I ask some questions about the Rust debugging symbols idea ? In-Reply-To: References: Message-ID: Hi Greg, These questions are fine. The key point you're missing in the existing debug code is that most of the functions in debuginfo.rs are called from within functions like create_local_var. I just realized that I linked to the potentially outdated version of the file on the master branch; https://github.com/mozilla/rust/blob/incoming/src/librustc/middle/trans/debuginfo.rsis the more interesting one as it shows how some of the other functions are called in create_ty. The actual API of debuginfo.rs from the point of view of the rest of rustc is quite limited; the rest of the compiler is usually only concerned with marking high-level constructs such as variables, functions, files, and line numbers. To answer your question, yes, the primary work of the project would be to finish the obvious gaps in the existing code in debuginfo.rs (such as the unimplemented types in create_ty) and create tests that exercise them all thoroughly. From there, the goal is to get rustc itself building with full debug symbols. The `-Z extra-debug-info` argument was put in place because the debug symbol generation was incomplete, and we hide incomplete things behind -Z flags. Once we expect debug symbol generation to work for arbitrary programs, we'll fold extra-debug-info into the existing -g flag. Cheers, Josh On 22 April 2013 10:22, Greg Weng wrote: > Sorry if I seemed too rude to ask these questions here... > > 1. The `debuginfo.rs` seems already implemented some LLVM debugging > symbols outputting functions, like `create_vec` or `create_local_var`. But > currently I can only find `create_local_var` already been used in other > components, and others are missing. > > So, should the first step be generating LLVM debugging information in > every language unit while compiling them ? > > 2. The Rust compiler owns the `-Z extra-debug-info` option, but it didn't > work and seems related to the not yet implemented debugging symbol feature. > Is this option created for outputting all language units' LLVM debugging > information ? Or it's expected to do more things than this ? > > 3. I've did some researching works on Rustc and LLVM debugging symbol > features, and will start to try to add those outputting function in other > components. Is any other step should I take to prepare the project ? > > Greg Weng > snowmantw at gamil.com > > _______________________________________________ > 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 psa at di.uminho.pt Mon Apr 22 11:10:05 2013 From: psa at di.uminho.pt (=?ISO-8859-1?Q?Paulo_S=E9rgio_Almeida?=) Date: Mon, 22 Apr 2013 19:10:05 +0100 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: <4158220.SHD5kegRtM@l10036> References: <51756392.5050202@di.uminho.pt> <4158220.SHD5kegRtM@l10036> Message-ID: <51757CFD.5040001@di.uminho.pt> On 4/22/13 5:48 PM, Diggory Hardy wrote: > Please don't use HTML when posting to lists. Sorry. I hope this one goes in plain text. (Added a text domain to Thunderbird.) >> 2) function parameter types or return type that are not type parameters have >> all the same implicit lifetime by default, but they can be qualified >> explicitly with some lifetime. > That would mean that a function with default-lifetime parameters taking two > borrowing references could not be called when the two parameters have different > lifetime, if I understand correctly (though I am not aware of the whole > situation). Example: > > fn f<'l>(x : & 'l int, y : & 'l int) -> & 'l int { > x > } This case would be written, with the same meaning, as: fn f(x : &int, y : &int) -> &int { x } > > fn caller<'l>(x : & 'l int) -> & 'l int { > let y = 2; > f(x, &y) > } fn caller(x : &int) -> &int { let y = 2; f(x, &y) } > > fn main() { > let x = 5; > io::println(fmt!("%i", *caller(&x))); > } > > (This fails, but giving parameter y an independent lifetime makes it succeed.) And would fail for the same reason. We would want to write, in the new proposal: fn f(x : &int, y : &'int) -> &int { x } or fn f(x : &'int, y : &int) -> &'int { x } and fn caller(x : &int) -> &int { let y = 2; f(x, &y) } And it would work as desired with quite less noise (with just one or two ' more than the plain version without lifetimes). Regards, Paulo > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From lists at dhardy.name Mon Apr 22 12:12:09 2013 From: lists at dhardy.name (Diggory Hardy) Date: Mon, 22 Apr 2013 21:12:09 +0200 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: <51757CFD.5040001@di.uminho.pt> References: <51756392.5050202@di.uminho.pt> <4158220.SHD5kegRtM@l10036> <51757CFD.5040001@di.uminho.pt> Message-ID: <3429478.fd3o27CIpT@l10036> > > fn f<'l>(x : & 'l int, y : & 'l int) -> & 'l int { > > > > x > > > > } > > This case would be written, with the same meaning, as: > > fn f(x : &int, y : &int) -> &int { > x > } > ... > > > > (This fails, but giving parameter y an independent lifetime makes it > > succeed.) > And would fail for the same reason. We would want to write, in the new > proposal: > > fn f(x : &int, y : &'int) -> &int { > x > } Yes, that's what I thought. Doesn't it make it too easy to write broken functions? On second thought, the broken functions are not dangerous and are easy to correct, so it might be worth the trade off. Kind-of sucks that new developers have think about things like variable lifetime with your changes (actually, even when no reference is returned, in your proposal). With the current syntax it isn't necessary per-se (in some cases a copy could be made instead of returning a reference). Best leave to Rust devs to comment further (I'm also new on the list). From banderson at mozilla.com Mon Apr 22 12:51:39 2013 From: banderson at mozilla.com (Brian Anderson) Date: Mon, 22 Apr 2013 12:51:39 -0700 Subject: [rust-dev] Main idea of DuplexStream In-Reply-To: References: Message-ID: <517594CB.4040307@mozilla.com> On 04/21/2013 05:17 AM, Alexander Stavonin wrote: > I'm trying to understand the idea of DuplexStream. First of all, it can't be used for cross-task communications: > > 13 let value = gen_data(); > 14 let (server, client) = DuplexStream(); > 15 > 16 do task::spawn { > 17 let val: ~[uint] = server.recv(); > 18 io::println(fmt!("Value: %?", val)); > 19 let res = val.map(|v| {v+1}); > 20 client.send(res) > 21 } > 22 > 23 server.send(value); > 24 io::println(fmt!("Resilt: %?", client.recv())); > > because of error: "21:5 note: `server` moved into closure environment here because its type is moved by default". > > In library sources I found example which passes messages inside one task, what IMHO is not too useful. > Would you please provide a brief explanation of DuplexStream usage scenario? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev Each end can both send and receive, so only one end needs to be moved into the closure: let (server, client) = DuplexStream(); do spawn { let val = server.recv(); let res = val.map(|v| v + 1); server.send(res); } client.send(value); let res = client.recv(); From clements at brinckerhoff.org Mon Apr 22 16:58:34 2013 From: clements at brinckerhoff.org (John Clements) Date: Mon, 22 Apr 2013 16:58:34 -0700 Subject: [rust-dev] Rust ANTLR grammar may be correct Message-ID: The rust ANTLR grammar that lives at https://github.com/jbclements/rust-antlr/ appears to be largely correct, in the sense that it parses Rust source. There's a problem, in that the parser is currently SO DARN SLOW that I haven't been able to test it on the entirety of the rust repository yet. Parsing of TTs runs at about 2K lines per second, but the full program grammar starts at 200 lines/sec, then drops to 50, and finally may simply stall out completely. Fortunately, running fast is not the point. I've made a passing attempt to format the grammar to be readable and to conform to certain formatting conventions. I'd be grateful to anyone who has the time to make suggestions. NB, for those interested: our "restriction" mechanism, as expected, makes the rules for expression parsing much less pleasant; in particular, most of the expr hierarchy is duplicated at least once, and some of it is duplicated three times. Thanks for your time! John From sebastian.sylvan at gmail.com Mon Apr 22 19:42:22 2013 From: sebastian.sylvan at gmail.com (Sebastian Sylvan) Date: Mon, 22 Apr 2013 19:42:22 -0700 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <517562EE.4000303@mozilla.com> References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> Message-ID: FWIW I'd *love* if all integer types could get efficient dynamic range checking turned on in Debug builds. So it wouldn't be a safety issue in the traditional sense because it would be disabled in shipping builds, but it would be great for catching bugs. Still needs to be efficient because Debug builds that aren't interactive don't get used for development. On Mon, Apr 22, 2013 at 9:18 AM, Graydon Hoare wrote: > On 21/04/2013 12:09 AM, tsam at tormail.org wrote: > > I worry that once Rust fixes memory safety it will quickly be >> time to replace Rust to correct all the other programmer-traps. >> > > Yeah. There are unfortunately always limits and compromises when making a > real language. Rust is attacking a very difficult niche so we have to spend > a lot of energy on things that are not strictly about safety. But I > appreciate your concern. > > > In Rust (like C) there doesn't appear to be any way to access the >> processor flags to cheaply detect overflow on machine types >> > > It would be done with some per-platform inline asm (which we support now), > or intrinsics, or an attribute on (say) newtyped integral types. Any of > these would probably be ok. The attribute form would make it part of the > type, so you'd wind up with checks performed on cast boundaries as well as > any non-approximated operations. > > > your "safe integer objects" will likely have poor performance and of >> course not work with the standard libraries. >> > > I believe any such integration -- inline asm, intrinsics or attribute -- > would be similar, performance-wise. Maybe LLVM's scheduler could do a > better job with them if it knows more about the instruction (an argument > for intrinsics), and if it knows about the type range itself it may > eliminate certain branches as dead code, but otherwise inlining should boil > off most of the abstractions equivalently. > > > Integrated ranged types would >> also be synergistic with memory safety since a function which takes >> limited-range inputs can sometimes be statically proven memory-safe when >> it couldn't otherwise be, allowing the boundary check to be hoisted out of >> functions entirely even across closed-source-library boundaries when their >> interfaces are range constrained. >> > > Not entirely. There are always limited approximations at work in these > things; range checks can only be statically eliminated in some cases when > the approximation is tight, otherwise it has to be repeated on each > potentially range-violating arithmetic operation. > > LLVM does expose range-limited types and, presumably, does some such > check-elimination. I'd not be opposed to absorbing this via a > well-integrated attribute on integer types. > > We've also had some requests for a mechanism to enable overflow checking > on _all_ integer types within a given static or dynamic program extent, > using attributes. And similar things are going to be desirable wrt. the > floating point environment, which is trickier since it's latent in the CPU > state rather than the (static) operations performed. Again, I'd be happy to > work through developing patches for this and exploring the problem space. > It's a set of bugs usually swept under the rug in C. > > > Overflow is something that ada seems to handle well, but ada doesn't >> really seem to be in the running for a wide spread next language outside >> of certain niches. >> > > Agreed. > > -Graydon > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- Sebastian Sylvan -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Mon Apr 22 20:44:28 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 22 Apr 2013 20:44:28 -0700 Subject: [rust-dev] New milestones, bug triage, maturity and completion Message-ID: <5176039C.6060805@mozilla.com> Hi, Mozilla research had a workweek recently where we discussed a number of process changes to the Rust project to try to bring a little more order to the chaos and wind down the rapid-growth, everything-on-fire phase of the project. This email explains those process changes in a little more detail. If you're employed on this project full time, please read this email carefully. 0. Bors, incoming and master Bors has been generally judged a success (modulo annoyingly regular timeouts on the buildbot) so we will be deleting the incoming branch and switching bors to move master directly. I'll send another notice when this is ready to happen. 1. Milestones split into two groups Previous rust releases have used milestones ineffectively, as they blurred the distinction between aspirations ("we think this bug _should_ get done") and prediction ("we think this bug _will_ get done"). As a result, they served neither purpose and were frequently overlooked or ignored. We will attempt to breathe new life into the "milestone" facility by splitting their roles into separate sets: for 0.7 and onwards, release-numbered milestones (0.7, 0.8, 0.9, etc.) will be _predictive only_. Bugs should be placed on those milestones only if they are assigned to you, and represent your best guess about _what you will do_ during a release cycle. You can take something off that milestone if it's assigned to you and you don't think you'll get it done, whenever you see fit. These milestones will have associated target dates, which we will aim to maintain on the quarterly cadence we've maintained so far. A separate set of milestones has been added called "maturity" milestones. These have no dates, and are "aspirational": they define subjective concepts "backwards compatible" or "feature complete" in terms of specific bugs, for external measurement of the project's state. The project's maturity can be judged against these more usefully than it can be judged against milestones like "0.7" (which tells the reader very little). Bugs will be assigned to maturity milestones by a nomination process. That's point #2. Maturity milestones will be reached "when we get there"; we will not hold releases for them. What we call "1.0" is a different conversation, but I imagine it needs to be somewhere after the "backwards compatible" milestone, just to suit the concept of major-version numbers in semantic versioning. 2. Nomination and acceptance Maturity milestones represent a subjective judgment about product maturity, as seen through the eyes of the repository owners (that is, mozilla engineers). Of course you're welcome to consider maturity in different terms, but this is for our own planning and measurement of the project. As such we'll be accepting _nomination_ of a bug for inclusion in one of these milestones liberally -- anyone should feel free to nominate a bug if they think it's really important -- but meeting weekly to either _accept_ or _decline_ inclusion in these milestones. This way we hope to establish and communicate a consensus concerning the project status and path towards completion. There is a new tag I-nominated for tagging a bug with nomination. These will be cleared weekly, at the meeting. Bugs that we decline to add to a maturity milestone will remain in the general bug pool, and will be addressed "best effort" by the repository owners, or (of course) through contributed pull requests. It's still worth keeping non-milestone bugs around. I should reiterate: the maturity milestones are there to _sharpen a concept_ like "feature complete" or "backwards compatible" into a particular bug-set. They are not there for scheduling a bug you "want to get done because it seems cool". The idea is that a bug should be assigned to a maturity milestone where it would be a _untenable_ to claim or argue the terms of the milestone were met without that bug. As such, the maturity milestones have extensive text associated with them. Please read them to make sure you understand the idea behind each: https://github.com/mozilla/rust/issues/milestones 3. Randomized triage and fixing in the general bug pool I've added a new script to our repertoire of project automation that selects a set least-recently-edited bugs every week and randomly assigns them in batches for triage to a set of project participants (who have signed up for this fate -- email me if you want to join in). This way we hope to visit, self-nominate, review and close bugs at a better rate and a more uniform breadth than we've been doing so far; and to improve this rate as we advance towards feature completion and can focus more and more energy on bug fixing. If you received a set of bugs from this script this week, please take a look at the bugs you were given and make time to look through them and post at least one change to them so they don't come up again next week. This could be as little as simply confirming that the bug still exists and makes sense, though searching for duplicates, narrowing cases, investigating causes and/or actually fixing bugs is also great if you can spare the effort. 4. WIP on "1.0 bugs" I'm presently mass-reassigning bugs that were formerly marked "1.0" to the maturity milestones (and doing a small amount of filtering and triage along the way). We will spend some time reviewing these in the next few nomination meetings, as a sort of backlog of implicit nominations, since "accepting" carries a bit more weight now than it did when a lot of them were put on "1.0" (back when that seemed "infinitely far away"). Hopefully it doesn't take _too_ many meetings to sort out; but in case you were wondering, that's why the maturity milestones currently already have (some) bugs assigned to them. I should be finished with the initial mass-reassignment of those 1.0 bugs before the meeting this week. At that point I'll remove the 1.0 milestone. We should probably also have a look through the 0.7 milestone to make sure it corresponds to the definition given above for numeric milestones (only bugs assigned-to-users and expected-to-complete by next release mark). If you have any questions on any of this, please mention them here. I'm happy to discuss further anything that's unclear, either here or on IRC / through direct email to me. We'd like the process to become more transparent and better-organized, so everyone should feel like they understand what's going on. Thanks for your attention, -Graydon From thadguidry at gmail.com Mon Apr 22 21:01:20 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Mon, 22 Apr 2013 23:01:20 -0500 Subject: [rust-dev] New milestones, bug triage, maturity and completion In-Reply-To: <5176039C.6060805@mozilla.com> References: <5176039C.6060805@mozilla.com> Message-ID: So what are the 2 labels applied for the milestones ? Was that 1. PREDICTIVE MILESTONES 2. MATURITY MILESTONES ?? On Mon, Apr 22, 2013 at 10:44 PM, Graydon Hoare wrote: > Hi, > > Mozilla research had a workweek recently where we discussed a number of > process changes to the Rust project to try to bring a little more order to > the chaos and wind down the rapid-growth, everything-on-fire phase of the > project. This email explains those process changes in a little more detail. > > If you're employed on this project full time, please read this email > carefully. > > 0. Bors, incoming and master > > Bors has been generally judged a success (modulo annoyingly regular > timeouts on the buildbot) so we will be deleting the incoming branch and > switching bors to move master directly. I'll send another notice when this > is ready to happen. > > > 1. Milestones split into two groups > > Previous rust releases have used milestones ineffectively, as they blurred > the distinction between aspirations ("we think this bug _should_ get done") > and prediction ("we think this bug _will_ get done"). As a result, they > served neither purpose and were frequently overlooked or ignored. > > We will attempt to breathe new life into the "milestone" facility by > splitting their roles into separate sets: for 0.7 and onwards, > release-numbered milestones (0.7, 0.8, 0.9, etc.) will be _predictive > only_. Bugs should be placed on those milestones only if they are assigned > to you, and represent your best guess about _what you will do_ during a > release cycle. You can take something off that milestone if it's assigned > to you and you don't think you'll get it done, whenever you see fit. These > milestones will have associated target dates, which we will aim to maintain > on the quarterly cadence we've maintained so far. > > A separate set of milestones has been added called "maturity" milestones. > These have no dates, and are "aspirational": they define subjective > concepts "backwards compatible" or "feature complete" in terms of specific > bugs, for external measurement of the project's state. The project's > maturity can be judged against these more usefully than it can be judged > against milestones like "0.7" (which tells the reader very little). > > Bugs will be assigned to maturity milestones by a nomination process. > That's point #2. Maturity milestones will be reached "when we get there"; > we will not hold releases for them. What we call "1.0" is a different > conversation, but I imagine it needs to be somewhere after the "backwards > compatible" milestone, just to suit the concept of major-version numbers in > semantic versioning. > > > 2. Nomination and acceptance > > Maturity milestones represent a subjective judgment about product > maturity, as seen through the eyes of the repository owners (that is, > mozilla engineers). Of course you're welcome to consider maturity in > different terms, but this is for our own planning and measurement of the > project. As such we'll be accepting _nomination_ of a bug for inclusion in > one of these milestones liberally -- anyone should feel free to nominate a > bug if they think it's really important -- but meeting weekly to either > _accept_ or _decline_ inclusion in these milestones. This way we hope to > establish and communicate a consensus concerning the project status and > path towards completion. There is a new tag I-nominated for tagging a bug > with nomination. These will be cleared weekly, at the meeting. > > Bugs that we decline to add to a maturity milestone will remain in the > general bug pool, and will be addressed "best effort" by the repository > owners, or (of course) through contributed pull requests. It's still worth > keeping non-milestone bugs around. > > I should reiterate: the maturity milestones are there to _sharpen a > concept_ like "feature complete" or "backwards compatible" into a > particular bug-set. They are not there for scheduling a bug you "want to > get done because it seems cool". The idea is that a bug should be assigned > to a maturity milestone where it would be a _untenable_ to claim or argue > the terms of the milestone were met without that bug. > > As such, the maturity milestones have extensive text associated with them. > Please read them to make sure you understand the idea behind each: > > https://github.com/mozilla/**rust/issues/milestones > > > 3. Randomized triage and fixing in the general bug pool > > I've added a new script to our repertoire of project automation that > selects a set least-recently-edited bugs every week and randomly assigns > them in batches for triage to a set of project participants (who have > signed up for this fate -- email me if you want to join in). This way we > hope to visit, self-nominate, review and close bugs at a better rate and a > more uniform breadth than we've been doing so far; and to improve this rate > as we advance towards feature completion and can focus more and more energy > on bug fixing. > > If you received a set of bugs from this script this week, please take a > look at the bugs you were given and make time to look through them and post > at least one change to them so they don't come up again next week. This > could be as little as simply confirming that the bug still exists and makes > sense, though searching for duplicates, narrowing cases, investigating > causes and/or actually fixing bugs is also great if you can spare the > effort. > > > 4. WIP on "1.0 bugs" > > I'm presently mass-reassigning bugs that were formerly marked "1.0" to the > maturity milestones (and doing a small amount of filtering and triage along > the way). We will spend some time reviewing these in the next few > nomination meetings, as a sort of backlog of implicit nominations, since > "accepting" carries a bit more weight now than it did when a lot of them > were put on "1.0" (back when that seemed "infinitely far away"). Hopefully > it doesn't take _too_ many meetings to sort out; but in case you were > wondering, that's why the maturity milestones currently already have (some) > bugs assigned to them. > > I should be finished with the initial mass-reassignment of those 1.0 bugs > before the meeting this week. At that point I'll remove the 1.0 milestone. > We should probably also have a look through the 0.7 milestone to make sure > it corresponds to the definition given above for numeric milestones (only > bugs assigned-to-users and expected-to-complete by next release mark). > > > If you have any questions on any of this, please mention them here. I'm > happy to discuss further anything that's unclear, either here or on IRC / > through direct email to me. We'd like the process to become more > transparent and better-organized, so everyone should feel like they > understand what's going on. > > Thanks for your attention, > > -Graydon > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Mon Apr 22 21:11:43 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 22 Apr 2013 21:11:43 -0700 Subject: [rust-dev] New milestones, bug triage, maturity and completion In-Reply-To: References: <5176039C.6060805@mozilla.com> Message-ID: <517609FF.4070605@mozilla.com> On 13-04-22 09:01 PM, Thad Guidry wrote: > So what are the 2 labels applied for the milestones ? > > Was that > > 1. PREDICTIVE MILESTONES > 2. MATURITY MILESTONES They're not labels. There are milestones in the bug tracker. They're called milestones, disjoint from labels. The maturity milestones are all named "maturity #N - ..." such as: maturity #2 - backwards compatible maturity #3 - feature complete maturity #5 - production ready and so forth. None of them have associated dates. The predictive milestones are named by release numbers, such as "0.7", "0.8", "0.9", etc. and will have definite dates (quarterly). -Graydon From zack at z0w0.me Mon Apr 22 21:25:16 2013 From: zack at z0w0.me (Zack Corr) Date: Tue, 23 Apr 2013 14:25:16 +1000 Subject: [rust-dev] New milestones, bug triage, maturity and completion In-Reply-To: <517609FF.4070605@mozilla.com> References: <5176039C.6060805@mozilla.com> <517609FF.4070605@mozilla.com> Message-ID: Any chance of making the triage script assign the user to the Github issue (as in actual assignment via the API)? I think it'd be useful. On Tue, Apr 23, 2013 at 2:11 PM, Graydon Hoare wrote: > On 13-04-22 09:01 PM, Thad Guidry wrote: > >> So what are the 2 labels applied for the milestones ? >> >> Was that >> >> 1. PREDICTIVE MILESTONES >> 2. MATURITY MILESTONES >> > > They're not labels. There are milestones in the bug tracker. They're > called milestones, disjoint from labels. > > The maturity milestones are all named "maturity #N - ..." such as: > > maturity #2 - backwards compatible > maturity #3 - feature complete > maturity #5 - production ready > > and so forth. None of them have associated dates. > > The predictive milestones are named by release numbers, such as "0.7", > "0.8", "0.9", etc. and will have definite dates (quarterly). > > > -Graydon > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Mon Apr 22 21:43:15 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Mon, 22 Apr 2013 21:43:15 -0700 Subject: [rust-dev] New milestones, bug triage, maturity and completion In-Reply-To: References: <5176039C.6060805@mozilla.com> <517609FF.4070605@mozilla.com> Message-ID: <51761163.5090307@mozilla.com> On 13-04-22 09:25 PM, Zack Corr wrote: > Any chance of making the triage script assign the user to the Github > issue (as in actual assignment via the API)? I think it'd be useful. No, they're just requests to do some triage (tidying, revisiting, reproducing, etc.) I think "assignment" in the github sense is too strong: much of the time, someone asked to do triage on a bug is not really able to fix it, it's not their area of specialization, they're just checking in on it to see if it's still relevant, or a dupe, or still reproducible / correctly classified / minimized etc. -Graydon From zack at z0w0.me Mon Apr 22 21:46:28 2013 From: zack at z0w0.me (Zack Corr) Date: Tue, 23 Apr 2013 14:46:28 +1000 Subject: [rust-dev] New milestones, bug triage, maturity and completion In-Reply-To: <51761163.5090307@mozilla.com> References: <5176039C.6060805@mozilla.com> <517609FF.4070605@mozilla.com> <51761163.5090307@mozilla.com> Message-ID: Fair enough. Just thought it would be nice to have Github automatically watch any issues that have been assigned to you in the triage. On Tue, Apr 23, 2013 at 2:43 PM, Graydon Hoare wrote: > On 13-04-22 09:25 PM, Zack Corr wrote: > >> Any chance of making the triage script assign the user to the Github >> issue (as in actual assignment via the API)? I think it'd be useful. >> > > No, they're just requests to do some triage (tidying, revisiting, > reproducing, etc.) I think "assignment" in the github sense is too strong: > much of the time, someone asked to do triage on a bug is not really able to > fix it, it's not their area of specialization, they're just checking in on > it to see if it's still relevant, or a dupe, or still reproducible / > correctly classified / minimized etc. > > -Graydon > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From robert at ocallahan.org Mon Apr 22 21:57:10 2013 From: robert at ocallahan.org (Robert O'Callahan) Date: Tue, 23 Apr 2013 16:57:10 +1200 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <517562EE.4000303@mozilla.com> References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> Message-ID: On Tue, Apr 23, 2013 at 4:18 AM, Graydon Hoare wrote: > We've also had some requests for a mechanism to enable overflow checking > on _all_ integer types within a given static or dynamic program extent, > using attributes. I, at least, made a request for overflow checking on all integer types, full stop :-). And I still want it; failure of obvious properties like "a >= 0 ===> a + b >= b" is just crazy, and I'm tired of living in crazy-land. On the other hand, I don't see this as important for floating point types. Accumulating NaNs and infinities is much saner than simply producing the wrong answer, has seldom led to critical browser bugs in my experience, and I can't see how it would without an intervening conversion to integer type which would, of course, be checked. (OK, I can recall exactly one infinite-recursion bug involving NaNs that didn't require an integer conversion.) Rob -- q?qIqfq qyqoquq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qtqhqeqmq.q qAqnqdq qiqfq qyqoquq qdqoq qgqoqoqdq qtqoq qtqhqoqsqeq qwqhqoq qaqrqeq qgqoqoqdq qtqoq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qdqoq qtqhqaqtq.q" -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Tue Apr 23 02:24:42 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Tue, 23 Apr 2013 11:24:42 +0200 Subject: [rust-dev] blog post with my proposal for associated item syntax Message-ID: <5176535A.5040107@mozilla.com> The team had some discussions recently regarding associated items. In Vancouver I outlined a small change to the grammar that might solve a lot of problems. I have written up the proposal here, with lots of gory background: http://blog.pnkfx.org/blog/2013/04/22/designing-syntax-for-associated-items-in-rust/ (If you already know all the background, then you should be okay just skipping to the proposal itself; see the Executive Summary at the beginning of the post.) Cheers, -Felix -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.org From a.stavonin at gmail.com Tue Apr 23 06:36:25 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Tue, 23 Apr 2013 17:36:25 +0400 Subject: [rust-dev] Shared 2 Owned Message-ID: Hi all, I'm really confused. What's about Shared 2 Owned conversions? This one looks ugly, nevertheless works: let a = @5; let b = *a; let c = ~b; io::println(fmt!("%?, %?, %?", a, b, c)); > @5, 5, ~5 But what about arrays? let a = @[5]; let b = *a; let c = ~b; > error: type @[] cannot be dereferenced Is it true, that there is no any way for converting between different boxes types without deep copying of objects?! I'm shocked %) -------------- next part -------------- An HTML attachment was scrubbed... URL: From pnkfelix at mozilla.com Tue Apr 23 06:42:08 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Tue, 23 Apr 2013 15:42:08 +0200 Subject: [rust-dev] Shared 2 Owned In-Reply-To: References: Message-ID: <51768FB0.7090305@mozilla.com> Alexander- What are you suggesting would be the semantics for a Shared -> Owned conversion? Just think about it in the the abstract for a moment: If X and Y are both sharing a reference to a @Pizza, and X decides it wants to hand the pizza to a customer who is expecting a ~Pizza, what is X supposed to do? Block until Y relinquishes its hold on the pizza? To my mind, X has no choice but to cook another pizza that looks just like the one it is shared with Y. (Now, Owned -> Shared conversion might actually make sense in the abstract; at that point I think we'd just be encountering implementation artifacts of the Rust language, rather than fundamental obstacles?) Cheers, -Felix On Tue Apr 23 15:36:25 2013, Alexander Stavonin wrote: > Hi all, I'm really confused. What's about Shared 2 Owned conversions? > This one looks ugly, nevertheless works: > > let a = @5; > let b = *a; > let c = ~b; > io::println(fmt!("%?, %?, %?", a, b, c)); > > > @5, 5, ~5 > > But what about arrays? > > let a = @[5]; > let b = *a; > let c = ~b; > > > error: type @[] cannot be dereferenced > > Is it true, that there is no any way for converting between different > boxes types without deep copying of objects?! I'm shocked %) > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.org From a.stavonin at gmail.com Tue Apr 23 06:54:16 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Tue, 23 Apr 2013 17:54:16 +0400 Subject: [rust-dev] Shared 2 Owned In-Reply-To: <51768FB0.7090305@mozilla.com> References: <51768FB0.7090305@mozilla.com> Message-ID: Felix, thank you for response. I agree with you about difference between Shared and Owned memory models. It's two different heaps with different management rules. It's clean. Now, lets go to practical things such as next one. We have two Tasks with some computations. For passing values between the tasks we have use Owned box but, internally, we usually are using Shared boxes. In this case, for all tasks we have to write converters from Shared to Owned and from Owned to Shared boxes. It's really big source code overhead from nothing. Regards, Alex. 2013/4/23 Felix S. Klock II > Alexander- > > What are you suggesting would be the semantics for a Shared -> Owned > conversion? > > Just think about it in the the abstract for a moment: If X and Y are both > sharing a reference to a @Pizza, and X decides it wants to hand the pizza > to a customer who is expecting a ~Pizza, what is X supposed to do? Block > until Y relinquishes its hold on the pizza? To my mind, X has no choice > but to cook another pizza that looks just like the one it is shared with Y. > > (Now, Owned -> Shared conversion might actually make sense in the > abstract; at that point I think we'd just be encountering implementation > artifacts of the Rust language, rather than fundamental obstacles?) > > Cheers, > -Felix > > > On Tue Apr 23 15:36:25 2013, Alexander Stavonin wrote: > >> Hi all, I'm really confused. What's about Shared 2 Owned conversions? >> This one looks ugly, nevertheless works: >> >> let a = @5; >> let b = *a; >> let c = ~b; >> io::println(fmt!("%?, %?, %?", a, b, c)); >> >> > @5, 5, ~5 >> >> But what about arrays? >> >> let a = @[5]; >> let b = *a; >> let c = ~b; >> >> > error: type @[] cannot be dereferenced >> >> Is it true, that there is no any way for converting between different >> boxes types without deep copying of objects?! I'm shocked %) >> >> >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > > > -- > irc: pnkfelix on irc.mozilla.org > email: {fklock, pnkfelix}@mozilla.org > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue Apr 23 07:38:49 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 07:38:49 -0700 Subject: [rust-dev] Shared 2 Owned In-Reply-To: References: <51768FB0.7090305@mozilla.com> Message-ID: <51769CF9.7090909@mozilla.com> On 13-04-23 06:54 AM, Alexander Stavonin wrote: > Felix, thank you for response. I agree with you about difference between > Shared and Owned memory models. It's two different heaps > with different management rules. It's clean. Now, lets go > to practical things such as next one. We have two Tasks with some > computations. For passing values between the tasks we have use Owned box > but, internally, we usually are using Shared boxes. In this case, for > all tasks we have to write converters from Shared to Owned and > from Owned to Shared boxes. It's really big source code overhead from > nothing. If you have constructive suggestions about how to generally convert a possibly-cyclic graph of possibly-multiply-referenced substructures into a proper tree without incurring a deep copy, we'd all be interested to hear it. Otherwise this is behaving as expected (and documented). We're all aware that the separation of heaps incurs some costs along with its benefits. I'm sorry if it comes as a surprise but it's the cost we carry in order to gain the many, many benefits of linearity in owned types. As far as I know one can't really have it both ways. Other languages don't get out of this for free either. They either incur the costs of pervasive memory contention, locking and concurrent garbage collection, or they copy _everything_ (like erlang) when transmitting. Non-constructive criticism like "big source code overhead from nothing", "shocked", "ugly" and such are not helpful (in addition to drifting outside the participation guidelines for the project[1]). -Graydon [1] https://github.com/mozilla/rust/wiki/Note-development-policy#conduct From swede at earthling.net Tue Apr 23 07:48:12 2013 From: swede at earthling.net (swede at earthling.net) Date: Tue, 23 Apr 2013 10:48:12 -0400 Subject: [rust-dev] Division and modulo for signed numbers Message-ID: <20130423144812.217310@gmx.com> Hello, I've been lurking on the Rust list for a while. The language looks very promising! However, Rust copies a misfeature in the division operator from C: truncating toward zero (T-division). A better definition of division is to round toward negative infinity (Flooring, or F-division). A quick summary: In truncating division (T-division) as used by C and current Rust: ?D / d is rounded toward zero ?D % d has the sign of the first argument In flooring division (F-division): ?D / d is rounded toward negative infinity ?D % d has the sign of the second argument Both definitions satisfy the "division rule": ?(D/d)*d + (D%d) = D For a mathematical discussion of why F-division is better than T-division, see this paper: "The Euclidean Definition of the Functions div and mod" by Raymond T. Boute https://biblio.ugent.be/input/download?func=downloadFile&recordOId=314490&fileOId=452146??? or??? http://dx.doi.org/10.1145/128861.128862 >From a programming perspective, F-division has several benefits: ?1.? x % len is always in the range [0, len-1) if len is positive ?2.? x / k will return each quotient k times as x is incremented ?3.? x / (2^n) can be converted to a bitwise right shift for any x ?4.? x % (2^n) can be converted to a bitwise and for any x None of these properties hold for T-division when x is negative. Property 1 is the most important, since converting integers to array indexes is a common operation (probably the most common use of the % operator). This single use is a convincing reason to switch to the F-definition, in my opinion. Property 2 is useful for things like sample-rate conversion or nearly-unbiased scaling of random numbers. Properties 3 and 4 are simply performance optimizations. While T-division is the most common choice (used by C, C++, etc) F-division is not uncommon. I've confirmed that Python and Ruby use F-division, and Wikipedia claims that TCL and D do too. F-division behavior won't be surprising or hard to explain to any users familiar with Python, which is most developers today. Performance should be about the same when using F-division: ?* Performance will go up for division by constant powers of two. ?* Performance will stay the same for division by compile-time constants, since these are transformed by the compiler into multiplies. (I actually think performance will go up slightly in this case, but it's been a while since I looked at the algorithm.) ?* Performance on ARM will stay the same for divides by variables (not known at compile-time), since ARM does not have a hardware divider. ?* Performance on x86/x64 for divides by variables will go down slightly, since Intel's idiv instruction implements F-division. So one already very slow operation (x86 idiv) gets slightly slower, one fast operation (divide by power-of-two) gets quite a bit faster. It probably nets out near zero. The T-division operator would still be needed for compatibility with C, but it should be provided as a library function instead of as the standard definition of "/" and "%". Thanks for your time, Erik From a.stavonin at gmail.com Tue Apr 23 07:51:00 2013 From: a.stavonin at gmail.com (Alexander Stavonin) Date: Tue, 23 Apr 2013 18:51:00 +0400 Subject: [rust-dev] Shared 2 Owned In-Reply-To: <51769CF9.7090909@mozilla.com> References: <51768FB0.7090305@mozilla.com> <51769CF9.7090909@mozilla.com> Message-ID: Second response not about deep copy but about simplifying deep copy operation. Actually, I understood the reason of deep-copy-only conversions immediately after sending the question. And "big source code overhead from nothing" means: we almost always have to write conversion manually rather than do it automatically. The proposal is adding auto conversion operation between Shared and Owned boxes. May be it should looks like C++ copy or move constructors. In case of move conversion, the operation can be allowed only if there is only one Shared box is owned a value. For copy conversion it can make deep object copy automatically. Regards, Alex. 2013/4/23 Graydon Hoare > > If you have constructive suggestions about how to generally convert a > possibly-cyclic graph of possibly-multiply-referenced substructures into a > proper tree without incurring a deep copy, we'd all be interested to hear > it. Otherwise this is behaving as expected (and documented). We're all > aware that the separation of heaps incurs some costs along with its > benefits. > > I'm sorry if it comes as a surprise but it's the cost we carry in order to > gain the many, many benefits of linearity in owned types. As far as I know > one can't really have it both ways. Other languages don't get out of this > for free either. They either incur the costs of pervasive memory > contention, locking and concurrent garbage collection, or they copy > _everything_ (like erlang) when transmitting. > > Non-constructive criticism like "big source code overhead from nothing", > "shocked", "ugly" and such are not helpful (in addition to drifting outside > the participation guidelines for the project[1]). > > -Graydon > > [1] https://github.com/mozilla/**rust/wiki/Note-development-** > policy#conduct > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Tue Apr 23 07:56:00 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 23 Apr 2013 07:56:00 -0700 Subject: [rust-dev] Shared 2 Owned In-Reply-To: References: <51768FB0.7090305@mozilla.com> <51769CF9.7090909@mozilla.com> Message-ID: <5176A100.90509@mozilla.com> On 4/23/13 7:51 AM, Alexander Stavonin wrote: > Second response not about deep copy but about simplifying deep copy > operation. Actually, I understood the reason of deep-copy-only > conversions immediately after sending the question. And "big source code > overhead from nothing" means: we almost always have to write conversion > manually rather than do it automatically. You can use flatpipes to automatically send data containing `@` smart pointers from task to task, if that's what you're looking for. (You may have to tag the structs involved with `#[auto_encode]` and `#[auto_decode]` though.) > The proposal is adding auto > conversion operation between Shared and Owned boxes. May be it should > looks like C++ copy or move constructors. In case of move conversion, > the operation can be allowed only if there is only one Shared box is > owned a value. This doesn't work if `@` is garbage collected. You'd have to trace the entire heap. > For copy conversion it can make deep object copy > automatically. But you can already do this. struct Pizza { ... } let managed_pizza = @Pizza { ... }; let owned_pizza = ~*managed_pizza; It only goes one level deep, but doing more than that wouldn't work in the type system; you can't have structures that are parameterized over the type of smart pointers they contain for various reasons. Patrick From pwalton at mozilla.com Tue Apr 23 08:02:22 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 23 Apr 2013 08:02:22 -0700 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <20130423144812.217310@gmx.com> References: <20130423144812.217310@gmx.com> Message-ID: <5176A27E.9010805@mozilla.com> On 4/23/13 7:48 AM, swede at earthling.net wrote: > Performance should be about the same when using F-division: > * Performance will go up for division by constant powers of two. > * Performance will stay the same for division by compile-time constants, since these are transformed by the compiler into multiplies. (I actually think performance will go up slightly in this case, but it's been a while since I looked at the algorithm.) > * Performance on ARM will stay the same for divides by variables (not known at compile-time), since ARM does not have a hardware divider. > * Performance on x86/x64 for divides by variables will go down slightly, since Intel's idiv instruction implements F-division. > > So one already very slow operation (x86 idiv) gets slightly slower, one fast operation (divide by power-of-two) gets quite a bit faster. It probably nets out near zero. I worry quite a bit about that last one. Rust language semantics strive to mirror the CPU instructions as closely as possible. This is why, for example, we were forced to make `<` respect NaN, unlike Haskell--if we didn't, we couldn't use the hardware floating point comparison instructions. I'm also nervous about C interoperability. Including F-division as a library function sounds fine to me though--macros or dot notation may be able to sweeten the syntax. Patrick From graydon at mozilla.com Tue Apr 23 08:06:49 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 08:06:49 -0700 Subject: [rust-dev] Shared 2 Owned In-Reply-To: References: <51768FB0.7090305@mozilla.com> <51769CF9.7090909@mozilla.com> Message-ID: <5176A389.8070406@mozilla.com> On 13-04-23 07:51 AM, Alexander Stavonin wrote: > Second response not about deep copy but about simplifying deep copy > operation. Actually, I understood the reason of deep-copy-only > conversions immediately after sending the question. And "big source code > overhead from nothing" means: we almost always have to write conversion > manually rather than do it automatically. The proposal is adding auto > conversion operation between Shared and Owned boxes. May be it should > looks like C++ copy or move constructors. In case of move conversion, > the operation can be allowed only if there is only one Shared box is > owned a value. For copy conversion it can make deep object copy > automatically. Just because an @-box has only one owner doesn't mean its substructures don't branch. We have to trace through all its pointed-to values performing the same action. That's a deep copy at any shared edges. We could try to implement deriving(Clone) to perform this operation sometimes (when running on a runtime where the managed and owned heaps are drawn from the same underlying allocator, or a compatible one). When the managed heap is specialized and pinned to a task, in general, it's not possible: the sending task may exit, invalidating all of its managed memory immediately. Beyond that, this is (largely) the same question you asked on apr 19 ("Passing managed value to task") so the answer is (largely) the same: we have attributes #[auto_encode] and #[auto_decode] that will serialize and deserialize values "fully" and can be used for passing managed values between tasks. -Graydon From niko at alum.mit.edu Tue Apr 23 08:11:58 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Tue, 23 Apr 2013 11:11:58 -0400 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: <51756392.5050202@di.uminho.pt> References: <51756392.5050202@di.uminho.pt> Message-ID: Thanks for your proposal. We've been through a number of rounds with the lifetime syntax, including an earlier scheme that was quite similar to what you propose in some regards (there was a single anonymous lifetime parameter that was used whenever you wrote `&T`, which meant that yes you often did not need to use explicit lifetime parameter names). However, we found that this was ultimately more confusing to people than helpful. One of the goals of the current syntax was to make the mechanism of named lifetimes more explicit and thus more clear to the reader. Smarter defaults have the disadvantage that they often obscure the underlying system, making it harder to learn what's really going on. In practice,named lifetimes don't seem to be that common, at least for me. We should do some numerical analysis, but I've found subjectively that most functions simply consume data and do not return pointers. This is particularly true for "non-library" code, and even more true with judicious use of `@` pointers (it is often not worth the trouble to avoid the GC; it can make life much easier, that's what it's there for). So in summary I do not think it likely we will change the current syntax. Niko On Mon, Apr 22, 2013 at 12:21 PM, Paulo S?rgio Almeida wrote: > Hi all, > > (My first post here.) > First, congrats for what you are trying to achieve with Rust. I arrived > very late to the party, and so I am not sure that what I will say can be of > use. But as I understand, lifetimes is one of those things that are not > completely solidified, and anyway, better late than never. > > Looking at some code, expressing lifetimes of borrowed references is one > of those things that is somewhat bewildering, making the code somewhat > noisy. I think it can be improved through a better choice of defaults and a > slight change in explicit lifetimes. > > The main thing I think is "wrong" is the defaults for function parameters. > From the tutorial: "the compiler simply creates a fresh name for the > lifetime automatically: that is, the lifetime name is guaranteed to refer > to a distinct lifetime from the lifetimes of all other parameters." > > This default is not very useful. For example, it is wrong basically > everytime we want to return a borrowed pointer (unless, for a global > variable?). The more common case is returning something with the same > lifetime as some parameter. In many cases we don't need to distinguish > parameters, and specify which we are returning, in others we want to split > parameters in two equivalence classes, the one from which we are returning, > and everything else. > > When type parameters are involved, a return type typically says where the > result comes from most of the times. Again, the default should be > different. E.g., when we are returning a borrowed reference to a "key" of > type parameter K, the default should be "other things also of type K in > parameters". > > Finally, with better defaults, in the remaining cases where we need to > explicitly express lifetimes, having to "invent" identifiers is a nuisance. > Also the space which must be used between the lifetime identifier and the > type is too distracting and makes it cumbersome (for humans) to "parse" the > type of some identifier. > > I have been thinking about this and have the following proposal. (Of > course there may be inumerous things that must have escaped me, but here it > goes anyway.) > > --- > Regarding types for borrowed references in function parameters or result, > and type parameters: > > 1) each type-parameter has an associated implicit lifetime, which by > default is different from the lifetimes of other type-parameters or normal > function parameter types, but it can be qualified in each declaration or > use with an explicit lifetime; > > 2) function parameter types or return type that are not type parameters > have all the same implicit lifetime by default, but they can be qualified > explicitly with some lifetime. > > 3) explicit lifetimes are written identifier' instead of 'identifier; a > null identifier is allowed, as in &'T, to qualify a reference &T with > lifetime '. > --- > > (Another useful possibility would be allowing several ' at the end, > allowing e.g., &T, &'T, &''T as borrowed references to the same type but > with different lifetimes. In practice, a single ' plus 1) and 2) will cover > "99%" of cases. We could even get rid of using identifiers, using only > several '. But this is not relevant for the main proposal.) > > 1) and 2) are about defaults for implicit lifetimes, which currently are > "fresh lifetime for each parameter", and 3) is about simplifying the > remaining cases of explicit expression. The motivation for 3) is to remove > both the need of a space separating lifetime from type and also the need to > "invent" lifetime identifiers. Rewriting examples from the tutorial and > elsewhere, under this proposal, would make code more legible and standard, > reducing a lot the need for explicit lifetime expression. Things would > "just work" as wanted most times. > > > -------------------------------------------------------------------------------- > > From the Rust Borrowed Pointers Tutorial > > --- > > fn get_x<'r>(p: &'r Point) -> &'r float { &p.x } > > becomes > > fn get_x(p: &Point) -> &float { &p.x } > > --- > > fn select<'r, T>(shape: &'r Shape, threshold: float, > a: &'r T, b: &'r T) -> &'r T { > if compute_area(shape) > threshold {a} else {b} > } > > becomes > > fn select<'T>(shape: &'Shape, threshold: float, > a: &'T, b: &'T) -> &'T { > if compute_area(shape) > threshold {a} else {b} > } > > (not very useful case) > > --- > > fn select<'r, T>(shape: &Shape, threshold: float, > a: &'r T, b: &'r T) -> &'r T { > if compute_area(shape) > threshold {a} else {b} > } > > becomes > > fn select(shape: &Shape, threshold: float, > a: &T, b: &T) -> &T { > if compute_area(shape) > threshold {a} else {b} > } > > > -------------------------------------------------------------------------------- > > Other examples: > > --- > > struct Iterator<'lt, T> { > source: &'lt [T], > index: uint > } > > fn has_next<'a, 'b, T>(iter: &'a Iterator<'b, T>) -> bool { > iter.index + 1 < iter.source.len() > } > > fn next<'a, 'b, T>(iter: &'a mut Iterator<'b, T>) -> Option<&'b T> { > iter.index += 1; > if iter.index < iter.source.len() { > Some(&iter.source[iter.index]) > } else { > None > } > } > > becomes: > > struct Iterator<'T> { > source: &'[T], > index: uint > } > > fn has_next(iter: &Iterator) -> bool { > iter.index + 1 < iter.source.len() > } > > fn next(iter: &mut Iterator) -> Option<&T> { > iter.index += 1; > if iter.index < iter.source.len() { > Some(&iter.source[iter.index]) > } else { > None > } > } > > --- > > impl<'b, T> Iterator<'b, T> { > fn has_next(&self) { /* same as before */ } > fn next(&mut self) -> Option<&'b T> { /* same as before */ } > } > > becomes > > impl Iterator { > fn has_next(&self) { /* same as before */ } > fn next(&mut self) -> Option<&T> { /* same as before */ } > } > > --- > > Regards, > Paulo > > > > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Tue Apr 23 08:26:40 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 23 Apr 2013 08:26:40 -0700 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: References: <51756392.5050202@di.uminho.pt> Message-ID: <5176A830.5020503@mozilla.com> On 4/23/13 8:11 AM, Niko Matsakis wrote: > Thanks for your proposal. We've been through a number of rounds with the > lifetime syntax, including an earlier scheme that was quite similar to > what you propose in some regards (there was a single anonymous lifetime > parameter that was used whenever you wrote `&T`, which meant that yes > you often did not need to use explicit lifetime parameter names). > > However, we found that this was ultimately more confusing to people than > helpful. One of the goals of the current syntax was to make the > mechanism of named lifetimes more explicit and thus more clear to the > reader. Smarter defaults have the disadvantage that they often obscure > the underlying system, making it harder to learn what's really going on. > > In practice,named lifetimes don't seem to be that common, at least for > me. We should do some numerical analysis, but I've found subjectively > that most functions simply consume data and do not return pointers. This > is particularly true for "non-library" code, and even more true with > judicious use of `@` pointers (it is often not worth the trouble to > avoid the GC; it can make life much easier, that's what it's there for). Another thing I like about the current system is that it has nice pedagogical aspects. Where named lifetimes come in is in two well-defined places: (a) returning a reference; (b) stuffing a reference into a data structure. This allows programmers to write lots of programs without having to know how to use named lifetimes, and it allows the compiler to be very clear in error messages about where a named lifetime must be used. Patrick From swede at earthling.net Tue Apr 23 08:50:48 2013 From: swede at earthling.net (Erik S) Date: Tue, 23 Apr 2013 09:50:48 -0600 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <5176A27E.9010805@mozilla.com> References: <20130423144812.217310@gmx.com> <5176A27E.9010805@mozilla.com> Message-ID: <5176ADD8.9080508@earthling.net> On 4/23/2013 9:02 AM, Patrick Walton wrote: > On 4/23/13 7:48 AM, swede at earthling.net wrote: >> Performance should be about the same when using F-division: >> * Performance will go up for division by constant powers of two. >> * Performance will stay the same for division by compile-time >> constants, since these are transformed by the compiler into >> multiplies. (I actually think performance will go up slightly in this >> case, but it's been a while since I looked at the algorithm.) >> * Performance on ARM will stay the same for divides by variables >> (not known at compile-time), since ARM does not have a hardware divider. >> * Performance on x86/x64 for divides by variables will go down >> slightly, since Intel's idiv instruction implements F-division. >> >> So one already very slow operation (x86 idiv) gets slightly slower, >> one fast operation (divide by power-of-two) gets quite a bit faster. >> It probably nets out near zero. > > I worry quite a bit about that last one. Rust language semantics > strive to mirror the CPU instructions as closely as possible. This is > why, for example, we were forced to make `<` respect NaN, unlike > Haskell--if we didn't, we couldn't use the hardware floating point > comparison instructions. > > I'm also nervous about C interoperability. > > Including F-division as a library function sounds fine to me > though--macros or dot notation may be able to sweeten the syntax. > > Patrick > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > Patrick, I would agree with you if it weren't for the cases where F-division performs *better*. Division by a constant power-of-two is pretty common, and is much faster in F-division. I don't think correctness should be sacrificed for a slight performance improvement in one case on one supported architecture. I've had real bugs in my C code caused by incorrectly casting (or forgetting to cast) to unsigned before a % operation. T-division causes *real* bugs. I'm willing to spend some time implementing F-division, if I can get some buy-in that the patch would be accepted. Erik From lists at dhardy.name Tue Apr 23 08:53:35 2013 From: lists at dhardy.name (Diggory Hardy) Date: Tue, 23 Apr 2013 17:53:35 +0200 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <5176A27E.9010805@mozilla.com> References: <20130423144812.217310@gmx.com> <5176A27E.9010805@mozilla.com> Message-ID: <19811987.VlzDZtLQXY@l10036> On Tuesday 23 April 2013 08:02:22 Patrick Walton wrote: > On 4/23/13 7:48 AM, swede at earthling.net wrote: > > Performance should be about the same when using F-division: > > * Performance will go up for division by constant powers of two. > > * Performance will stay the same for division by compile-time constants, > > since these are transformed by the compiler into multiplies. (I > > actually think performance will go up slightly in this case, but it's > > been a while since I looked at the algorithm.) * Performance on ARM > > will stay the same for divides by variables (not known at > > compile-time), since ARM does not have a hardware divider. * > > Performance on x86/x64 for divides by variables will go down slightly, > > since Intel's idiv instruction implements F-division.> > > So one already very slow operation (x86 idiv) gets slightly slower, one > > fast operation (divide by power-of-two) gets quite a bit faster. It > > probably nets out near zero. > I worry quite a bit about that last one. Rust language semantics strive > to mirror the CPU instructions as closely as possible. This is why, for > example, we were forced to make `<` respect NaN, unlike Haskell--if we > didn't, we couldn't use the hardware floating point comparison instructions. > > I'm also nervous about C interoperability. > > Including F-division as a library function sounds fine to me > though--macros or dot notation may be able to sweeten the syntax. May I jump on the band-wagon? I also worry slightly about C interop ? not from using libraries but because copy and paste subtly changes the meaning. However, I agree with Erik ? F-division should be the default. For any case in which I've cared, it's what I've wanted, and I've had a couple of bugs because it's not in C++ (in code like arr[(ind - offset) % size]). I suspect (please correct me if I'm wrong) that if it wasn't for C and x86 compatibility then most people would fall into two categories: don't know/don't care, and prefer F-division. It's one of those little things like tau vs. pi which would have been less confusing if we'd started off on the other foot to start with. Diggory From pwalton at mozilla.com Tue Apr 23 09:20:02 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 23 Apr 2013 09:20:02 -0700 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <5176ADD8.9080508@earthling.net> References: <20130423144812.217310@gmx.com> <5176A27E.9010805@mozilla.com> <5176ADD8.9080508@earthling.net> Message-ID: <5176B4B2.3060102@mozilla.com> On 4/23/13 8:50 AM, Erik S wrote: > Patrick, > I would agree with you if it weren't for the cases where F-division > performs *better*. Division by a constant power-of-two is pretty common, > and is much faster in F-division. > > I don't think correctness should be sacrificed for a slight performance > improvement in one case on one supported architecture. I've had real > bugs in my C code caused by incorrectly casting (or forgetting to cast) > to unsigned before a % operation. T-division causes *real* bugs. > > I'm willing to spend some time implementing F-division, if I can get > some buy-in that the patch would be accepted. Keep in mind that you will also need to implement an LLVM intrinsic, port all of the LLVM optimizations that apply to division to it, and make sure that they don't regress LLVM benchmarks. (You may want to add it to clang first actually.) Patrick From pwalton at mozilla.com Tue Apr 23 09:35:01 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 23 Apr 2013 09:35:01 -0700 Subject: [rust-dev] Renaming of core and std Message-ID: <5176B835.20301@mozilla.com> Hi everyone, There's been consensus lately that `core` and `std` are somewhat misnamed. `core` is really the standard library--the one that would be specified in a specification if we had one. `std` is an "extras" library and may well end up sliced up and moved to various packages. So it seems prudent to rename `core` to `std`. But that leaves the question of what to name `std` in the interim. Options that have been suggested are `extra`, `ext`, and `contrib`. Any other opinions? Patrick From thadguidry at gmail.com Tue Apr 23 09:38:01 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Tue, 23 Apr 2013 11:38:01 -0500 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176B835.20301@mozilla.com> References: <5176B835.20301@mozilla.com> Message-ID: +1 for "extra". It has a nice semantic smiley face all over it. On Tue, Apr 23, 2013 at 11:35 AM, Patrick Walton wrote: > Hi everyone, > > There's been consensus lately that `core` and `std` are somewhat misnamed. > `core` is really the standard library--the one that would be specified in a > specification if we had one. `std` is an "extras" library and may well end > up sliced up and moved to various packages. > > So it seems prudent to rename `core` to `std`. But that leaves the > question of what to name `std` in the interim. Options that have been > suggested are `extra`, `ext`, and `contrib`. > > Any other opinions? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From erick.tryzelaar at gmail.com Tue Apr 23 09:44:47 2013 From: erick.tryzelaar at gmail.com (Erick Tryzelaar) Date: Tue, 23 Apr 2013 09:44:47 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> Message-ID: There are still a couple things in std that depend on rustrt: arena.rs dbg.rs net_tcp.rs rl.rs test.rs time.rs uv_ll.rs Can we include moving these into core as part of a rename? I believe that's the one main holdup that is keeping us from breaking std up into external packages. On Tue, Apr 23, 2013 at 9:38 AM, Thad Guidry wrote: > +1 for "extra". It has a nice semantic smiley face all over it. > > > On Tue, Apr 23, 2013 at 11:35 AM, Patrick Walton wrote: > >> Hi everyone, >> >> There's been consensus lately that `core` and `std` are somewhat >> misnamed. `core` is really the standard library--the one that would be >> specified in a specification if we had one. `std` is an "extras" library >> and may well end up sliced up and moved to various packages. >> >> So it seems prudent to rename `core` to `std`. But that leaves the >> question of what to name `std` in the interim. Options that have been >> suggested are `extra`, `ext`, and `contrib`. >> >> Any other opinions? >> >> Patrick >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Tue Apr 23 09:54:59 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Tue, 23 Apr 2013 09:54:59 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> Message-ID: <5176BCE3.6020304@mozilla.com> On 4/23/13 9:44 AM, Erick Tryzelaar wrote: > There are still a couple things in std that depend on rustrt: > > arena.rs > dbg.rs > net_tcp.rs > rl.rs > test.rs > time.rs > uv_ll.rs > > Can we include moving these into core as part of a rename? I believe > that's the one main holdup that is keeping us from breaking std up into > external packages. Could we just break the dependencies on rustrt? Note that we agreed to get rid of net_tcp, time, and uv_ll per the meeting today. Patrick From graydon at mozilla.com Tue Apr 23 10:06:52 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 10:06:52 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> Message-ID: <5176BFAC.1040603@mozilla.com> On 23/04/2013 9:44 AM, Erick Tryzelaar wrote: > There are still a couple things in std that depend on rustrt: > > arena.rs > dbg.rs > net_tcp.rs > rl.rs > test.rs > time.rs > uv_ll.rs > > Can we include moving these into core as part of a rename? I believe > that's the one main holdup that is keeping us from breaking std up into > external packages. Yes. Though I'd ask that we also take a moment to revisit the original motivation for the core/std split, and confirm that everyone's ok with collapsing them back together: https://mail.mozilla.org/pipermail/rust-dev/2011-December/001037.html Namely: - When we support static linking, will it be possible to link subsets of "the standard library" for space constrained devices? E.g. will we be able to compile it with section-per-function or such? - Is it ok that "the standard library" winds up 'use'd in every module by default? You can still shadow its definitions, but there is some risk of confusion due to use of paths qualified by un-mentioned modules. - Is it ok that "packages" in "ext" cannot be mutually recursive with one another? Will this happen often? - Is the "large standard library" approach of python and haskell (say) really problematic wrt. pace of library evolution? Is it wise to even _have_ an "ext"? If so, what does it mean? Supported and tested non-mutually-dependent selections from the package ecosystem? The moral equivalent of boost? Finally, wrt. naming, in the meeting someone mentioned that: extern mod "rust-lang.org/ext"; might not really read well. Lots of "ext" in there. Any other names come to mind? Thanks, -Graydon From lindsey at composition.al Tue Apr 23 10:22:36 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Tue, 23 Apr 2013 13:22:36 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176B835.20301@mozilla.com> References: <5176B835.20301@mozilla.com> Message-ID: On Tue, Apr 23, 2013 at 12:35 PM, Patrick Walton wrote: > Hi everyone, > > There's been consensus lately that `core` and `std` are somewhat misnamed. > `core` is really the standard library--the one that would be specified in a > specification if we had one. `std` is an "extras" library and may well end > up sliced up and moved to various packages. > > So it seems prudent to rename `core` to `std`. But that leaves the question > of what to name `std` in the interim. Options that have been suggested are > `extra`, `ext`, and `contrib`. > > Any other opinions? +1 for renaming `core` to `std`. `std` seems more, uh, standard. +1 for `ext`, short for "extended library". `extra` is OK, too. I'm not a big fan of `contrib`. Lindsey From graydon at mozilla.com Tue Apr 23 10:43:30 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 10:43:30 -0700 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> Message-ID: <5176C842.1060407@mozilla.com> On 22/04/2013 9:57 PM, Robert O'Callahan wrote: > On Tue, Apr 23, 2013 at 4:18 AM, Graydon Hoare > wrote: > > We've also had some requests for a mechanism to enable overflow > checking on _all_ integer types within a given static or dynamic > program extent, using attributes. > > > I, at least, made a request for overflow checking on all integer types, > full stop :-). And I still want it; failure of obvious properties like > "a >= 0 ===> a + b >= b" is just crazy, and I'm tired of living in > crazy-land. How much of a performance penalty is it worth? I believe you can trap this in C presently with a gcc flag too (-ftrapv); but it's a flag rarely turned on. (I generally concur and wanted rust integers to overflow to bignums originally! But I have had to retreat from such stances due to complaints about performance / not-C-ness. I suspect the attribute mechanism is the right approach for such pragmas; would it be acceptable to put one attribute in each of your crates?) -Graydon From asb at asbradbury.org Tue Apr 23 10:44:10 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Tue, 23 Apr 2013 18:44:10 +0100 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176BFAC.1040603@mozilla.com> References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> Message-ID: On 23 April 2013 18:06, Graydon Hoare wrote: > - When we support static linking, will it be possible to link subsets > of "the standard library" for space constrained devices? E.g. will > we be able to compile it with section-per-function or such? That would be ideal. > - Is the "large standard library" approach of python and haskell (say) > really problematic wrt. pace of library evolution? Is it wise to > even _have_ an "ext"? If so, what does it mean? Supported and > tested non-mutually-dependent selections from the package ecosystem? > The moral equivalent of boost? I think the Python and Haskell approaches are actually rather different. Compare the number of packages at http://www.haskell.org/platform/changelog.html vs http://docs.python.org/3/library/ To me the Haskell platform approach of having a pre-populated bunch of packages seems sensible, and makes it rather easy to packages to evolve independently. I actually quite like the idea of having Rust + minimal standard library and a time-based release of the "Rust platform" (as is done in Haskell, and is planned in Ocaml). > Finally, wrt. naming, in the meeting someone mentioned that: > > extern mod "rust-lang.org/ext"; It actually seems rather inoffensive to me. Alex From graydon at mozilla.com Tue Apr 23 10:46:15 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 10:46:15 -0700 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <19811987.VlzDZtLQXY@l10036> References: <20130423144812.217310@gmx.com> <5176A27E.9010805@mozilla.com> <19811987.VlzDZtLQXY@l10036> Message-ID: <5176C8E7.7070109@mozilla.com> On 23/04/2013 8:53 AM, Diggory Hardy wrote: > I suspect (please correct me if I'm wrong) that if it wasn't for C and x86 > compatibility then most people would fall into two categories: don't > know/don't care, and prefer F-division. It's one of those little things like > tau vs. pi which would have been less confusing if we'd started off on the > other foot to start with. And IP addresses would have been 64 or 128bit from the start, there would only be one endianness, and so forth ... yes, sure. But we don't cast off the weight of the past so easily, and I do not think this is something it's wise to fiddle with. A very widely-applied design choice in rust is that the basic types are machine-sized and the arithmetic operations on them are (as close as reasonable to) machine operations. The machine operation is remainder. Moreover, it's not "just C and x86". This same choice is taken (more or less) by PowerPC, LLVM, C++, C#, Java, D, Go, JS, Scala, Ocaml, etc. etc. The path we've taken here is to admit _two_ operation-pairs, div/mod and quot/rem. This path is taken by several languages and specs (Scheme, Common Lisp, Ruby, Smalltalk, SML, Prolog, Haskell, Ada, and ISO 10967 and IEEE 754). The work for this landed last week: https://github.com/mozilla/rust/pull/5990 https://github.com/mozilla/rust/pull/6013 https://github.com/mozilla/rust/issues/4565 https://github.com/mozilla/rust/issues/4917 (Phew! This must really be the week for integer division!) The only remaining thing to struggle with is "which of the two operation-pairs to assign the / and % symbols to", in the operator-overloading sense. For this, we've gone with quot/rem, as in the other languages above, and in keeping with the design preference above. You have to call .mod() or .div() to get the other operators. It does mean there's a bit of a footgun surrounding the symbols / and % specifically, on signed integer types. I would not be at all opposed to adding a lint flag to calls-to-/-and-%-on-signed-integer-types, such that you could trap them all. As with many things here, the design space includes a variety of (sensible) preferences. -Graydon (Please correct me if I've swapped which of the two meanings we've actually assigned; this is one of those issues like double-negation and off-by-one indexing where I get things backwards no matter how much energy I spend on making sure I get it right.) From danielmicay at gmail.com Tue Apr 23 10:50:41 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 23 Apr 2013 13:50:41 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176BFAC.1040603@mozilla.com> References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> Message-ID: On Tue, Apr 23, 2013 at 1:06 PM, Graydon Hoare wrote: > Namely: > > - When we support static linking, will it be possible to link subsets > of "the standard library" for space constrained devices? E.g. will > we be able to compile it with section-per-function or such? Release builds could just be done with link-time optimization. It's okay if it takes 5x as long and 3GiB of memory if it's just a single build. Although I think there would have to be 3 versions of the libraries (lto, static, dynamic). From ncm at cantrip.org Tue Apr 23 11:00:11 2013 From: ncm at cantrip.org (Nathan Myers) Date: Tue, 23 Apr 2013 11:00:11 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176BFAC.1040603@mozilla.com> References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> Message-ID: <5176CC2B.3080809@cantrip.org> > - Is the "large standard library" approach of python and haskell (say) > really problematic wrt. pace of library evolution? Is it wise to > even _have_ an "ext"? If so, what does it mean? Supported and > tested non-mutually-dependent selections from the package ecosystem? > The moral equivalent of boost? > > Finally, wrt. naming, in the meeting someone mentioned that: > > extern mod "rust-lang.org/ext"; > > might not really read well. Lots of "ext" in there. Any other names > come to mind? A name reflecting its true role seems appropriate. Drawing on the Linux kernel experience, I propose "staging". Alternatively, "trial", "proposed", "experimental", "unstable". The Boost experience suggests that explicit interface versioning, if only by naming convention, would be wise: the most frequently expressed reason for Boost non-use has been interface instability between releases. A policy of supporting use of old interfaces in scrupulously module-name-qualified code, enabling interface evolution without breaking existing uses, would aid adoption. As a meta-comment, the reflexive use of abbreviations in not-frequently-typed names seems like a problem. Surely modern editors with auto-complete make these unnecessary? Do we need a policy on what sort of names merit abbreviation, and how much? (I am forced to admit disappointment at "fn" instead of "fun".) Alex Stepanov's policy designing STL was to avoid abbreviations wherever defensible. It mostly worked out well, although "iterator" turned out to be too long. Nathan Myers ncm at cantrip.org From danielmicay at gmail.com Tue Apr 23 11:01:41 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 23 Apr 2013 14:01:41 -0400 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <5176C842.1060407@mozilla.com> References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> Message-ID: On Tue, Apr 23, 2013 at 1:43 PM, Graydon Hoare wrote: > On 22/04/2013 9:57 PM, Robert O'Callahan wrote: >> >> On Tue, Apr 23, 2013 at 4:18 AM, Graydon Hoare > > wrote: >> >> We've also had some requests for a mechanism to enable overflow >> checking on _all_ integer types within a given static or dynamic >> program extent, using attributes. >> >> >> I, at least, made a request for overflow checking on all integer types, >> full stop :-). And I still want it; failure of obvious properties like >> "a >= 0 ===> a + b >= b" is just crazy, and I'm tired of living in >> crazy-land. > > > How much of a performance penalty is it worth? I believe you can trap this > in C presently with a gcc flag too (-ftrapv); but it's a flag rarely turned > on. > > (I generally concur and wanted rust integers to overflow to bignums > originally! But I have had to retreat from such stances due to complaints > about performance / not-C-ness. I suspect the attribute mechanism is the > right approach for such pragmas; would it be acceptable to put one attribute > in each of your crates?) > > -Graydon I don't really think you need an attribute, just good support for an integer type in the library that traps the overflow and expands to a big integer. At the very least, the overhead would involve making integers 2 words instead of 1 for a tag, adding a branch to every operation and also adding a branch after almost every fixnum representation. From i at cantor.mx Tue Apr 23 11:05:33 2013 From: i at cantor.mx (Max Cantor) Date: Tue, 23 Apr 2013 11:05:33 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> Message-ID: I'm pretty new to Rust (lurking on the list for a while) but have been in the Haskell community for a while. While cabal in general is nothing that should be emulated, perhaps the Haskell hierarchy would be informative. In Haskell, there are somewhat unofficial hierarchies, but here they are: prelude: http://hackage.haskell.org/packages/archive/base/4.6.0.1/doc/html/Prelude.html the "default" module that is included by default in all source files. base: http://hackage.haskell.org/package/base package that includes the prelude module and other core functionality. ghc libraries: http://www.haskell.org/ghc/docs/7.6.2/html/libraries/ ghc is the de facto reference implementation for haskell (queue flamewar) and includes a large set of libraries in addition to base haskell platform http://www.haskell.org/platform/changelog.html the "batteries included" distribution that includes many very commonly used libraries as a starting point for a new project On Tue, Apr 23, 2013 at 10:50 AM, Daniel Micay wrote: > On Tue, Apr 23, 2013 at 1:06 PM, Graydon Hoare > wrote: > > Namely: > > > > - When we support static linking, will it be possible to link subsets > > of "the standard library" for space constrained devices? E.g. will > > we be able to compile it with section-per-function or such? > > Release builds could just be done with link-time optimization. It's > okay if it takes 5x as long and 3GiB of memory if it's just a single > build. Although I think there would have to be 3 versions of the > libraries (lto, static, dynamic). > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jack at metajack.im Tue Apr 23 11:07:09 2013 From: jack at metajack.im (Jack Moffitt) Date: Tue, 23 Apr 2013 12:07:09 -0600 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176CC2B.3080809@cantrip.org> References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> <5176CC2B.3080809@cantrip.org> Message-ID: > A name reflecting its true role seems appropriate. Drawing on > the Linux kernel experience, I propose "staging". Alternatively, > "trial", "proposed", "experimental", "unstable". The Clojure community uses "incubator". It typically signifies experiments that may end up in the core library or in the set of canonical add on libs (core.logic, data.json, etc). jack. From psa at di.uminho.pt Tue Apr 23 11:17:16 2013 From: psa at di.uminho.pt (=?ISO-8859-1?Q?Paulo_S=E9rgio_Almeida?=) Date: Tue, 23 Apr 2013 19:17:16 +0100 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: References: <51756392.5050202@di.uminho.pt> Message-ID: <5176D02C.4090203@di.uminho.pt> Ok. Suppose the current syntax is frozen. But I talked about two things: syntax for explicit lifetimes (mainly point 3, altough a bit also in points 1 and 2) and defaults for when no explicit (named) lifetimes are used. Even if no syntax change is made, for the cases when named lifetimes are used, what I find specially painful is the default rule when no explicit lifetimes are used: "an implicit fresh lifetime for each parameter and result". This rule, specially when a result is involved, which is exactly one of the cases when stating lifetime is needed, seems to make little sense, and will force named lifetimes to be used in many cases, causing noise and distraction and decreasing legibility. In what way is the default that I propose, which basically is: "one implicit fresh lifetime for each type parameter and another for all the remainder parameter types" confusing or a possible source of obscurity? I find it quite natural that, e.g., if I am returning a borrowed reference (not a copy, not an owned, not a @) of type T and I have received one or more borrowed references to T, i.e.: fn f(p1: &T, p2: &T, ...) -> &T { ... } the *natural* thing to expect is that the result comes from one of the T that I received as parameters, and the default that I propose is not obscure at all, but makes the code cristal clear. I find having to write fn f<'r, T>(p1: &'r T, p2: &'r T, ...) -> &'r T { ... } because of the current defaults, needlessly painful and distracting. Is the current default less obscure? Will it cause less surprise? Or it is the other way around ... Regards, Paulo On 4/23/13 4:11 PM, Niko Matsakis wrote: > Thanks for your proposal. We've been through a number of rounds with the > lifetime syntax, including an earlier scheme that was quite similar to > what you propose in some regards (there was a single anonymous lifetime > parameter that was used whenever you wrote `&T`, which meant that yes > you often did not need to use explicit lifetime parameter names). > > However, we found that this was ultimately more confusing to people than > helpful. One of the goals of the current syntax was to make the > mechanism of named lifetimes more explicit and thus more clear to the > reader. Smarter defaults have the disadvantage that they often obscure > the underlying system, making it harder to learn what's really going on. > > In practice,named lifetimes don't seem to be that common, at least for > me. We should do some numerical analysis, but I've found subjectively > that most functions simply consume data and do not return pointers. This > is particularly true for "non-library" code, and even more true with > judicious use of `@` pointers (it is often not worth the trouble to > avoid the GC; it can make life much easier, that's what it's there for). > > So in summary I do not think it likely we will change the current syntax. > > > Niko > > > > On Mon, Apr 22, 2013 at 12:21 PM, Paulo S?rgio Almeida > wrote: > > Hi all, > > (My first post here.) > First, congrats for what you are trying to achieve with Rust. I > arrived very late to the party, and so I am not sure that what I > will say can be of use. But as I understand, lifetimes is one of > those things that are not completely solidified, and anyway, better > late than never. > > Looking at some code, expressing lifetimes of borrowed references is > one of those things that is somewhat bewildering, making the code > somewhat noisy. I think it can be improved through a better choice > of defaults and a slight change in explicit lifetimes. > > The main thing I think is "wrong" is the defaults for function > parameters. From the tutorial: "the compiler simply creates a fresh > name for the lifetime automatically: that is, the lifetime name is > guaranteed to refer to a distinct lifetime from the lifetimes of all > other parameters." > > This default is not very useful. For example, it is wrong basically > everytime we want to return a borrowed pointer (unless, for a global > variable?). The more common case is returning something with the > same lifetime as some parameter. In many cases we don't need to > distinguish parameters, and specify which we are returning, in > others we want to split parameters in two equivalence classes, the > one from which we are returning, and everything else. > > When type parameters are involved, a return type typically says > where the result comes from most of the times. Again, the default > should be different. E.g., when we are returning a borrowed > reference to a "key" of type parameter K, the default should be > "other things also of type K in parameters". > > Finally, with better defaults, in the remaining cases where we need > to explicitly express lifetimes, having to "invent" identifiers is a > nuisance. Also the space which must be used between the lifetime > identifier and the type is too distracting and makes it cumbersome > (for humans) to "parse" the type of some identifier. > > I have been thinking about this and have the following proposal. (Of > course there may be inumerous things that must have escaped me, but > here it goes anyway.) > > --- > Regarding types for borrowed references in function parameters or > result, and type parameters: > > 1) each type-parameter has an associated implicit lifetime, which by > default is different from the lifetimes of other type-parameters or > normal function parameter types, but it can be qualified in each > declaration or use with an explicit lifetime; > > 2) function parameter types or return type that are not type > parameters have all the same implicit lifetime by default, but they > can be qualified explicitly with some lifetime. > > 3) explicit lifetimes are written identifier' instead of > 'identifier; a null identifier is allowed, as in &'T, to qualify a > reference &T with lifetime '. > --- > > (Another useful possibility would be allowing several ' at the end, > allowing e.g., &T, &'T, &''T as borrowed references to the same type > but with different lifetimes. In practice, a single ' plus 1) and 2) > will cover "99%" of cases. We could even get rid of using > identifiers, using only several '. But this is not relevant for the > main proposal.) > > 1) and 2) are about defaults for implicit lifetimes, which currently > are "fresh lifetime for each parameter", and 3) is about simplifying > the remaining cases of explicit expression. The motivation for 3) is > to remove both the need of a space separating lifetime from type and > also the need to "invent" lifetime identifiers. Rewriting examples > from the tutorial and elsewhere, under this proposal, would make > code more legible and standard, reducing a lot the need for explicit > lifetime expression. Things would "just work" as wanted most times. > > -------------------------------------------------------------------------------- > > From the Rust Borrowed Pointers Tutorial > > --- > > fn get_x<'r>(p: &'r Point) -> &'r float { &p.x } > > becomes > > fn get_x(p: &Point) -> &float { &p.x } > > --- > > fn select<'r, T>(shape: &'r Shape, threshold: float, > a: &'r T, b: &'r T) -> &'r T { > if compute_area(shape) > threshold {a} else {b} > } > > becomes > > fn select<'T>(shape: &'Shape, threshold: float, > a: &'T, b: &'T) -> &'T { > if compute_area(shape) > threshold {a} else {b} > } > > (not very useful case) > > --- > > fn select<'r, T>(shape: &Shape, threshold: float, > a: &'r T, b: &'r T) -> &'r T { > if compute_area(shape) > threshold {a} else {b} > } > > becomes > > fn select(shape: &Shape, threshold: float, > a: &T, b: &T) -> &T { > if compute_area(shape) > threshold {a} else {b} > } > > -------------------------------------------------------------------------------- > > Other examples: > > --- > > struct Iterator<'lt, T> { > source: &'lt [T], > index: uint > } > > fn has_next<'a, 'b, T>(iter: &'a Iterator<'b, T>) -> bool { > iter.index + 1 < iter.source.len() > } > > fn next<'a, 'b, T>(iter: &'a mut Iterator<'b, T>) -> > Option<&'b T> { > iter.index += 1; > if iter.index < iter.source.len() { > Some(&iter.source[iter.index]) > } else { > None > } > } > > becomes: > > struct Iterator<'T> { > source: &'[T], > index: uint > } > > fn has_next(iter: &Iterator) -> bool { > iter.index + 1 < iter.source.len() > } > > fn next(iter: &mut Iterator) -> Option<&T> { > iter.index += 1; > if iter.index < iter.source.len() { > Some(&iter.source[iter.index]) > } else { > None > } > } > > --- > > impl<'b, T> Iterator<'b, T> { > fn has_next(&self) { /* same as before */ } > fn next(&mut self) -> Option<&'b T> { /* same as before > */ } > } > > becomes > > impl Iterator { > fn has_next(&self) { /* same as before */ } > fn next(&mut self) -> Option<&T> { /* same as before */ } > } > > --- > > Regards, > Paulo > > > > > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > From doy at tozt.net Tue Apr 23 11:22:40 2013 From: doy at tozt.net (Jesse Luehrs) Date: Tue, 23 Apr 2013 13:22:40 -0500 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: <5176D02C.4090203@di.uminho.pt> References: <51756392.5050202@di.uminho.pt> <5176D02C.4090203@di.uminho.pt> Message-ID: <20130423182240.GY26639@tozt.net> Most of the time that I've seen return value lifetimes specified, they aren't returning something of the same type as a parameter. For instance, the vec module has "fn head<'r, T>(v: &'r [T]) -> &'r T". How common is it for functions to actually return something of the same type, as opposed to a type that the parameter type contains? -doy On Tue, Apr 23, 2013 at 07:17:16PM +0100, Paulo S?rgio Almeida wrote: > Ok. Suppose the current syntax is frozen. But I talked about two > things: syntax for explicit lifetimes (mainly point 3, altough a bit > also in points 1 and 2) and defaults for when no explicit (named) > lifetimes are used. > > Even if no syntax change is made, for the cases when named lifetimes > are used, what I find specially painful is the default rule when no > explicit lifetimes are used: > > "an implicit fresh lifetime for each parameter and result". > > This rule, specially when a result is involved, which is exactly one > of the cases when stating lifetime is needed, seems to make little > sense, and will force named lifetimes to be used in many cases, > causing noise and distraction and decreasing legibility. > > In what way is the default that I propose, which basically is: > > "one implicit fresh lifetime for each type parameter and another for > all the remainder parameter types" > > confusing or a possible source of obscurity? I find it quite natural > that, e.g., if I am returning a borrowed reference (not a copy, not > an owned, not a @) of type T and I have received one or more > borrowed references to T, i.e.: > > fn f(p1: &T, p2: &T, ...) -> &T { ... } > > the *natural* thing to expect is that the result comes from one of > the T that I received as parameters, and the default that I propose > is not obscure at all, but makes the code cristal clear. I find > having to write > > fn f<'r, T>(p1: &'r T, p2: &'r T, ...) -> &'r T { ... } > > because of the current defaults, needlessly painful and distracting. > Is the current default less obscure? Will it cause less surprise? Or > it is the other way around ... > > Regards, > Paulo > > > On 4/23/13 4:11 PM, Niko Matsakis wrote: > >Thanks for your proposal. We've been through a number of rounds with the > >lifetime syntax, including an earlier scheme that was quite similar to > >what you propose in some regards (there was a single anonymous lifetime > >parameter that was used whenever you wrote `&T`, which meant that yes > >you often did not need to use explicit lifetime parameter names). > > > >However, we found that this was ultimately more confusing to people than > >helpful. One of the goals of the current syntax was to make the > >mechanism of named lifetimes more explicit and thus more clear to the > >reader. Smarter defaults have the disadvantage that they often obscure > >the underlying system, making it harder to learn what's really going on. > > > >In practice,named lifetimes don't seem to be that common, at least for > >me. We should do some numerical analysis, but I've found subjectively > >that most functions simply consume data and do not return pointers. This > >is particularly true for "non-library" code, and even more true with > >judicious use of `@` pointers (it is often not worth the trouble to > >avoid the GC; it can make life much easier, that's what it's there for). > > > >So in summary I do not think it likely we will change the current syntax. > > > > > >Niko > > > > > > > >On Mon, Apr 22, 2013 at 12:21 PM, Paulo S?rgio Almeida >> wrote: > > > > Hi all, > > > > (My first post here.) > > First, congrats for what you are trying to achieve with Rust. I > > arrived very late to the party, and so I am not sure that what I > > will say can be of use. But as I understand, lifetimes is one of > > those things that are not completely solidified, and anyway, better > > late than never. > > > > Looking at some code, expressing lifetimes of borrowed references is > > one of those things that is somewhat bewildering, making the code > > somewhat noisy. I think it can be improved through a better choice > > of defaults and a slight change in explicit lifetimes. > > > > The main thing I think is "wrong" is the defaults for function > > parameters. From the tutorial: "the compiler simply creates a fresh > > name for the lifetime automatically: that is, the lifetime name is > > guaranteed to refer to a distinct lifetime from the lifetimes of all > > other parameters." > > > > This default is not very useful. For example, it is wrong basically > > everytime we want to return a borrowed pointer (unless, for a global > > variable?). The more common case is returning something with the > > same lifetime as some parameter. In many cases we don't need to > > distinguish parameters, and specify which we are returning, in > > others we want to split parameters in two equivalence classes, the > > one from which we are returning, and everything else. > > > > When type parameters are involved, a return type typically says > > where the result comes from most of the times. Again, the default > > should be different. E.g., when we are returning a borrowed > > reference to a "key" of type parameter K, the default should be > > "other things also of type K in parameters". > > > > Finally, with better defaults, in the remaining cases where we need > > to explicitly express lifetimes, having to "invent" identifiers is a > > nuisance. Also the space which must be used between the lifetime > > identifier and the type is too distracting and makes it cumbersome > > (for humans) to "parse" the type of some identifier. > > > > I have been thinking about this and have the following proposal. (Of > > course there may be inumerous things that must have escaped me, but > > here it goes anyway.) > > > > --- > > Regarding types for borrowed references in function parameters or > > result, and type parameters: > > > > 1) each type-parameter has an associated implicit lifetime, which by > > default is different from the lifetimes of other type-parameters or > > normal function parameter types, but it can be qualified in each > > declaration or use with an explicit lifetime; > > > > 2) function parameter types or return type that are not type > > parameters have all the same implicit lifetime by default, but they > > can be qualified explicitly with some lifetime. > > > > 3) explicit lifetimes are written identifier' instead of > > 'identifier; a null identifier is allowed, as in &'T, to qualify a > > reference &T with lifetime '. > > --- > > > > (Another useful possibility would be allowing several ' at the end, > > allowing e.g., &T, &'T, &''T as borrowed references to the same type > > but with different lifetimes. In practice, a single ' plus 1) and 2) > > will cover "99%" of cases. We could even get rid of using > > identifiers, using only several '. But this is not relevant for the > > main proposal.) > > > > 1) and 2) are about defaults for implicit lifetimes, which currently > > are "fresh lifetime for each parameter", and 3) is about simplifying > > the remaining cases of explicit expression. The motivation for 3) is > > to remove both the need of a space separating lifetime from type and > > also the need to "invent" lifetime identifiers. Rewriting examples > > from the tutorial and elsewhere, under this proposal, would make > > code more legible and standard, reducing a lot the need for explicit > > lifetime expression. Things would "just work" as wanted most times. > > > > -------------------------------------------------------------------------------- > > > > From the Rust Borrowed Pointers Tutorial > > > > --- > > > > fn get_x<'r>(p: &'r Point) -> &'r float { &p.x } > > > > becomes > > > > fn get_x(p: &Point) -> &float { &p.x } > > > > --- > > > > fn select<'r, T>(shape: &'r Shape, threshold: float, > > a: &'r T, b: &'r T) -> &'r T { > > if compute_area(shape) > threshold {a} else {b} > > } > > > > becomes > > > > fn select<'T>(shape: &'Shape, threshold: float, > > a: &'T, b: &'T) -> &'T { > > if compute_area(shape) > threshold {a} else {b} > > } > > > > (not very useful case) > > > > --- > > > > fn select<'r, T>(shape: &Shape, threshold: float, > > a: &'r T, b: &'r T) -> &'r T { > > if compute_area(shape) > threshold {a} else {b} > > } > > > > becomes > > > > fn select(shape: &Shape, threshold: float, > > a: &T, b: &T) -> &T { > > if compute_area(shape) > threshold {a} else {b} > > } > > > > -------------------------------------------------------------------------------- > > > > Other examples: > > > > --- > > > > struct Iterator<'lt, T> { > > source: &'lt [T], > > index: uint > > } > > > > fn has_next<'a, 'b, T>(iter: &'a Iterator<'b, T>) -> bool { > > iter.index + 1 < iter.source.len() > > } > > > > fn next<'a, 'b, T>(iter: &'a mut Iterator<'b, T>) -> > > Option<&'b T> { > > iter.index += 1; > > if iter.index < iter.source.len() { > > Some(&iter.source[iter.index]) > > } else { > > None > > } > > } > > > > becomes: > > > > struct Iterator<'T> { > > source: &'[T], > > index: uint > > } > > > > fn has_next(iter: &Iterator) -> bool { > > iter.index + 1 < iter.source.len() > > } > > > > fn next(iter: &mut Iterator) -> Option<&T> { > > iter.index += 1; > > if iter.index < iter.source.len() { > > Some(&iter.source[iter.index]) > > } else { > > None > > } > > } > > > > --- > > > > impl<'b, T> Iterator<'b, T> { > > fn has_next(&self) { /* same as before */ } > > fn next(&mut self) -> Option<&'b T> { /* same as before > > */ } > > } > > > > becomes > > > > impl Iterator { > > fn has_next(&self) { /* same as before */ } > > fn next(&mut self) -> Option<&T> { /* same as before */ } > > } > > > > --- > > > > Regards, > > Paulo > > > > > > > > > > > > > > _______________________________________________ > > 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 lindsey at composition.al Tue Apr 23 11:29:05 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Tue, 23 Apr 2013 14:29:05 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176CC2B.3080809@cantrip.org> References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> <5176CC2B.3080809@cantrip.org> Message-ID: On Tue, Apr 23, 2013 at 2:00 PM, Nathan Myers wrote: > A name reflecting its true role seems appropriate. Drawing on > the Linux kernel experience, I propose "staging". Alternatively, > "trial", "proposed", "experimental", "unstable". I think it would be great to have a way to tag libraries as unstable or experimental, but that seems orthogonal to "linked in by default"/"not linked in by default". I think of the current `std` not as a place for unstable/experimental libraries, just as a place for stuff not linked by default. (Of course, `std` *is* rather unstable, but only because everything written in Rust is unstable. :) ) Lindsey From vadimcn at gmail.com Tue Apr 23 11:51:41 2013 From: vadimcn at gmail.com (Vadim) Date: Tue, 23 Apr 2013 11:51:41 -0700 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> Message-ID: If all that's needed is the safety from overflow exploits, a better option would be to raise a condition on overflow. That would avoid any size overhead. On Tue, Apr 23, 2013 at 11:01 AM, Daniel Micay wrote: > On Tue, Apr 23, 2013 at 1:43 PM, Graydon Hoare > wrote: > > On 22/04/2013 9:57 PM, Robert O'Callahan wrote: > >> > >> On Tue, Apr 23, 2013 at 4:18 AM, Graydon Hoare >> > wrote: > >> > >> We've also had some requests for a mechanism to enable overflow > >> checking on _all_ integer types within a given static or dynamic > >> program extent, using attributes. > >> > >> > >> I, at least, made a request for overflow checking on all integer types, > >> full stop :-). And I still want it; failure of obvious properties like > >> "a >= 0 ===> a + b >= b" is just crazy, and I'm tired of living in > >> crazy-land. > > > > > > How much of a performance penalty is it worth? I believe you can trap > this > > in C presently with a gcc flag too (-ftrapv); but it's a flag rarely > turned > > on. > > > > (I generally concur and wanted rust integers to overflow to bignums > > originally! But I have had to retreat from such stances due to complaints > > about performance / not-C-ness. I suspect the attribute mechanism is the > > right approach for such pragmas; would it be acceptable to put one > attribute > > in each of your crates?) > > > > -Graydon > > I don't really think you need an attribute, just good support for an > integer type in the library that traps the overflow and expands to a > big integer. > > At the very least, the overhead would involve making integers 2 words > instead of 1 for a tag, adding a branch to every operation and also > adding a branch after almost every fixnum representation. > _______________________________________________ > 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 steven099 at gmail.com Tue Apr 23 11:59:26 2013 From: steven099 at gmail.com (Steven Blenkinsop) Date: Tue, 23 Apr 2013 14:59:26 -0400 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: <5176D02C.4090203@di.uminho.pt> References: <51756392.5050202@di.uminho.pt> <5176D02C.4090203@di.uminho.pt> Message-ID: A fresh lifetime is a better default behaviour. For example, fn F(x: &mut T) could be either fn A<'a>(x: &'a mut T<'a>) or fn B<'a, 'b>(x: &'a mut T<'b>) In A, it's possible for any borrow with lifetime 'a to escape via the mutable state in x, including the borrow into x itself. This makes it so you can't call A with any `&mut T` that has a shorter lifetime than the contents of the T, and the borrow into A will be alive and inaccessible for the remainder of the lifetime of the contents of the T. B is almost certainly what people will want when they write F. On Tuesday, April 23, 2013, Paulo S?rgio Almeida wrote: > Ok. Suppose the current syntax is frozen. But I talked about two things: > syntax for explicit lifetimes (mainly point 3, altough a bit also in points > 1 and 2) and defaults for when no explicit (named) lifetimes are used. > > Even if no syntax change is made, for the cases when named lifetimes are > used, what I find specially painful is the default rule when no explicit > lifetimes are used: > > "an implicit fresh lifetime for each parameter and result". > > This rule, specially when a result is involved, which is exactly one of > the cases when stating lifetime is needed, seems to make little sense, and > will force named lifetimes to be used in many cases, causing noise and > distraction and decreasing legibility. > > In what way is the default that I propose, which basically is: > > "one implicit fresh lifetime for each type parameter and another for all > the remainder parameter types" > > confusing or a possible source of obscurity? I find it quite natural that, > e.g., if I am returning a borrowed reference (not a copy, not an owned, not > a @) of type T and I have received one or more borrowed references to T, > i.e.: > > fn f(p1: &T, p2: &T, ...) -> &T { ... } > > the *natural* thing to expect is that the result comes from one of the T > that I received as parameters, and the default that I propose is not > obscure at all, but makes the code cristal clear. I find having to write > > fn f<'r, T>(p1: &'r T, p2: &'r T, ...) -> &'r T { ... } > > because of the current defaults, needlessly painful and distracting. Is > the current default less obscure? Will it cause less surprise? Or it is the > other way around ... > > Regards, > Paulo > > > On 4/23/13 4:11 PM, Niko Matsakis wrote: > >> Thanks for your proposal. We've been through a number of rounds with the >> lifetime syntax, including an earlier scheme that was quite similar to >> what you propose in some regards (there was a single anonymous lifetime >> parameter that was used whenever you wrote `&T`, which meant that yes >> you often did not need to use explicit lifetime parameter names). >> >> However, we found that this was ultimately more confusing to people than >> helpful. One of the goals of the current syntax was to make the >> mechanism of named lifetimes more explicit and thus more clear to the >> reader. Smarter defaults have the disadvantage that they often obscure >> the underlying system, making it harder to learn what's really going on. >> >> In practice,named lifetimes don't seem to be that common, at least for >> me. We should do some numerical analysis, but I've found subjectively >> that most functions simply consume data and do not return pointers. This >> is particularly true for "non-library" code, and even more true with >> judicious use of `@` pointers (it is often not worth the trouble to >> avoid the GC; it can make life much easier, that's what it's there for). >> >> So in summary I do not think it likely we will change the current syntax. >> >> >> Niko >> >> >> >> On Mon, Apr 22, 2013 at 12:21 PM, Paulo S?rgio Almeida > > wrote: >> >> Hi all, >> >> (My first post here.) >> First, congrats for what you are trying to achieve with Rust. I >> arrived very late to the party, and so I am not sure that what I >> will say can be of use. But as I understand, lifetimes is one of >> those things that are not completely solidified, and anyway, better >> late than never. >> >> Looking at some code, expressing lifetimes of borrowed references is >> one of those things that is somewhat bewildering, making the code >> somewhat noisy. I think it can be improved through a better choice >> of defaults and a slight change in explicit lifetimes. >> >> The main thing I think is "wrong" is the defaults for function >> parameters. From the tutorial: "the compiler simply creates a fresh >> name for the lifetime automatically: that is, the lifetime name is >> guaranteed to refer to a distinct lifetime from the lifetimes of all >> other parameters." >> >> This default is not very useful. For example, it is wrong basically >> everytime we want to return a borrowed pointer (unless, for a global >> variable?). The more common case is returning something with the >> same lifetime as some parameter. In many cases we don't need to >> distinguish parameters, and specify which we are returning, in >> others we want to split parameters in two equivalence classes, the >> one from which we are returning, and everything else. >> >> When type parameters are involved, a return type typically says >> where the result comes from most of the times. Again, the default >> should be different. E.g., when we are returning a borrowed >> reference to a "key" of type parameter K, the default should be >> "other things also of type K in parameters". >> >> Finally, with better defaults, in the remaining cases where we need >> to explicitly express lifetimes, having to "invent" identifiers is a >> nuisance. Also the space which must be used between the lifetime >> identifier and the type is too distracting and makes it cumbersome >> (for humans) to "parse" the type of some identifier. >> >> I have been thinking about this and have the following proposal. (Of >> course there may be inumerous things that must have escaped me, but >> here it goes anyway.) >> >> --- >> Regarding types for borrowed references in function parameters or >> result, and type parameters: >> >> 1) each type-parameter has an associated implicit lifetime, which by >> default is different from the lifetimes of other type-parameters or >> normal function parameter types, but it can be qualified in each >> declaration or use with an explicit lifetime; >> >> 2) function parameter types or return type that are not type >> parameters have all the same implicit lifetime by default, but they >> can be qualified explicitly with some lifetime. >> >> 3) explicit lifetimes are written identifier' instead of >> 'identifier; a null identifier is allowed, as in &'T, to qualify a >> reference &T with lifetime '. >> --- >> >> (Another useful possibility would be allowing several ' at the end, >> allowing e.g., &T, &'T, &''T as borrowed references to the same type >> but with different lifetimes. In practice, a single ' plus 1) and 2) >> will cover "99%" of cases. We could even get rid of using >> identifiers, using only several '. But this is not relevant for the >> main proposal.) >> >> 1) and 2) are about defaults for implicit lifetimes, which currently >> are "fresh lifetime for each parameter", and 3) is about simplifying >> the remaining cases of explicit expression. The motivation for 3) is >> to remove both the need of a space separating lifetime from type and >> also the need to "invent" lifetime identifiers. Rewriting examples >> from the tutorial and elsewhere, under this proposal, would make >> code more legible and standard, reducing a lot the need for explicit >> lifetime expression. Things would "just work" as wanted most times. >> >> ------------------------------**------------------------------** >> -------------------- >> >> From the Rust Borrowed Pointers Tutorial >> >> --- >> >> fn get_x<'r>(p: &'r Point) -> &'r float { &p.x } >> >> becomes >> >> fn get_x(p: &Point) -> &float { &p.x } >> >> --- >> >> fn select<'r, T>(shape: &'r Shape, threshold: float, >> a: &'r T, b: &'r T) -> &'r T { >> if compute_area(shape) > threshold {a} else {b} >> } >> >> becomes >> >> 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 steven099 at gmail.com Tue Apr 23 12:10:49 2013 From: steven099 at gmail.com (Steven Blenkinsop) Date: Tue, 23 Apr 2013 15:10:49 -0400 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: References: <51756392.5050202@di.uminho.pt> <5176D02C.4090203@di.uminho.pt> Message-ID: One potential default that might be useful/not terrible, though I can't say I've thought of all the possible implications, is for the lifetimes in the return value to default to the intersection of the lifetimes in the parameters, thereby allowing anything borrowed by one of the parameters to be returned by the function by default. On Tuesday, April 23, 2013, Steven Blenkinsop wrote: > A fresh lifetime is a better default behaviour. For example, > fn F(x: &mut T) > could be either > fn A<'a>(x: &'a mut T<'a>) > or > fn B<'a, 'b>(x: &'a mut T<'b>) > > In A, it's possible for any borrow with lifetime 'a to escape via the > mutable state in x, including the borrow into x itself. This makes it so > you can't call A with any `&mut T` that has a shorter lifetime than the > contents of the T, and the borrow into A will be alive and inaccessible for > the remainder of the lifetime of the contents of the T. B is almost > certainly what people will want when they write F. > > On Tuesday, April 23, 2013, Paulo S?rgio Almeida wrote: > >> Ok. Suppose the current syntax is frozen. But I talked about two things: >> syntax for explicit lifetimes (mainly point 3, altough a bit also in points >> 1 and 2) and defaults for when no explicit (named) lifetimes are used. >> >> Even if no syntax change is made, for the cases when named lifetimes are >> used, what I find specially painful is the default rule when no explicit >> lifetimes are used: >> >> "an implicit fresh lifetime for each parameter and result". >> >> This rule, specially when a result is involved, which is exactly one of >> the cases when stating lifetime is needed, seems to make little sense, and >> will force named lifetimes to be used in many cases, causing noise and >> distraction and decreasing legibility. >> >> In what way is the default that I propose, which basically is: >> >> "one implicit fresh lifetime for each type parameter and another for all >> the remainder parameter types" >> >> confusing or a possible source of obscurity? I find it quite natural >> that, e.g., if I am returning a borrowed reference (not a copy, not an >> owned, not a @) of type T and I have received one or more borrowed >> references to T, i.e.: >> >> fn f(p1: &T, p2: &T, ...) -> &T { ... } >> >> the *natural* thing to expect is that the result comes from one of the T >> that I received as parameters, and the default that I propose is not >> obscure at all, but makes the code cristal clear. I find having to write >> >> fn f<'r, T>(p1: &'r T, p2: &'r T, ...) -> &'r T { ... } >> >> because of the current defaults, needlessly painful and distracting. Is >> the current default less obscure? Will it cause less surprise? Or it is the >> other way around ... >> >> Regards, >> Paulo >> >> >> On 4/23/13 4:11 PM, Niko Matsakis wrote: >> >>> Thanks for your proposal. We've been through a number of rounds with the >>> lifetime syntax, including an earlier scheme that was quite similar to >>> what you propose in some regards (there was a single anonymous lifetime >>> parameter that was used whenever you wrote `&T`, which meant that yes >>> you often did not need to use explicit lifetime parameter names). >>> >>> However, we found that this was ultimately more confusing to people than >>> helpful. One of the goals of the current syntax was to make the >>> mechanism of named lifetimes more explicit and thus more clear to the >>> reader. Smarter defaults have the disadvantage that they often obscure >>> the underlying system, making it harder to learn what's really going on. >>> >>> In practice,named lifetimes don't seem to be that common, at least for >>> me. We should do some numerical analysis, but I've found subjectively >>> that most functions simply consume data and do not return pointers. This >>> is particularly true for "non-library" code, and even more true with >>> judicious use of `@` pointers (it is often not worth the trouble to >>> avoid the GC; it can make life much easier, that's what it's there for). >>> >>> So in summary I do not think it likely we will change the current syntax. >>> >>> >>> Niko >>> >>> >>> >>> On Mon, Apr 22, 2013 at 12:21 PM, Paulo S?rgio Almeida >> > wrote: >>> >>> Hi all, >>> >>> (My first post here.) >>> First, congrats for what you are trying to achieve with Rust. I >>> arrived very late to the party, and so I am not sure that what I >>> will say can be of use. But as I understand, lifetimes is one of >>> those things that are not completely solidified, and anyway, better >>> late than never. >>> >>> Looking at some code, expressing lifetimes of borrowed references is >>> one of those things that is somewhat bewildering, making the code >>> somewhat noisy. I think it can be improved through a better choice >>> of defaults and a slight change in explicit lifetimes. >>> >>> The main thing I think is "wrong" is the defaults for function >>> parameters. From the tutorial: "the compiler simply creates a fresh >>> name for the lifetime automatically: that is, the lifetime name is >>> guaranteed to refer to a distinct lifetime from the lifetimes of all >>> other parameters." >>> >>> This default is not very useful. For example, it is wrong basically >>> everytime we want to return a borrowed pointer (unless, for a global >>> variable?). The more common case is returning something with the >>> same lifetime as some parameter. In many cases we don't need to >>> distinguish parameters, and specify which we are returning, in >>> others we want to split parameters in two equivalence classes, the >>> one from which we are returning, and everything else. >>> >>> When type parameters are involved, a return type typically says >>> where the result comes from most of the times. Again, the default >>> should be different. E.g., when we are returning a borrowed >>> reference to a "key" of type parameter K, the default should be >>> "other things also of type K in parameters". >>> >>> Finally, with better defaults, in the remaining cases where we need >>> to explicitly express lifetimes, having to "invent" identifiers is a >>> nuisance. Also the space which must be used between the lifetime >>> identifier and the type is too distracting and makes it cumbersome >>> (for humans) to "parse" the type of some identifier. >>> >>> I have been thinking about this and have the following proposal. (Of >>> course there may be inumerous things that must have escaped me, but >>> here it goes anyway.) >>> >>> --- >>> Regarding types for borrowed references in function parameters or >>> result, and type parameters: >>> >>> 1) each type-parameter has an associated implicit lifetime, which by >>> default is different from the lifetimes of other type-parameters or >>> normal function parameter types, but it can be qualified in each >>> declaration or use with an explicit lifetime; >>> >>> 2) function parameter types or return type that are not type >>> parameters have all the same implicit lifetime by default, but they >>> can be qualified explicitly with some lifetime. >>> >>> 3) explicit lifetimes are written identifier' instead of >>> 'identifier; a null identifier is allowed, as in &'T, to qualify a >>> reference &T with lifetime '. >>> --- >>> >>> (Another useful possibility would be allowing several ' at the end, >>> allowing e.g., &T, &'T, &''T as borrowed references to the same type >>> but with different lifetimes. In practice, a single ' plus 1) and 2) >>> will cover "99%" of cases. We Rust-dev at mozilla.org >> Rust-dev at mozilla.org> >>> https://mail.mozilla.org/**listinfo/rust-dev >>> >>> >>> >> ______________________________**_________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/**listinfo/rust-dev >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Tue Apr 23 13:04:19 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Tue, 23 Apr 2013 16:04:19 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176B835.20301@mozilla.com> References: <5176B835.20301@mozilla.com> Message-ID: I propose "libmantle", because it floats just above libcore. :P On Tue, Apr 23, 2013 at 12:35 PM, Patrick Walton wrote: > Hi everyone, > > There's been consensus lately that `core` and `std` are somewhat misnamed. > `core` is really the standard library--the one that would be specified in a > specification if we had one. `std` is an "extras" library and may well end > up sliced up and moved to various packages. > > So it seems prudent to rename `core` to `std`. But that leaves the > question of what to name `std` in the interim. Options that have been > suggested are `extra`, `ext`, and `contrib`. > > Any other opinions? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Tue Apr 23 13:44:45 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 23 Apr 2013 13:44:45 -0700 Subject: [rust-dev] New milestones, bug triage, maturity and completion In-Reply-To: <5176039C.6060805@mozilla.com> References: <5176039C.6060805@mozilla.com> Message-ID: <5176F2BD.7000103@mozilla.com> On 04/22/2013 08:44 PM, Graydon Hoare wrote: > Hi, > > 1. Milestones split into two groups > > Previous rust releases have used milestones ineffectively, as they > blurred the distinction between aspirations ("we think this bug > _should_ get done") and prediction ("we think this bug _will_ get > done"). As a result, they served neither purpose and were frequently > overlooked or ignored. > > We will attempt to breathe new life into the "milestone" facility by > splitting their roles into separate sets: for 0.7 and onwards, > release-numbered milestones (0.7, 0.8, 0.9, etc.) will be _predictive > only_. Bugs should be placed on those milestones only if they are > assigned to you, and represent your best guess about _what you will > do_ during a release cycle. You can take something off that milestone > if it's assigned to you and you don't think you'll get it done, > whenever you see fit. These milestones will have associated target > dates, which we will aim to maintain on the quarterly cadence we've > maintained so far. > > A separate set of milestones has been added called "maturity" > milestones. These have no dates, and are "aspirational": they define > subjective concepts "backwards compatible" or "feature complete" in > terms of specific bugs, for external measurement of the project's > state. The project's maturity can be judged against these more > usefully than it can be judged against milestones like "0.7" (which > tells the reader very little). Is closing any or all maturity milestones a prerequisite for releasing 1.0? From banderson at mozilla.com Tue Apr 23 14:00:41 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 23 Apr 2013 14:00:41 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> Message-ID: <5176F679.4020502@mozilla.com> On 04/23/2013 09:44 AM, Erick Tryzelaar wrote: > There are still a couple things in std that depend on rustrt: > > arena.rs > dbg.rs > net_tcp.rs > rl.rs > test.rs > time.rs > uv_ll.rs > > Can we include moving these into core as part of a rename? I believe > that's the one main holdup that is keeping us from breaking std up > into external packages. > > I strongly prefer going in the other direction, move native parts into the crates they logically belong in instead of putting things in core because they have native components. My specific suggestions for each of these: * arena - move whatever it needs to 'extra' * dbg - delete. obsolete * net_tcp - delete, being rewritten in core * rl - statically link native components to 'extra' * test - this one has been vexing me a long time. Just moving it to core would solve a lot of problems, but that also pulls in std::term, which I'm not crazy about having in core. * time - not sure * uv_ll - delete Additionally, core::flate belongs in std. It lives in core because it uses native parts of rt. -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Tue Apr 23 14:03:06 2013 From: clements at brinckerhoff.org (John Clements) Date: Tue, 23 Apr 2013 14:03:06 -0700 Subject: [rust-dev] plaintive cry (please don't use #[cfg(stage2)]) Message-ID: Okay, I'm having no luck getting local folks upset about this, so I'm going to phrase it as a polite request: It appears to me that there's a common Rust idiom of using #[cfg(stage0)] OLD CODE #[cfg(stage1)] #[cfg(stage2)] #[cfg(stage3)] NEW CODE The problem with this is that if you try to compile this code from the command line, using, e.g.: rustc syntax.rc ? it fails, because no stageN flag was supplied. It appears to me that this problem has a straightforward solution, using new(ish) syntax. Rather than the above, it appears we can now write: #[cfg(stage0)] OLD CODE #[cfg(not(stage0))] NEW CODE ? which, besides being shorter, works when no config flag is supplied. This is especially vital to those of us who use rust test syntax.rc ?as part of their development cycle. If I'm wrong, let me know. If I'm not wrong, consider using this form in the future?. Best, John From banderson at mozilla.com Tue Apr 23 14:04:04 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 23 Apr 2013 14:04:04 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> <5176CC2B.3080809@cantrip.org> Message-ID: <5176F744.3000304@mozilla.com> On 04/23/2013 11:29 AM, Lindsey Kuper wrote: > On Tue, Apr 23, 2013 at 2:00 PM, Nathan Myers wrote: >> A name reflecting its true role seems appropriate. Drawing on >> the Linux kernel experience, I propose "staging". Alternatively, >> "trial", "proposed", "experimental", "unstable". > I think it would be great to have a way to tag libraries as unstable > or experimental, but that seems orthogonal to "linked in by > default"/"not linked in by default". > > I think of the current `std` not as a place for unstable/experimental > libraries, just as a place for stuff not linked by default. (Of > course, `std` *is* rather unstable, but only because everything > written in Rust is unstable. :) ) > I agree. We should have the idea of an incubator for packages that are on track to becoming 'standard', but that is probably not the role of this library. I imagine that this 'extra' library will ultimately dismantled into individual packages and dropped into the package incubator. From banderson at mozilla.com Tue Apr 23 14:05:38 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 23 Apr 2013 14:05:38 -0700 Subject: [rust-dev] plaintive cry (please don't use #[cfg(stage2)]) In-Reply-To: References: Message-ID: <5176F7A2.5000105@mozilla.com> On 04/23/2013 02:03 PM, John Clements wrote: > Okay, I'm having no luck getting local folks upset about this, so I'm going to phrase it as a polite request: > > It appears to me that there's a common Rust idiom of using > > #[cfg(stage0)] > OLD CODE > #[cfg(stage1)] > #[cfg(stage2)] > #[cfg(stage3)] > NEW CODE > > The problem with this is that if you try to compile this code from the command line, using, e.g.: > > rustc syntax.rc > > ? it fails, because no stageN flag was supplied. > > It appears to me that this problem has a straightforward solution, using new(ish) syntax. Rather than the above, it appears we can now write: > > #[cfg(stage0)] > OLD CODE > #[cfg(not(stage0))] > NEW CODE > > > ? which, besides being shorter, works when no config flag is supplied. This is especially vital to those of us who use > > rust test syntax.rc > > ?as part of their development cycle. > > If I'm wrong, let me know. If I'm not wrong, consider using this form in the future?. Will do! From steven099 at gmail.com Tue Apr 23 14:18:53 2013 From: steven099 at gmail.com (Steven Blenkinsop) Date: Tue, 23 Apr 2013 17:18:53 -0400 Subject: [rust-dev] Shared 2 Owned In-Reply-To: References: <51768FB0.7090305@mozilla.com> Message-ID: The only alternative I can think of is to really twist up the notion of lifetimes/regions to enforce correctness. For example, regions could be added to shared pointers, and then two tasks could rendezvous with both of their heaps being accessible, with the type system ensuring that tasks don't end up with references into each other's heaps. Plausibly, you could then create owned "task" values which you could pass between tasks, whose sole purpose was to encapsulate the shared pointers belonging to one of these regions. But this is stretching the notion of lifetimes a bit far. On Tue, Apr 23, 2013 at 9:54 AM, Alexander Stavonin wrote: > Felix, thank you for response. I agree with you about difference between > Shared and Owned memory models. It's two different heaps > with different management rules. It's clean. Now, lets go > to practical things such as next one. We have two Tasks with some > computations. For passing values between the tasks we have use Owned box > but, internally, we usually are using Shared boxes. In this case, for all > tasks we have to write converters from Shared to Owned and > from Owned to Shared boxes. It's really big source code overhead from > nothing. > > Regards, > Alex. > > > 2013/4/23 Felix S. Klock II > > Alexander- >> >> What are you suggesting would be the semantics for a Shared -> Owned >> conversion? >> >> Just think about it in the the abstract for a moment: If X and Y are both >> sharing a reference to a @Pizza, and X decides it wants to hand the pizza >> to a customer who is expecting a ~Pizza, what is X supposed to do? Block >> until Y relinquishes its hold on the pizza? To my mind, X has no choice >> but to cook another pizza that looks just like the one it is shared with Y. >> >> (Now, Owned -> Shared conversion might actually make sense in the >> abstract; at that point I think we'd just be encountering implementation >> artifacts of the Rust language, rather than fundamental obstacles?) >> >> Cheers, >> -Felix >> >> >> On Tue Apr 23 15:36:25 2013, Alexander Stavonin wrote: >> >>> Hi all, I'm really confused. What's about Shared 2 Owned conversions? >>> This one looks ugly, nevertheless works: >>> >>> let a = @5; >>> let b = *a; >>> let c = ~b; >>> io::println(fmt!("%?, %?, %?", a, b, c)); >>> >>> > @5, 5, ~5 >>> >>> But what about arrays? >>> >>> let a = @[5]; >>> let b = *a; >>> let c = ~b; >>> >>> > error: type @[] cannot be dereferenced >>> >>> Is it true, that there is no any way for converting between different >>> boxes types without deep copying of objects?! I'm shocked %) >>> >>> >>> ______________________________**_________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/**listinfo/rust-dev >>> >> >> >> >> -- >> irc: pnkfelix on irc.mozilla.org >> email: {fklock, pnkfelix}@mozilla.org >> >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Tue Apr 23 14:29:31 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 14:29:31 -0700 Subject: [rust-dev] plaintive cry (please don't use #[cfg(stage2)]) In-Reply-To: References: Message-ID: <5176FD3B.4020606@mozilla.com> On 13-04-23 02:03 PM, John Clements wrote: > If I'm wrong, let me know. If I'm not wrong, consider using this form in the future?. Absolutely right! It just .. only started working this past month. New style >>> Old style :) -Graydon From graydon at mozilla.com Tue Apr 23 15:50:37 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 15:50:37 -0700 Subject: [rust-dev] New milestones, bug triage, maturity and completion In-Reply-To: <5176F2BD.7000103@mozilla.com> References: <5176039C.6060805@mozilla.com> <5176F2BD.7000103@mozilla.com> Message-ID: <5177103D.9040805@mozilla.com> On 13-04-23 01:44 PM, Brian Anderson wrote: > Is closing any or all maturity milestones a prerequisite for releasing 1.0? Not sure. I think it'll become clear which of them represents 1.0 as we get further along. My guess is, as I said in this email, the "backwards compatible" one. But it could be after that, or before it. -Graydon From robert at ocallahan.org Tue Apr 23 16:25:36 2013 From: robert at ocallahan.org (Robert O'Callahan) Date: Wed, 24 Apr 2013 11:25:36 +1200 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <5176C842.1060407@mozilla.com> References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> Message-ID: On Wed, Apr 24, 2013 at 5:43 AM, Graydon Hoare wrote: > How much of a performance penalty is it worth? I believe you can trap this > in C presently with a gcc flag too (-ftrapv); but it's a flag rarely turned > on. > That's a hard question to answer, but if it cost only 1%, I'd say it's a no-brainer. If it cost 10%, I might say it's not worth it. So the question is how much would it cost? I believe the answer will depend on whether the language also does array bounds checking, since there must be a significant amount of synergy between array bounds checking and overflow checking when you try to intelligently optimize them both. For that and other reasons I think it would be difficult to extrapolate from C to Rust (except maybe to establish an upper bound). (I generally concur and wanted rust integers to overflow to bignums > originally! I do NOT want overflow to bignums. I don't think that's useful in a browser and would cause a larger performance penalty than necessary for the no-overflow common case. I think integer overflow should simply cause the task to fail. Overflowing to bignums sounds way more expensive then just failing --- it would introduce internal polymorphism all over the place, and would tightly constrain the scheduling of overflow checks. If overflow simply causes the task to fail, then you (or your out-of-order CPU) can schedule overflow checking very freely. I don't think bignums are useful in a browser because as a browser developer I will choose data types that cover the ranges of values I want to handle. If I think I need to handle integer values that don't fit in 32 bits, I'll use a 64-bit integer type, or a floating point type. Overflow always means I have a bug*. Overflows in the field usually mean my code is being maliciously attacked, in which case fail-fast is definitely the best thing to do. * Sometimes developers use overflow to get modulo-2^N behavior (which is incorrect in C anyway), and intrinsic functions for those operations would be helpful. But I have had to retreat from such stances due to complaints about > performance / not-C-ness. I suspect the attribute mechanism is the right > approach for such pragmas; would it be acceptable to put one attribute in > each of your crates?) > Much better than nothing, but if the overhead of overflow checking is very low, I think the case for making it the default would be very strong. Rob -- q?qIqfq qyqoquq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qtqhqeqmq.q qAqnqdq qiqfq qyqoquq qdqoq qgqoqoqdq qtqoq qtqhqoqsqeq qwqhqoq qaqrqeq qgqoqoqdq qtqoq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qdqoq qtqhqaqtq.q" -------------- next part -------------- An HTML attachment was scrubbed... URL: From psa at di.uminho.pt Tue Apr 23 16:36:33 2013 From: psa at di.uminho.pt (=?ISO-8859-1?Q?Paulo_S=E9rgio_Almeida?=) Date: Wed, 24 Apr 2013 00:36:33 +0100 Subject: [rust-dev] Simplifying lifetime expression In-Reply-To: <20130423182240.GY26639@tozt.net> References: <51756392.5050202@di.uminho.pt> <5176D02C.4090203@di.uminho.pt> <20130423182240.GY26639@tozt.net> Message-ID: <51771B01.9040401@di.uminho.pt> On 4/23/13 7:22 PM, Jesse Luehrs wrote: > Most of the time that I've seen return value lifetimes specified, they > aren't returning something of the same type as a parameter. For > instance, the vec module has "fn head<'r, T>(v: &'r [T]) -> &'r T". How > common is it for functions to actually return something of the same > type, as opposed to a type that the parameter type contains? > > -doy This is a good example. When I say that there is an implicit lifetime for each type parameter T, the idea is that this implicit lifetime, is used not only in parameters with exact type &T but also in other cases where "borrowed references to Ts are involved". The case of &[T] is the simplest one. As an array has the same lifetime as its components, function parameters as in this case: fn head(v: &[T]) -> &T would also inherit that implicit lifetime. The idea would be to have a simple definition which is "natural", raising no doubts, and does not look to have many special cases, or as Niko says, does not look a too "smart" default. I thought of a simple definition for the types of parameters in which the implicit lifetime would get used. For a type parameter T, the implicit lifetime would get used in parameters of types &T, &[T], in mutable variants thereof, and also (because generic types would also have implicit lifetimes associated to type parameters) would be passed to generic types that have been instantiated with T, as in: SomeGenericContainer i.e., the implicit lifetime associated with the type parameter T of the function would be passed as argument of the generic container, to fill the implicit lifetime of the corresponding SomeGenericContainer<'lt, T> This rules would apply not only to generic function type parameters but also to fields of generic types. The intuition is that the association of lifetimes regarding borrowed references of type T, either directly, in arrays, or as components of some generic container would "flow" naturally with much less syntactic noise. (Or at least, that's my hope.) Recalling the iterator example: struct Iterator<'lt, T> { source: &'lt [T], index: uint } could be written as struct Iterator { source: &[T], index: uint } and the implicit 'lt would be used for the source field, by the rules above. fn has_next<'a, 'b, T>(iter: &'a Iterator<'b, T>) -> bool { iter.index + 1 < iter.source.len() } could be written as: fn has_next(iter: &Iterator) -> bool { iter.index + 1 < iter.source.len() } with the same meaning, applying the same rules: - Iterator would get one implicit lifetime (corresponding to 'a), the one of the "remaining types"; - T would get another implicit lifetime (corresponding to 'b); also fn next<'a, 'b, T>(iter: &'a mut Iterator<'b, T>) -> Option<&'b T> { iter.index += 1; if iter.index < iter.source.len() { Some(&iter.source[iter.index]) } else { None } } could be written as: fn next(iter: &Iterator) -> Option<&T> { iter.index += 1; if iter.index < iter.source.len() { Some(&iter.source[iter.index]) } else { None } } and here the result would get the same implicit lifetime (corresponding to 'b) that was also passed to be used in Ts inside the definition of Iterator. Paulo > > On Tue, Apr 23, 2013 at 07:17:16PM +0100, Paulo S?rgio Almeida wrote: >> Ok. Suppose the current syntax is frozen. But I talked about two >> things: syntax for explicit lifetimes (mainly point 3, altough a bit >> also in points 1 and 2) and defaults for when no explicit (named) >> lifetimes are used. >> >> Even if no syntax change is made, for the cases when named lifetimes >> are used, what I find specially painful is the default rule when no >> explicit lifetimes are used: >> >> "an implicit fresh lifetime for each parameter and result". >> >> This rule, specially when a result is involved, which is exactly one >> of the cases when stating lifetime is needed, seems to make little >> sense, and will force named lifetimes to be used in many cases, >> causing noise and distraction and decreasing legibility. >> >> In what way is the default that I propose, which basically is: >> >> "one implicit fresh lifetime for each type parameter and another for >> all the remainder parameter types" >> >> confusing or a possible source of obscurity? I find it quite natural >> that, e.g., if I am returning a borrowed reference (not a copy, not >> an owned, not a @) of type T and I have received one or more >> borrowed references to T, i.e.: >> >> fn f(p1: &T, p2: &T, ...) -> &T { ... } >> >> the *natural* thing to expect is that the result comes from one of >> the T that I received as parameters, and the default that I propose >> is not obscure at all, but makes the code cristal clear. I find >> having to write >> >> fn f<'r, T>(p1: &'r T, p2: &'r T, ...) -> &'r T { ... } >> >> because of the current defaults, needlessly painful and distracting. >> Is the current default less obscure? Will it cause less surprise? Or >> it is the other way around ... >> >> Regards, >> Paulo >> >> >> On 4/23/13 4:11 PM, Niko Matsakis wrote: >>> Thanks for your proposal. We've been through a number of rounds with the >>> lifetime syntax, including an earlier scheme that was quite similar to >>> what you propose in some regards (there was a single anonymous lifetime >>> parameter that was used whenever you wrote `&T`, which meant that yes >>> you often did not need to use explicit lifetime parameter names). >>> >>> However, we found that this was ultimately more confusing to people than >>> helpful. One of the goals of the current syntax was to make the >>> mechanism of named lifetimes more explicit and thus more clear to the >>> reader. Smarter defaults have the disadvantage that they often obscure >>> the underlying system, making it harder to learn what's really going on. >>> >>> In practice,named lifetimes don't seem to be that common, at least for >>> me. We should do some numerical analysis, but I've found subjectively >>> that most functions simply consume data and do not return pointers. This >>> is particularly true for "non-library" code, and even more true with >>> judicious use of `@` pointers (it is often not worth the trouble to >>> avoid the GC; it can make life much easier, that's what it's there for). >>> >>> So in summary I do not think it likely we will change the current syntax. >>> >>> >>> Niko >>> >>> >>> >>> On Mon, Apr 22, 2013 at 12:21 PM, Paulo S?rgio Almeida >> > wrote: >>> >>> Hi all, >>> >>> (My first post here.) >>> First, congrats for what you are trying to achieve with Rust. I >>> arrived very late to the party, and so I am not sure that what I >>> will say can be of use. But as I understand, lifetimes is one of >>> those things that are not completely solidified, and anyway, better >>> late than never. >>> >>> Looking at some code, expressing lifetimes of borrowed references is >>> one of those things that is somewhat bewildering, making the code >>> somewhat noisy. I think it can be improved through a better choice >>> of defaults and a slight change in explicit lifetimes. >>> >>> The main thing I think is "wrong" is the defaults for function >>> parameters. From the tutorial: "the compiler simply creates a fresh >>> name for the lifetime automatically: that is, the lifetime name is >>> guaranteed to refer to a distinct lifetime from the lifetimes of all >>> other parameters." >>> >>> This default is not very useful. For example, it is wrong basically >>> everytime we want to return a borrowed pointer (unless, for a global >>> variable?). The more common case is returning something with the >>> same lifetime as some parameter. In many cases we don't need to >>> distinguish parameters, and specify which we are returning, in >>> others we want to split parameters in two equivalence classes, the >>> one from which we are returning, and everything else. >>> >>> When type parameters are involved, a return type typically says >>> where the result comes from most of the times. Again, the default >>> should be different. E.g., when we are returning a borrowed >>> reference to a "key" of type parameter K, the default should be >>> "other things also of type K in parameters". >>> >>> Finally, with better defaults, in the remaining cases where we need >>> to explicitly express lifetimes, having to "invent" identifiers is a >>> nuisance. Also the space which must be used between the lifetime >>> identifier and the type is too distracting and makes it cumbersome >>> (for humans) to "parse" the type of some identifier. >>> >>> I have been thinking about this and have the following proposal. (Of >>> course there may be inumerous things that must have escaped me, but >>> here it goes anyway.) >>> >>> --- >>> Regarding types for borrowed references in function parameters or >>> result, and type parameters: >>> >>> 1) each type-parameter has an associated implicit lifetime, which by >>> default is different from the lifetimes of other type-parameters or >>> normal function parameter types, but it can be qualified in each >>> declaration or use with an explicit lifetime; >>> >>> 2) function parameter types or return type that are not type >>> parameters have all the same implicit lifetime by default, but they >>> can be qualified explicitly with some lifetime. >>> >>> 3) explicit lifetimes are written identifier' instead of >>> 'identifier; a null identifier is allowed, as in &'T, to qualify a >>> reference &T with lifetime '. >>> --- >>> >>> (Another useful possibility would be allowing several ' at the end, >>> allowing e.g., &T, &'T, &''T as borrowed references to the same type >>> but with different lifetimes. In practice, a single ' plus 1) and 2) >>> will cover "99%" of cases. We could even get rid of using >>> identifiers, using only several '. But this is not relevant for the >>> main proposal.) >>> >>> 1) and 2) are about defaults for implicit lifetimes, which currently >>> are "fresh lifetime for each parameter", and 3) is about simplifying >>> the remaining cases of explicit expression. The motivation for 3) is >>> to remove both the need of a space separating lifetime from type and >>> also the need to "invent" lifetime identifiers. Rewriting examples >>> from the tutorial and elsewhere, under this proposal, would make >>> code more legible and standard, reducing a lot the need for explicit >>> lifetime expression. Things would "just work" as wanted most times. >>> >>> -------------------------------------------------------------------------------- >>> >>> From the Rust Borrowed Pointers Tutorial >>> >>> --- >>> >>> fn get_x<'r>(p: &'r Point) -> &'r float { &p.x } >>> >>> becomes >>> >>> fn get_x(p: &Point) -> &float { &p.x } >>> >>> --- >>> >>> fn select<'r, T>(shape: &'r Shape, threshold: float, >>> a: &'r T, b: &'r T) -> &'r T { >>> if compute_area(shape) > threshold {a} else {b} >>> } >>> >>> becomes >>> >>> fn select<'T>(shape: &'Shape, threshold: float, >>> a: &'T, b: &'T) -> &'T { >>> if compute_area(shape) > threshold {a} else {b} >>> } >>> >>> (not very useful case) >>> >>> --- >>> >>> fn select<'r, T>(shape: &Shape, threshold: float, >>> a: &'r T, b: &'r T) -> &'r T { >>> if compute_area(shape) > threshold {a} else {b} >>> } >>> >>> becomes >>> >>> fn select(shape: &Shape, threshold: float, >>> a: &T, b: &T) -> &T { >>> if compute_area(shape) > threshold {a} else {b} >>> } >>> >>> -------------------------------------------------------------------------------- >>> >>> Other examples: >>> >>> --- >>> >>> struct Iterator<'lt, T> { >>> source: &'lt [T], >>> index: uint >>> } >>> >>> fn has_next<'a, 'b, T>(iter: &'a Iterator<'b, T>) -> bool { >>> iter.index + 1 < iter.source.len() >>> } >>> >>> fn next<'a, 'b, T>(iter: &'a mut Iterator<'b, T>) -> >>> Option<&'b T> { >>> iter.index += 1; >>> if iter.index < iter.source.len() { >>> Some(&iter.source[iter.index]) >>> } else { >>> None >>> } >>> } >>> >>> becomes: >>> >>> struct Iterator<'T> { >>> source: &'[T], >>> index: uint >>> } >>> >>> fn has_next(iter: &Iterator) -> bool { >>> iter.index + 1 < iter.source.len() >>> } >>> >>> fn next(iter: &mut Iterator) -> Option<&T> { >>> iter.index += 1; >>> if iter.index < iter.source.len() { >>> Some(&iter.source[iter.index]) >>> } else { >>> None >>> } >>> } >>> >>> --- >>> >>> impl<'b, T> Iterator<'b, T> { >>> fn has_next(&self) { /* same as before */ } >>> fn next(&mut self) -> Option<&'b T> { /* same as before >>> */ } >>> } >>> >>> becomes >>> >>> impl Iterator { >>> fn has_next(&self) { /* same as before */ } >>> fn next(&mut self) -> Option<&T> { /* same as before */ } >>> } >>> >>> --- >>> >>> Regards, >>> Paulo >>> >>> >>> >>> >>> >>> >>> _______________________________________________ >>> 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 Apr 23 16:47:08 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Tue, 23 Apr 2013 16:47:08 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176CC2B.3080809@cantrip.org> References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> <5176CC2B.3080809@cantrip.org> Message-ID: <51771D7C.1050709@mozilla.com> On 13-04-23 11:00 AM, Nathan Myers wrote: > A name reflecting its true role seems appropriate. Drawing on > the Linux kernel experience, I propose "staging". Alternatively, > "trial", "proposed", "experimental", "unstable". The Boost experience > suggests that explicit interface versioning, if only by naming > convention, would be wise: the most frequently expressed reason > for Boost non-use has been interface instability between releases. > A policy of supporting use of old interfaces in scrupulously > module-name-qualified code, enabling interface evolution > without breaking existing uses, would aid adoption. It's not for experimental stuff. Let me clarify the role we're discussing. The "ext" library, for lack of a better name, will: - Be a library hosted in a mozilla and/or rust-lang.org repo - That _just re-exports_ (pub extern mod's) a bunch of packages - Each of which is: - Developed independently in their own repos - By their own contributor communities - At their own pace - Applying some editorial standards to the selected packages - And supporting them version-to-version even if they bitrot or radically change upstream > As a meta-comment, the reflexive use of abbreviations in > not-frequently-typed names seems like a problem. I don't find it a problem. A bunch of people have expressed distaste, but a bunch of others have expressed pleasure. As a recently-tweeted quip put it, "One person's idiom is another's boilerplate." > modern editors with auto-complete make these unnecessary? We've generally avoided (and I am opposed to) design choices that require a "modern editor". At least anything more modern than vi or emacs. I know some people even write code in acme, or microemacs. > Do we need a policy on what sort of names merit abbreviation, > and how much? For keywords, it's "5 chars or less", where 5 is defined as 6 for cases that you don't have to write very often (extern, static, struct, unsafe), and 3 when you have to write it a lot (use, let, for). We could have used "fun" rather than "fn" but I figure the sml lambda form and the rc shell are both pretty much unassailable good taste, so I'm happy with "fn". For other names there's not much of a guideline. "Eschew obfuscation"? > Alex Stepanov's policy designing STL was > to avoid abbreviations wherever defensible. It mostly worked > out well, although "iterator" turned out to be too long. Where a name in STL is short and pithy, I'm not averse to following suit. I would consider these STL names fine: begin end set reset clear size flip test assign insert erase swap clear front back push pop top and these STL names perhaps "a little overwrought": iterator const_iterator reverse_iterator reference value_type pointer difference_type allocator shared_ptr unique_ptr static_cast unordered_map uniform_int_distribution lexicographical_compare set_symmetric_difference But when there's nothing appropriate and short, long sometimes has to do. I guess we can't always pick nice 1-2 syllable names. There was some work on this sort of guideline-making in the style guide recently, but I recall you objecting to those guidelines (indeed, the mere idea of them). And you also suggested we sacrifice everything for "conscious attention, screen space, editing time, short-term memory", which suggests (to me) a strong preference for short names. So I can't really tell what if anything you feel like we should be doing differently. -Graydon From robert at ocallahan.org Tue Apr 23 16:53:14 2013 From: robert at ocallahan.org (Robert O'Callahan) Date: Wed, 24 Apr 2013 11:53:14 +1200 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> Message-ID: On Wed, Apr 24, 2013 at 11:25 AM, Robert O'Callahan wrote: > I don't think bignums are useful in a browser because as a browser > developer I will choose data types that cover the ranges of values I want > to handle. If I think I need to handle integer values that don't fit in 32 > bits, I'll use a 64-bit integer type, or a floating point type. Overflow > always means I have a bug*. > Well, in C and C++ it does, and of course that's what most browser developers are going to be used to. If we could rely on checked overflows in Rust, then we could start to lean on that and declare that some tests that trigger overflow are simply tests where task failure is an acceptable result. (Offensive as this may to the cult of correctness, in practice priorities dictate we have to do this kind of thing all the time --- declare that a bug is not worth fixing as long as it's not exploitable.) Rob -- q?qIqfq qyqoquq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qlqoqvqeq qtqhqoqsqeq qwqhqoq qlqoqvqeq qtqhqeqmq.q qAqnqdq qiqfq qyqoquq qdqoq qgqoqoqdq qtqoq qtqhqoqsqeq qwqhqoq qaqrqeq qgqoqoqdq qtqoq qyqoquq,q qwqhqaqtq qcqrqeqdqiqtq qiqsq qtqhqaqtq qtqoq qyqoquq?q qEqvqeqnq qsqiqnqnqeqrqsq qdqoq qtqhqaqtq.q" -------------- next part -------------- An HTML attachment was scrubbed... URL: From loebel.marvin at gmail.com Tue Apr 23 15:24:55 2013 From: loebel.marvin at gmail.com (=?ISO-8859-1?Q?Marvin_L=F6bel?=) Date: Wed, 24 Apr 2013 00:24:55 +0200 Subject: [rust-dev] Making fail!() and assert!() usage nicer In-Reply-To: <5176F2BD.7000103@mozilla.com> References: <5176039C.6060805@mozilla.com> <5176F2BD.7000103@mozilla.com> Message-ID: <51770A37.8080300@googlemail.com> Ever since fail and assert got turned into macros, failing with a string message has become quite line-noisy: fail!(~"cause") And including additional informations in the fail message makes the line quite heavy, even though it should be encouraged for better failure messages: fail!(fmt!("failed because of %?", cause)) For context: fail takes a ~str because it needs to own the string, so that it can be send to the platform thread and displayed during task failure. assert has the same requirement for its optional second argument, but currently accepts a &str because it performs a copy internally. A discussion on IRC resulted in these possible options: 1. Rewrite fail!() and assert!() to accept both ~str or &'static str: fail!(): unchanged fail!(~"cause"): unchanged (not possible now) -> fail!("cause") fail!(fmt!("failed because of %?", cause)): unchanged ...etc Pro: No unnecessary copy, 100% backwards compatible. Con: Kinda hard to implement, fail!(fmt!()) still heavy. 2. Turn fail and assert into diverging functions: fail!() -> fail() fail!(~"cause") -> fail_owned(~"cause") (not possible now) -> fail_static("cause") fail!(fmt!("failed because of %?", cause)) -> fail_owned(fmt!("failed because of %?", cause)) ...etc Pro: No macros necessary. Con: Users need to remember different function signatures for failing, fail_owned(fmt!()) even more heavy. 3. Rewrite fail!() and assert!() to pass arguments to fmt!(): fail!(): unchanged fail!(~"cause") -> fail!("s", ~"cause") (not possible now) -> fail!("cause") fail!(fmt!("failed because of %?, cause)) -> fail!("failed because of %?", cause) ...etc Pro: Easy formatted message per default, common case fail!("static str") needs no '~' sigil, failure macros work similar to logging macros. Con: Heavier syntax if you have a ~str already, always copies string. (however, fmt!() could get an optimisation so that fmt!("...") expands to ~"...", and fmt!("s", s) to s) 4. (1 + 3) Rewrite fail!() and assert!() to accept ~str and &'static str if 1 argument, pass arguments to fmt!() if more than 1: fail!(): unchanged fail!(~"cause"): unchanged (not possible now) -> fail!("cause") fail!(fmt!("failed because of %?, cause)) -> fail!("failed because of %?", cause) Pro: All of 1 and 3. Con: Even harder to implement than 1, quite complex. Personally I think 3 is the easiest to implement option, and nice even without the fmt! optimisation. I already locally implemented the necessary changes that would allow switching to it after an snapshot, but I wanted to ask what others think. From adaszko at gmail.com Tue Apr 23 10:36:49 2013 From: adaszko at gmail.com (Adam Dariusz Szkoda) Date: Tue, 23 Apr 2013 19:36:49 +0200 Subject: [rust-dev] Code hot-swapping In-Reply-To: <51755F8D.1080704@mozilla.com> References: <20130420231502.GA63794@grom.local> <51755F8D.1080704@mozilla.com> Message-ID: <20130423173649.GA96638@grom.local> On Mon, Apr 22, 2013 at 09:04:29AM -0700, Graydon Hoare wrote: > On 20/04/2013 4:15 PM, Adam Szkoda wrote: > > >First of all, let me just say that Rust is quite a beauty and I look > >forward to how it will develop. > > Thanks! > > >Discovering that there?s an interactive interpreter (rusti) was a very > >pleasant surprise. Taking this a step further, I would like to ask > >what?s the language designers? stance on hot code swapping a la Erlang > >or Common Lisp. > > That it's incompatible with the way PLTs currently work on various > operating systems, so out of scope. Sorry. When we were doing our > own runtime linking (yes, really) this was more possible. Now that > we're trying to integrate with the native C toolchains (including > runtime linker), it's not, and won't be. I see, thank you. ? Adam From gmaxwell at gmail.com Tue Apr 23 13:11:14 2013 From: gmaxwell at gmail.com (Gregory Maxwell) Date: Tue, 23 Apr 2013 13:11:14 -0700 Subject: [rust-dev] No range integer type? Saftey beyond memory? Message-ID: Graydon Hoare wrote: > I believe you can trap > this in C presently with a gcc flag too (-ftrapv); but it's a flag > rarely turned on. -ftrapv basically doesn't work, e.g. doesn't work (at all?) on x86_64, doesn't prevent algebraic simplification which assumes no overflow (and thus hides the overflow). I haven't tried it with GCC 4.8 yet, but I assume the story is the same there too. It's also only for signed overflow... since signed overflow is undefined in C and the compiler will happily optimize relative to that it is extra important, but that ignores all the unsigned cases where overflow is indicative of a bug. The integer overflow checker in clang (http://embed.cs.utah.edu/ioc/) is _much_ better, and I utilized it extensively in the development of the Opus codec, but again it only covers signed. Checking of unsigned would also suffer from needing some kind of instrumentation to annotate the cases where you actually expect the overflow. > How much of a performance penalty is it worth? The clang IOC seemed to have fairly little impact on "typical" code, but on gnarly fixed-point DSP code it was a fairly major slowdown e.g. >3x and something that wouldn't be acceptable in production code if it were inescapable. Absolutely fantastic for debug builds... but again, it was only on signed which is undefined in C so there were no "false positives", every instance was a bug even if the result was discarded. I think in rust signed overflow is defined? If so then even signed can't have false-positive-free detection from pure compiler instrumentation. Certainly there are cases where any performance hit is not really acceptable, but I imagine that most uses of integers are not these places. The alternative of "use a full bignum" seems inelegant especially if the bignum comes with a big performance/memory/icache hit even in places where a Sufficiently Smart compiler could statically prove that a regular integer would suffice. These also don't do anything for cases when the "bug free range" is still within the machine word being used... it's a real element of software correctness, but perhaps too obscure to worry about. I would speculate that when the range constraints comes from the problem being solved rather than the machine the author is more likely aware of them. Robert O'Callahan wrote: > On the other hand, I don't see this as important for floating point types. > Accumulating NaNs and infinities is much saner than simply producing the > wrong answer, has seldom led to critical browser bugs in my experience, and > I can't see how it would without an intervening conversion to integer type > which would, of course, be checked. I've seen things like code infinite looping because NAN != NAN, but I agree that I've seen far fewer serious bugs from "surprising" divergences between floating point values and real numbers. In general, I think float-weirdness is something which could be addressed by better dynamic checking tools, but wouldn't benefit from language support in the same way that integer overflow does because code which intentionally creates NANs and Infinities and expects to do things with them is fairly uncommon. While overflow of fixed size integers is moderately common and useful (e.g. fast hashes and prngs implemented as arithmetic on GF(2^N)). From gmaxwell at gmail.com Tue Apr 23 14:24:12 2013 From: gmaxwell at gmail.com (Gregory Maxwell) Date: Tue, 23 Apr 2013 14:24:12 -0700 Subject: [rust-dev] Division and modulo for signed numbers Message-ID: swede at earthling.net wrote: > While T-division is the most common choice (used by C, C++, etc) F-division is not uncommon. I've confirmed that Python and Ruby use F-division, and Wikipedia claims that TCL and D do too. F-division behavior won't be surprising or hard to explain to any users familiar with Python, which is most developers today. FWIW, I've personally been burned by this in python and I went around asking people if they were aware of it and even very experienced pythonists friends were not. Certainly a better job could be done communicating about it than Python has done. I encountered more people who were surprised at what python was doing than people who were unaware that integer divide was usually truncating (this may be a product of sampling too many low level C programmers). The C behavior makes / truncating, which makes it consistent with casting. There are certainly common cases where what you want is the quotient and remainder. error_feet = error_in/12; error_in %=12; > 3. x / (2^n) can be converted to a bitwise right shift for any x > 4. x % (2^n) can be converted to a bitwise and for any x When I want these cases I use the shifts and ands explicitly. At least in C this isn't out of line with writing code that reflects the underlying behavior and performance. This helps make it clear that changing the divisor has implications in whats actually being performed. Perhaps I'm weird. > Property 2 is useful for things like sample-rate conversion If you're doing sample rate conversion in a way that this comes up? you likely have bigger problems. :) Not having the truncating case available would be bad... Graydon's comments about both being available sounds good at least. > * Performance will stay the same for division by compile-time constants, since these are transformed by the compiler into multiplies. (I actually think performance will go up slightly in this case, but it's been a while since I looked at the algorithm.) For many constants its the same number of operations, for some the flooring division saves an add and an and (or a shift and a subtract) though I wouldn't actually expect this to make a measurable performance difference anywhere. From danielmicay at gmail.com Tue Apr 23 17:32:27 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Tue, 23 Apr 2013 20:32:27 -0400 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: References: Message-ID: On Tue, Apr 23, 2013 at 4:11 PM, Gregory Maxwell wrote: > > Certainly there are cases where any performance hit is not really > acceptable, but I imagine that most uses of integers are not these > places. The alternative of "use a full bignum" seems inelegant > especially if the bignum comes with a big performance/memory/icache > hit even in places where a Sufficiently Smart compiler could > statically prove that a regular integer would suffice. With a flexible integer type like the one used in CPython, the compiler is free to eliminate the branch for handling the big integer variant and the one for catching overflow. It's only really a cache/memory hit where it has to be (an extra word for the enum variant isn't that bad) but I doubt it will be able to eliminate the runtime cost most of the time. I don't think there's anything wrong with offering it as a library type. I just wish the integer literals were overloadable so it could be as first-class as the other integer types. From jack at metajack.im Tue Apr 23 19:25:15 2013 From: jack at metajack.im (Jack Moffitt) Date: Tue, 23 Apr 2013 20:25:15 -0600 Subject: [rust-dev] Making fail!() and assert!() usage nicer In-Reply-To: <51770A37.8080300@googlemail.com> References: <5176039C.6060805@mozilla.com> <5176F2BD.7000103@mozilla.com> <51770A37.8080300@googlemail.com> Message-ID: > Con: Even harder to implement than 1, quite complex. Hard to implement hardly seems like much of a con. This macro is going to be used a lot, and making it nice seems like something that should be done, even if it's a bit tricky to do. jack. From andrew.webb at gmail.com Tue Apr 23 19:25:36 2013 From: andrew.webb at gmail.com (Andrew Webb) Date: Wed, 24 Apr 2013 14:25:36 +1200 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: Message-ID: <967ADE184399428B832529FDFDDF9678@gmail.com> Maybe it is from spending too much time with java, but I tend to name those kind of libs `util`, because often what they are is adding extra functionality to the standard library. In order for it to be really useful, though, I think that its role needs to be clearly defined (as below), and that definition adhered to. I really like the haskell package idea, but only if there is a lighter-weight default as well. > > It's not for experimental stuff. Let me clarify the role we're > discussing. The "ext" library, for lack of a better name, will: > > - Be a library hosted in a mozilla and/or rust-lang.org (http://rust-lang.org) repo > - That _just re-exports_ (pub extern mod's) a bunch of packages > - Each of which is: > - Developed independently in their own repos > - By their own contributor communities > - At their own pace > - Applying some editorial standards to the selected packages > - And supporting them version-to-version even if they bitrot > or radically change upstream > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Tue Apr 23 19:36:00 2013 From: banderson at mozilla.com (Brian Anderson) Date: Tue, 23 Apr 2013 19:36:00 -0700 Subject: [rust-dev] Making fail!() and assert!() usage nicer In-Reply-To: <51770A37.8080300@googlemail.com> References: <5176039C.6060805@mozilla.com> <5176F2BD.7000103@mozilla.com> <51770A37.8080300@googlemail.com> Message-ID: <51774510.5060701@mozilla.com> On 04/23/2013 03:24 PM, Marvin L?bel wrote: > Ever since fail and assert got turned into macros, failing with a > string message has become quite line-noisy: > > fail!(~"cause") > > Personally I think 3 is the easiest to implement option, and nice even > without the fmt! optimisation. I already locally implemented the > necessary changes that would allow switching to it after an snapshot, > but I wanted to ask what others think. > From what you've presented, I like 3. I agree with this sentiment in general, and agree that all these related string-taking macros, assert, fail, debug, etc. should behave similarly, generally accepting whatever you throw at them. It would be very desirable I think to not duplicate the string in the case where ~str is the only argument. This could probably be done with a trait that converts to ~str by value (so ~str.to_str_by_val() is a no-op). We have always had this lingering notion that fail *could* accept a dynamically typed twiddle, called `~Any`. If we go this direction of passing everything through `fmt!` then that becomes more complicated. I think there will be solutions though. In the case where `fail` is passed just one argument it could be interpreted as an instance of some trait, Exceptiony, that can be called to cast the value to `~Any`. When multiple arguments are passed it delegates to fmt. From tcdknutson at gmail.com Tue Apr 23 22:22:08 2013 From: tcdknutson at gmail.com (Dylan Knutson) Date: Tue, 23 Apr 2013 22:22:08 -0700 Subject: [rust-dev] Calling static methods on type parameters? Message-ID: Hello everyone, I've been pretty enamored with Rust the past few weeks, and I'm loving the language so far. However, there is one feature of generics that doesn't seem to exist in the language, which is being able to call static methods on type parameters (provided that the type parameter can be guaranteed to implement it). I'm not all that familiar with the technical details of the language, so I'm not sure if this is impossible, or just decided against for some reason. I'm not even sure if I'm using the terminology correctly, so let me illustrate with some code: trait Newable { fn new() -> Self; } struct Foo(int); impl Newable for Foo { fn new() -> Foo { return Foo(1); } } fn getOneOfThese() -> T { T::new() } fn main() { let test = getOneOfThese(); } But, this code is currently invalid. Could this be a useful addition to the language? Thank you, Dylan Knutson -------------- next part -------------- An HTML attachment was scrubbed... URL: From swede at earthling.net Tue Apr 23 22:43:43 2013 From: swede at earthling.net (Erik S) Date: Tue, 23 Apr 2013 23:43:43 -0600 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <5176C8E7.7070109@mozilla.com> References: <20130423144812.217310@gmx.com> <5176A27E.9010805@mozilla.com> <19811987.VlzDZtLQXY@l10036> <5176C8E7.7070109@mozilla.com> Message-ID: <5177710F.7020805@earthling.net> Thanks Graydon for the detailed reply to a newbie suggestion. It looks like I'm a little too late, this ship has already sailed. You're right that it's a topic reasonable people can disagree on. Adding Lint warnings seems like a poor workaround, but maybe the reduced confusion from C developers will outweigh the bugs caused. Or maybe all right-thinking people will agree to use the F-division function calls, and "/" and "%" will be unknown to Rust developers :-) I just looked over the Numeric traits bikeshed and pull 5990, and have a few comments. ( https://github.com/mozilla/rust/wiki/Bikeshed-Numeric-Traits and https://github.com/mozilla/rust/pull/5990 ) The floating point "quot" operator is now misnamed. It returns "D/d", which is a floating point divide, not a quotient. (src/libcore/num/f32.rs line 323) I would suggest having floating point "quot" and "rem" return proper quotient and remainder (i.e. "D.quot(d)" has the same value for int and float, if the input/result is representable). Then the floating-point "/" operator needs to be mapped to a something other than "quot" (maybe "div_float"?). The "%" operator can be removed on floating point numbers. When a floating-point remainder is needed, you would have to call rem() explicitly. The numeric traits do not appear to require a "%" operator (which is probably a good thing, because it is hard to define for complex numbers). Finally some code review comments (possible already fixed, I didn't have time to check the tip - sorry) "modulo" replaced with "rem" inappropriately in a comment src/libstd/base64.rs line 118 "Divide by zero" error string became "Quotient of zero" src/libstd/num/rational.rs line 54 src/librustc/middle/trans/base.rs line 788, 790 src/test/compile-fail/eval-enum.rs line 2,3 Regards, Erik On 4/23/2013 11:46 AM, Graydon Hoare wrote: > On 23/04/2013 8:53 AM, Diggory Hardy wrote: > >> I suspect (please correct me if I'm wrong) that if it wasn't for C >> and x86 >> compatibility then most people would fall into two categories: don't >> know/don't care, and prefer F-division. It's one of those little >> things like >> tau vs. pi which would have been less confusing if we'd started off >> on the >> other foot to start with. > > And IP addresses would have been 64 or 128bit from the start, there > would only be one endianness, and so forth ... yes, sure. But we > don't cast off the weight of the past so easily, and I do not think > this is something it's wise to fiddle with. > > A very widely-applied design choice in rust is that the basic types > are machine-sized and the arithmetic operations on them are (as close > as reasonable to) machine operations. The machine operation is remainder. > > Moreover, it's not "just C and x86". This same choice is taken (more > or less) by PowerPC, LLVM, C++, C#, Java, D, Go, JS, Scala, Ocaml, > etc. etc. > > The path we've taken here is to admit _two_ operation-pairs, div/mod > and quot/rem. This path is taken by several languages and specs > (Scheme, Common Lisp, Ruby, Smalltalk, SML, Prolog, Haskell, Ada, and > ISO 10967 and IEEE 754). The work for this landed last week: > > https://github.com/mozilla/rust/pull/5990 > https://github.com/mozilla/rust/pull/6013 > https://github.com/mozilla/rust/issues/4565 > https://github.com/mozilla/rust/issues/4917 > > (Phew! This must really be the week for integer division!) > > The only remaining thing to struggle with is "which of the two > operation-pairs to assign the / and % symbols to", in the > operator-overloading sense. For this, we've gone with quot/rem, as in > the other languages above, and in keeping with the design preference > above. You have to call .mod() or .div() to get the other operators. > > It does mean there's a bit of a footgun surrounding the symbols / and > % specifically, on signed integer types. I would not be at all opposed > to adding a lint flag to calls-to-/-and-%-on-signed-integer-types, > such that you could trap them all. As with many things here, the > design space includes a variety of (sensible) preferences. > > -Graydon > > (Please correct me if I've swapped which of the two meanings we've > actually assigned; this is one of those issues like double-negation > and off-by-one indexing where I get things backwards no matter how > much energy I spend on making sure I get it right.) > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > From pwalton at mozilla.com Wed Apr 24 00:58:44 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 24 Apr 2013 00:58:44 -0700 Subject: [rust-dev] Calling static methods on type parameters? In-Reply-To: References: Message-ID: <517790B4.3070700@mozilla.com> On 4/23/13 10:22 PM, Dylan Knutson wrote: > Hello everyone, > I've been pretty enamored with Rust the past few weeks, and I'm loving > the language so far. However, there is one feature of generics that > doesn't seem to exist in the language, which is being able to call > static methods on type parameters (provided that the type parameter can > be guaranteed to implement it). I'm not all that familiar with > the technical details of the language, so I'm not sure if this is > impossible, or just decided against for some reason. I'm not even sure > if I'm using the terminology correctly, so let me illustrate with some > code: > > trait Newable { > fn new() -> Self; > } > > struct Foo(int); > impl Newable for Foo { > fn new() -> Foo { > return Foo(1); > } > } > > fn getOneOfThese() -> T { > T::new() > } > > fn main() { > let test = getOneOfThese(); > } Inside `getOneOfThese`, try this: let x: T = Newable::new(); Patrick From ncm at cantrip.org Wed Apr 24 02:50:04 2013 From: ncm at cantrip.org (Nathan Myers) Date: Wed, 24 Apr 2013 02:50:04 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: <51771D7C.1050709@mozilla.com> References: <5176B835.20301@mozilla.com> <5176BFAC.1040603@mozilla.com> <5176CC2B.3080809@cantrip.org> <51771D7C.1050709@mozilla.com> Message-ID: <5177AACC.6070800@cantrip.org> Thanks, Graydon, for the detailed reply. > > As a meta-comment, the reflexive use of abbreviations in > > not-frequently-typed names seems like a problem. > I don't find it a problem. A bunch of people have expressed distaste, > but a bunch of others have expressed pleasure. As a recently-tweeted > quip put it, "One person's idiom is another's boilerplate." Fair enough. But familiarity creates bias. How much does the reaction of newcomers to the language matter? Too-cryptic names add to cognitive load at a time when there is little capacity to spare. Your reservations about "ext" are well placed. >> modern editors with auto-complete make these unnecessary? > We've generally avoided (and I am opposed to) design choices that > require a "modern editor". At least anything more modern than vi or > emacs. I know some people even write code in acme, or microemacs. This is a wholly admirable policy, but "require" seems like a pretty strong word, here. > There was some work on this sort of guideline-making in the style guide > recently, but I recall you objecting to those guidelines (indeed, the > mere idea of them). And you also suggested we sacrifice everything for > "conscious attention, screen space, editing time, short-term memory", > which suggests (to me) a strong preference for short names. So I can't > really tell what if anything you feel like we should be doing differently. My opinion may be worth only as much as it weighs, but I do not object to guidelines in general; I just hope to see proposals traceable, in detail, to defensible principles and measurable consequences. Without, there's a real temptation to enshrine personal preferences that owe more to history than to sense. As a new language, Rust offers a rare opportunity to leave old mistakes behind. (I would count StudlyCapsNames among such mistakes, but that bridge seems burnt.) Short names are good, but Kernighan's "telephone test" identifies a sane natural limit. Too, language constructs that are considered poor form benefit from unwieldy names (e.g. C++ "reinterpret_cast"). - Nathan Myers From lists at dhardy.name Wed Apr 24 05:33:27 2013 From: lists at dhardy.name (Diggory Hardy) Date: Wed, 24 Apr 2013 14:33:27 +0200 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <5176C8E7.7070109@mozilla.com> References: <20130423144812.217310@gmx.com> <19811987.VlzDZtLQXY@l10036> <5176C8E7.7070109@mozilla.com> Message-ID: <1486845.Eo0P33FOQu@l10036> On Tuesday 23 April 2013 10:46:15 Graydon Hoare wrote: > On 23/04/2013 8:53 AM, Diggory Hardy wrote: > > I suspect (please correct me if I'm wrong) that if it wasn't for C and x86 > > compatibility then most people would fall into two categories: don't > > know/don't care, and prefer F-division. It's one of those little things > > like tau vs. pi which would have been less confusing if we'd started off > > on the other foot to start with. > > And IP addresses would have been 64 or 128bit from the start, there > would only be one endianness, and so forth ... yes, sure. But we don't > cast off the weight of the past so easily, and I do not think this is > something it's wise to fiddle with. > > A very widely-applied design choice in rust is that the basic types are > machine-sized and the arithmetic operations on them are (as close as > reasonable to) machine operations. The machine operation is remainder. > > Moreover, it's not "just C and x86". This same choice is taken (more or > less) by PowerPC, LLVM, C++, C#, Java, D, Go, JS, Scala, Ocaml, etc. etc. > > The path we've taken here is to admit _two_ operation-pairs, div/mod and > quot/rem. This path is taken by several languages and specs (Scheme, > Common Lisp, Ruby, Smalltalk, SML, Prolog, Haskell, Ada, and ISO 10967 > and IEEE 754). The work for this landed last week: > > https://github.com/mozilla/rust/pull/5990 > https://github.com/mozilla/rust/pull/6013 > https://github.com/mozilla/rust/issues/4565 > https://github.com/mozilla/rust/issues/4917 > > (Phew! This must really be the week for integer division!) > > The only remaining thing to struggle with is "which of the two > operation-pairs to assign the / and % symbols to", in the > operator-overloading sense. For this, we've gone with quot/rem, as in > the other languages above, and in keeping with the design preference > above. You have to call .mod() or .div() to get the other operators. > > It does mean there's a bit of a footgun surrounding the symbols / and % > specifically, on signed integer types. I would not be at all opposed to > adding a lint flag to calls-to-/-and-%-on-signed-integer-types, such > that you could trap them all. As with many things here, the design space > includes a variety of (sensible) preferences. Wow, what a big post! Sorry, looks like I've missed far too much of the past discussion. (And I'm a little surprised at your patience!) I for one am happy so long as arr[ind.mod(z)] is possible (though arr[ind mod z] would be neater), and this is covered somewhere in the documentation. From aatch at aatch.net Wed Apr 24 07:17:23 2013 From: aatch at aatch.net (James Miller) Date: Thu, 25 Apr 2013 02:17:23 +1200 Subject: [rust-dev] Rust XCB Bindings Message-ID: <20130424141722.GB8813@tyr.home.aatch.net> Hi Guys, I've been working on XCB bindings for Rust. They are generated from the same xml files that XCB uses to generate its code, so it matches up pretty well. It also has some wrappers around the C bindings, though only the core protocol and xinerama are up at the moment since the wrappers are still pretty unstable. I've only just started working on this, so the code is pretty rough and there are some sharp corners here and there. However, it's up on github at https://github.com/Aatch/rust-xcb, I welcome issues and pull requests. Thanks -- James Miller From o.renaud at gmx.fr Wed Apr 24 07:47:28 2013 From: o.renaud at gmx.fr (Olivier Renaud) Date: Wed, 24 Apr 2013 16:47:28 +0200 Subject: [rust-dev] Re : Renaming of core and std Message-ID: <20130424144728.239780@gmx.com> Considering the content of the current libstd, I think "util" is indeed an appropriate name for this module. Some other propositions : - "base" - "rust" - "platform" - "stock" > Maybe it is from spending too much time with java, but I tend to name those kind of libs `util`, > because often what they are is adding extra functionality to the standard library. > > In order for it to be really useful, though, I think that its role needs to be clearly defined > (as below), and that definition adhered to. I really like the haskell package idea, but only if > there is a lighter-weight default as well. > >> It's not for experimental stuff. Let me clarify the role we're >> discussing. The "ext" library, for lack of a better name, will: >> >> - Be a library hosted in a mozilla and/or rust-lang.org repo >> - That _just re-exports_ (pub extern mod's) a bunch of packages >> - Each of which is: >> - Developed independently in their own repos >> - By their own contributor communities >> - At their own pace >> - Applying some editorial standards to the selected packages >> - And supporting them version-to-version even if they bitrot >> ? or radically change upstream From eddycizeron at gmail.com Wed Apr 24 11:02:20 2013 From: eddycizeron at gmail.com (Eddy Cizeron) Date: Wed, 24 Apr 2013 20:02:20 +0200 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <1486845.Eo0P33FOQu@l10036> References: <20130423144812.217310@gmx.com> <19811987.VlzDZtLQXY@l10036> <5176C8E7.7070109@mozilla.com> <1486845.Eo0P33FOQu@l10036> Message-ID: I'm a bit suprised by the suddenness of all these discussions. When I tried to call the attention on this issue 4 month ago in a thread called "Arithmetics and programming", apparently nobody cared :-p > Moreover, it's not "just C and x86". This same choice is taken (more > or less) by PowerPC, LLVM, C++, C#, Java, D, Go, JS, Scala, Ocaml, > etc. etc. Sorry Graydon, but I don't buy this argument. It's obvious to me that these languages just followed the hardware choice because either they didn't thought about the potential issue or they intentionally decided to focus on performance. I mean that the fact these languages have T-division + remainder is not an additional argument and that should not count when considering if which option(s) Rust must have. This said, I can understand that Rust also cares about performance or compatibility with hardware and for that reasons want to keep T-division + remainder as the main behaviour. > The only remaining thing to struggle with is "which of the two operation-pairs to assign the / and % symbols to", in the operator-overloading sense. > For this, we've gone with quot/rem, as in the other languages above, and in keeping with the design preference above. You have to call .mod() or .div() to get the other operators My opinion (that nobody will follow, but I still give it) is that integers should not have the "/" operator at all. This was one of the bad choices of C (or maybe of a previous language). > The floating point "quot" operator is now misnamed. It returns "D/d", > which is a floating point divide, not a quotient. > (src/libcore/num/f32.rs line 323) Well, technically a quotient is always the result of a division. The problem is that contrary to what the name suggests an euclidean division is not a division. > Then the floating-point "/" operator needs to be mapped to a something > other than "quot" (maybe "div_float"?). The "%" operator can be removed > on floating point numbers. When a floating-point remainder is needed, > you would have to call rem() explicitly. The numeric traits do not > appear to require a "%" operator (which is probably a good thing, > because it is hard to define for complex numbers). Right but in that case they shouldn't have a division either: for the reason given above (integers have no notion of natural division) 2013/4/24 Diggory Hardy > On Tuesday 23 April 2013 10:46:15 Graydon Hoare wrote: > > On 23/04/2013 8:53 AM, Diggory Hardy wrote: > > > I suspect (please correct me if I'm wrong) that if it wasn't for C and > x86 > > > compatibility then most people would fall into two categories: don't > > > know/don't care, and prefer F-division. It's one of those little things > > > like tau vs. pi which would have been less confusing if we'd started > off > > > on the other foot to start with. > > > > And IP addresses would have been 64 or 128bit from the start, there > > would only be one endianness, and so forth ... yes, sure. But we don't > > cast off the weight of the past so easily, and I do not think this is > > something it's wise to fiddle with. > > > > A very widely-applied design choice in rust is that the basic types are > > machine-sized and the arithmetic operations on them are (as close as > > reasonable to) machine operations. The machine operation is remainder. > > > > Moreover, it's not "just C and x86". This same choice is taken (more or > > less) by PowerPC, LLVM, C++, C#, Java, D, Go, JS, Scala, Ocaml, etc. etc. > > > > The path we've taken here is to admit _two_ operation-pairs, div/mod and > > quot/rem. This path is taken by several languages and specs (Scheme, > > Common Lisp, Ruby, Smalltalk, SML, Prolog, Haskell, Ada, and ISO 10967 > > and IEEE 754). The work for this landed last week: > > > > https://github.com/mozilla/rust/pull/5990 > > https://github.com/mozilla/rust/pull/6013 > > https://github.com/mozilla/rust/issues/4565 > > https://github.com/mozilla/rust/issues/4917 > > > > (Phew! This must really be the week for integer division!) > > > > The only remaining thing to struggle with is "which of the two > > operation-pairs to assign the / and % symbols to", in the > > operator-overloading sense. For this, we've gone with quot/rem, as in > > the other languages above, and in keeping with the design preference > > above. You have to call .mod() or .div() to get the other operators. > > > > It does mean there's a bit of a footgun surrounding the symbols / and % > > specifically, on signed integer types. I would not be at all opposed to > > adding a lint flag to calls-to-/-and-%-on-signed-integer-types, such > > that you could trap them all. As with many things here, the design space > > includes a variety of (sensible) preferences. > > Wow, what a big post! Sorry, looks like I've missed far too much of the > past > discussion. (And I'm a little surprised at your patience!) > > I for one am happy so long as arr[ind.mod(z)] is possible (though > arr[ind mod z] would be neater), and this is covered somewhere in the > documentation. > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Eddy Cizeron 06-87-16-03-64 41 rue de l'Orillon 75011 Paris -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Wed Apr 24 11:31:01 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 24 Apr 2013 11:31:01 -0700 Subject: [rust-dev] Rust ANTLR grammar may be correct In-Reply-To: References: Message-ID: <517824E5.6020504@mozilla.com> On 04/22/2013 04:58 PM, John Clements wrote: > The rust ANTLR grammar that lives at > > https://github.com/jbclements/rust-antlr/ > > appears to be largely correct, in the sense that it parses Rust source. There's a problem, in that the parser is currently SO DARN SLOW that I haven't been able to test it on the entirety of the rust repository yet. Parsing of TTs runs at about 2K lines per second, but the full program grammar starts at 200 lines/sec, then drops to 50, and finally may simply stall out completely. > > Fortunately, running fast is not the point. I've made a passing attempt to format the grammar to be readable and to conform to certain formatting conventions. I'd be grateful to anyone who has the time to make suggestions. > > NB, for those interested: our "restriction" mechanism, as expected, makes the rules for expression parsing much less pleasant; in particular, most of the expr hierarchy is duplicated at least once, and some of it is duplicated three times. > > Thanks for your time! > This looks amazing. Thanks. Is this grammar suitable to replace the official grammar in the manual? Will we be able to set up some automation around it to validate that it reflects the behavior of the rustc parser, and to keep it up to date? From loebel.marvin at gmail.com Wed Apr 24 01:53:34 2013 From: loebel.marvin at gmail.com (=?ISO-8859-1?Q?Marvin_L=F6bel?=) Date: Wed, 24 Apr 2013 10:53:34 +0200 Subject: [rust-dev] Making fail!() and assert!() usage nicer In-Reply-To: <51774510.5060701@mozilla.com> References: <5176039C.6060805@mozilla.com> <5176F2BD.7000103@mozilla.com> <51770A37.8080300@googlemail.com> <51774510.5060701@mozilla.com> Message-ID: <51779D8E.50809@googlemail.com> Am 24.04.2013 04:36, schrieb Brian Anderson: > On 04/23/2013 03:24 PM, Marvin L?bel wrote: >> Ever since fail and assert got turned into macros, failing with a >> string message has become quite line-noisy: >> >> fail!(~"cause") > >> >> Personally I think 3 is the easiest to implement option, and nice >> even without the fmt! optimisation. I already locally implemented the >> necessary changes that would allow switching to it after an snapshot, >> but I wanted to ask what others think. >> > > From what you've presented, I like 3. > > I agree with this sentiment in general, and agree that all these > related string-taking macros, assert, fail, debug, etc. should behave > similarly, generally accepting whatever you throw at them. It would be > very desirable I think to not duplicate the string in the case where > ~str is the only argument. This could probably be done with a trait > that converts to ~str by value (so ~str.to_str_by_val() is a no-op). > > We have always had this lingering notion that fail *could* accept a > dynamically typed twiddle, called `~Any`. If we go this direction of > passing everything through `fmt!` then that becomes more complicated. > > I think there will be solutions though. In the case where `fail` is > passed just one argument it could be interpreted as an instance of > some trait, Exceptiony, that can be called to cast the value to > `~Any`. When multiple arguments are passed it delegates to fmt. > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev Ah, didn't even think of the trait solution, that would probably be another way to achieve 4. (But it wouldn't be able to accept both &'statc str as no copy, and every other &str as a copy) In fact, there is already a ToStrConsume trait (currently still stuck in an pull request) that could be used for that, though it's currently blocked on rustc not crashing with owned self. I could just implement the macros it as a copy with a call to to_str() for now, and once that bug is sorted out change it to to_str_consume() if not accepting a non-'static str directly is acceptable. Actually, seeing as that would just shift the need to copy a slice into user code, I think it wouldn't even be that bad, and more obvious about what's going on. From graydon at mozilla.com Wed Apr 24 11:44:07 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 24 Apr 2013 11:44:07 -0700 Subject: [rust-dev] Rust ANTLR grammar may be correct In-Reply-To: <517824E5.6020504@mozilla.com> References: <517824E5.6020504@mozilla.com> Message-ID: <517827F7.2060102@mozilla.com> On 13-04-24 11:31 AM, Brian Anderson wrote: > This looks amazing. Thanks. Is this grammar suitable to replace the > official grammar in the manual? Will we be able to set up some > automation around it to validate that it reflects the behavior of the > rustc parser, and to keep it up to date? Yeah. This (automating its inclusion / extraction / testing) is on my 0.7 list for Very Important Stuff. (Also to John: I didn't comment at the time, but bravo! This is great. So excited to see it. Thanks.) -Graydon From lindsey at composition.al Wed Apr 24 12:46:19 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Wed, 24 Apr 2013 15:46:19 -0400 Subject: [rust-dev] Rust ANTLR grammar may be correct In-Reply-To: References: Message-ID: On Mon, Apr 22, 2013 at 7:58 PM, John Clements wrote: > The rust ANTLR grammar that lives at > > https://github.com/jbclements/rust-antlr/ > > appears to be largely correct, in the sense that it parses Rust source. I'll pile on and say that this is fantastic. I've wanted this for years! Hooray! Lindsey From ben.striegel at gmail.com Wed Apr 24 13:05:26 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 24 Apr 2013 16:05:26 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: <5176B835.20301@mozilla.com> References: <5176B835.20301@mozilla.com> Message-ID: It's important to keep in mind that much of the value of calling something the "standard" library is so that users *know* that the libraries within are blessed by the language developers themselves, and therefore gives them the peace of mind that the code within is featureful, reliable, supported in the long-term, and well-known by the community. Please select a name that adequately expresses the authority of such a library. On Tue, Apr 23, 2013 at 12:35 PM, Patrick Walton wrote: > Hi everyone, > > There's been consensus lately that `core` and `std` are somewhat misnamed. > `core` is really the standard library--the one that would be specified in a > specification if we had one. `std` is an "extras" library and may well end > up sliced up and moved to various packages. > > So it seems prudent to rename `core` to `std`. But that leaves the > question of what to name `std` in the interim. Options that have been > suggested are `extra`, `ext`, and `contrib`. > > Any other opinions? > > Patrick > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Wed Apr 24 14:37:42 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 24 Apr 2013 14:37:42 -0700 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> Message-ID: <517850A6.7080409@mozilla.com> On 13-04-23 04:53 PM, Robert O'Callahan wrote: > On Wed, Apr 24, 2013 at 11:25 AM, Robert O'Callahan > > wrote: > > I don't think bignums are useful in a browser because as a browser > developer I will choose data types that cover the ranges of values I > want to handle. If I think I need to handle integer values that > don't fit in 32 bits, I'll use a 64-bit integer type, or a floating > point type. Overflow always means I have a bug*. > > > Well, in C and C++ it does, and of course that's what most browser > developers are going to be used to. > > If we could rely on checked overflows in Rust, then we could start to > lean on that and declare that some tests that trigger overflow are > simply tests where task failure is an acceptable result. (Offensive as > this may to the cult of correctness, in practice priorities dictate we > have to do this kind of thing all the time --- declare that a bug is not > worth fixing as long as it's not exploitable.) Sure. I'd be happy to look into this as a mode for rust; I don't think we can expect to make it "always on", but we could possibly make it "reasonably easy to turn on" on a crate-by-crate basis. First thing to do is look into enabling it. There are a variety of pieces lying around we could look into: http://llvm.org/docs/LangRef.html#range-metadata http://llvm.org/docs/LangRef.html#arithmetic-with-overflow-intrinsics http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation http://embed.cs.utah.edu/ioc/ I suspect there's enough to work with there. It might require duplicating some of the lowerings that clang does in rust's trans layer. -Graydon From clements at brinckerhoff.org Wed Apr 24 15:36:07 2013 From: clements at brinckerhoff.org (John Clements) Date: Wed, 24 Apr 2013 15:36:07 -0700 Subject: [rust-dev] sub-grammar for range pattern constants? Message-ID: Right now, the Rust parser accepts arbitrary expressions in certain pattern locations, most notably on the right-hand-side of a ".." range pattern. In talking to Patrick about this, though, he conjectured that it might be pretty easy to explicitly define the grammar of constants. In fact? for range patterns, would it be reasonable to restrict the left- and right-hand-sides to simply be literals? I was poking through the source code, and I found some reference to the possibility of these patterns being strings, which I found intriguing, but I couldn't make it work: fn f() -> int { 14 } fn main() { match ~"abc" { "abb" .. "zzz" => io::println(~"success"), _ => fail!() } } ? yields this error: jclements-09740:~/tryrust clements> rustc /tmp/foo.rs Running /usr/local/bin/rustc: /tmp/foo.rs:5:8: 5:13 error: mismatched types: expected `~str` but found `&'static str` (str storage differs: expected ~ but found &'static ) /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), ^~~~~ /tmp/foo.rs:5:17: 5:22 error: mismatched types: expected `~str` but found `&'static str` (str storage differs: expected ~ but found &'static ) /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), ^~~~~ /tmp/foo.rs:5:8: 5:25 error: non-numeric type used in range /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), ^~~~~~~~~~~~~~~~~ error: aborting due to 3 previous errors ? which seems to be suggesting that I use patterns like ~"abc", but those don't work either?. they signal a type error using "uniq", which I think? is a compiler bug. Erm. NOT IMPORTANT NOW. The real question is this: can we define a simple grammar for what's legal on the lhs and rhs of a "range" pattern? perhaps simply pat = ? | range_lit DOTDOT range_lit ... range_lit = LIT_INT | LIT_FLOAT ? Note that LIT_INT includes LIT_CHAR in this grammar. I haven't been able to find any legal Rust programs that would be made illegal by this restriction, but perhaps there are funny corner cases: once things get beyond the parser, I have no idea what kind of crazy stuff goes on. :) As an additional benefit, it would eliminate bug/partial features such as the one above and the ICE I reported earlier today. John From banderson at mozilla.com Wed Apr 24 15:38:32 2013 From: banderson at mozilla.com (Brian Anderson) Date: Wed, 24 Apr 2013 15:38:32 -0700 Subject: [rust-dev] Update on I/O progress Message-ID: <51785EE8.1000206@mozilla.com> Hi. As you may know, I'm in the process of redesigning the I/O module on top of a new task scheduler. With my [latest pull request] I've built enough infrastructure that I'm about ready to start implementing TCP streams. Before I get too deep though I want to make sure that everybody who cares is aware of the design. [latest pull request]: https://github.com/mozilla/rust/pull/6046 I had a grand idea that I would be able to produce a full [design doc], but that's not going to happen I think. What I do have is a fair bit of [API documentation], along with a growing list of [unresolved issues], some of which I'll present here. [design doc]: https://github.com/mozilla/rust/wiki/Lib-io [API documentation]: https://github.com/brson/rust/blob/io/src/libcore/rt/io/mod.rs#L11 [unresolved issues]: https://github.com/brson/rust/blob/io/src/libcore/rt/io/mod.rs#L220 # Scope What I am focused on now is the design of a synchronous API for sending and receiving streams of bytes, along with an implementation built on an internal *asynchronous* I/O interface attached to the scheduler event loop. This includes reading and writing files, TCP, UDP, Unix sockets, stdio, pipes, adapters for string parsing, compression, memory buffers, etc. There are plenty of important and related issues that I have not considered yet, such as file and directory traversal, application-level protocols like HTTP, async I/O. We need to take important use cases into account, but don't necessarily need to implement them now. I am particularly interested in making sure that common operations are convenient and don't require a lot of boilerplate. To that end I've been collecting [aspirational examples] of succinctly written Rust I/O code using the hypothetical API. The goal will be to turn these into test cases. I welcome additional examples. [aspirational examples]: https://github.com/brson/rust/blob/io/src/libcore/rt/io/mod.rs#L24 # Overview The API I am proposing has a structure based on what we have now, with a Reader and Writer trait that define a few primitive operations, along with a number of types that implement them. Types that implement Reader and Writer are called 'streams' and automatically implement `Stream`. The types are influenced primarily by the existing `core::io`, .NET, Go, and Ruby. I recommend reading the previously linked module documentation for the complete story. # Issues Here I'll discuss some of the issues I've encountered so far. ## Error handling I've spent a lot of time thinking about - and talking to Patrick about - how I/O should deal with errors (the old `io` doesn't have a consistent strategy). The [error handling strategy] I'm proposing is intended to eliminate boilerplate and allow efficient recovery from errors, but it uses some uncommon patterns. [error handling strategy]: https://github.com/brson/rust/blob/io/src/libcore/rt/io/mod.rs#L128 In particular, it forces all return values to be 'nullable' or 'zeroable', which will lead to the usual logic errors under the right circumstances. It also uses conditions, which aren't used much yet in Rust. ## String encoding I have not yet put much thought about how to deal with string encoding and decoding. The existing `io` module simply has Reader and Writer extension traits that add a number of methods like `read_str`, etc. I think this is the wrong approach because it doesn't allow any extra state for the encoding/decoding, e.g. there's no way to customize the way newline is handled. Probably we'll need some decorator types like `StringReader`, etc. ## Close Do we need to have `close` methods or do we depend solely on RAII for closing streams? ## Constructor options There tend to be a lot of ways to open I/O types. Some potential examples: * File::open("diary.txt") * File::open(Path("diary.txt")) * File::open(Path("diary.txt"), Create, WriteOnly) * File::open(Url("file://diary.txt")) The one you want to put at the front of the tutorial is the simple `File::open("diary.txt")`, but then how do you use the other variations? `File::open_path(...)`, `File::open_with_options(...)`? I am considering defining `open` more like `fn open:(spec: S)`, then implementing `OpenSpec` for e.g. `&str`, `Path`, `(Path, FileFlags, FileAccess), `Url`, etc. Does this seem reasonable? # Closing Sorry for the barrage of random notes. Again I encourage those interested to read the [rt::io module docs] and the rest of the [rt::io module] to get a clearer idea of where I'm going with this. [rt::io module docs]: https://github.com/brson/rust/blob/io/src/libcore/rt/io/mod.rs#L11 [rt::io module]: https://github.com/brson/rust/tree/io/src/libcore/rt/io -Brian From graydon at mozilla.com Wed Apr 24 15:58:46 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 24 Apr 2013 15:58:46 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> Message-ID: <517863A6.5000209@mozilla.com> On 13-04-24 01:05 PM, Benjamin Striegel wrote: > It's important to keep in mind that much of the value of calling > something the "standard" library is so that users *know* that the > libraries within are blessed by the language developers themselves, and > therefore gives them the peace of mind that the code within is > featureful, reliable, supported in the long-term, and well-known by the > community. Please select a name that adequately expresses the authority > of such a library. Agreed. This packaging will be of a sort that _does_ represent a level of support from the language maintainers, version-to-version. So ... absent other suggestions I will return to my preferred passtime of thesaurus hunting: - Common - Platform - Staple - Stock - Supported - Base - Basis - Usual - Normal - Favored - Selected - Endorsed - Chosen - Prime Any of these sound pleasant to the hear? -Graydon From jack at metajack.im Wed Apr 24 16:24:09 2013 From: jack at metajack.im (Jack Moffitt) Date: Wed, 24 Apr 2013 17:24:09 -0600 Subject: [rust-dev] Renaming of core and std In-Reply-To: <517863A6.5000209@mozilla.com> References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: > Any of these sound pleasant to the hear? I'm fond of Prime. jack. From brandon at mintern.net Wed Apr 24 16:58:10 2013 From: brandon at mintern.net (Brandon Mintern) Date: Wed, 24 Apr 2013 16:58:10 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: I was thinking the same. On Wed, Apr 24, 2013 at 4:24 PM, Jack Moffitt wrote: > > Any of these sound pleasant to the hear? > > I'm fond of Prime. > > jack. > _______________________________________________ > 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 andrew.webb at gmail.com Wed Apr 24 17:21:06 2013 From: andrew.webb at gmail.com (Andrew Webb) Date: Thu, 25 Apr 2013 12:21:06 +1200 Subject: [rust-dev] Rust-dev Digest, Vol 34, Issue 68 In-Reply-To: References: Message-ID: This is just my opinion, but to me Prime sounds more important than standard, which is a tad confusing > I was thinking the same. > > > On Wed, Apr 24, 2013 at 4:24 PM, Jack Moffitt wrote: > > > > Any of these sound pleasant to the hear? > > > > I'm fond of Prime. > > > > jack. > > _______________________________________________ > -------------- next part -------------- An HTML attachment was scrubbed... URL: From martindemello at gmail.com Wed Apr 24 17:39:45 2013 From: martindemello at gmail.com (Martin DeMello) Date: Wed, 24 Apr 2013 17:39:45 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: <517863A6.5000209@mozilla.com> References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: I like "platform"; a few other languages seem to have converged on it to describe a blessed set of third-party packages. Of the others "common" and "base" sound too much like they are a part of core. martin On Wed, Apr 24, 2013 at 3:58 PM, Graydon Hoare wrote: > On 13-04-24 01:05 PM, Benjamin Striegel wrote: >> It's important to keep in mind that much of the value of calling >> something the "standard" library is so that users *know* that the >> libraries within are blessed by the language developers themselves, and >> therefore gives them the peace of mind that the code within is >> featureful, reliable, supported in the long-term, and well-known by the >> community. Please select a name that adequately expresses the authority >> of such a library. > > Agreed. This packaging will be of a sort that _does_ represent a level > of support from the language maintainers, version-to-version. So ... > absent other suggestions I will return to my preferred passtime of > thesaurus hunting: > > - Common > - Platform > - Staple > - Stock > - Supported > - Base > - Basis > - Usual > - Normal > - Favored > - Selected > - Endorsed > - Chosen > - Prime > > Any of these sound pleasant to the hear? > > -Graydon > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From thadguidry at gmail.com Wed Apr 24 18:37:21 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 24 Apr 2013 20:37:21 -0500 Subject: [rust-dev] Renaming of core and std In-Reply-To: <517863A6.5000209@mozilla.com> References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: +1 Prime Prime comes from the Latin " pr?mus ", which means First... so it's above Chosen, Favored, Normal, Selected, and all the rest. In Old French, prim, means the first hour, go fig. On Wed, Apr 24, 2013 at 5:58 PM, Graydon Hoare wrote: > On 13-04-24 01:05 PM, Benjamin Striegel wrote: > > It's important to keep in mind that much of the value of calling > > something the "standard" library is so that users *know* that the > > libraries within are blessed by the language developers themselves, and > > therefore gives them the peace of mind that the code within is > > featureful, reliable, supported in the long-term, and well-known by the > > community. Please select a name that adequately expresses the authority > > of such a library. > > Agreed. This packaging will be of a sort that _does_ represent a level > of support from the language maintainers, version-to-version. So ... > absent other suggestions I will return to my preferred passtime of > thesaurus hunting: > > - Common > - Platform > - Staple > - Stock > - Supported > - Base > - Basis > - Usual > - Normal > - Favored > - Selected > - Endorsed > - Chosen > - Prime > > Any of these sound pleasant to the hear? > > -Graydon > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Wed Apr 24 19:06:42 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 24 Apr 2013 19:06:42 -0700 Subject: [rust-dev] LL(1) problems Message-ID: <51788FB2.3020103@mozilla.com> I've refactored the Rust grammar to get it as close to LL(1) as I could. I made some minor language changes along the way which should not break code, but there are a few things that are still preventing me from making it LL(1): 1. Explicit self and patterns-as-arguments require two tokens of lookahead to find the `self` (or `mut` or lifetime). fn foo(&self, ...) vs. fn foo(&a: &int) { ... } This is because arguments are patterns, and `&a` is a valid pattern. 2. There is a production called "maybe-named argument", which is part of the trait declaration form. (It also shows up in function types.) This allows you to write: trait Foo { fn bar(&int, &int); } Instead of: trait Foo { fn bar(x: &int, y: &int); } However, because arguments can be patterns, lookahead is required to distinguish between that and this: trait Foo { fn bar(&x: &int, &y: int); } I believe this can actually be *unbounded* lookahead. Consider: trait Foo { fn bar(&&&&&&&&&&x: &&&&&&&&&&int); } Versus: trait Foo { fn bar(&&&&&&&&&&int); } This has a relatively straightforward fix though: just restrict the argument name to be an identifier. There is little need for the pattern form here. This reduces the complexity to LL(2); I haven't investigated whether it can be reduced further. 3. `unsafe` blocks and `unsafe` function declarations are both allowed inside blocks, and therefore two tokens of lookahead are required. fn foo() { unsafe fn bar() { ... } } Versus: fn foo() { unsafe { ... } } The parser needs to look ahead two tokens to find the `fn` or `{` keyword. These were the only warnings that the Python yapps2 module emitted when compiling the Rust grammar, after suitable refactoring. My general feeling is that, given how valuable explicit self and argument patterns are, LL(2) is okay, especially if we turn out to be LALR(1). Others may feel differently, however; thoughts? Patrick From graydon at mozilla.com Wed Apr 24 20:04:46 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Wed, 24 Apr 2013 20:04:46 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <51788FB2.3020103@mozilla.com> References: <51788FB2.3020103@mozilla.com> Message-ID: <51789D4E.7070100@mozilla.com> On 13-04-24 07:06 PM, Patrick Walton wrote: > These were the only warnings that the Python yapps2 module emitted when > compiling the Rust grammar, after suitable refactoring. My general > feeling is that, given how valuable explicit self and argument patterns > are, LL(2) is okay, especially if we turn out to be LALR(1). Others may > feel differently, however; thoughts? My skill at grammar-factoring is ... minimal, but I thought you could generally factor anything that's just a common-prefix situation like these by introducing new rules that go one (common) token further and then decide between the two remaining possible branches. Not to say it's pretty, but it ... ought to work, I think? (TBH I don't actually understand any of the examples I can find of LL(2) grammars that "can't be factored into LL(1)"; the compiler texts I have all suggest that you can factor most reasonable LL(*) things into LL(1) with sufficiently many intermediate nodes. This page for example shows one http://stackoverflow.com/questions/10634197/ll2-language-that-is-not-ll1 but I can't tell exactly what's going on there, something to do with having to look 1 token past a choice point that may expand infinitely? It seems quite rare / unlikely.) If we absolutely, resolutely can't factor the current grammar down to LL(1) I guess I'll live. LL(2) is not the end of the world. But it seems awfully close, given the results so far! 2 or 3 remaining conflicts? That's _amazing_. I thought we'd be fighting this for months. I agree that removing pattern arguments and explicit self would be a high price, probably too high, if that's what it comes down to. -Graydon From andres.osinski at gmail.com Wed Apr 24 20:30:07 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Thu, 25 Apr 2013 00:30:07 -0300 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: "Platform" is highly descriptive and its "value" is not as subjetive as "prime". On Wed, Apr 24, 2013 at 10:37 PM, Thad Guidry wrote: > +1 Prime > > Prime comes from the Latin " pr?mus ", which means First... so it's above > Chosen, Favored, Normal, Selected, and all the rest. In Old French, prim, > means the first hour, go fig. > > > On Wed, Apr 24, 2013 at 5:58 PM, Graydon Hoare wrote: > >> On 13-04-24 01:05 PM, Benjamin Striegel wrote: >> > It's important to keep in mind that much of the value of calling >> > something the "standard" library is so that users *know* that the >> > libraries within are blessed by the language developers themselves, and >> > therefore gives them the peace of mind that the code within is >> > featureful, reliable, supported in the long-term, and well-known by the >> > community. Please select a name that adequately expresses the authority >> > of such a library. >> >> Agreed. This packaging will be of a sort that _does_ represent a level >> of support from the language maintainers, version-to-version. So ... >> absent other suggestions I will return to my preferred passtime of >> thesaurus hunting: >> >> - Common >> - Platform >> - Staple >> - Stock >> - Supported >> - Base >> - Basis >> - Usual >> - Normal >> - Favored >> - Selected >> - Endorsed >> - Chosen >> - Prime >> >> Any of these sound pleasant to the hear? >> >> -Graydon >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Wed Apr 24 20:35:55 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 24 Apr 2013 22:35:55 -0500 Subject: [rust-dev] LL(1) problems In-Reply-To: <51788FB2.3020103@mozilla.com> References: <51788FB2.3020103@mozilla.com> Message-ID: It looks like, from reading and gaining insight in the 5 minutes I spared... That you can use or should use operator-precedence rules sometimes and deal with the non-terminals and you should have it licked ? instead of long lookaheads ? -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From mozilla at mcpherrin.ca Wed Apr 24 20:41:01 2013 From: mozilla at mcpherrin.ca (Matthew McPherrin) Date: Wed, 24 Apr 2013 23:41:01 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: A straw poll of a few developers in the room with me leads "Platform" and "Util" as the leading choices. On Wed, Apr 24, 2013 at 11:30 PM, Andres Osinski wrote: > "Platform" is highly descriptive and its "value" is not as subjetive as > "prime". > > > On Wed, Apr 24, 2013 at 10:37 PM, Thad Guidry wrote: > >> +1 Prime >> >> Prime comes from the Latin " pr?mus ", which means First... so it's above >> Chosen, Favored, Normal, Selected, and all the rest. In Old French, prim, >> means the first hour, go fig. >> >> >> On Wed, Apr 24, 2013 at 5:58 PM, Graydon Hoare wrote: >> >>> On 13-04-24 01:05 PM, Benjamin Striegel wrote: >>> > It's important to keep in mind that much of the value of calling >>> > something the "standard" library is so that users *know* that the >>> > libraries within are blessed by the language developers themselves, and >>> > therefore gives them the peace of mind that the code within is >>> > featureful, reliable, supported in the long-term, and well-known by the >>> > community. Please select a name that adequately expresses the authority >>> > of such a library. >>> >>> Agreed. This packaging will be of a sort that _does_ represent a level >>> of support from the language maintainers, version-to-version. So ... >>> absent other suggestions I will return to my preferred passtime of >>> thesaurus hunting: >>> >>> - Common >>> - Platform >>> - Staple >>> - Stock >>> - Supported >>> - Base >>> - Basis >>> - Usual >>> - Normal >>> - Favored >>> - Selected >>> - Endorsed >>> - Chosen >>> - Prime >>> >>> Any of these sound pleasant to the hear? >>> >>> -Graydon >>> >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >> >> >> >> -- >> -Thad >> http://www.freebase.com/view/en/thad_guidry >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> > > > -- > Andr?s Osinski > http://www.andresosinski.com.ar/ > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lindsey at composition.al Wed Apr 24 20:42:47 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Wed, 24 Apr 2013 23:42:47 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: <517863A6.5000209@mozilla.com> References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: On Wed, Apr 24, 2013 at 6:58 PM, Graydon Hoare wrote: > Agreed. This packaging will be of a sort that _does_ represent a level > of support from the language maintainers, version-to-version. So ... > absent other suggestions I will return to my preferred passtime of > thesaurus hunting: > > - Common > - Platform > - Staple > - Stock > - Supported > - Base > - Basis > - Usual > - Normal > - Favored > - Selected > - Endorsed > - Chosen > - Prime Are these synonyms for "standard"? Since `core` is being renamed to `std` (correct?), we'd want the new name of `std` to convey "supported, but not as essential as what's in `std`", right? Lindsey From andres.osinski at gmail.com Wed Apr 24 20:48:24 2013 From: andres.osinski at gmail.com (Andres Osinski) Date: Thu, 25 Apr 2013 00:48:24 -0300 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: If I may comment on "util", the problem is that it has been (in my experience) a catch-all for some common miscellaneous functionality that may be used to tie strings together in a project (error formatters, special strin g manipulation functions, helpers, etc). I don't believe that most of the functionality in current std classifies as such. For examples of this, check out the "util" namespaces in Java and Python projects; the current std is far more focused and useful for general use cases. On Thu, Apr 25, 2013 at 12:42 AM, Lindsey Kuper wrote: > On Wed, Apr 24, 2013 at 6:58 PM, Graydon Hoare > wrote: > > Agreed. This packaging will be of a sort that _does_ represent a level > > of support from the language maintainers, version-to-version. So ... > > absent other suggestions I will return to my preferred passtime of > > thesaurus hunting: > > > > - Common > > - Platform > > - Staple > > - Stock > > - Supported > > - Base > > - Basis > > - Usual > > - Normal > > - Favored > > - Selected > > - Endorsed > > - Chosen > > - Prime > > Are these synonyms for "standard"? > > Since `core` is being renamed to `std` (correct?), we'd want the new > name of `std` to convey "supported, but not as essential as what's in > `std`", right? > > Lindsey > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- Andr?s Osinski http://www.andresosinski.com.ar/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Wed Apr 24 20:59:11 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Wed, 24 Apr 2013 23:59:11 -0400 Subject: [rust-dev] sub-grammar for range pattern constants? In-Reply-To: References: Message-ID: > would it be reasonable to restrict the left- and right-hand-sides to simply be literals? Literals only? So then would the following be illegal? static END = 2; ... match bar { 0 .. END => ... } On Wed, Apr 24, 2013 at 6:36 PM, John Clements wrote: > Right now, the Rust parser accepts arbitrary expressions in certain > pattern locations, most notably on the right-hand-side of a ".." range > pattern. In talking to Patrick about this, though, he conjectured that it > might be pretty easy to explicitly define the grammar of constants. In > fact? for range patterns, would it be reasonable to restrict the left- and > right-hand-sides to simply be literals? > > I was poking through the source code, and I found some reference to the > possibility of these patterns being strings, which I found intriguing, but > I couldn't make it work: > > fn f() -> int { 14 } > > fn main() { > match ~"abc" { > "abb" .. "zzz" => io::println(~"success"), > _ => fail!() > } > } > > ? yields this error: > > jclements-09740:~/tryrust clements> rustc /tmp/foo.rs > Running /usr/local/bin/rustc: > /tmp/foo.rs:5:8: 5:13 error: mismatched types: expected `~str` but found > `&'static str` (str storage differs: expected ~ but found &'static ) > /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), > ^~~~~ > /tmp/foo.rs:5:17: 5:22 error: mismatched types: expected `~str` but found > `&'static str` (str storage differs: expected ~ but found &'static ) > /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), > ^~~~~ > /tmp/foo.rs:5:8: 5:25 error: non-numeric type used in range > /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), > ^~~~~~~~~~~~~~~~~ > error: aborting due to 3 previous errors > > > ? which seems to be suggesting that I use patterns like ~"abc", but those > don't work either?. they signal a type error using "uniq", which I think? > is a compiler bug. Erm. NOT IMPORTANT NOW. > > The real question is this: can we define a simple grammar for what's legal > on the lhs and rhs of a "range" pattern? perhaps simply > > pat = ? > | range_lit DOTDOT range_lit > ... > > range_lit = LIT_INT | LIT_FLOAT > > ? > > Note that LIT_INT includes LIT_CHAR in this grammar. > > I haven't been able to find any legal Rust programs that would be made > illegal by this restriction, but perhaps there are funny corner cases: once > things get beyond the parser, I have no idea what kind of crazy stuff goes > on. :) > > As an additional benefit, it would eliminate bug/partial features such as > the one above and the ICE I reported earlier today. > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Wed Apr 24 21:11:43 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 25 Apr 2013 00:11:43 -0400 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: I concur, "util" is one of the ones that I would definitely avoid. It sounds like somewhere that you would just put code that you couldn't rightly stick anywhere else. I like the sound of both "prime" and "platform". On Wed, Apr 24, 2013 at 11:48 PM, Andres Osinski wrote: > If I may comment on "util", the problem is that it has been (in my > experience) a catch-all for some common miscellaneous functionality that > may be used to tie strings together in a project (error formatters, > special strin g manipulation functions, helpers, etc). I don't believe that > most of the functionality in current std classifies as such. For examples > of this, check out the "util" namespaces in Java and Python projects; the > current std is far more focused and useful for general use cases. > > > On Thu, Apr 25, 2013 at 12:42 AM, Lindsey Kuper wrote: > >> On Wed, Apr 24, 2013 at 6:58 PM, Graydon Hoare >> wrote: >> > Agreed. This packaging will be of a sort that _does_ represent a level >> > of support from the language maintainers, version-to-version. So ... >> > absent other suggestions I will return to my preferred passtime of >> > thesaurus hunting: >> > >> > - Common >> > - Platform >> > - Staple >> > - Stock >> > - Supported >> > - Base >> > - Basis >> > - Usual >> > - Normal >> > - Favored >> > - Selected >> > - Endorsed >> > - Chosen >> > - Prime >> >> Are these synonyms for "standard"? >> >> Since `core` is being renamed to `std` (correct?), we'd want the new >> name of `std` to convey "supported, but not as essential as what's in >> `std`", right? >> >> Lindsey >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > > > -- > Andr?s Osinski > http://www.andresosinski.com.ar/ > > _______________________________________________ > 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 thadguidry at gmail.com Wed Apr 24 21:25:51 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 24 Apr 2013 23:25:51 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) Message-ID: I've been working on getting the right settings, configure options, etc... for Windows users to setup a Cygwin installation and be able to use it to build Rust with Clang / LLVM. We've run into a few problems and I'm asking the community for a bit of help. It seems that there's a Clang test that fails, and apparently because the header files are not correctly found for whatever reason. Here's the pastebin of the current Cygwin environment I'm working against and modifying as I go along...that shows the errors and my directory structures under a Cygwin install...hope it reads well enough for folks to understand. I need help with trying to understand why Clang or my setup in Cygwin might be confused with this test_me.c that Brian found for me: https://gist.github.com/brson/5456999 -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From thadguidry at gmail.com Wed Apr 24 21:31:26 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Wed, 24 Apr 2013 23:31:26 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: Message-ID: OOps, let's try that again with including the pastebin URL ! http://pastebin.mozilla.org/2344954 On Wed, Apr 24, 2013 at 11:25 PM, Thad Guidry wrote: > I've been working on getting the right settings, configure options, etc... > for Windows users to setup a Cygwin installation and be able to use it to > build Rust with Clang / LLVM. > > We've run into a few problems and I'm asking the community for a bit of > help. > > It seems that there's a Clang test that fails, and apparently because the > header files are not correctly found for whatever reason. > > Here's the pastebin of the current Cygwin environment I'm working against > and modifying as I go along...that shows the errors and my directory > structures under a Cygwin install...hope it reads well enough for folks to > understand. > > I need help with trying to understand why Clang or my setup in Cygwin > might be confused with this test_me.c that Brian found for me: > https://gist.github.com/brson/5456999 > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Wed Apr 24 22:25:13 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Wed, 24 Apr 2013 22:25:13 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <51789D4E.7070100@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> Message-ID: <5178BE39.3050307@mozilla.com> On 4/24/13 8:04 PM, Graydon Hoare wrote: > My skill at grammar-factoring is ... minimal, but I thought you could > generally factor anything that's just a common-prefix situation like > these by introducing new rules that go one (common) token further and > then decide between the two remaining possible branches. Not to say it's > pretty, but it ... ought to work, I think? I tried harder to refactor it. I have an untested grammar for Rust here, with the token regexes not yet filled in: https://gist.github.com/anonymous/5457664 yapps2 reports that this grammar is LL(1). Note that the refactorings I made resulted in a grammar which isn't that great for tooling or parsing in many places. In particular the contortions needed to make `self_ty_and_maybenamed_args` result in an AST that combines the self type and the type of the first argument together in bizarre ways. Since this is untested, I'm sure there are bugs, but it's probably a good sign that I could at least refactor the grammar to what I think is LL(1). Patrick From i at cantor.mx Wed Apr 24 23:27:46 2013 From: i at cantor.mx (Max Cantor) Date: Wed, 24 Apr 2013 23:27:46 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: Unless `std` has been settled on, I think that `base` for `std` and `platform` for `core` are the most informative and most likely to not require explanation for new users. The reason I don't like `std` is that, AFAIK, the usual explanations for packages like `core` in other languages is: "a standard set of packages for building in the language" which of course would collide a bit with `std`. Also, I do think this is important. I'm pretty sure if the early haskell guys renamed "Monad" to "Context" the language would have an order of magnitude more adoption. On Wed, Apr 24, 2013 at 9:11 PM, Benjamin Striegel wrote: > I concur, "util" is one of the ones that I would definitely avoid. It > sounds like somewhere that you would just put code that you couldn't > rightly stick anywhere else. > > I like the sound of both "prime" and "platform". > > > On Wed, Apr 24, 2013 at 11:48 PM, Andres Osinski > wrote: > >> If I may comment on "util", the problem is that it has been (in my >> experience) a catch-all for some common miscellaneous functionality that >> may be used to tie strings together in a project (error formatters, >> special strin g manipulation functions, helpers, etc). I don't believe that >> most of the functionality in current std classifies as such. For examples >> of this, check out the "util" namespaces in Java and Python projects; the >> current std is far more focused and useful for general use cases. >> >> >> On Thu, Apr 25, 2013 at 12:42 AM, Lindsey Kuper wrote: >> >>> On Wed, Apr 24, 2013 at 6:58 PM, Graydon Hoare >>> wrote: >>> > Agreed. This packaging will be of a sort that _does_ represent a level >>> > of support from the language maintainers, version-to-version. So ... >>> > absent other suggestions I will return to my preferred passtime of >>> > thesaurus hunting: >>> > >>> > - Common >>> > - Platform >>> > - Staple >>> > - Stock >>> > - Supported >>> > - Base >>> > - Basis >>> > - Usual >>> > - Normal >>> > - Favored >>> > - Selected >>> > - Endorsed >>> > - Chosen >>> > - Prime >>> >>> Are these synonyms for "standard"? >>> >>> Since `core` is being renamed to `std` (correct?), we'd want the new >>> name of `std` to convey "supported, but not as essential as what's in >>> `std`", right? >>> >>> Lindsey >>> _______________________________________________ >>> Rust-dev mailing list >>> Rust-dev at mozilla.org >>> https://mail.mozilla.org/listinfo/rust-dev >>> >> >> >> >> -- >> Andr?s Osinski >> http://www.andresosinski.com.ar/ >> >> _______________________________________________ >> 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 lindsey at composition.al Wed Apr 24 23:39:24 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Thu, 25 Apr 2013 02:39:24 -0400 Subject: [rust-dev] LL(1) problems In-Reply-To: <5178BE39.3050307@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> Message-ID: On Thu, Apr 25, 2013 at 1:25 AM, Patrick Walton wrote: > I have an untested grammar for Rust here, > with the token regexes not yet filled in: > > https://gist.github.com/anonymous/5457664 > > yapps2 reports that this grammar is LL(1). > > Note that the refactorings I made resulted in a grammar which isn't that > great for tooling or parsing in many places. In particular the contortions > needed to make `self_ty_and_maybenamed_args` result in an AST that combines > the self type and the type of the first argument together in bizarre ways. > > Since this is untested, I'm sure there are bugs, but it's probably a good > sign that I could at least refactor the grammar to what I think is LL(1). This is really cool, but I'm sort of confused about the apparent multiple ongoing efforts toward having a precise and machine-readable Rust grammar. Should we consider one of these the "real" grammar? Lindsey From asb at asbradbury.org Thu Apr 25 00:08:22 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Thu, 25 Apr 2013 08:08:22 +0100 Subject: [rust-dev] LL(1) problems In-Reply-To: <5178BE39.3050307@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> Message-ID: On 25 April 2013 06:25, Patrick Walton wrote: > Note that the refactorings I made resulted in a grammar which isn't that > great for tooling or parsing in many places. In particular the contortions > needed to make `self_ty_and_maybenamed_args` result in an AST that combines > the self type and the type of the first argument together in bizarre ways. So that implies disallowing self as an identifier might be useful. Are there other changes of a similar nature that should be considered? Alex From abhijeet.gaiha at gmail.com Thu Apr 25 01:39:28 2013 From: abhijeet.gaiha at gmail.com (Abhijeet Gaiha) Date: Thu, 25 Apr 2013 14:09:28 +0530 Subject: [rust-dev] String Internment Library In-Reply-To: References: Message-ID: There is an issue on Servo #282, which talks about having a uniform string internment strategy across Rust, Spidermonkey and NetsurfCSS. Is there any existing string internment library in Rust? If not, any plans to provide one? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ncm at cantrip.org Thu Apr 25 05:25:12 2013 From: ncm at cantrip.org (Nathan Myers) Date: Thu, 25 Apr 2013 05:25:12 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <51785EE8.1000206@mozilla.com> References: <51785EE8.1000206@mozilla.com> Message-ID: <517920A8.5020509@cantrip.org> On 04/24/2013 03:38 PM, Brian Anderson wrote: > ## String encoding > > I have not yet put much thought about how to deal with string encoding > and decoding. The existing `io` module simply has Reader and Writer > extension traits that add a number of methods like `read_str`, etc. I > think this is the wrong approach because it doesn't allow any extra > state for the encoding/decoding, e.g. there's no way to customize the > way newline is handled. Probably we'll need some decorator types like > `StringReader`, etc. An opportunity not to be missed... since I/O objects are often propagated through a system from top to bottom, they are an excellent place to attach state that intermediate levels does not need to know about. Such state traditionally includes locale-ish formatting services, but the possibilities are much broader: time zone, measurement-unit system, debug level, encryption/ authentication apparatus, undo/redo log, cumulative stats, rate and resource limits -- the list goes on. Some of these can be standardized, and many have been, but users need to be able to add their own on an equal basis with standard services. > ## Close > > Do we need to have `close` methods or do we depend solely on RAII for > closing streams? close() can fail and report an error code. When you are not interested in that, the destructor can do the job and throw away the result, but often enough you need to know. Usually there's not much to do about it beyond reporting the event, but that report can be essential: did the data sent reach its destination? If not, why not? Nathan Myers ncm at cantrip.org From graydon at mozilla.com Thu Apr 25 07:04:12 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 07:04:12 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> Message-ID: <517937DC.3090007@mozilla.com> On 13-04-24 11:39 PM, Lindsey Kuper wrote: > On Thu, Apr 25, 2013 at 1:25 AM, Patrick Walton wrote: >> I have an untested grammar for Rust here, >> with the token regexes not yet filled in: >> >> https://gist.github.com/anonymous/5457664 >> >> yapps2 reports that this grammar is LL(1). >> >> Note that the refactorings I made resulted in a grammar which isn't that >> great for tooling or parsing in many places. In particular the contortions >> needed to make `self_ty_and_maybenamed_args` result in an AST that combines >> the self type and the type of the first argument together in bizarre ways. >> >> Since this is untested, I'm sure there are bugs, but it's probably a good >> sign that I could at least refactor the grammar to what I think is LL(1). > > This is really cool, but I'm sort of confused about the apparent > multiple ongoing efforts toward having a precise and machine-readable > Rust grammar. Should we consider one of these the "real" grammar? This is a translation of the one John just finished (which was for antlr4, a very flexible "any LL(k)" grammar) into input for yapps2, which (as far as I know) has the distinguishing features of being-in-python and being-able-to-tell-us-about-LL(1)-conflicts. I believe it's still the "same" grammar as John did, just massaged to target a different tool. At some point I'd like a library that can consume/emit the 97 different equivalent dialects of EBNF used by different tools, so we can do this sort of exercise a little more readily. In any case that is (as far as I know) the only multiplicity of grammars floating about. The previous attempt here was one I made, targeting llnextgen, but it was abandoned mid-way-through (the results of which are currently on display in the reference manual). Are there others? -Graydon From danielmicay at gmail.com Thu Apr 25 07:12:49 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Thu, 25 Apr 2013 10:12:49 -0400 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517920A8.5020509@cantrip.org> References: <51785EE8.1000206@mozilla.com> <517920A8.5020509@cantrip.org> Message-ID: On Thu, Apr 25, 2013 at 8:25 AM, Nathan Myers wrote: > On 04/24/2013 03:38 PM, Brian Anderson wrote: >> >> ## String encoding >> >> I have not yet put much thought about how to deal with string encoding and >> decoding. The existing `io` module simply has Reader and Writer extension >> traits that add a number of methods like `read_str`, etc. I think this is >> the wrong approach because it doesn't allow any extra state for the >> encoding/decoding, e.g. there's no way to customize the way newline is >> handled. Probably we'll need some decorator types like `StringReader`, etc. > > > An opportunity not to be missed... since I/O objects are often > propagated through a system from top to bottom, they are an > excellent place to attach state that intermediate levels does not > need to know about. Such state traditionally includes locale-ish > formatting services, but the possibilities are much broader: time > zone, measurement-unit system, debug level, encryption/ > authentication apparatus, undo/redo log, cumulative stats, > rate and resource limits -- the list goes on. Some of these > can be standardized, and many have been, but users need to > be able to add their own on an equal basis with standard > services. > >> ## Close >> >> Do we need to have `close` methods or do we depend solely on RAII for >> closing streams? > > > close() can fail and report an error code. When you are not > interested in that, the destructor can do the job and throw > away the result, but often enough you need to know. Usually > there's not much to do about it beyond reporting the event, > but that report can be essential: did the data sent reach its > destination? If not, why not? > > Nathan Myers > ncm at cantrip.org > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev You can get the errors that close would have thrown by calling flush. Closing pretty much has to be in a destructor unless you want to write finally blocks everywhere, which aren't as pretty in Rust as they are in languages which actually have that as a first-class thing. It becomes non-trivial when the lifetime isn't just based on a single scope, and can live for different periods of time. You can get deterministic destruction inside @mut with @mut Option or @mut [File]. However, you already know that anything in @ will go away when the task ends, so there's already a deterministic upper-bound on the lifetime. From illissius at gmail.com Thu Apr 25 07:18:26 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Thu, 25 Apr 2013 16:18:26 +0200 Subject: [rust-dev] Update on I/O progress In-Reply-To: <51785EE8.1000206@mozilla.com> References: <51785EE8.1000206@mozilla.com> Message-ID: You write: > So what actually happens if `new` encounters an error? To understand > that it's important to know that what `new` returns is not a `File` > but an `Option`. If the file does not open, and the condition > is handled, then `new` will simply return `None`. Because there is an > implementation of `Writer` (the trait required ultimately required for > types to implement `write_line`) there is no need to inspect or unwrap > the `Option` and we simply call `write_line` on it. If `new` > returned a `None` then the followup call to `write_line` will also > raise an error. I'm an outsider, so apologies if I'm off the right track. But this sounds wrong to me. Isn't the point of condition handlers to /handle the condition/? Meaning resolve the problem, so that processing can continue? Here as far as I can tell, they're only being used to say "fail differently", which then leads to failing again the next time you try to do something. Opening a file was actually one of the examples used to illustrate the condition system way back when[1]. > * XXX: How should we use condition handlers that return values? IMHO the right way would be to provide more fine-grained information about the error (perhaps raising different conditions depending on the error, instead of always the same condition and a giant enum describing it), and use the return value of the condition to set policy wrt how to handle it and/or to provide a substitute (as in the example). If there's nothing reasonable that could be done, don't raise a condition, fail unconditionally. Whether to respond to failure by failing the task or by indicating it in the return value seems like it would be better handled by having separate functions for each. In the case where you expect success, the result shouldn't be an Option. If the result is an Option, it shouldn't fail the task (whether or not a condition handler is present). So for example: open(path: &P, mode: FileMode, access: FileAccess) -> FileStream try_open(path: &P, mode: FileMode, access: FileAccess) -> Option If the expect-success version of a function returns (), the try_ version would return bool rather than Option<()> (which are isomorphic). Upon encountering an error, open() would raise a condition, and then continue if possible, otherwise fail!(). I'm not sure whether try_open() would raise a condition or not. The way conditions were described, if they aren't handled, the task fails. try_open() definitely shouldn't fail. Would it be reasonable to raise a condition and instead of failing, return None if it's not handled? If not, then try_open() shouldn't raise any conditions, and should just return None. The obvious drawback is twice as many functions, but it feels preferable to forcing two different behaviours onto the same function. The fast (expect-success) path would be just as clean as before, if not cleaner. [1] https://mail.mozilla.org/pipermail/rust-dev/2012-October/002545.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at dhardy.name Thu Apr 25 07:52:08 2013 From: lists at dhardy.name (Diggory Hardy) Date: Thu, 25 Apr 2013 16:52:08 +0200 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: References: <20130423144812.217310@gmx.com> <1486845.Eo0P33FOQu@l10036> Message-ID: <1529933.oVftDTLAFD@l10036> > My opinion (that nobody will follow, but I still give it) is that integers > should not have the "/" operator at all. This was one of the bad choices of > C (or maybe of a previous language). Hmm, maybe, though I can imagine plenty of people being surprised at that. What really gets me though is that % is commonly called the "mod" operator and yet has nothing to do with modular arithmatic (I actually wrote a blog post about it a few months back: [1]). If it were my choice I'd either make "x % y" do real modular arithmatic (possibly even throwing if y is not positive) or have no % operator (just mod and rem keywords). [1]: http://diggoryhardy.wordpress.com/2013/01/08/why-division-remainder-and-modulus-are-not-the-same/ -Diggory From clements at brinckerhoff.org Thu Apr 25 08:30:50 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 25 Apr 2013 08:30:50 -0700 Subject: [rust-dev] sub-grammar for range pattern constants? In-Reply-To: References: Message-ID: <9C0DF66F-B470-4F39-915A-18EFBC6C0D30@brinckerhoff.org> On Apr 24, 2013, at 8:59 PM, Benjamin Striegel wrote: > > would it be reasonable to restrict the left- and right-hand-sides to simply be literals? > > Literals only? So then would the following be illegal? > > static END = 2; > ... > match bar { > 0 .. END => ... > } Good! I knew there were forms I was missing. so, from the grammar standpoint, we now have RANGE_LIT = LIT_INT | LIT_FLOAT | ident Other important ones that I'm missing? John > > > On Wed, Apr 24, 2013 at 6:36 PM, John Clements wrote: > Right now, the Rust parser accepts arbitrary expressions in certain pattern locations, most notably on the right-hand-side of a ".." range pattern. In talking to Patrick about this, though, he conjectured that it might be pretty easy to explicitly define the grammar of constants. In fact? for range patterns, would it be reasonable to restrict the left- and right-hand-sides to simply be literals? > > I was poking through the source code, and I found some reference to the possibility of these patterns being strings, which I found intriguing, but I couldn't make it work: > > fn f() -> int { 14 } > > fn main() { > match ~"abc" { > "abb" .. "zzz" => io::println(~"success"), > _ => fail!() > } > } > > ? yields this error: > > jclements-09740:~/tryrust clements> rustc /tmp/foo.rs > Running /usr/local/bin/rustc: > /tmp/foo.rs:5:8: 5:13 error: mismatched types: expected `~str` but found `&'static str` (str storage differs: expected ~ but found &'static ) > /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), > ^~~~~ > /tmp/foo.rs:5:17: 5:22 error: mismatched types: expected `~str` but found `&'static str` (str storage differs: expected ~ but found &'static ) > /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), > ^~~~~ > /tmp/foo.rs:5:8: 5:25 error: non-numeric type used in range > /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), > ^~~~~~~~~~~~~~~~~ > error: aborting due to 3 previous errors > > > ? which seems to be suggesting that I use patterns like ~"abc", but those don't work either?. they signal a type error using "uniq", which I think? is a compiler bug. Erm. NOT IMPORTANT NOW. > > The real question is this: can we define a simple grammar for what's legal on the lhs and rhs of a "range" pattern? perhaps simply > > pat = ? > | range_lit DOTDOT range_lit > ... > > range_lit = LIT_INT | LIT_FLOAT > > ? > > Note that LIT_INT includes LIT_CHAR in this grammar. > > I haven't been able to find any legal Rust programs that would be made illegal by this restriction, but perhaps there are funny corner cases: once things get beyond the parser, I have no idea what kind of crazy stuff goes on. :) > > As an additional benefit, it would eliminate bug/partial features such as the one above and the ICE I reported earlier today. > > John > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From paul.stansifer at gmail.com Thu Apr 25 08:33:08 2013 From: paul.stansifer at gmail.com (Paul Stansifer) Date: Thu, 25 Apr 2013 11:33:08 -0400 Subject: [rust-dev] LL(1) problems In-Reply-To: <51789D4E.7070100@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> Message-ID: On Wed, Apr 24, 2013 at 11:04 PM, Graydon Hoare wrote: > My skill at grammar-factoring is ... minimal, but I thought you could > generally factor anything that's just a common-prefix situation like these > by introducing new rules that go one (common) token further and then decide > between the two remaining possible branches. Not to say it's pretty, but it > ... ought to work, I think? Please don't do this to the official parser! (I don't know if this is the plan or not.) The structure of the AST is (indirectly) exposed to the user by the macro system (and will be directly exposed by any procedural macro system), and we may miss out on providing the abstractions we want to. (For example: suppose that some statements and some expressions shared a common prefix that had to be merged in order to make the grammar LL(1); instead of having `stmt` and `expr` nonterminals in macros, we'd need to split them into `most_stmt` `most_expr` and `some_stmt_and_expr`.) Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: From clements at brinckerhoff.org Thu Apr 25 08:33:33 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 25 Apr 2013 08:33:33 -0700 Subject: [rust-dev] String Internment Library In-Reply-To: References: Message-ID: <6F7DF24C-A4C3-4D6D-9955-6B7C8552DE60@brinckerhoff.org> On Apr 25, 2013, at 1:39 AM, Abhijeet Gaiha wrote: > There is an issue on Servo #282, which talks about having a uniform string internment strategy across Rust, Spidermonkey and NetsurfCSS. > > Is there any existing string internment library in Rust? > If not, any plans to provide one? > > The Rust parser currently performs interning on the strings that represent identifiers. That code lives in libsyntax/util/interner.rs. I think it wouldn't be hard to reformulate it as a library, but it does expose some unpleasant elements of thread-local-state, at the moment. John Clements -------------- next part -------------- An HTML attachment was scrubbed... URL: From lucian.branescu at gmail.com Thu Apr 25 08:34:15 2013 From: lucian.branescu at gmail.com (Lucian Branescu) Date: Thu, 25 Apr 2013 16:34:15 +0100 Subject: [rust-dev] sub-grammar for range pattern constants? In-Reply-To: <9C0DF66F-B470-4F39-915A-18EFBC6C0D30@brinckerhoff.org> References: <9C0DF66F-B470-4F39-915A-18EFBC6C0D30@brinckerhoff.org> Message-ID: What about match bar { 0 .. (end - 1) = > ... } Shouldn't it include an expression? On 25 April 2013 16:30, John Clements wrote: > > On Apr 24, 2013, at 8:59 PM, Benjamin Striegel wrote: > > > would it be reasonable to restrict the left- and right-hand-sides to > simply be literals? > > Literals only? So then would the following be illegal? > > static END = 2; > ... > match bar { > 0 .. END => ... > } > > > Good! I knew there were forms I was missing. > > so, from the grammar standpoint, we now have > > RANGE_LIT = LIT_INT | LIT_FLOAT | ident > > Other important ones that I'm missing? > > John > > > > On Wed, Apr 24, 2013 at 6:36 PM, John Clements wrote: > >> Right now, the Rust parser accepts arbitrary expressions in certain >> pattern locations, most notably on the right-hand-side of a ".." range >> pattern. In talking to Patrick about this, though, he conjectured that it >> might be pretty easy to explicitly define the grammar of constants. In >> fact? for range patterns, would it be reasonable to restrict the left- and >> right-hand-sides to simply be literals? >> >> I was poking through the source code, and I found some reference to the >> possibility of these patterns being strings, which I found intriguing, but >> I couldn't make it work: >> >> fn f() -> int { 14 } >> >> fn main() { >> match ~"abc" { >> "abb" .. "zzz" => io::println(~"success"), >> _ => fail!() >> } >> } >> >> ? yields this error: >> >> jclements-09740:~/tryrust clements> rustc /tmp/foo.rs >> Running /usr/local/bin/rustc: >> /tmp/foo.rs:5:8: 5:13 error: mismatched types: expected `~str` but found >> `&'static str` (str storage differs: expected ~ but found &'static ) >> /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), >> ^~~~~ >> /tmp/foo.rs:5:17: 5:22 error: mismatched types: expected `~str` but >> found `&'static str` (str storage differs: expected ~ but found &'static ) >> /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), >> ^~~~~ >> /tmp/foo.rs:5:8: 5:25 error: non-numeric type used in range >> /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), >> ^~~~~~~~~~~~~~~~~ >> error: aborting due to 3 previous errors >> >> >> ? which seems to be suggesting that I use patterns like ~"abc", but those >> don't work either?. they signal a type error using "uniq", which I think? >> is a compiler bug. Erm. NOT IMPORTANT NOW. >> >> The real question is this: can we define a simple grammar for what's >> legal on the lhs and rhs of a "range" pattern? perhaps simply >> >> pat = ? >> | range_lit DOTDOT range_lit >> ... >> >> range_lit = LIT_INT | LIT_FLOAT >> >> ? >> >> Note that LIT_INT includes LIT_CHAR in this grammar. >> >> I haven't been able to find any legal Rust programs that would be made >> illegal by this restriction, but perhaps there are funny corner cases: once >> things get beyond the parser, I have no idea what kind of crazy stuff goes >> on. :) >> >> As an additional benefit, it would eliminate bug/partial features such as >> the one above and the ICE I reported earlier today. >> >> John >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > > _______________________________________________ > 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 clements at brinckerhoff.org Thu Apr 25 08:37:39 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 25 Apr 2013 08:37:39 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <517937DC.3090007@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> Message-ID: <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> On Apr 25, 2013, at 7:04 AM, Graydon Hoare wrote: > On 13-04-24 11:39 PM, Lindsey Kuper wrote: >> On Thu, Apr 25, 2013 at 1:25 AM, Patrick Walton wrote: >>> I have an untested grammar for Rust here, >>> with the token regexes not yet filled in: >>> >>> https://gist.github.com/anonymous/5457664 >>> >>> yapps2 reports that this grammar is LL(1). >>> >>> Note that the refactorings I made resulted in a grammar which isn't that >>> great for tooling or parsing in many places. In particular the contortions >>> needed to make `self_ty_and_maybenamed_args` result in an AST that combines >>> the self type and the type of the first argument together in bizarre ways. >>> >>> Since this is untested, I'm sure there are bugs, but it's probably a good >>> sign that I could at least refactor the grammar to what I think is LL(1). >> >> This is really cool, but I'm sort of confused about the apparent >> multiple ongoing efforts toward having a precise and machine-readable >> Rust grammar. Should we consider one of these the "real" grammar? > > This is a translation of the one John just finished (which was for antlr4, a very flexible "any LL(k)" grammar) into input for yapps2, which (as far as I know) has the distinguishing features of being-in-python and being-able-to-tell-us-about-LL(1)-conflicts. I believe it's still the "same" grammar as John did, just massaged to target a different tool. At some point I'd like a library that can consume/emit the 97 different equivalent dialects of EBNF used by different tools, so we can do this sort of exercise a little more readily. > > In any case that is (as far as I know) the only multiplicity of grammars floating about. The previous attempt here was one I made, targeting llnextgen, but it was abandoned mid-way-through (the results of which are currently on display in the reference manual). FWIW, I'm (mildly) concerned too. In particular, I'm disappointed to discover that in its present form (and using my present caveman-like invocation style), ANTLR parses source files so slowly that it's impossible to use directly as a validation tool; I would very much like to directly validate the grammar used for documentation purposes against the existing sources. I haven't yet asked for help from the ANTLR folks, because I don't yet feel like I've finished due diligence on RTFMing ANTLR, which I would prefer to do before dumping the problem in their lap. John From clements at brinckerhoff.org Thu Apr 25 08:40:38 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 25 Apr 2013 08:40:38 -0700 Subject: [rust-dev] sub-grammar for range pattern constants? In-Reply-To: References: <9C0DF66F-B470-4F39-915A-18EFBC6C0D30@brinckerhoff.org> Message-ID: <39FDCB3F-FC88-4ADC-AA78-6CB253824713@brinckerhoff.org> On Apr 25, 2013, at 8:34 AM, Lucian Branescu wrote: > What about > > match bar { > 0 .. (end - 1) = > ... > } > > Shouldn't it include an expression? Well, that's the question. Currently the grammar (and compiler) allow this. I'd like to define a grammar here that nails down what's allowed a little more tightly, rather than deferring entirely to (currently broken) constant evaluation. John > > > On 25 April 2013 16:30, John Clements wrote: > > On Apr 24, 2013, at 8:59 PM, Benjamin Striegel wrote: > >> > would it be reasonable to restrict the left- and right-hand-sides to simply be literals? >> >> Literals only? So then would the following be illegal? >> >> static END = 2; >> ... >> match bar { >> 0 .. END => ... >> } > > Good! I knew there were forms I was missing. > > so, from the grammar standpoint, we now have > > RANGE_LIT = LIT_INT | LIT_FLOAT | ident > > Other important ones that I'm missing? > > John > >> >> >> On Wed, Apr 24, 2013 at 6:36 PM, John Clements wrote: >> Right now, the Rust parser accepts arbitrary expressions in certain pattern locations, most notably on the right-hand-side of a ".." range pattern. In talking to Patrick about this, though, he conjectured that it might be pretty easy to explicitly define the grammar of constants. In fact? for range patterns, would it be reasonable to restrict the left- and right-hand-sides to simply be literals? >> >> I was poking through the source code, and I found some reference to the possibility of these patterns being strings, which I found intriguing, but I couldn't make it work: >> >> fn f() -> int { 14 } >> >> fn main() { >> match ~"abc" { >> "abb" .. "zzz" => io::println(~"success"), >> _ => fail!() >> } >> } >> >> ? yields this error: >> >> jclements-09740:~/tryrust clements> rustc /tmp/foo.rs >> Running /usr/local/bin/rustc: >> /tmp/foo.rs:5:8: 5:13 error: mismatched types: expected `~str` but found `&'static str` (str storage differs: expected ~ but found &'static ) >> /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), >> ^~~~~ >> /tmp/foo.rs:5:17: 5:22 error: mismatched types: expected `~str` but found `&'static str` (str storage differs: expected ~ but found &'static ) >> /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), >> ^~~~~ >> /tmp/foo.rs:5:8: 5:25 error: non-numeric type used in range >> /tmp/foo.rs:5 "abb" .. "zzz" => io::println(~"success"), >> ^~~~~~~~~~~~~~~~~ >> error: aborting due to 3 previous errors >> >> >> ? which seems to be suggesting that I use patterns like ~"abc", but those don't work either?. they signal a type error using "uniq", which I think? is a compiler bug. Erm. NOT IMPORTANT NOW. >> >> The real question is this: can we define a simple grammar for what's legal on the lhs and rhs of a "range" pattern? perhaps simply >> >> pat = ? >> | range_lit DOTDOT range_lit >> ... >> >> range_lit = LIT_INT | LIT_FLOAT >> >> ? >> >> Note that LIT_INT includes LIT_CHAR in this grammar. >> >> I haven't been able to find any legal Rust programs that would be made illegal by this restriction, but perhaps there are funny corner cases: once things get beyond the parser, I have no idea what kind of crazy stuff goes on. :) >> >> As an additional benefit, it would eliminate bug/partial features such as the one above and the ICE I reported earlier today. >> >> John >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev >> >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Thu Apr 25 08:44:45 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 25 Apr 2013 08:44:45 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> Message-ID: <51794F6D.7070102@mozilla.com> On 4/25/13 12:08 AM, Alex Bradbury wrote: > On 25 April 2013 06:25, Patrick Walton wrote: >> Note that the refactorings I made resulted in a grammar which isn't that >> great for tooling or parsing in many places. In particular the contortions >> needed to make `self_ty_and_maybenamed_args` result in an AST that combines >> the self type and the type of the first argument together in bizarre ways. > > So that implies disallowing self as an identifier might be useful. Are > there other changes of a similar nature that should be considered? In general I needed to disable keywords as identifiers to make it work. There were a few other minor changes: reducing patterns to literals as discussed in the other thread, and removing the ability to call methods on statements without parentheses. Patrick From graydon at mozilla.com Thu Apr 25 09:12:50 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 09:12:50 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> Message-ID: <51795602.8050809@mozilla.com> On 13-04-25 08:37 AM, John Clements wrote: > FWIW, I'm (mildly) concerned too. In particular, I'm disappointed to discover that in its present form (and using my present caveman-like invocation style), ANTLR parses source files so slowly that it's impossible to use directly as a validation tool; I would very much like to directly validate the grammar used for documentation purposes against the existing sources. I haven't yet asked for help from the ANTLR folks, because I don't yet feel like I've finished due diligence on RTFMing ANTLR, which I would prefer to do before dumping the problem in their lap. I'm sorry for the confusion; I don't think patrick's work here represents a divergence from yours so much as a continuation of it, in a direction that answers a question I've asked repeatedly while you were working on your grammar: "can we actually find an LL(1) factoring?". Also "can any other non-antlr tools consume this grammar?" Since you chose antlr4 rather than antlr3, the LL(1) question in particular was obscured under the "antlr4 will parse anything!" sales pitch[1]. Which is fine as far as getting the grammar roughed out and running -- I'm not criticizing that decision, it was yours to make, as was the choice of antlr in the first place. But it _did_ dodge a question I've been quite persistent about asking; one which I wanted to have an answer for before considering the grammar "done". Longer term, I would like whatever grammar we wind up denoting as canonical / documented / spec'ed to be as (re)target-able as possible. I've been relatively insistent on LL(1) since it is a nice intersection-of-inputs, practically guaranteed to parse under any framework we retarget it to. IOW I do _not_ want to force anyone working with rust grammars in the future to use antlr (3, 4, or anything else). That's too tool-specific[2]. A grammar that is trivally translatable between antlr4, antlr3, yapp2, llgen, llnextgen, coco, javacc, parsec, spirit, "some rust parser-generator", and so forth is my "eventual" goal here. -Graydon [1]: "We parse any grammar" is unfortunately common in parser-generator sales pitches these days, with a profusion GLR and LL(*) things. As a downstream consumer of parser-generator technology, let me point out that while I appreciate broad guarantees by tool-makers, I very much _dislike_ a tool that offers broad guarantees at the expense of being able to make promises about efficiency, grammar class and algorithmic complexity. IOW I actually prefer tools that can tell me what I need to leave out (or change) in my grammar in order to arrive at an efficient parser in a given complexity class. "Don't worry about it" is the wrong answer here. I want to worry about it. [2]: we also seem to be most-invested in python for in-tree "maintainer-mode" tools associated with rust development; it seems like a lot to ask to install a JDK in order to verify the grammar. If the grammar-check _can_ be done in a python module, I'm happy to shift over to using it. Unless antlr-ness is an important part of the grammar in some way I'm not perceiving; do you have a strong preference for keeping the java + antlr dependency? From wmatyjewicz at fastmail.fm Thu Apr 25 09:14:37 2013 From: wmatyjewicz at fastmail.fm (Wojciech Matyjewicz) Date: Thu, 25 Apr 2013 18:14:37 +0200 Subject: [rust-dev] LL(1) problems In-Reply-To: <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> Message-ID: <5179566D.30500@fastmail.fm> Hello, > FWIW, I'm (mildly) concerned too. In particular, I'm disappointed to discover that in its present form (and using my present caveman-like invocation style), ANTLR parses source files so slowly that it's impossible to use directly as a validation tool; I would very much like to directly validate the grammar used for documentation purposes against the existing sources. I haven't yet asked for help from the ANTLR folks, because I don't yet feel like I've finished due diligence on RTFMing ANTLR, which I would prefer to do before dumping the problem in their lap. I have not yet tried ANTLR v4, but I have used ANTLR v3 for a few grammars. From what I have read in "Why do we need ANTLR v4" [1], the new version focuses on ease-of-use rather than performance by accepting "any grammar we care to write" and "pushing all the grammar analysis effort to runtime". It seems to me that even the grammar option bounding the LL-lookahead (k=xxx) does not longer exist in v4. May it be the reason why the parser is so slow? Have you considered trying v3 instead of v4? It would allow to set the LL-lookahead even per rule basis. Wojtek [1] http://www.antlr.org/wiki/pages/viewpage.action?pageId=29130850 From pwalton at mozilla.com Thu Apr 25 09:16:21 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 25 Apr 2013 09:16:21 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <51795602.8050809@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> Message-ID: <517956D5.3020805@mozilla.com> On 4/25/13 9:12 AM, Graydon Hoare wrote: > Longer term, I would like whatever grammar we wind up denoting as > canonical / documented / spec'ed to be as (re)target-able as possible. > I've been relatively insistent on LL(1) since it is a nice > intersection-of-inputs, practically guaranteed to parse under any > framework we retarget it to. IOW I do _not_ want to force anyone working > with rust grammars in the future to use antlr (3, 4, or anything else). > That's too tool-specific[2]. A grammar that is trivally translatable > between antlr4, antlr3, yapp2, llgen, llnextgen, coco, javacc, parsec, > spirit, "some rust parser-generator", and so forth is my "eventual" goal > here. Are you concerned about the left-factoring needed to make the LL(1) grammar work? To me that's the biggest issue: the resulting grammar is kind of messy, and a tool that uses the LL(1) grammar is going to have a fun time reconstructing the first argument to method signatures (for example)... Patrick From graydon at mozilla.com Thu Apr 25 09:16:56 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 09:16:56 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> Message-ID: <517956F8.8030208@mozilla.com> On 13-04-25 08:33 AM, Paul Stansifer wrote: > (For example: suppose that some statements and some expressions shared a > common prefix that had to be merged in order to make the grammar LL(1); > instead of having `stmt` and `expr` nonterminals in macros, we'd need to > split them into `most_stmt` `most_expr` and `some_stmt_and_expr`.) That would of course be undesirable. It is not clear to me that the factorings patrick was struggling with had that property. I think both suffixes of 'unsafe' were inside $stmt (branching to sub-rules shared by $item and $expr) and both suffixes of '&' were branching to sub-rules of $ty and $pat. But I might be misreading. I agree that we want to keep relatively pithy named entrypoints in the grammar for the macro nonterminal parser to hook in at (even if they're artificial). Difficult balancing act, but I think it may be possible. Or at least it's not evident to me yet that it's not. -Graydon From pnkfelix at mozilla.com Thu Apr 25 09:23:47 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Thu, 25 Apr 2013 18:23:47 +0200 Subject: [rust-dev] LL(1) problems In-Reply-To: <51795602.8050809@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> Message-ID: <51795893.7020306@mozilla.com> On 25/04/2013 18:12, Graydon Hoare wrote: > I've been relatively insistent on LL(1) since it is a nice > intersection-of-inputs, practically guaranteed to parse under any > framework we retarget it to. I'm a fan of this choice too, if only because the simplest efficient parser-generators and/or parser-composition methodologies I know of take an LL(1) grammar as input. However, Paul's earlier plea on this thread ("Please don't do this [grammar factoring] to the official parser!") raised the following question in my mind: Are we allowing for the possibility of choosing the semi-middle ground of: "There *exists* an LL(1) grammar for Rust that is derivable from the non-LL(1)-but-official grammar for Rust." ? Or do we want to go all the way to ensuring that our own grammar that we e.g. use for defining the syntactic classes of the macro system etc is strictly LL(1) (or perhaps LL(k) for some small but known fixed k)? (I'd have to go review my compiler text books at home to review how much this would actually buy us.) If we've already discussed the latter, mea culpa. :) Cheers, -Felix On 25/04/2013 18:12, Graydon Hoare wrote: > On 13-04-25 08:37 AM, John Clements wrote: > >> FWIW, I'm (mildly) concerned too. In particular, I'm disappointed to >> discover that in its present form (and using my present caveman-like >> invocation style), ANTLR parses source files so slowly that it's >> impossible to use directly as a validation tool; I would very much >> like to directly validate the grammar used for documentation purposes >> against the existing sources. I haven't yet asked for help from the >> ANTLR folks, because I don't yet feel like I've finished due >> diligence on RTFMing ANTLR, which I would prefer to do before dumping >> the problem in their lap. > > I'm sorry for the confusion; I don't think patrick's work here > represents a divergence from yours so much as a continuation of it, in > a direction that answers a question I've asked repeatedly while you > were working on your grammar: "can we actually find an LL(1) > factoring?". Also "can any other non-antlr tools consume this grammar?" > > Since you chose antlr4 rather than antlr3, the LL(1) question in > particular was obscured under the "antlr4 will parse anything!" sales > pitch[1]. Which is fine as far as getting the grammar roughed out and > running -- I'm not criticizing that decision, it was yours to make, as > was the choice of antlr in the first place. But it _did_ dodge a > question I've been quite persistent about asking; one which I wanted > to have an answer for before considering the grammar "done". > > Longer term, I would like whatever grammar we wind up denoting as > canonical / documented / spec'ed to be as (re)target-able as possible. > I've been relatively insistent on LL(1) since it is a nice > intersection-of-inputs, practically guaranteed to parse under any > framework we retarget it to. IOW I do _not_ want to force anyone > working with rust grammars in the future to use antlr (3, 4, or > anything else). That's too tool-specific[2]. A grammar that is > trivally translatable between antlr4, antlr3, yapp2, llgen, llnextgen, > coco, javacc, parsec, spirit, "some rust parser-generator", and so > forth is my "eventual" goal here. > > -Graydon > > [1]: "We parse any grammar" is unfortunately common in > parser-generator sales pitches these days, with a profusion GLR and > LL(*) things. As a downstream consumer of parser-generator technology, > let me point out that while I appreciate broad guarantees by > tool-makers, I very much _dislike_ a tool that offers broad guarantees > at the expense of being able to make promises about efficiency, > grammar class and algorithmic complexity. IOW I actually prefer tools > that can tell me what I need to leave out (or change) in my grammar in > order to arrive at an efficient parser in a given complexity class. > "Don't worry about it" is the wrong answer here. I want to worry about > it. > > [2]: we also seem to be most-invested in python for in-tree > "maintainer-mode" tools associated with rust development; it seems > like a lot to ask to install a JDK in order to verify the grammar. If > the grammar-check _can_ be done in a python module, I'm happy to shift > over to using it. Unless antlr-ness is an important part of the > grammar in some way I'm not perceiving; do you have a strong > preference for keeping the java + antlr dependency? > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.org From graydon at mozilla.com Thu Apr 25 09:25:30 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 09:25:30 -0700 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <1529933.oVftDTLAFD@l10036> References: <20130423144812.217310@gmx.com> <1486845.Eo0P33FOQu@l10036> <1529933.oVftDTLAFD@l10036> Message-ID: <517958FA.7080605@mozilla.com> On 13-04-25 07:52 AM, Diggory Hardy wrote: >> My opinion (that nobody will follow, but I still give it) is that integers >> should not have the "/" operator at all. This was one of the bad choices of >> C (or maybe of a previous language). > > Hmm, maybe, though I can imagine plenty of people being surprised at that. > > What really gets me though is that % is commonly called the "mod" operator and > yet has nothing to do with modular arithmatic (I actually wrote a blog post > about it a few months back: [1]). If it were my choice I'd either make "x % y" > do real modular arithmatic (possibly even throwing if y is not positive) or > have no % operator (just mod and rem keywords). While it's true that people often pronounce % as "mod", the fact is most of the languages in the lineage we're looking at treat it as "rem". http://en.wikipedia.org/wiki/Modulo_operation 50 languages in that list expose 'remainder' and 19 of them map it to '%'. As well, as a "systems language", it _is_ salient that the instructions on the CPUs we're targeting and the code generator IR for said machines (LLVM) expose a remainder operation, not a modulo one. Of the 35 languages that expose _anything_ that does "proper mod", only interpreted/script languages (TCL, Perl, Python, Ruby, Lua, Rexx, Pike and Dart) call it %. That's not our family. I'm sorry; if we're arguing over "what the % symbol means", it means remainder in "our" language family (the one including C, C++, C#, D, Go, F#, Java, Scala). (more gruesome comparisons available here: http://rigaux.org/language-study/syntax-across-languages/Mthmt.html#MthmtcDBQAM ) There are other questions to answer in this thread. We had a complex set of conversations yesterday on IRC concerning exposure of multiple named methods for the "other variants" -- ceiling, floor and truncating division, in particular. We may need to expose all 3, and it might be the case that calling any of them 'quot' is just misleading; it's not clear to me yet whether there's a consistent method _name_ to assign '/' to (floating point divide seems to do the opposite of integer divide on chips that have both). But I don't think it's wise to map % to 'mod' if we're exposing both 'mod' and 'rem'. That's a separate issue and one with (I think) a simpler answer for us. -Graydon From clements at brinckerhoff.org Thu Apr 25 09:26:41 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 25 Apr 2013 09:26:41 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <517956F8.8030208@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <517956F8.8030208@mozilla.com> Message-ID: On Apr 25, 2013, at 9:16 AM, Graydon Hoare wrote: > On 13-04-25 08:33 AM, Paul Stansifer wrote: > >> (For example: suppose that some statements and some expressions shared a >> common prefix that had to be merged in order to make the grammar LL(1); >> instead of having `stmt` and `expr` nonterminals in macros, we'd need to >> split them into `most_stmt` `most_expr` and `some_stmt_and_expr`.) > > That would of course be undesirable. It is not clear to me that the factorings patrick was struggling with had that property. I think both suffixes of 'unsafe' were inside $stmt (branching to sub-rules shared by $item and $expr) and both suffixes of '&' were branching to sub-rules of $ty and $pat. But I might be misreading. I agree that we want to keep relatively pithy named entrypoints in the grammar for the macro nonterminal parser to hook in at (even if they're artificial). Difficult balancing act, but I think it may be possible. Or at least it's not evident to me yet that it's not. FWIW, I strongly suspect that the LL(1)-refactoring of the grammar will not be as nice to use for documentation purposes as a non-LL(1) one. In my eyes, the principal virtue of ANTLR 4 is the ability to specify a grammar that is easily readable for humans, and can easily be split up into documentation. To take a really simple example, consider IMPL type LBRACE ? RBRACE and IMPL trait FOR type LBRACE ? RBRACE I think we'd probably like to preserve the ability to present these as separate and complete rules in separate parts of the manual. This is much more true for parts of the expression grammar, but I don't want to get bogged down in details. Naturally, the proof of the pudding is in the eating. Apologies if I've misunderstood you. John From graydon at mozilla.com Thu Apr 25 09:31:13 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 09:31:13 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <51795893.7020306@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> Message-ID: <51795A51.1010705@mozilla.com> On 13-04-25 09:23 AM, Felix S. Klock II wrote: > Are we allowing for the possibility of choosing the semi-middle ground > of: "There *exists* an LL(1) grammar for Rust that is derivable from the > non-LL(1)-but-official grammar for Rust." ? Or do we want to go all the > way to ensuring that our own grammar that we e.g. use for defining the > syntactic classes of the macro system etc is strictly LL(1) (or perhaps > LL(k) for some small but known fixed k)? We are (or at least, I am) allowing for this (and related) possibilities. This is an aspirational conversation. I can't rule out anything really; if we found that there were grammar bits that were essential to our expressiveness and put us in "nothing short of GLR", that would be ... sad, but not ship-sinking. Until this week I had no idea where we were, grammar-wise; it might have required a turing complete recognizer for all I knew. Hand written parsers often contain gruesome hacks. Ours certainly has in the past! I'm just trying to find out how good we can get things (without major surgery). LL(1) is icing on the cake. But who doesn't like icing on their cake? -Graydon From lindsey at composition.al Thu Apr 25 09:47:19 2013 From: lindsey at composition.al (Lindsey Kuper) Date: Thu, 25 Apr 2013 12:47:19 -0400 Subject: [rust-dev] LL(1) problems In-Reply-To: <517937DC.3090007@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> Message-ID: On Thu, Apr 25, 2013 at 10:04 AM, Graydon Hoare wrote: > On 13-04-24 11:39 PM, Lindsey Kuper wrote: >> This is really cool, but I'm sort of confused about the apparent >> multiple ongoing efforts toward having a precise and machine-readable >> Rust grammar. Should we consider one of these the "real" grammar? > > > This is a translation of the one John just finished (which was for antlr4, a > very flexible "any LL(k)" grammar) into input for yapps2, which (as far as I > know) has the distinguishing features of being-in-python and > being-able-to-tell-us-about-LL(1)-conflicts. I believe it's still the "same" > grammar as John did, just massaged to target a different tool. At some point > I'd like a library that can consume/emit the 97 different equivalent > dialects of EBNF used by different tools, so we can do this sort of exercise > a little more readily. > > In any case that is (as far as I know) the only multiplicity of grammars > floating about. The previous attempt here was one I made, targeting > llnextgen, but it was abandoned mid-way-through (the results of which are > currently on display in the reference manual). > > Are there others? OK, thanks for explaining! (By "multiple" I just meant "two". I'm not aware of others.) Lindsey From pwalton at mozilla.com Thu Apr 25 09:53:59 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 25 Apr 2013 09:53:59 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: <51795893.7020306@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> Message-ID: <51795FA7.9080300@mozilla.com> On 4/25/13 9:23 AM, Felix S. Klock II wrote: > On 25/04/2013 18:12, Graydon Hoare wrote: >> I've been relatively insistent on LL(1) since it is a nice >> intersection-of-inputs, practically guaranteed to parse under any >> framework we retarget it to. > I'm a fan of this choice too, if only because the simplest efficient > parser-generators and/or parser-composition methodologies I know of take > an LL(1) grammar as input. > > However, Paul's earlier plea on this thread ("Please don't do this > [grammar factoring] to the official parser!") raised the following > question in my mind: > > Are we allowing for the possibility of choosing the semi-middle ground > of: "There *exists* an LL(1) grammar for Rust that is derivable from the > non-LL(1)-but-official grammar for Rust." ? Or do we want to go all the > way to ensuring that our own grammar that we e.g. use for defining the > syntactic classes of the macro system etc is strictly LL(1) (or perhaps > LL(k) for some small but known fixed k)? I'm not sure we can do the latter. There are too many issues relating to `unsafe`, `loop`, the `self` argument, etc. to make the LL(1) derivable from the human-readable grammar in an automated fashion, in my eyes. At least, I'm pretty sure that if we did want to go down that route, we'd probably be doing months of parser research (and I do mean *research*, as far as I know). Patrick From matthieu.monrocq at gmail.com Thu Apr 25 10:12:16 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Thu, 25 Apr 2013 19:12:16 +0200 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <517958FA.7080605@mozilla.com> References: <20130423144812.217310@gmx.com> <1486845.Eo0P33FOQu@l10036> <1529933.oVftDTLAFD@l10036> <517958FA.7080605@mozilla.com> Message-ID: I was thinking about the mapping of / and % and indeed maybe the simplest option is not to map them. Of course, having an infix syntax would make things easier: 5 % 3 vs 5 rem 3 vs 5.rem(3), in increasing order of typed keys (and visual noise for the latter ?). On the other hand, if there is no mapping I can imagine people keeping asking whether to use mod or rem... -- Matthieu On Thu, Apr 25, 2013 at 6:25 PM, Graydon Hoare wrote: > On 13-04-25 07:52 AM, Diggory Hardy wrote: > >> My opinion (that nobody will follow, but I still give it) is that integers >>> should not have the "/" operator at all. This was one of the bad choices >>> of >>> C (or maybe of a previous language). >>> >> >> Hmm, maybe, though I can imagine plenty of people being surprised at that. >> >> What really gets me though is that % is commonly called the "mod" >> operator and >> yet has nothing to do with modular arithmatic (I actually wrote a blog >> post >> about it a few months back: [1]). If it were my choice I'd either make "x >> % y" >> do real modular arithmatic (possibly even throwing if y is not positive) >> or >> have no % operator (just mod and rem keywords). >> > > While it's true that people often pronounce % as "mod", the fact is most > of the languages in the lineage we're looking at treat it as "rem". > > http://en.wikipedia.org/wiki/**Modulo_operation > > 50 languages in that list expose 'remainder' and 19 of them map it to '%'. > As well, as a "systems language", it _is_ salient that the instructions on > the CPUs we're targeting and the code generator IR for said machines (LLVM) > expose a remainder operation, not a modulo one. Of the 35 languages that > expose _anything_ that does "proper mod", only interpreted/script languages > (TCL, Perl, Python, Ruby, Lua, Rexx, Pike and Dart) call it %. That's not > our family. I'm sorry; if we're arguing over "what the % symbol means", it > means remainder in "our" language family (the one including C, C++, C#, D, > Go, F#, Java, Scala). > > (more gruesome comparisons available here: http://rigaux.org/language-** > study/syntax-across-languages/**Mthmt.html#MthmtcDBQAM) > > There are other questions to answer in this thread. We had a complex set > of conversations yesterday on IRC concerning exposure of multiple named > methods for the "other variants" -- ceiling, floor and truncating division, > in particular. We may need to expose all 3, and it might be the case that > calling any of them 'quot' is just misleading; it's not clear to me yet > whether there's a consistent method _name_ to assign '/' to (floating point > divide seems to do the opposite of integer divide on chips that have both). > > But I don't think it's wise to map % to 'mod' if we're exposing both 'mod' > and 'rem'. That's a separate issue and one with (I think) a simpler answer > for us. > > -Graydon > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthieu.monrocq at gmail.com Thu Apr 25 10:20:59 2013 From: matthieu.monrocq at gmail.com (Matthieu Monrocq) Date: Thu, 25 Apr 2013 19:20:59 +0200 Subject: [rust-dev] LL(1) problems In-Reply-To: <51795FA7.9080300@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> <51795FA7.9080300@mozilla.com> Message-ID: On Thu, Apr 25, 2013 at 6:53 PM, Patrick Walton wrote: > On 4/25/13 9:23 AM, Felix S. Klock II wrote: > >> On 25/04/2013 18:12, Graydon Hoare wrote: >> >>> I've been relatively insistent on LL(1) since it is a nice >>> intersection-of-inputs, practically guaranteed to parse under any >>> framework we retarget it to. >>> >> I'm a fan of this choice too, if only because the simplest efficient >> parser-generators and/or parser-composition methodologies I know of take >> an LL(1) grammar as input. >> >> However, Paul's earlier plea on this thread ("Please don't do this >> [grammar factoring] to the official parser!") raised the following >> question in my mind: >> >> Are we allowing for the possibility of choosing the semi-middle ground >> of: "There *exists* an LL(1) grammar for Rust that is derivable from the >> non-LL(1)-but-official grammar for Rust." ? Or do we want to go all the >> way to ensuring that our own grammar that we e.g. use for defining the >> syntactic classes of the macro system etc is strictly LL(1) (or perhaps >> LL(k) for some small but known fixed k)? >> > > I'm not sure we can do the latter. There are too many issues relating to > `unsafe`, `loop`, the `self` argument, etc. to make the LL(1) derivable > from the human-readable grammar in an automated fashion, in my eyes. At > least, I'm pretty sure that if we did want to go down that route, we'd > probably be doing months of parser research (and I do mean *research*, as > far as I know). > > Patrick > > > On the other hand, should you content yourself with LL(2), and actually have a tool like yapp2 guarantee that it is indeed LL(2) (and does not degenerate), would it not be sufficient ? (in case LL(1) really is gruesome compared to LL(2)) -- Matthieu > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Apr 25 11:41:10 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 11:41:10 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517920A8.5020509@cantrip.org> References: <51785EE8.1000206@mozilla.com> <517920A8.5020509@cantrip.org> Message-ID: <517978C6.1030800@mozilla.com> On 04/25/2013 05:25 AM, Nathan Myers wrote: > On 04/24/2013 03:38 PM, Brian Anderson wrote: >> ## String encoding >> >> I have not yet put much thought about how to deal with string >> encoding and decoding. The existing `io` module simply has Reader and >> Writer extension traits that add a number of methods like `read_str`, >> etc. I think this is the wrong approach because it doesn't allow any >> extra state for the encoding/decoding, e.g. there's no way to >> customize the way newline is handled. Probably we'll need some >> decorator types like `StringReader`, etc. > > An opportunity not to be missed... since I/O objects are often > propagated through a system from top to bottom, they are an > excellent place to attach state that intermediate levels does not > need to know about. Such state traditionally includes locale-ish > formatting services, but the possibilities are much broader: time > zone, measurement-unit system, debug level, encryption/ > authentication apparatus, undo/redo log, cumulative stats, > rate and resource limits -- the list goes on. Some of these > can be standardized, and many have been, but users need to > be able to add their own on an equal basis with standard > services. > >> ## Close >> >> Do we need to have `close` methods or do we depend solely on RAII for >> closing streams? > > close() can fail and report an error code. When you are not > interested in that, the destructor can do the job and throw > away the result, but often enough you need to know. Usually > there's not much to do about it beyond reporting the event, > but that report can be essential: did the data sent reach its > destination? If not, why not? Thanks, that's an important consideration, so we do need 'close'. From clements at brinckerhoff.org Thu Apr 25 11:46:15 2013 From: clements at brinckerhoff.org (John Clements) Date: Thu, 25 Apr 2013 11:46:15 -0700 Subject: [rust-dev] stmt inside expr grammar question Message-ID: <12D772AE-B6CE-447D-8368-864B1172F753@brinckerhoff.org> Huh? Looks like my first message didn't go through. Perhaps I'm being moderated, and I just didn't know it? Apologies if this appears twice. Per our meeting today, I'm sending this out to see whether we want to make a change. Currently, our grammar parses if (true) {3} else {4} + 10 As a statement followed by a (non-parseable) expression. This is to prevent things like if (true) {3} else {4} |a| {foo()} ? from being parsed as two uses of the "or" operator, for instance. The basic restriction is that when something that could be a statement occurs in a position where it could be a statement, then it should be parsed as a statement and not as an expression. Keep in mind that you can always force a statement-y thing to be allowable in any position by using parens. So, for instance, (if (true) {3} else {4}) + 10 is a perfectly legitimate expression. This restriction is the cause of no small ugliness in the grammar. Simplifying it might concievably avoid certain errors. However, it would probably make some people unhappy. One way to fix it would be simply to lift the restriction entirely. In this case, if (true) {3} else {4} |a| {foo()} ? would be parsed as ((if (true) {3} else {4} |a) | {foo()}) ? which some people might be surprised by. Another solution would be to *always* require semicolons, even after blocks. This would probably make lots of people immediately unhappy. Another solution, the "shift the burden to those kooky functional folks", would be to say that using a statement as an expression *only* works when it's enclosed in parens. This would simplify things a lot. This would not change the behavior of the first example at all, but it would for instance rule out 14 + if (true) {3} else {4} ? requiring instead 14 + (if (true) {3} else {4}) But indeed, I think I would probably opt for the latter one as more readable anyway. Another example that would have to change would be changing something like for foo.each |a| {f(a)}.bar() into (for foo.each |a| {f(a)}).bar() But honestly, that one makes me happier as well. The more I think about this alternative, the more I like it. Either way, this ship's gangplank is up and it's straining at its hawsers. We should probably make a decision on this now-ish. John From graydon at mozilla.com Thu Apr 25 12:09:11 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 12:09:11 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> Message-ID: <51797F57.1010903@mozilla.com> On 25/04/2013 7:18 AM, G?bor Lehel wrote: > I'm an outsider, so apologies if I'm off the right track. But this > sounds wrong to me. Isn't the point of condition handlers to /handle the > condition/? Meaning resolve the problem, so that processing can > continue? Here as far as I can tell, they're only being used to say > "fail differently", which then leads to failing again the next time you > try to do something. Opening a file was actually one of the examples > used to illustrate the condition system way back when[1]. Yeah. I read this design a few times and felt uneasy about the combination of files, options and conditions. I couldn't put my finger on exactly how to arrange it, but it felt off. I thought about it some more and I think I can now put my concern plainly. When a condition is handled -- not-in-failure -- there are _many_ possible ways the user might want to handle it. All these are plausible: - This error is ok but subsequent errors on the same filehandle should cause retriggering of the condition (so we can count errors and fail after too many). - This error is ok and all subsequent errors on the same filehandle should be absorbed silently; turn it into /dev/null. - This error should cause a state-change to the existing file, such as closing it, truncating it, creating it, reopening it, or similar. If it's a socket, maybe we want to try reestablishing it. Maybe redirect it to an in-memory pseudo-file. Because of this variety of possible solutions, the approach in the current design is inadequate: the Some(existing_file) and None strategies are only two of the possible strategies, and both are statically dispatched due to the implementation of file methods on Option. The condition handler isn't really involved in picking the strategy, only choosing between a fixed menu. It should be able to _provide_ a strategy, which means providing an implementation of File (or more likely: ~Stream). In other words (very much thinking-out-loud here) I suspect that any concrete stream type in our IO library that has serious error modes like this ought to be able to "replace itself" after a failed operation with a ~Stream that points to some other implementation. So it should be something like: enum FileStream { FileDescriptor(libc::fd_t), FileSimulation(~Stream) } and so forth on other types. Then your file conditions would look like: condition! { no_such_file : Path -> FileStream; } and condition! { write_error : (libc::fd_t, libc::errno_t) -> FileStream; } and we'd assume that any handler for that condition will either provide you a "real" FileDescriptor or else a "fake" simulation of a file that directs to some other Stream type. And the 'write' operation would look like: fn write(&mut self, bytes: &[u8]) { match self { FileSimulation(s) => s.write(bytes), FileDescriptor(fd) => { let e = libc::write(bytes.to_ptr, bytes.len()); if e != 0 { *self = no_such_file.cond.raise(fd, e); } } } } Apologies for the sketchines; I realize real code looks gnarlier than this, just trying to convey a possible strategy. I say all this, again, because the alternatives (option or a single "bad" flag, as in many IO libraries) seems to provide very few recovery options to a user. (Also aware that getting the abstraction layer right might be challenging; maybe FileStream is the wrong place to put in this redirection, and it should be one layer further up, or down..) It's not clear to me if MemStream or other such things have quite as wide a repertoire of conditions. I think if there are no operations that raise conditions of this sort, then there'd be no reason to use such an enum. -Graydon From banderson at mozilla.com Thu Apr 25 12:11:16 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 12:11:16 -0700 Subject: [rust-dev] String Internment Library In-Reply-To: References: Message-ID: <51797FD4.8040209@mozilla.com> On 04/25/2013 01:39 AM, Abhijeet Gaiha wrote: > > There is an issue on Servo #282, which talks about having a uniform > string internment strategy across Rust, Spidermonkey and NetsurfCSS. > > Is there any existing string internment library in Rust? > If not, any plans to provide one? > This is not and there aren't any plans. Servo's requirements are complex enough that it may not be worth generalizing our string internment solution (though if we do come up with a general internment library that's great). From thadguidry at gmail.com Thu Apr 25 12:12:09 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 25 Apr 2013 14:12:09 -0500 Subject: [rust-dev] stmt inside expr grammar question In-Reply-To: <12D772AE-B6CE-447D-8368-864B1172F753@brinckerhoff.org> References: <12D772AE-B6CE-447D-8368-864B1172F753@brinckerhoff.org> Message-ID: John, Functional ways would be an approach I would admire and +1 for. I like the alternative also. In OpenRefine with the GREL expression language, we did something similar. Parenthesis rule. Go Lisp. err, wait, Go Go. Oops, wrong business... Go Rust ! On Thu, Apr 25, 2013 at 1:46 PM, John Clements wrote: > Huh? Looks like my first message didn't go through. Perhaps I'm being > moderated, and I just didn't know it? > > Apologies if this appears twice. > > Per our meeting today, I'm sending this out to see whether we want to make > a change. > > Currently, our grammar parses > > if (true) {3} else {4} + 10 > > As a statement followed by a (non-parseable) expression. This is to > prevent things like > > if (true) {3} else {4} > |a| {foo()} > > ? from being parsed as two uses of the "or" operator, for instance. The > basic restriction is that when something that could be a statement occurs > in a position where it could be a statement, then it should be parsed as a > statement and not as an expression. > > Keep in mind that you can always force a statement-y thing to be allowable > in any position by using parens. So, for instance, > > (if (true) {3} else {4}) + 10 > > is a perfectly legitimate expression. > > This restriction is the cause of no small ugliness in the grammar. > > Simplifying it might concievably avoid certain errors. However, it would > probably make some people unhappy. > > One way to fix it would be simply to lift the restriction entirely. In > this case, > > if (true) {3} else {4} > |a| {foo()} > > ? would be parsed as > > ((if (true) {3} else {4} > |a) > | {foo()}) > > ? which some people might be surprised by. > > Another solution would be to *always* require semicolons, even after > blocks. This would probably make lots of people immediately unhappy. > > Another solution, the "shift the burden to those kooky functional folks", > would be to say that using a statement as an expression *only* works when > it's enclosed in parens. This would simplify things a lot. This would not > change the behavior of the first example at all, but it would for instance > rule out > 14 + if (true) {3} else {4} > ? requiring instead > 14 + (if (true) {3} else {4}) > But indeed, I think I would probably opt for the latter one as more > readable anyway. > Another example that would have to change would be changing something like > for foo.each |a| {f(a)}.bar() > into > (for foo.each |a| {f(a)}).bar() > But honestly, that one makes me happier as well. > > The more I think about this alternative, the more I like it. > > Either way, this ship's gangplank is up and it's straining at its hawsers. > We should probably make a decision on this now-ish. > > John > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Apr 25 12:22:36 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 12:22:36 -0700 Subject: [rust-dev] stmt inside expr grammar question In-Reply-To: <12D772AE-B6CE-447D-8368-864B1172F753@brinckerhoff.org> References: <12D772AE-B6CE-447D-8368-864B1172F753@brinckerhoff.org> Message-ID: <5179827C.7000008@mozilla.com> On 04/25/2013 11:46 AM, John Clements wrote: > Huh? Looks like my first message didn't go through. Perhaps I'm being moderated, and I just didn't know it? > > Apologies if this appears twice. > > Per our meeting today, I'm sending this out to see whether we want to make a change. > > Currently, our grammar parses > > if (true) {3} else {4} + 10 > > As a statement followed by a (non-parseable) expression. This is to prevent things like > > if (true) {3} else {4} > |a| {foo()} > > ? from being parsed as two uses of the "or" operator, for instance. The basic restriction is that when something that could be a statement occurs in a position where it could be a statement, then it should be parsed as a statement and not as an expression. > > Keep in mind that you can always force a statement-y thing to be allowable in any position by using parens. So, for instance, > > (if (true) {3} else {4}) + 10 > > is a perfectly legitimate expression. > > This restriction is the cause of no small ugliness in the grammar. > > Simplifying it might concievably avoid certain errors. However, it would probably make some people unhappy. > > One way to fix it would be simply to lift the restriction entirely. In this case, > > if (true) {3} else {4} > |a| {foo()} > > ? would be parsed as > > ((if (true) {3} else {4} > |a) > | {foo()}) > > ? which some people might be surprised by. > > Another solution would be to *always* require semicolons, even after blocks. This would probably make lots of people immediately unhappy. > > Another solution, the "shift the burden to those kooky functional folks", would be to say that using a statement as an expression *only* works when it's enclosed in parens. This would simplify things a lot. This would not change the behavior of the first example at all, but it would for instance rule out > 14 + if (true) {3} else {4} > ? requiring instead > 14 + (if (true) {3} else {4}) > But indeed, I think I would probably opt for the latter one as more readable anyway. > Another example that would have to change would be changing something like > for foo.each |a| {f(a)}.bar() > into > (for foo.each |a| {f(a)}).bar() > But honestly, that one makes me happier as well. > > The more I think about this alternative, the more I like it. > > Either way, this ship's gangplank is up and it's straining at its hawsers. We should probably make a decision on this now-ish. > How does this rule impact expressions that occur in the 'tail' expression of a block? fn foo() -> bool { if true { false } else { true } } This is a very common place where block expressions are used. Will the parser still know this is an expression? From banderson at mozilla.com Thu Apr 25 12:32:44 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 12:32:44 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> <517920A8.5020509@cantrip.org> Message-ID: <517984DC.4000008@mozilla.com> On 04/25/2013 07:12 AM, Daniel Micay wrote: > On Thu, Apr 25, 2013 at 8:25 AM, Nathan Myers wrote: >> On 04/24/2013 03:38 PM, Brian Anderson wrote: >>> ## String encoding >>> >>> I have not yet put much thought about how to deal with string encoding and >>> decoding. The existing `io` module simply has Reader and Writer extension >>> traits that add a number of methods like `read_str`, etc. I think this is >>> the wrong approach because it doesn't allow any extra state for the >>> encoding/decoding, e.g. there's no way to customize the way newline is >>> handled. Probably we'll need some decorator types like `StringReader`, etc. >> >> An opportunity not to be missed... since I/O objects are often >> propagated through a system from top to bottom, they are an >> excellent place to attach state that intermediate levels does not >> need to know about. Such state traditionally includes locale-ish >> formatting services, but the possibilities are much broader: time >> zone, measurement-unit system, debug level, encryption/ >> authentication apparatus, undo/redo log, cumulative stats, >> rate and resource limits -- the list goes on. Some of these >> can be standardized, and many have been, but users need to >> be able to add their own on an equal basis with standard >> services. >> >>> ## Close >>> >>> Do we need to have `close` methods or do we depend solely on RAII for >>> closing streams? >> >> close() can fail and report an error code. When you are not >> interested in that, the destructor can do the job and throw >> away the result, but often enough you need to know. Usually >> there's not much to do about it beyond reporting the event, >> but that report can be essential: did the data sent reach its >> destination? If not, why not? >> >> Nathan Myers >> ncm at cantrip.org >> _______________________________________________ >> Rust-dev mailing list >> Rust-dev at mozilla.org >> https://mail.mozilla.org/listinfo/rust-dev > You can get the errors that close would have thrown by calling flush. Are the only possible `close` errors related to flushing buffers? > > Closing pretty much has to be in a destructor unless you want to write > finally blocks everywhere, which aren't as pretty in Rust as they are > in languages which actually have that as a first-class thing. It > becomes non-trivial when the lifetime isn't just based on a single > scope, and can live for different periods of time. I'm assuming that, if we have `close`, then we would still make the destructors close the stream. The point about catch though reminds me that, given the error handling strategy we're using to catch a close error you would still need to write: do io_error::cond.trap(|err| { printfln!(err); }).in { file.close(); } Which could as easily be done by moving the file: do io_error::cond.trap(|err| { printfln!(err); }).in { let _ = file; } Both require trapping something. From banderson at mozilla.com Thu Apr 25 13:00:36 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 13:00:36 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> Message-ID: <51798B64.9020008@mozilla.com> On 04/25/2013 07:18 AM, G?bor Lehel wrote: > You write: > > > So what actually happens if `new` encounters an error? To understand > > that it's important to know that what `new` returns is not a `File` > > but an `Option`. If the file does not open, and the condition > > is handled, then `new` will simply return `None`. Because there is an > > implementation of `Writer` (the trait required ultimately required for > > types to implement `write_line`) there is no need to inspect or unwrap > > the `Option` and we simply call `write_line` on it. If `new` > > returned a `None` then the followup call to `write_line` will also > > raise an error. > > I'm an outsider, so apologies if I'm off the right track. But this > sounds wrong to me. Isn't the point of condition handlers to /handle > the condition/? Meaning resolve the problem, so that processing can > continue? Here as far as I can tell, they're only being used to say > "fail differently", which then leads to failing again the next time > you try to do something. Opening a file was actually one of the > examples used to illustrate the condition system way back when[1]. > That's right. This isn't using conditions the way they are typically described. > > * XXX: How should we use condition handlers that return values? > > IMHO the right way would be to provide more fine-grained information > about the error (perhaps raising different conditions depending on the > error, instead of always the same condition and a giant enum > describing it), and use the return value of the condition to set > policy wrt how to handle it and/or to provide a substitute (as in the > example). If there's nothing reasonable that could be done, don't > raise a condition, fail unconditionally. That is how you would expect a condition system to work, I agree. It has been argued to me that failing unconditionally is not acceptable because the recovery strategy requires creating new tasks, which is much more expensive than unwinding a few frames of stack. > > Whether to respond to failure by failing the task or by indicating it > in the return value seems like it would be better handled by having > separate functions for each. In the case where you expect success, the > result shouldn't be an Option. If the result is an Option, it > shouldn't fail the task (whether or not a condition handler is > present). So for example: > > open(path: &P, mode: FileMode, access: FileAccess) -> > FileStream > > try_open(path: &P, mode: FileMode, access: FileAccess) -> > Option > > If the expect-success version of a function returns (), the try_ > version would return bool rather than Option<()> (which are isomorphic). > > Upon encountering an error, open() would raise a condition, and then > continue if possible, otherwise fail!(). > > I'm not sure whether try_open() would raise a condition or not. The > way conditions were described, if they aren't handled, the task fails. > try_open() definitely shouldn't fail. Would it be reasonable to raise > a condition and instead of failing, return None if it's not handled? > If not, then try_open() shouldn't raise any conditions, and should > just return None. > > The obvious drawback is twice as many functions, but it feels > preferable to forcing two different behaviours onto the same function. > The fast (expect-success) path would be just as clean as before, if > not cleaner. > > [1] https://mail.mozilla.org/pipermail/rust-dev/2012-October/002545.html With this strategy could we make the `try_` return values return `Result` (not using conditions at all)? Then nil-returning functions would need to be `Option`. Having two ways to perform every I/O operation will 'infect' all code that uses I/O indirectly. For instance, we have a `ReaderUtil` trait that defines maybe two dozen methods. Do those all get duplicated? That seems pretty disastrous to me. You mentioned disliking the giant IoError enum, and I agree, but I don't know a better way to represent it. We don't have subclassing to create an Exception type hierarchy. Do you have any suggestions? -Brian From ben.striegel at gmail.com Thu Apr 25 13:40:51 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Thu, 25 Apr 2013 16:40:51 -0400 Subject: [rust-dev] stmt inside expr grammar question In-Reply-To: <5179827C.7000008@mozilla.com> References: <12D772AE-B6CE-447D-8368-864B1172F753@brinckerhoff.org> <5179827C.7000008@mozilla.com> Message-ID: FWIW, I both enjoy and have written things along the lines of `14 + if (true) {3} else {4}` (a.k.a. Rust's answer to C's ternary operator) and `for foo.each |a| {f(a)}.bar()` (method chaining FTW). I would be sad to be forced to wrap either of those in parens. But more pertinently I worry that such a rule would make it impossible to remember when the parens are required and when they are not. I've never been bitten by the rare case of "self-executing closure following a block" (it would have to be self-executing, otherwise the closure is a useless no-op). But I can definitely see being bitten by this and feeling bitter about it. On Thu, Apr 25, 2013 at 3:22 PM, Brian Anderson wrote: > On 04/25/2013 11:46 AM, John Clements wrote: > >> Huh? Looks like my first message didn't go through. Perhaps I'm being >> moderated, and I just didn't know it? >> >> Apologies if this appears twice. >> >> Per our meeting today, I'm sending this out to see whether we want to >> make a change. >> >> Currently, our grammar parses >> >> if (true) {3} else {4} + 10 >> >> As a statement followed by a (non-parseable) expression. This is to >> prevent things like >> >> if (true) {3} else {4} >> |a| {foo()} >> >> ? from being parsed as two uses of the "or" operator, for instance. The >> basic restriction is that when something that could be a statement occurs >> in a position where it could be a statement, then it should be parsed as a >> statement and not as an expression. >> >> Keep in mind that you can always force a statement-y thing to be >> allowable in any position by using parens. So, for instance, >> >> (if (true) {3} else {4}) + 10 >> >> is a perfectly legitimate expression. >> >> This restriction is the cause of no small ugliness in the grammar. >> >> Simplifying it might concievably avoid certain errors. However, it would >> probably make some people unhappy. >> >> One way to fix it would be simply to lift the restriction entirely. In >> this case, >> >> if (true) {3} else {4} >> |a| {foo()} >> >> ? would be parsed as >> >> ((if (true) {3} else {4} >> |a) >> | {foo()}) >> >> ? which some people might be surprised by. >> >> Another solution would be to *always* require semicolons, even after >> blocks. This would probably make lots of people immediately unhappy. >> >> Another solution, the "shift the burden to those kooky functional folks", >> would be to say that using a statement as an expression *only* works when >> it's enclosed in parens. This would simplify things a lot. This would not >> change the behavior of the first example at all, but it would for instance >> rule out >> 14 + if (true) {3} else {4} >> ? requiring instead >> 14 + (if (true) {3} else {4}) >> But indeed, I think I would probably opt for the latter one as more >> readable anyway. >> Another example that would have to change would be changing something like >> for foo.each |a| {f(a)}.bar() >> into >> (for foo.each |a| {f(a)}).bar() >> But honestly, that one makes me happier as well. >> >> The more I think about this alternative, the more I like it. >> >> Either way, this ship's gangplank is up and it's straining at its >> hawsers. We should probably make a decision on this now-ish. >> >> > How does this rule impact expressions that occur in the 'tail' expression > of a block? > > fn foo() -> bool { > if true { false } else { true } > } > > This is a very common place where block expressions are used. Will the > parser still know this is an expression? > > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Apr 25 15:46:29 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 15:46:29 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <51797F57.1010903@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51797F57.1010903@mozilla.com> Message-ID: <5179B245.8010908@mozilla.com> On 04/25/2013 12:09 PM, Graydon Hoare wrote: > On 25/04/2013 7:18 AM, G?bor Lehel wrote: > >> I'm an outsider, so apologies if I'm off the right track. But this >> sounds wrong to me. Isn't the point of condition handlers to /handle the >> condition/? Meaning resolve the problem, so that processing can >> continue? Here as far as I can tell, they're only being used to say >> "fail differently", which then leads to failing again the next time you >> try to do something. Opening a file was actually one of the examples >> used to illustrate the condition system way back when[1]. > > Yeah. I read this design a few times and felt uneasy about the > combination of files, options and conditions. I couldn't put my finger > on exactly how to arrange it, but it felt off. I thought about it some > more and I think I can now put my concern plainly. > > When a condition is handled -- not-in-failure -- there are _many_ > possible ways the user might want to handle it. All these are plausible: > > - This error is ok but subsequent errors on the same filehandle > should cause retriggering of the condition (so we can count > errors and fail after too many). > > - This error is ok and all subsequent errors on the same filehandle > should be absorbed silently; turn it into /dev/null. > > - This error should cause a state-change to the existing file, > such as closing it, truncating it, creating it, reopening it, > or similar. If it's a socket, maybe we want to try reestablishing > it. Maybe redirect it to an in-memory pseudo-file. > > Because of this variety of possible solutions, the approach in the > current design is inadequate: the Some(existing_file) and None > strategies are only two of the possible strategies, and both are > statically dispatched due to the implementation of file methods on > Option. The condition handler isn't really involved in picking > the strategy, only choosing between a fixed menu. It should be able to > _provide_ a strategy, which means providing an implementation of File > (or more likely: ~Stream). > > In other words (very much thinking-out-loud here) I suspect that any > concrete stream type in our IO library that has serious error modes > like this ought to be able to "replace itself" after a failed > operation with a ~Stream that points to some other implementation. So > it should be something like: > > enum FileStream { > FileDescriptor(libc::fd_t), > FileSimulation(~Stream) > } Having your stream type be called `FileStream` instead of `Option` is nice. I would still want a way here to recover without allocating, making this data type more like enum FileStream { RtFileStream(rtio::FileStream), // Not an fd_t, a boxed wrapper around uv/rt handles FileSimulation(~Stream), NullFileStream } With this factoring though you are going to be duplicating a lot of logic for FileStream, TcpStream, etc. - they all have to define this enum, handle the pass-through, and null cases. > > and so forth on other types. Then your file conditions would look like: > > condition! { > no_such_file : Path -> FileStream; > } > > and > > condition! { > write_error : (libc::fd_t, libc::errno_t) -> FileStream; > } I think the idea here is that you could take your open file handle and possibly put it into a new FileStream. In that case presumably it would be the condition handler's responsibility to close the file handle, so it would need to be wrapped in some RAII. The main I/O implementation will not be dealing in file descriptors though, it will be using boxed types defined in the `rtio` module that wrap Rust uv handles that wrap native uv handles, none of which should be exposed in the public interface. A condition that exposes C types is not appropriate there. Furthermore, if we intend for the 'native' and uv implementations to be interchangeable then they must raise the same conditions. A generic write error condition could be more like: condition! { file_write_error: (IoError) -> FileStream; } This though doesn't give you any access at all to the original I/O stream or handle. You could instead define it more like condition! { file_write_error: (IoError, &mut FileStream) -> (); } Which would let you both inspect the original or replace it (though I don't think you can put borrowed pointers in conditions today). > > and we'd assume that any handler for that condition will either > provide you a "real" FileDescriptor or else a "fake" simulation of a > file that directs to some other Stream type. And the 'write' operation > would look like: > > fn write(&mut self, bytes: &[u8]) { > match self { > FileSimulation(s) => s.write(bytes), > FileDescriptor(fd) => { > let e = libc::write(bytes.to_ptr, bytes.len()); > if e != 0 { > *self = no_such_file.cond.raise(fd, e); > } > } > } > } > > Apologies for the sketchines; I realize real code looks gnarlier than > this, just trying to convey a possible strategy. I say all this, > again, because the alternatives (option or a single "bad" flag, > as in many IO libraries) seems to provide very few recovery options to > a user. > > (Also aware that getting the abstraction layer right might be > challenging; maybe FileStream is the wrong place to put in this > redirection, and it should be one layer further up, or down..) > > It's not clear to me if MemStream or other such things have quite as > wide a repertoire of conditions. I think if there are no operations > that raise conditions of this sort, then there'd be no reason to use > such an enum. > > -Graydon > Thanks for the feedback. -Brian From pwalton at mozilla.com Thu Apr 25 15:48:15 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 25 Apr 2013 15:48:15 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179B245.8010908@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51797F57.1010903@mozilla.com> <5179B245.8010908@mozilla.com> Message-ID: <5179B2AF.9010805@mozilla.com> On 4/25/13 3:46 PM, Brian Anderson wrote: > enum FileStream { > RtFileStream(rtio::FileStream), // Not an fd_t, a boxed wrapper > around uv/rt handles > FileSimulation(~Stream), > NullFileStream > } > > With this factoring though you are going to be duplicating a lot of > logic for FileStream, TcpStream, etc. - they all have to define this > enum, handle the pass-through, and null cases. I'm not crazy about the Option thing either. Why not just have a "closed/in-error" flag on the stream? Seems like the worse-is-better solution, and the OS is doing that anyway... Patrick From banderson at mozilla.com Thu Apr 25 16:02:15 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 16:02:15 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179B245.8010908@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51797F57.1010903@mozilla.com> <5179B245.8010908@mozilla.com> Message-ID: <5179B5F7.4040309@mozilla.com> On 04/25/2013 03:46 PM, Brian Anderson wrote: > On 04/25/2013 12:09 PM, Graydon Hoare wrote: > >> >> and so forth on other types. Then your file conditions would look like: >> >> condition! { >> no_such_file : Path -> FileStream; >> } >> >> and >> >> condition! { >> write_error : (libc::fd_t, libc::errno_t) -> FileStream; >> } > > I think the idea here is that you could take your open file handle and > possibly put it into a new FileStream. In that case presumably it > would be the condition handler's responsibility to close the file > handle, so it would need to be wrapped in some RAII. > > The main I/O implementation will not be dealing in file descriptors > though, it will be using boxed types defined in the `rtio` module that > wrap Rust uv handles that wrap native uv handles, none of which should > be exposed in the public interface. A condition that exposes C types > is not appropriate there. Furthermore, if we intend for the 'native' > and uv implementations to be interchangeable then they must raise the > same conditions. A generic write error condition could be more like: This doesn't necessarily have to be the case, actually, depending on which types need to be interchangeable. This is how the I/O types relate (with names adjusted for clarity) mod rt { // The internal runtime I/O interface mod rtio { trait RtTcpStream; } // The internal interface as implemented for uv mod uvio { impl RtTcpStream for UvTcpStream; } // The internal interface as implemented for the native (fd, socket) types mod nativertio { impl RtTcpStream for fd_t; } // The public I/O interface mod io { trait TcpStream; // The public interface as implemented for the runtime private interface impl TcpStream for ~RtTcpStream; mod native { // The public interface as implemented for the native (fd, socket) types impl TcpStream for fd_t; } } } The main TCP implementation, `TcpStream for ~RtTcpStream`, will delegate to whatever boxed RtTcpStream it is given. Because TcpStream is responsible for raising conditions, then you can configure the scheduler to provide you with either uv-based or native implementations and you will get the same conditions raised. It's only if you want to replace one implementation of the public interface for another that you need to worry about whether they raise the same conditions - and that may not be a real requirement. Of course, with an error handling mechanism that lets you replace any Stream with a proxy, then all bets are off and you can end up in situations where unexpected conditions are being raised. -Brian From graydon at mozilla.com Thu Apr 25 16:47:59 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 16:47:59 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179B5F7.4040309@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51797F57.1010903@mozilla.com> <5179B245.8010908@mozilla.com> <5179B5F7.4040309@mozilla.com> Message-ID: <5179C0AF.8020303@mozilla.com> On 25/04/2013 4:02 PM, Brian Anderson wrote: > The main TCP implementation, `TcpStream for ~RtTcpStream`, will delegate > to whatever boxed RtTcpStream it is given. Because TcpStream is > responsible for raising conditions, then you can configure the scheduler > to provide you with either uv-based or native implementations and you > will get the same conditions raised. Oh! Ok then. If there's already this level of indirection, maybe we could arrange for conditions to return an optional ~RtTcpStream to take over from the current one? > It's only if you want to replace one implementation of the public > interface for another that you need to worry about whether they raise > the same conditions - and that may not be a real requirement. Indeed. I only wanted to gesture at the solution-space I had in mind, not dictate an exact solution; I suspect you have the set of actually-occurring constraints (and conditions) much more firmly in mind than I do. If there's a mechanism to swap in a user-provided "proxy" ~RtTcpStream or such at a lower level, that may be fine too. -Graydon From illissius at gmail.com Thu Apr 25 17:08:39 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Fri, 26 Apr 2013 02:08:39 +0200 Subject: [rust-dev] Update on I/O progress In-Reply-To: <51798B64.9020008@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> Message-ID: On Thu, Apr 25, 2013 at 10:00 PM, Brian Anderson wrote: > On 04/25/2013 07:18 AM, G?bor Lehel wrote: > >> >> Whether to respond to failure by failing the task or by indicating it in >> the return value seems like it would be better handled by having separate >> functions for each. In the case where you expect success, the result >> shouldn't be an Option. If the result is an Option, it shouldn't fail the >> task (whether or not a condition handler is present). So for example: >> >> open(path: &P, mode: FileMode, access: FileAccess) -> >> FileStream >> >> try_open(path: &P, mode: FileMode, access: FileAccess) -> >> Option >> >> If the expect-success version of a function returns (), the try_ version >> would return bool rather than Option<()> (which are isomorphic). >> >> Upon encountering an error, open() would raise a condition, and then >> continue if possible, otherwise fail!(). >> >> I'm not sure whether try_open() would raise a condition or not. The way >> conditions were described, if they aren't handled, the task fails. >> try_open() definitely shouldn't fail. Would it be reasonable to raise a >> condition and instead of failing, return None if it's not handled? If not, >> then try_open() shouldn't raise any conditions, and should just return None. >> >> The obvious drawback is twice as many functions, but it feels preferable >> to forcing two different behaviours onto the same function. The fast >> (expect-success) path would be just as clean as before, if not cleaner. >> >> [1] https://mail.mozilla.org/pipermail/rust-dev/2012-October/002545.html >> > > With this strategy could we make the `try_` return values return > `Result` (not using conditions at all)? Don't see why not. The other option would be to return Option and provide a (task-local) function to retrieve the details of the last error (I think I saw something like that mentioned somewhere). I don't have a clear preference. > Then nil-returning functions would need to be `Option`. > Having two ways to perform every I/O operation will 'infect' all code that > uses I/O indirectly. For instance, we have a `ReaderUtil` trait that > defines maybe two dozen methods. Do those all get duplicated? That seems > pretty disastrous to me. > That's a good point. If all higher-up IO libraries end up having to write two versions of everything too, that's pretty bad. Ideally, you'd want to have everything do it one way consistently, and provide some convenient method to translate it to the other way. But if the default is condition-raising/fail!()ing, then the translation to Option involves spawning a task which is unacceptably expensive, and if the default is Option, then the translation to fail!() involves mucking with Options, which makes straightline expect-success code unacceptably ugly. It feels like a failure of the language if there's no adequate way to abstract this out, honestly, I don't know what else to say. None of the options look appealing. (If you have to abuse conditions and Options in counteridiomatic ways to cram both behaviours into half the functions in a workable way, that doesn't reflect well on the language either.) If the recoverable/substitute-providing condition raising versions can be done satisfactorally, would be that remove the need for the try_ versions? I think you'd still want some way to say "okay, give up on opening the file, let's do something else instead", without failing the task. Which is presumably what NullFileStream would be about. But removing these kinds of hidden error conditions is what Option is supposed to be about. Going in circles... > You mentioned disliking the giant IoError enum, and I agree, but I don't > know a better way to represent it. We don't have subclassing to create an > Exception type hierarchy. Do you have any suggestions? > I was only thinking that instead of condition! { io_error: super::IoError -> (); } you might have condition! { file_not_found_error: super::FileNotFoundError -> Foo; } condition! { file_permission_error: super::FilePermissionError -> Bar; } and so forth. In other words, instead of the branching in the IoError enum, branching at the condition and error-describing-type level. That only makes sense in the as-you-would-expect-a-condition-system-to-work scenario though. (FWIW, it might be possible to emulate an exception hierarchy Haskell-style[1] like: trait Exception: Typeable { fn to_exception<'lt>(&'lt self) -> &'lt Exception; fn from_exception<'lt>(&'lt Exception) -> Option<&'lt Self>; } trait Typeable { // does anything like this exist already? fn type_of(&self) -> TypeRep; } impl Eq for TypeRep { ... } fn cast(x: &'lt T) -> Option<&'lt U> { unsafe { ... } } fn cast_obj(x: &'lt Typeable) -> Option<&'lt U> { unsafe { ... } } Dunno if I got self/Self and lifetimes and all of that right. IOW an Exception object can wrap any exception (to_exception) and you can test whether it's an instance of any particular exception with from_exception (which would typically be implemented with cast_obj). And you can make similar traits further down the 'hierarchy'. Don't know if this would be any good, just saying.) [1] http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html > -Brian > > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Thu Apr 25 17:29:18 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 17:29:18 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> Message-ID: <5179CA5E.8070304@mozilla.com> On 04/25/2013 05:08 PM, G?bor Lehel wrote: > > > On Thu, Apr 25, 2013 at 10:00 PM, Brian Anderson > > wrote: > > On 04/25/2013 07:18 AM, G?bor Lehel wrote: > > > Whether to respond to failure by failing the task or by > indicating it in the return value seems like it would be > better handled by having separate functions for each. In the > case where you expect success, the result shouldn't be an > Option. If the result is an Option, it shouldn't fail the task > (whether or not a condition handler is present). So for example: > > open(path: &P, mode: FileMode, access: > FileAccess) -> FileStream > > try_open(path: &P, mode: FileMode, access: > FileAccess) -> Option > > If the expect-success version of a function returns (), the > try_ version would return bool rather than Option<()> (which > are isomorphic). > > Upon encountering an error, open() would raise a condition, > and then continue if possible, otherwise fail!(). > > I'm not sure whether try_open() would raise a condition or > not. The way conditions were described, if they aren't > handled, the task fails. try_open() definitely shouldn't fail. > Would it be reasonable to raise a condition and instead of > failing, return None if it's not handled? If not, then > try_open() shouldn't raise any conditions, and should just > return None. > > The obvious drawback is twice as many functions, but it feels > preferable to forcing two different behaviours onto the same > function. The fast (expect-success) path would be just as > clean as before, if not cleaner. > > [1] > https://mail.mozilla.org/pipermail/rust-dev/2012-October/002545.html > > > With this strategy could we make the `try_` return values return > `Result` (not using conditions at all)? > > > Don't see why not. The other option would be to return Option and > provide a (task-local) function to retrieve the details of the last > error (I think I saw something like that mentioned somewhere). I don't > have a clear preference. > > Then nil-returning functions would need to be > `Option`. Having two ways to perform every I/O > operation will 'infect' all code that uses I/O indirectly. For > instance, we have a `ReaderUtil` trait that defines maybe two > dozen methods. Do those all get duplicated? That seems pretty > disastrous to me. > > > That's a good point. If all higher-up IO libraries end up having to > write two versions of everything too, that's pretty bad. > > Ideally, you'd want to have everything do it one way consistently, and > provide some convenient method to translate it to the other way. But > if the default is condition-raising/fail!()ing, then the translation > to Option involves spawning a task which is unacceptably expensive, > and if the default is Option, then the translation to fail!() involves > mucking with Options, which makes straightline expect-success code > unacceptably ugly. It feels like a failure of the language if there's > no adequate way to abstract this out, honestly, I don't know what else > to say. None of the options look appealing. (If you have to abuse > conditions and Options in counteridiomatic ways to cram both > behaviours into half the functions in a workable way, that doesn't > reflect well on the language either.) It's almost taboo here, but we could consider adding catchable exceptions. > > If the recoverable/substitute-providing condition raising versions can > be done satisfactorally, would be that remove the need for the try_ > versions? I think you'd still want some way to say "okay, give up on > opening the file, let's do something else instead", without failing > the task. Which is presumably what NullFileStream would be about. But > removing these kinds of hidden error conditions is what Option is > supposed to be about. Going in circles... Yes, the Option and NullFileStream approach are just two different ways of saying the same thing. > > > You mentioned disliking the giant IoError enum, and I agree, but I > don't know a better way to represent it. We don't have subclassing > to create an Exception type hierarchy. Do you have any suggestions? > > > I was only thinking that instead of > > condition! { io_error: super::IoError -> (); } > > you might have > > condition! { file_not_found_error: super::FileNotFoundError -> Foo; } > condition! { file_permission_error: super::FilePermissionError -> Bar; } > > and so forth. In other words, instead of the branching in the IoError > enum, branching at the condition and error-describing-type level. That > only makes sense in the as-you-would-expect-a-condition-system-to-work > scenario though. This is attractive, but how could you then create a block of code that trapped *all* errors? > (FWIW, it might be possible to emulate an exception hierarchy > Haskell-style[1] like: > > trait Exception: Typeable { > fn to_exception<'lt>(&'lt self) -> &'lt Exception; > fn from_exception<'lt>(&'lt Exception) -> Option<&'lt Self>; > } > > trait Typeable { // does anything like this exist already? > fn type_of(&self) -> TypeRep; > } > > impl Eq for TypeRep { ... } > > fn cast(x: &'lt T) -> Option<&'lt U> { > unsafe { ... } } > fn cast_obj(x: &'lt Typeable) -> Option<&'lt U> { > unsafe { ... } } > > Dunno if I got self/Self and lifetimes and all of that right. > > IOW an Exception object can wrap any exception (to_exception) and you > can test whether it's an instance of any particular exception with > from_exception (which would typically be implemented with cast_obj). > And you can make similar traits further down the 'hierarchy'. Don't > know if this would be any good, just saying.) > > [1] > http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Exception.html Unfortunately there is no equivalent to `Typeable` yet in Rust, but we have talked about it (called `Any`). I would also like `fail!()` take an `Any`, so this seems like an appropriate place for it. -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Thu Apr 25 17:30:33 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Thu, 25 Apr 2013 17:30:33 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179CA5E.8070304@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> Message-ID: <5179CAA9.5000505@mozilla.com> On 4/25/13 5:29 PM, Brian Anderson wrote: > It's almost taboo here, but we could consider adding catchable exceptions. I would be in favor of catchable exceptions, for what it's worth. Patrick From vadimcn at gmail.com Thu Apr 25 17:48:38 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 25 Apr 2013 17:48:38 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> Message-ID: > > > Then nil-returning functions would need to be `Option`. >> Having two ways to perform every I/O operation will 'infect' all code that >> uses I/O indirectly. For instance, we have a `ReaderUtil` trait that >> defines maybe two dozen methods. Do those all get duplicated? That seems >> pretty disastrous to me. >> > > That's a good point. If all higher-up IO libraries end up having to write > two versions of everything too, that's pretty bad. > If you are worried about the implementers of such traits, you could provide default implementations of failing methods that use try_... methods internally. If you are worried about higher-level I/O abstractions, then yes, unfortunately they will have to provide both versions of each of their methods. -------------- next part -------------- An HTML attachment was scrubbed... URL: From vadimcn at gmail.com Thu Apr 25 18:09:56 2013 From: vadimcn at gmail.com (Vadim) Date: Thu, 25 Apr 2013 18:09:56 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179CAA9.5000505@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> <5179CAA9.5000505@mozilla.com> Message-ID: What if Result implemented the Drop trait and fail()'ed in drop() unless it's been "disarmed" by calling some method (get_err?) which indicates that the error has been observed? On Thu, Apr 25, 2013 at 5:30 PM, Patrick Walton wrote: > On 4/25/13 5:29 PM, Brian Anderson wrote: > >> It's almost taboo here, but we could consider adding catchable exceptions. >> > > I would be in favor of catchable exceptions, for what it's worth. > > 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 banderson at mozilla.com Thu Apr 25 18:12:41 2013 From: banderson at mozilla.com (Brian Anderson) Date: Thu, 25 Apr 2013 18:12:41 -0700 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: Message-ID: <5179D489.8000407@mozilla.com> On 04/24/2013 09:25 PM, Thad Guidry wrote: > I've been working on getting the right settings, configure options, > etc... for Windows users to setup a Cygwin installation and be able to > use it to build Rust with Clang / LLVM. > > We've run into a few problems and I'm asking the community for a bit > of help. > > It seems that there's a Clang test that fails, and apparently because > the header files are not correctly found for whatever reason. > > Here's the pastebin of the current Cygwin environment I'm working > against and modifying as I go along...that shows the errors and my > directory structures under a Cygwin install...hope it reads well > enough for folks to understand. > > I need help with trying to understand why Clang or my setup in Cygwin > might be confused with this test_me.c that Brian found for me: > https://gist.github.com/brson/5456999 > > -- > -Thad > http://www.freebase.com/view/en/thad_guidry > Although I don't have any particular advice, I just wanted to say thanks for working on this. Cygwin will be a much nicer windows environment for casual development. From thadguidry at gmail.com Thu Apr 25 18:16:52 2013 From: thadguidry at gmail.com (Thad Guidry) Date: Thu, 25 Apr 2013 20:16:52 -0500 Subject: [rust-dev] LLVM Clang and Cygwin happiness (not quite yet) In-Reply-To: References: Message-ID: Sweet bbq ribs... this is a cool way to find your libstdc++ headers... 'gcc -v -x c++ /dev/null -fsyntax-only' - which will get the path for you and other things. So... Further on Cygwin ! ... I'm past the limits.h and standard C++ headers by pointing Clang on Cygwin specifically to my libstdc++ header path (found by using above) with this: Thad at Thad-Windows ~ $ clang test_me.c -isystem /usr/lib/gcc/i686-pc-cygwin/4.7.2/include/* But now another complaint is shown ...help ? ->> http://pastebin.mozilla.org/2347844 -- -Thad http://www.freebase.com/view/en/thad_guidry -------------- next part -------------- An HTML attachment was scrubbed... URL: From illissius at gmail.com Thu Apr 25 18:24:14 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Fri, 26 Apr 2013 03:24:14 +0200 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179CA5E.8070304@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> Message-ID: On Fri, Apr 26, 2013 at 2:29 AM, Brian Anderson wrote: > It's almost taboo here, but we could consider adding catchable exceptions. > ...which would let you default to the failing/throwing versions of functions, and allow (or obviate) an efficient translation to Result/Option. (Though: the None/Err cases would presumably still be slower than a direct implementation, exception handling isn't typically considered a fast path either. Is there a use case where that's a problem?) I don't know how I feel about the prospect of catchable exceptions. Is there a way to do them that doesn't suck? (i.e. other than how C++ or Java do them) The other direction would be some kind of syntax sugar to make interacting with Options/Results seamless (less seamful), but I have no idea how that might look. I was only thinking that instead of condition! { io_error: super::IoError -> (); } you might have condition! { file_not_found_error: super::FileNotFoundError -> Foo; } condition! { file_permission_error: super::FilePermissionError -> Bar; } and so forth. In other words, instead of the branching in the IoError enum, branching at the condition and error-describing-type level. That only makes sense in the as-you-would-expect-a-condition-system-to-work scenario though. This is attractive, but how could you then create a block of code that > trapped *all* errors? > Good question. That would only make sense if there's also a uniform way to recover from all the errors. I think you could do it by making a trap()/cond()-like that takes a fn(IoError) -> RecoveryType (where IoError is an enum wrapping all of the specialized error types), installs condition handlers for all of the specific conditions, and delegates all of them to the general IoError-handling closure. So yeah, you'd still have a big IoError enum, but you would only have to deal with it if you really did want to handle all of the possibilities. -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Thu Apr 25 18:40:03 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 18:40:03 -0700 Subject: [rust-dev] Renaming of core and std In-Reply-To: References: <5176B835.20301@mozilla.com> <517863A6.5000209@mozilla.com> Message-ID: <5179DAF3.2020702@mozilla.com> On 24/04/2013 8:42 PM, Lindsey Kuper wrote: > On Wed, Apr 24, 2013 at 6:58 PM, Graydon Hoare wrote: >> Agreed. This packaging will be of a sort that _does_ represent a level >> of support from the language maintainers, version-to-version. So ... >> absent other suggestions I will return to my preferred passtime of >> thesaurus hunting: >> >> - Common >> - Platform >> - Staple >> - Stock >> - Supported >> - Base >> - Basis >> - Usual >> - Normal >> - Favored >> - Selected >> - Endorsed >> - Chosen >> - Prime > > Are these synonyms for "standard"? Some. Others are synonyms of "supported", or 2-degrees-off "standard", synonyms of things that are synonyms for "standard". Thesauruses are the original transitive-hyperlink-surfing vortex. Hooray! > Since `core` is being renamed to `std` (correct?), we'd want the new > name of `std` to convey "supported, but not as essential as what's in > `std`", right? Yes. -Graydon From graydon at mozilla.com Thu Apr 25 20:41:49 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Thu, 25 Apr 2013 20:41:49 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179CA5E.8070304@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> Message-ID: <5179F77D.5090909@mozilla.com> On 25/04/2013 5:29 PM, Brian Anderson wrote: > It's almost taboo here, but we could consider adding catchable exceptions. For reference sake on this taboo -- let it not be too opaque! -- I will point to the amazing powers of IRC logging, and the conversation that contains the memorable phrase: please remind me of these things next time someone asks us about "resumable exceptions"; I had forgotten how convinced I was of this last time through the design-space http://irclog.gr/#show/irc.mozilla.org/rust/381023 In particular, to summarize for the impatient: once you get resumable exceptions, your code can only be correct if it leaves every data structure that might persist through an unwind-and-catch (that it acquired through &mut or @mut or the like, and live in an outer frame) in an internally-consistent state, at every possible exception-point. I.e. you have to write in transactional/atomic-writes style in order to be correct. This is both performance-punitive and very hard to get right. Most C++ code simply isn't correct in this sense. Convince yourself via a quick read through the GotWs strcat linked to: http://www.gotw.ca/gotw/059.htm http://www.gotw.ca/gotw/008.htm Now granted, we don't have 'operator=' overloading, so some quantity of this is exaggerated. But not much. Any nontrivial sequence of writes and other-operations winds up requiring transactional treatment if you have resumable exceptions. This is a big tax. If we stay away from that feature, we get to hold on to sequential logic. Your can reason about state strictly in terms of "the sequence of operations as-written", or prefixes thereof. You never have to think about "someone might call another method on this object after it was half-modified and unwound mid-operation". >> I was only thinking that instead of >> >> condition! { io_error: super::IoError -> (); } >> >> you might have >> >> condition! { file_not_found_error: super::FileNotFoundError -> Foo; } >> condition! { file_permission_error: super::FilePermissionError -> Bar; } >> >> and so forth. In other words, instead of the branching in the IoError >> enum, branching at the condition and error-describing-type level. That >> only makes sense in the as-you-would-expect-a-condition-system-to-work >> scenario though. > > This is attractive, but how could you then create a block of code that > trapped *all* errors? I would be _totally_ amenable to enhancing the condition-declaring system to provide a means of chaining the default of a condition into raising a different one at the declaration-site. We have to do some further hacking on the condition-declaring system anyways, to handle passing & properly. At the moment, you _could_ do this if you were fastidious about it at the raise sites. Namely: condition! { file_not_found_error: (Path) -> File; } condition! { general_file_error: (Path, File) -> File; } condition! { general_io_error: ~RtStream -> ~RtStream; } ... let p = Path::new(...); ... do file_no_found_error.cond.raise_default(copy p) { let f = File::null_file(); do general_file_error.cond.raise_default(p, f) { File::stream_file(general_io_error.cond.raise(f.rts)); } } If you moved this kind of idiom into a helper function, you could call it from multiple locations without much boilerplate or possibility of getting the chaining wrong. But it'd be nicer to do it at condition-declaration site, certainly. More arguments for revisiting the condition! macro. > Unfortunately there is no equivalent to `Typeable` yet in Rust, but we > have talked about it (called `Any`). I would also like `fail!()` take an > `Any`, so this seems like an appropriate place for it. +1 yes please. I suspect we're _close_ to having enough machinery for this now. -Graydon From swede at earthling.net Thu Apr 25 21:44:36 2013 From: swede at earthling.net (Erik S) Date: Thu, 25 Apr 2013 22:44:36 -0600 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: References: <20130423144812.217310@gmx.com> <1486845.Eo0P33FOQu@l10036> <1529933.oVftDTLAFD@l10036> <517958FA.7080605@mozilla.com> Message-ID: <517A0634.8070900@earthling.net> An HTML attachment was scrubbed... URL: From i at cantor.mx Thu Apr 25 22:36:08 2013 From: i at cantor.mx (Max Cantor) Date: Thu, 25 Apr 2013 22:36:08 -0700 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <1529933.oVftDTLAFD@l10036> References: <20130423144812.217310@gmx.com> <1486845.Eo0P33FOQu@l10036> <1529933.oVftDTLAFD@l10036> Message-ID: Haskell doesn't expose / to integers. only mod and rem. / is only exposed to rationals and reals. On Thu, Apr 25, 2013 at 7:52 AM, Diggory Hardy wrote: > > My opinion (that nobody will follow, but I still give it) is that > integers > > should not have the "/" operator at all. This was one of the bad choices > of > > C (or maybe of a previous language). > > Hmm, maybe, though I can imagine plenty of people being surprised at that. > > What really gets me though is that % is commonly called the "mod" operator > and > yet has nothing to do with modular arithmatic (I actually wrote a blog post > about it a few months back: [1]). If it were my choice I'd either make "x > % y" > do real modular arithmatic (possibly even throwing if y is not positive) or > have no % operator (just mod and rem keywords). > > [1]: > http://diggoryhardy.wordpress.com/2013/01/08/why-division-remainder-and-modulus-are-not-the-same/ > > -Diggory > _______________________________________________ > 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 james at mansionfamily.plus.com Thu Apr 25 22:42:05 2013 From: james at mansionfamily.plus.com (james) Date: Fri, 26 Apr 2013 06:42:05 +0100 Subject: [rust-dev] Update on I/O progress In-Reply-To: <51785EE8.1000206@mozilla.com> References: <51785EE8.1000206@mozilla.com> Message-ID: <517A13AD.8000705@mansionfamily.plus.com> On 24/04/2013 23:38, Brian Anderson wrote: > What I am focused on now is the design of a synchronous API for > sending and receiving streams of bytes, along with an implementation > built on an internal *asynchronous* I/O interface attached to the > scheduler event loop. This includes reading and writing files, TCP, > UDP, Unix sockets, stdio, pipes, adapters for string parsing, > compression, memory buffers, etc. This always concerns me - the design will tend towards having state on the stack etc and 'pull' processing rather than focussing on a clean design for a chain of state machines that handle 'push' of data coming from AIO completion events. Now I know that with say Erlang this is less concerning because processes are very lightweight there and you have process-specific GC, and I guess Rust has an ambition to be like that - but is it ready to handle this sort of IO framework in that way? Specifically, will your IO framework be practical with 50,000 connections in reasonable memory (say a constrained 32 bit process)? If not, I wonder if there should be more effort on the AIO layer first, and then consider a synchronous shim on top. Also - can I ask that any AIO layer be integrated with a semaphore-type system natively, then at least one can write some subprocess and use shared memory and integrate it into the main loop. -------------- next part -------------- An HTML attachment was scrubbed... URL: From swede at earthling.net Fri Apr 26 00:45:27 2013 From: swede at earthling.net (Erik S) Date: Fri, 26 Apr 2013 01:45:27 -0600 Subject: [rust-dev] LL(1) problems In-Reply-To: <51795FA7.9080300@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> <51795FA7.9080300@mozilla.com> Message-ID: <517A3097.4030506@earthling.net> An HTML attachment was scrubbed... URL: From niko at alum.mit.edu Fri Apr 26 02:48:55 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 26 Apr 2013 05:48:55 -0400 Subject: [rust-dev] LL(1) problems In-Reply-To: <51788FB2.3020103@mozilla.com> References: <51788FB2.3020103@mozilla.com> Message-ID: Patrick, Nice work! I'm still digesting your full mail. With respect to the pattern-names-as-type problem, I don't know if restricting the pattern name to be an identifier is the right thing to do. Would we be adding that restriction for all fn items, or just those that appear in traits? There are default methods to consider. I think it'd be best to have the same rules for all fn items (and maybe those rules should be: no patterns, those can only appear in closures). The other option is just to require parameter names on all method declarations, which would be more consistent, but would also sometimes be annoying for lightweight traits where the parameter names are uninteresting. Finally, one could imagine requiring that patterns be parenthesized or something like that? I confess that I sometimes find the current syntax hard to parse, but I think that's at least partially because of the old mode syntax (which is indeed ambiguous), parentheses might make it clearer. But I think I wouldn't want them to be required in the `|...|` closure syntax, so for consistency this option is probably out. Niko On Wed, Apr 24, 2013 at 10:06 PM, Patrick Walton wrote: > I've refactored the Rust grammar to get it as close to LL(1) as I could. I > made some minor language changes along the way which should not break code, > but there are a few things that are still preventing me from making it > LL(1): > > 1. Explicit self and patterns-as-arguments require two tokens of lookahead > to find the `self` (or `mut` or lifetime). > > fn foo(&self, ...) vs. fn foo(&a: &int) { ... } > > This is because arguments are patterns, and `&a` is a valid pattern. > > 2. There is a production called "maybe-named argument", which is part of > the trait declaration form. (It also shows up in function types.) This > allows you to write: > > trait Foo { > fn bar(&int, &int); > } > > Instead of: > > trait Foo { > fn bar(x: &int, y: &int); > } > > However, because arguments can be patterns, lookahead is required to > distinguish between that and this: > > trait Foo { > fn bar(&x: &int, &y: int); > } > > I believe this can actually be *unbounded* lookahead. Consider: > > trait Foo { > fn bar(&&&&&&&&&&x: &&&&&&&&&&int); > } > > Versus: > > trait Foo { > fn bar(&&&&&&&&&&int); > } > > This has a relatively straightforward fix though: just restrict the > argument name to be an identifier. There is little need for the pattern > form here. This reduces the complexity to LL(2); I haven't investigated > whether it can be reduced further. > > 3. `unsafe` blocks and `unsafe` function declarations are both allowed > inside blocks, and therefore two tokens of lookahead are required. > > fn foo() { > unsafe fn bar() { ... } > } > > Versus: > > fn foo() { > unsafe { ... } > } > > The parser needs to look ahead two tokens to find the `fn` or `{` keyword. > > These were the only warnings that the Python yapps2 module emitted when > compiling the Rust grammar, after suitable refactoring. My general feeling > is that, given how valuable explicit self and argument patterns are, LL(2) > is okay, especially if we turn out to be LALR(1). Others may feel > differently, however; 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 niko at alum.mit.edu Fri Apr 26 03:07:09 2013 From: niko at alum.mit.edu (Niko Matsakis) Date: Fri, 26 Apr 2013 06:07:09 -0400 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <517850A6.7080409@mozilla.com> References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> <517850A6.7080409@mozilla.com> Message-ID: I think checked integer overflow could be a good idea, presuming the cost is reasonable, but I am somewhat skeptical of having it be enabled or disabled on a module-by-module basis. This would imply that if I move a function from one module to another, it stops working? It seems surprising. Having the overflow checking be based on the type seems more robust. But maybe this would not be a big issue in practice; after all, it's already the case that moving a function requires various corrections (name resolution etc) to account for the new scope. But somehow this feels "different" than those, because this would mean that compilation succeeds but the dynamic behavior silently changes. In the past I had thought about saying that the unsized types (`uint`, `int`) are overflow checked but the sized types (`u32`, `i32`, etc) act as they do in C. But Roc's email made me reconsider if that is reasonable. Perhaps it's just too pat, and we would actually want a distinct family of "overflow-checked" types (perhaps a library, as Graydon suggests, though it seems like something that you might want to opt out of, rather than opt in). Definitely a Milestone 2 consideration ;) Niko On Wed, Apr 24, 2013 at 5:37 PM, Graydon Hoare wrote: > On 13-04-23 04:53 PM, Robert O'Callahan wrote: > > On Wed, Apr 24, 2013 at 11:25 AM, Robert O'Callahan > > > wrote: > > > > I don't think bignums are useful in a browser because as a browser > > developer I will choose data types that cover the ranges of values I > > want to handle. If I think I need to handle integer values that > > don't fit in 32 bits, I'll use a 64-bit integer type, or a floating > > point type. Overflow always means I have a bug*. > > > > > > Well, in C and C++ it does, and of course that's what most browser > > developers are going to be used to. > > > > If we could rely on checked overflows in Rust, then we could start to > > lean on that and declare that some tests that trigger overflow are > > simply tests where task failure is an acceptable result. (Offensive as > > this may to the cult of correctness, in practice priorities dictate we > > have to do this kind of thing all the time --- declare that a bug is not > > worth fixing as long as it's not exploitable.) > > Sure. I'd be happy to look into this as a mode for rust; I don't think > we can expect to make it "always on", but we could possibly make it > "reasonably easy to turn on" on a crate-by-crate basis. > > First thing to do is look into enabling it. There are a variety of > pieces lying around we could look into: > > http://llvm.org/docs/LangRef.html#range-metadata > http://llvm.org/docs/LangRef.html#arithmetic-with-overflow-intrinsics > http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation > http://embed.cs.utah.edu/ioc/ > > I suspect there's enough to work with there. It might require > duplicating some of the lowerings that clang does in rust's trans layer. > > -Graydon > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben.striegel at gmail.com Fri Apr 26 05:40:55 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Fri, 26 Apr 2013 08:40:55 -0400 Subject: [rust-dev] LL(1) problems In-Reply-To: <517A3097.4030506@earthling.net> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> <51795FA7.9080300@mozilla.com> <517A3097.4030506@earthling.net> Message-ID: > why is "continue" spelled "loop" in Rust? "continue" violates Rust's six-character policy, and the original keyword, "cont", was undesirable for obvious reasons. Considering how rarely-used it is (there are eight uses in the whole compiler), the decision was made to simply reuse "loop" and save a keyword. On Fri, Apr 26, 2013 at 3:45 AM, Erik S wrote: > On 4/25/2013 10:53 AM, Patrick Walton wrote: > > I'm not sure we can do the latter. There are too many issues relating to > `unsafe`, `loop`, the `self` argument, etc. to make the LL(1) derivable > from the human-readable grammar in an automated fashion, in my eyes. > > Total bikeshed... but why is "continue" spelled "loop" in Rust? Especially > if it's causing problems? Rust is the only language [1] > that > uses "loop" to mean "continue". It seems like an arbitrary incompatibility > with C/C++/Java/JS/etc. > > Erik > > [1] > http://rigaux.org/language-study/syntax-across-languages/CntrFlow.html#CntrFlowBrkCntFlo > > _______________________________________________ > 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 illissius at gmail.com Fri Apr 26 06:53:57 2013 From: illissius at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Fri, 26 Apr 2013 15:53:57 +0200 Subject: [rust-dev] Update on I/O progress In-Reply-To: <5179F77D.5090909@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> <5179F77D.5090909@mozilla.com> Message-ID: Probably a crazy idea, but would it be possible to do something where if the parent task launches a child task, and then does nothing else except wait for the child to finish, it's not actually implemented by launching a new task, but instead by calling the closure in place? It seems semantically equivalent, superficially. Presumably there would be (insurmountable?) complications with task-local storage, the managed heap, (and actually making task unwinding stop at the boundary), and so forth. But (if it's not totally unreasonable) it would allow an efficient implementation of try() and not be catchable exceptions. On Fri, Apr 26, 2013 at 5:41 AM, Graydon Hoare wrote: > On 25/04/2013 5:29 PM, Brian Anderson wrote: > > It's almost taboo here, but we could consider adding catchable exceptions. >> > > For reference sake on this taboo -- let it not be too opaque! -- I will > point to the amazing powers of IRC logging, and the conversation that > contains the memorable phrase: > > please remind me of these things next time someone asks > us about "resumable exceptions"; I had forgotten how > convinced I was of this last time through the design-space > > http://irclog.gr/#show/irc.mozilla.org/rust/381023 > > In particular, to summarize for the impatient: once you get resumable > exceptions, your code can only be correct if it leaves every data structure > that might persist through an unwind-and-catch (that it acquired through > &mut or @mut or the like, and live in an outer frame) in an > internally-consistent state, at every possible exception-point. > > I.e. you have to write in transactional/atomic-writes style in order to be > correct. This is both performance-punitive and very hard to get right. Most > C++ code simply isn't correct in this sense. Convince yourself via a quick > read through the GotWs strcat linked to: > > http://www.gotw.ca/gotw/059.htm > http://www.gotw.ca/gotw/008.htm > > Now granted, we don't have 'operator=' overloading, so some quantity of > this is exaggerated. But not much. Any nontrivial sequence of writes and > other-operations winds up requiring transactional treatment if you have > resumable exceptions. This is a big tax. > > If we stay away from that feature, we get to hold on to sequential logic. > Your can reason about state strictly in terms of "the sequence of > operations as-written", or prefixes thereof. You never have to think about > "someone might call another method on this object after it was > half-modified and unwound mid-operation". > > > I was only thinking that instead of >>> >>> condition! { io_error: super::IoError -> (); } >>> >>> you might have >>> >>> condition! { file_not_found_error: super::FileNotFoundError -> Foo; } >>> condition! { file_permission_error: super::FilePermissionError -> Bar; } >>> >>> and so forth. In other words, instead of the branching in the IoError >>> enum, branching at the condition and error-describing-type level. That >>> only makes sense in the as-you-would-expect-a-condition-system-to-work >>> scenario though. >>> >> >> This is attractive, but how could you then create a block of code that >> trapped *all* errors? >> > > I would be _totally_ amenable to enhancing the condition-declaring system > to provide a means of chaining the default of a condition into raising a > different one at the declaration-site. We have to do some further hacking > on the condition-declaring system anyways, to handle passing & properly. > > At the moment, you _could_ do this if you were fastidious about it at the > raise sites. Namely: > > condition! { file_not_found_error: (Path) -> File; } > condition! { general_file_error: (Path, File) -> File; } > condition! { general_io_error: ~RtStream -> ~RtStream; } > > ... > > let p = Path::new(...); > ... > > do file_no_found_error.cond.raise_default(copy p) { > let f = File::null_file(); > do general_file_error.cond.raise_default(p, f) { > File::stream_file(general_io_error.cond.raise(f.rts)); > } > } > > If you moved this kind of idiom into a helper function, you could call it > from multiple locations without much boilerplate or possibility of getting > the chaining wrong. But it'd be nicer to do it at condition-declaration > site, certainly. More arguments for revisiting the condition! macro. > > > Unfortunately there is no equivalent to `Typeable` yet in Rust, but we >> have talked about it (called `Any`). I would also like `fail!()` take an >> `Any`, so this seems like an appropriate place for it. >> > > +1 yes please. I suspect we're _close_ to having enough machinery for this > now. > > -Graydon > -- Your ship was destroyed in a monadic eruption. -------------- next part -------------- An HTML attachment was scrubbed... URL: From swede at earthling.net Fri Apr 26 08:15:06 2013 From: swede at earthling.net (Erik S) Date: Fri, 26 Apr 2013 09:15:06 -0600 Subject: [rust-dev] LL(1) problems In-Reply-To: References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> <51795FA7.9080300@mozilla.com> <517A3097.4030506@earthling.net> Message-ID: <517A99FA.4030200@earthling.net> An HTML attachment was scrubbed... URL: From lists at dhardy.name Fri Apr 26 08:16:07 2013 From: lists at dhardy.name (Diggory Hardy) Date: Fri, 26 Apr 2013 17:16:07 +0200 Subject: [rust-dev] Division and modulo for signed numbers In-Reply-To: <517958FA.7080605@mozilla.com> References: <20130423144812.217310@gmx.com> <1529933.oVftDTLAFD@l10036> <517958FA.7080605@mozilla.com> Message-ID: <1443310.JzpqZXE9jM@l10036> On Thursday 25 April 2013 09:25:30 Graydon Hoare wrote: > While it's true that people often pronounce % as "mod", the fact is most > of the languages in the lineage we're looking at treat it as "rem". > > http://en.wikipedia.org/wiki/Modulo_operation > > 50 languages in that list expose 'remainder' and 19 of them map it to > '%'. As well, as a "systems language", it _is_ salient that the > instructions on the CPUs we're targeting and the code generator IR for > said machines (LLVM) expose a remainder operation, not a modulo one. Of > the 35 languages that expose _anything_ that does "proper mod", only > interpreted/script languages (TCL, Perl, Python, Ruby, Lua, Rexx, Pike > and Dart) call it %. That's not our family. I'm sorry; if we're arguing > over "what the % symbol means", it means remainder in "our" language > family (the one including C, C++, C#, D, Go, F#, Java, Scala). > > (more gruesome comparisons available here: > http://rigaux.org/language-study/syntax-across-languages/Mthmt.html#MthmtcDB > QAM ) Good argument. > There are other questions to answer in this thread. We had a complex set > of conversations yesterday on IRC concerning exposure of multiple named > methods for the "other variants" -- ceiling, floor and truncating > division, in particular. We may need to expose all 3, and it might be > the case that calling any of them 'quot' is just misleading; it's not > clear to me yet whether there's a consistent method _name_ to assign '/' > to (floating point divide seems to do the opposite of integer divide on > chips that have both). > > But I don't think it's wise to map % to 'mod' if we're exposing both > 'mod' and 'rem'. That's a separate issue and one with (I think) a > simpler answer for us. 'system_divide' or 'hardware_divide' would make it clear that it's intended to do what the hardware provides, if that's what matters. Or 'c_div' if it's meant to be C compatible. From asb at asbradbury.org Fri Apr 26 08:22:36 2013 From: asb at asbradbury.org (Alex Bradbury) Date: Fri, 26 Apr 2013 16:22:36 +0100 Subject: [rust-dev] LL(1) problems In-Reply-To: <517A99FA.4030200@earthling.net> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> <51795FA7.9080300@mozilla.com> <517A3097.4030506@earthling.net> <517A99FA.4030200@earthling.net> Message-ID: On 26 April 2013 16:15, Erik S wrote: > For how rarely used "continue" is, four extra characters don't much matter. > The time savings from not having to check the documentation to confirm what > the keyword is will outweigh four characters of typing. Indeed, Lua for example doesn't even feature continue. It is an issue of much consternation though. Alex From pnkfelix at mozilla.com Fri Apr 26 08:24:31 2013 From: pnkfelix at mozilla.com (Felix S. Klock II) Date: Fri, 26 Apr 2013 17:24:31 +0200 Subject: [rust-dev] continue and related keyword bikeshed [was Re: LL(1) problems] In-Reply-To: References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> <51795FA7.9080300@mozilla.com> <517A3097.4030506@earthling.net> <517A99FA.4030200@earthling.net> Message-ID: <517A9C2F.8090003@mozilla.com> On 26/04/2013 17:22, Alex Bradbury wrote: > On 26 April 2013 16:15, Erik S wrote: >> For how rarely used "continue" is, four extra characters don't much matter. >> The time savings from not having to check the documentation to confirm what >> the keyword is will outweigh four characters of typing. > Indeed, Lua for example doesn't even feature continue. It is an issue > of much consternation though. > > Alex > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev (Felix-Hulk would appreciate it if further discussion on this fork of the thread had a subject line that reflected its content.) -- irc: pnkfelix on irc.mozilla.org email: {fklock, pnkfelix}@mozilla.org From pwalton at mozilla.com Fri Apr 26 09:01:59 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 26 Apr 2013 09:01:59 -0700 Subject: [rust-dev] LL(1) problems In-Reply-To: References: <51788FB2.3020103@mozilla.com> Message-ID: <517AA4F7.1040404@mozilla.com> On 4/26/13 2:48 AM, Niko Matsakis wrote: > Patrick, > > Nice work! I'm still digesting your full mail. > > With respect to the pattern-names-as-type problem, I don't know if > restricting the pattern name to be an identifier is the right thing to > do. Would we be adding that restriction for all fn items, or just those > that appear in traits? There are default methods to consider. Oh yes, you're right. This option is out then. > The other option is just to require parameter names on all method > declarations, which would be more consistent, but would also sometimes > be annoying for lightweight traits where the parameter names are > uninteresting. I think we have to do this to avoid unbounded lookahead. > Finally, one could imagine requiring that patterns be parenthesized or > something like that? I confess that I sometimes find the current syntax > hard to parse, but I think that's at least partially because of the old > mode syntax (which is indeed ambiguous), parentheses might make it > clearer. But I think I wouldn't want them to be required in the `|...|` > closure syntax, so for consistency this option is probably out. Yeah, I don't really like this idea, for the reason you gave. Patrick From pwalton at mozilla.com Fri Apr 26 09:04:54 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 26 Apr 2013 09:04:54 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> <5179F77D.5090909@mozilla.com> Message-ID: <517AA5A6.4030708@mozilla.com> On 4/26/13 6:53 AM, G?bor Lehel wrote: > Probably a crazy idea, but would it be possible to do something where if > the parent task launches a child task, and then does nothing else except > wait for the child to finish, it's not actually implemented by launching > a new task, but instead by calling the closure in place? The new scheduler is designed to allow *almost* this -- `spawn` will simply grab a cached stack segment (assuming there's one available) and context switch to the task immediately. Patrick From pwalton at mozilla.com Fri Apr 26 09:06:03 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 26 Apr 2013 09:06:03 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517A13AD.8000705@mansionfamily.plus.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> Message-ID: <517AA5EB.4090508@mozilla.com> On 4/25/13 10:42 PM, james wrote: > If not, I wonder if there should be more effort on the AIO layer first, > and then consider a synchronous shim on top. That's exactly what's being done. Patrick From graydon at mozilla.com Fri Apr 26 09:23:52 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 26 Apr 2013 09:23:52 -0700 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> <517850A6.7080409@mozilla.com> Message-ID: <517AAA18.3070200@mozilla.com> On 26/04/2013 3:07 AM, Niko Matsakis wrote: > I think checked integer overflow could be a good idea, presuming the > cost is reasonable, but I am somewhat skeptical of having it be enabled > or disabled on a module-by-module basis. This would imply that if I move > a function from one module to another, it stops working? It seems > surprising. Having the overflow checking be based on the type seems more > robust. But maybe this would not be a big issue in practice; after all, > it's already the case that moving a function requires various > corrections (name resolution etc) to account for the new scope. But > somehow this feels "different" than those, because this would mean that > compilation succeeds but the dynamic behavior silently changes. Yeah. This is tricky state to enforce. Reminds me a bit of locales, tbh. If you think that's awful, allow me also to direct your attention to the _global_ state that controls the interpretation of floating point arithmetic. How on earth does a programmer influence that reliably, when composing programs from subprograms with differing assumptions? Save-and-reload at module-crossings? Attach the modes to types? Figure out a subtype lattice for dispatching operations? Hahaha. Thankfully the 754 authors left all of this undefined, for us to struggle with. There _is_ some interesting work in this space. I recommend browsing through these notes: http://grouper.ieee.org/groups/754/meeting-materials/2001-10-18-langdesign.pdf and perhaps the Borneo design. It might (oh, interesting!) also influence how we think about rounding modes on integer division. Weirdly. > In the past I had thought about saying that the unsized types (`uint`, > `int`) are overflow checked but the sized types (`u32`, `i32`, etc) act > as they do in C. But Roc's email made me reconsider if that is > reasonable. Perhaps it's just too pat, and we would actually want a > distinct family of "overflow-checked" types (perhaps a library, as > Graydon suggests, though it seems like something that you might want to > opt out of, rather than opt in). I think it has to be opt-in, yeah. Sadly. I mean, I wish we were living in the world of hardware garbage collection and tagged memory words too, and hensel codes had won out over floating point, and all our languages had well defined total functional subsets with industrial strength provers attached to them that we were legally obliged to use. But some such dreams remain off the table when competing for market acceptance with C++ :) > Definitely a Milestone 2 consideration ;) Maybe. At least consideration. I think any variant would have to be additive (backwards compatible) simply because in languages like this, it's _really_ not what people assume as the default. We've already got in trouble for / trapping divide-by-zero by a branch/fault rather than a signal; it hits inner loops and costs us performance. Really. (We don't currently have a way to route signals into task failure; we will need this and hopefully the new UV-based scheduler will help here. I believe it will.) -Graydon From ben.striegel at gmail.com Fri Apr 26 09:37:27 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Fri, 26 Apr 2013 12:37:27 -0400 Subject: [rust-dev] LL(1) problems In-Reply-To: <517AA4F7.1040404@mozilla.com> References: <51788FB2.3020103@mozilla.com> <517AA4F7.1040404@mozilla.com> Message-ID: > The other option is just to require parameter names on all method declarations I honestly wasn't even aware that it was possible to omit the parameter names when declaring traits (it's not mentioned in the tutorial or in any code I've ever seen). It makes sense in retrospect, but I wouldn't really miss it. On Fri, Apr 26, 2013 at 12:01 PM, Patrick Walton wrote: > On 4/26/13 2:48 AM, Niko Matsakis wrote: > >> Patrick, >> >> Nice work! I'm still digesting your full mail. >> >> With respect to the pattern-names-as-type problem, I don't know if >> restricting the pattern name to be an identifier is the right thing to >> do. Would we be adding that restriction for all fn items, or just those >> that appear in traits? There are default methods to consider. >> > > Oh yes, you're right. This option is out then. > > > The other option is just to require parameter names on all method >> declarations, which would be more consistent, but would also sometimes >> be annoying for lightweight traits where the parameter names are >> uninteresting. >> > > I think we have to do this to avoid unbounded lookahead. > > > Finally, one could imagine requiring that patterns be parenthesized or >> something like that? I confess that I sometimes find the current syntax >> hard to parse, but I think that's at least partially because of the old >> mode syntax (which is indeed ambiguous), parentheses might make it >> clearer. But I think I wouldn't want them to be required in the `|...|` >> closure syntax, so for consistency this option is probably out. >> > > Yeah, I don't really like this idea, for the reason you gave. > > > Patrick > > ______________________________**_________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/**listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From graydon at mozilla.com Fri Apr 26 09:46:04 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 26 Apr 2013 09:46:04 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517A13AD.8000705@mansionfamily.plus.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> Message-ID: <517AAF4C.6070301@mozilla.com> On 25/04/2013 10:42 PM, james wrote: > This always concerns me - the design will tend towards having state on > the stack etc and 'pull' processing rather than focussing on a clean > design for a chain of state machines that handle 'push' of data coming > from AIO completion events. I think "push" and "pull" are a bit ... too vague to critique directly. The underlying IO model admits issuing IO requests and waiting on responses. If you want to issue lots of them and wait on lots of responses, you can use lots of tasks; it will make debugging and understanding the program harder (cf. the variety of hand-rolled mechanisms for event-tracing and causal stack-trace reconstruction in chain-of-state-machine systems). If you want to issue one, wait on response, and then issue another, you can use one task and let its program counter and call stack serialize things; the IO library will interleave you with _other tasks_, but your own task logic remains straight-line. Our goal is to provide some flexibility to the language user, to choose a balance between straight-line (understandable and debuggable) code and broken-into-pieces (concurrent and interleavable) code. If you want code to interleave, you put it in separate tasks. That should be efficient enough to be practical. If it's not, the task model is not useful. We're betting it will be. I'm sorry if this bet strikes you as irresponsible or unacceptable, but it's the one we're making. > Specifically, will your IO framework be practical with 50,000 > connections in reasonable memory (say a constrained 32 bit process)? If we assume a page-based stack model, 50k tasks (if they can stay in one page of stack) fits in about 200mb. So yes, or maybe, in terms of memory use. In terms of scheduler latency, it's certainly feasible to either operate a normal scheduling algorithm on 50k tasks, or let the OS kernel do it if you're on something fast like linux, or just follow task->chan->port->task links and schedule task-to-task as messages flow through (the "newsqueak way", which I suspect we'll wind up doing for latency sake). Or, put another way, I'm pretty sure we'll push on the design and implementation to be able to meet numbers like that. We've been doing "million task message-passing tests" since the beginning (on 32bit -- task stacks used to only be a couple hundred bytes to start). They're usually synthetic and we keep overhauling scheduling and the task model, but this sort of number is not at all outside the ballpark we're looking at. Getting a good balance is an engineering tradeoff between a lot of factors. Ease of debugging is one of them. > If not, I wonder if there should be more effort on the AIO layer first, > and then consider a synchronous shim on top. > > Also - can I ask that any AIO layer be integrated with a semaphore-type > system natively, then at least one can write some subprocess and use > shared memory and integrate it into the main loop. This is too vague to be able to promise much about, but IPC-in-general is certainly part of any core event loops we'd be sitting atop, and I expect some variants of IPC to use shared memory when appropriate. Beyond saying that, it's just a big pile of engineering tradeoffs. Sometimes pipes are fast enough. Sometimes staying-in-process is safe enough. Sometimes subprocesses and shared memory is "more right" for other reasons (sandboxing, say). Hard to be concrete while saying anything general. -Graydon From pwalton at mozilla.com Fri Apr 26 10:06:44 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Fri, 26 Apr 2013 10:06:44 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> Message-ID: <517AB424.1010304@mozilla.com> So here are my ideas. They are very worse-is-better at this point. * Failing to perform a basic I/O operation should result in a call to the `io_error` condition (default behavior: fail task) and should set an internal flag saying that this stream is dead. Stream constructors like `open` should return a dead stream. Operations like read or write on dead streams should be no-ops. Rationale: When in doubt as to the right semantics, it's best to just delegate to the OS. The OS has the concept of a stream in an error state already; we can possibly just piggyback on its concept of a stream in the error state in some cases and not have to store a flag at all. We could store the internal FD or FILE* as `Option` or `Option<*FILE>` respectively to handle streams that didn't succeed to open or were closed. * Stream readers such as `read_uint` should be duplicated into two methods for convenience: `read_uint` and `try_read_uint`. The former just delegates to the latter with `.get()`. Rationale: It's a bit of a burden on library implementors, but this is a classic convenience-versus-robustness tradeoff. It's like array indexing `[]` on `[T]` returning `T` instead of `Option`: it's extra work for the library, but well worth it for programmer convenience. In other words, this isn't really an I/O specific question at all: we have this tradeoff throughout the library and language, and usually we've resolved it by having convenient `foo()` and robust `try_foo()` methods (under a variety of naming conventions). This is no different. Patrick From graydon at mozilla.com Fri Apr 26 10:16:15 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 26 Apr 2013 10:16:15 -0700 Subject: [rust-dev] continue and related keyword bikeshed [was Re: LL(1) problems] In-Reply-To: <517A9C2F.8090003@mozilla.com> References: <51788FB2.3020103@mozilla.com> <51789D4E.7070100@mozilla.com> <5178BE39.3050307@mozilla.com> <517937DC.3090007@mozilla.com> <4673AC59-E02C-4DC0-A46A-506D0D6D1A8F@brinckerhoff.org> <51795602.8050809@mozilla.com> <51795893.7020306@mozilla.com> <51795FA7.9080300@mozilla.com> <517A3097.4030506@earthling.net> <517A99FA.4030200@earthling.net> <517A9C2F.8090003@mozilla.com> Message-ID: <517AB65F.9000709@mozilla.com> On 26/04/2013 8:24 AM, Felix S. Klock II wrote: > (Felix-Hulk would appreciate it if further discussion on this fork of > the thread had a subject line that reflected its content.) Tech-lead-graydon asks that we _not_ revisit 'loop', on this thread or any other. We've been over it so many times that it makes me cry just to see it on the list. It's been dormant for almost a year. Let it remain dormant. I'd rather the language be proven LL(7) than entertain another conversation about it. I will offer instead, as distraction, a short video about loops: http://www.youtube.com/watch?v=QER_yqTcmjM You can also re-read issue 2229 if you want to fall into a hall of mirrors for a while and argue yourself into exhaustion: https://github.com/mozilla/rust/issues/2229 -Graydon From fw at deneb.enyo.de Fri Apr 26 11:45:52 2013 From: fw at deneb.enyo.de (Florian Weimer) Date: Fri, 26 Apr 2013 20:45:52 +0200 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <5176C842.1060407@mozilla.com> (Graydon Hoare's message of "Tue, 23 Apr 2013 10:43:30 -0700") References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> Message-ID: <87ehdxt9jz.fsf@mid.deneb.enyo.de> * Graydon Hoare: > How much of a performance penalty is it worth? I believe you can trap > this in C presently with a gcc flag too (-ftrapv); but it's a flag > rarely turned on. GCC cannot use the OF flag, but LLVM has overflow-checking instructions, and Clang actually emits instructions using the OF flag for operator new[]: With undefined or trapping overflow, it's even more difficult to write overflow checks. GNAT addresses this by offering a mode which evaluates comparisons with infinite precision (with appropriate optimizations for common cases where full bignum arithmetic is not necessary). Ada allows suppressing an overflow exception as long as the mathematically correct result is produced. For a memory-safe language such as Java where pointer arithmetic or equivalents are rare (although some native code wrappers contain security-relevant range checks in Java code), overflow checking for integer types is not absolutely essential. For writing unsafe modules, I imagine overflow checks whould be rather helpful. For Rust, the interaction with resource management would be tricky, I think. From banderson at mozilla.com Fri Apr 26 14:11:06 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 26 Apr 2013 14:11:06 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517AA5A6.4030708@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> <5179F77D.5090909@mozilla.com> <517AA5A6.4030708@mozilla.com> Message-ID: <517AED6A.6010702@mozilla.com> On 04/26/2013 09:04 AM, Patrick Walton wrote: > On 4/26/13 6:53 AM, G?bor Lehel wrote: >> Probably a crazy idea, but would it be possible to do something where if >> the parent task launches a child task, and then does nothing else except >> wait for the child to finish, it's not actually implemented by launching >> a new task, but instead by calling the closure in place? > > The new scheduler is designed to allow *almost* this -- `spawn` will > simply grab a cached stack segment (assuming there's one available) > and context switch to the task immediately. Yeah, and I'm trying to make it so most of the resources held by tasks, even the task object itself, is cacheable. So when you spawn in an ideal scenario you occupy the dead husk of some other task and just start running. We can also probably lazily initialize *all* the local services (logging, local heap, gc, etc). We're going to have a lot of options to reduce the expense of spawning once things are written in Rust. From banderson at mozilla.com Fri Apr 26 14:23:06 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 26 Apr 2013 14:23:06 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517A13AD.8000705@mansionfamily.plus.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> Message-ID: <517AF03A.3020704@mozilla.com> On 04/25/2013 10:42 PM, james wrote: > On 24/04/2013 23:38, Brian Anderson wrote: >> What I am focused on now is the design of a synchronous API for >> sending and receiving streams of bytes, along with an implementation >> built on an internal *asynchronous* I/O interface attached to the >> scheduler event loop. This includes reading and writing files, TCP, >> UDP, Unix sockets, stdio, pipes, adapters for string parsing, >> compression, memory buffers, etc. > > This always concerns me - the design will tend towards having state on > the stack etc and 'pull' processing rather than focussing on a clean > design for a chain of state machines that handle 'push' of data coming > from AIO completion events. > > Now I know that with say Erlang this is less concerning because > processes are very lightweight there and you have process-specific GC, > and I guess Rust has an ambition to be like that - but is it ready to > handle this sort of IO framework in that way? I share your concern. It's likely that Rust tasks will never scale as well as Erlang and I suspect that we will ultimately want an async API that does not impose the expense of 1 task per I/O stream. I hope though that the current approach will scale 'pretty well'. > > Specifically, will your IO framework be practical with 50,000 > connections in reasonable memory (say a constrained 32 bit process)? I do think 50,000 I/O-performing tasks in a 32-bit process is within our reach. Last year I demonstrated 500,000 simultaneous Rust tasks (that did nothing but wait) in a 32-bit process, but there have been severe regressions since. On Linux I think we can get the initial allocation overhead for a single task into the ~2k range for sure. > > If not, I wonder if there should be more effort on the AIO layer > first, and then consider a synchronous shim on top. > > Also - can I ask that any AIO layer be integrated with a > semaphore-type system natively, then at least one can write some > subprocess and use shared memory and integrate it into the main loop. > I don't understand this question. -Brian -------------- next part -------------- An HTML attachment was scrubbed... URL: From banderson at mozilla.com Fri Apr 26 14:31:10 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 26 Apr 2013 14:31:10 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <5179CA5E.8070304@mozilla.com> <5179CAA9.5000505@mozilla.com> Message-ID: <517AF21E.9070409@mozilla.com> On 04/25/2013 06:09 PM, Vadim wrote: > What if Result implemented the Drop trait and fail()'ed in drop() > unless it's been "disarmed" by calling some method (get_err?) which > indicates that the error has been observed? > I've had a few bits of code recently that called for this sort of pattern (similar to a promise?). I would rather come up with a different abstraction than putting this behavior into Result though. From mikhail.zabaluev at gmail.com Fri Apr 26 14:34:38 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Sat, 27 Apr 2013 00:34:38 +0300 Subject: [rust-dev] Cross-task stack use (was: Update on I/O progress) Message-ID: Hi, 2013/4/26 Patrick Walton > > On 4/26/13 6:53 AM, G?bor Lehel wrote: >> >> Probably a crazy idea, but would it be possible to do something where if >> the parent task launches a child task, and then does nothing else except >> wait for the child to finish, it's not actually implemented by launching >> a new task, but instead by calling the closure in place? > > > The new scheduler is designed to allow *almost* this -- `spawn` will simply grab a cached stack segment (assuming there's one available) and context switch to the task immediately. I have a closely related issue currently. To implement thread-safe method calls to GLib objects, I chose to add a slow (and lock-prone) path of making a blocking FFI call passing an owned closure to another thread, which runs the event processing loop where the call's data are presumed to be safely accessible. This is done as the last resort when invoking the call on stack is not possible. It is admittedly quite ugly [1]. Now, if I were certain that one task can always read and write data (in unsafe code) on another task's stack provided that the latter task is blocked, I could scrap half of that logic and data copying, and just pass a stack closure across the threads. I'm pretty sure it actually works now. But I need a word from On High that it should be a supported use case. [1] https://github.com/mzabaluev/grust/blob/879f51ff84168d5757bdb370afe108bd347a1552/fauxgen/gio.rc#L179 From banderson at mozilla.com Fri Apr 26 15:54:09 2013 From: banderson at mozilla.com (Brian Anderson) Date: Fri, 26 Apr 2013 15:54:09 -0700 Subject: [rust-dev] Cross-task stack use (was: Update on I/O progress) In-Reply-To: References: Message-ID: <517B0591.5060007@mozilla.com> On 04/26/2013 02:34 PM, Mikhail Zabaluev wrote: > Hi, > > 2013/4/26 Patrick Walton >> On 4/26/13 6:53 AM, G?bor Lehel wrote: >>> Probably a crazy idea, but would it be possible to do something where if >>> the parent task launches a child task, and then does nothing else except >>> wait for the child to finish, it's not actually implemented by launching >>> a new task, but instead by calling the closure in place? >> >> The new scheduler is designed to allow *almost* this -- `spawn` will simply grab a cached stack segment (assuming there's one available) and context switch to the task immediately. > I have a closely related issue currently. To implement thread-safe > method calls to GLib objects, I chose to add a slow (and lock-prone) > path of making a blocking FFI call passing an owned closure to another > thread, which runs the event processing loop where the call's data are > presumed to be safely accessible. This is done as the last resort when > invoking the call on stack is not possible. It is admittedly quite > ugly [1]. > > Now, if I were certain that one task can always read and write data > (in unsafe code) on another task's stack provided that the latter task > is blocked, I could scrap half of that logic and data copying, and > just pass a stack closure across the threads. I'm pretty sure it > actually works now. But I need a word from On High that it should be a > supported use case. > > [1] https://github.com/mzabaluev/grust/blob/879f51ff84168d5757bdb370afe108bd347a1552/fauxgen/gio.rc#L179 > _______________________________________________ Without looking too closely at the details, this sounds like a very similar pattern to what the new scheduler does to return data through context switches: 1) take a pointer to the local stack, 2) deschedule the task, 3) fill the pointer in with a result, 4) reschedule task. Barring whatever thread synchronization issues apply here, I think this is an ok thing to do. From vadimcn at gmail.com Fri Apr 26 16:40:57 2013 From: vadimcn at gmail.com (Vadim) Date: Fri, 26 Apr 2013 16:40:57 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517AF03A.3020704@mozilla.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> Message-ID: > I share your concern. It's likely that Rust tasks will never scale as well > as Erlang and I suspect that we will ultimately want an async API that does > not impose the expense of 1 task per I/O stream. I hope though that the > current approach will scale 'pretty well'. > Is there something inherent in Rusts segmented stacks scheme that requires segments to be a multiple of a whole page? Could tasks be marked for fine-grained stack allocation and extend stack one function frame at a time? -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Fri Apr 26 18:47:53 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sat, 27 Apr 2013 11:47:53 +1000 Subject: [rust-dev] Random number generation Message-ID: <517B2E49.5000302@gmail.com> Hi all, Recently I've been doing quite a bit of experimentation with random number generation in Rust, and I've got a few ideas/suggestions/experiments that I'd like feedback on before I clean them up and open pull requests (or not). (I know that random numbers are spectacularly easy to screw up, and can have bad consequences, so I'm trying to be as careful and as explicit as possible with any changes.) Some background: the main RNG that Rust currently uses is ISAAC (http://burtleburtle.net/bob/rand/isaacafa.html), and is implemented in the runtime, which core::rand calls into. The runtime calls are quite slow, so I opened #6073 which is a pure Rust implementation of it, which gives speeds comparable to the pure C version (yay for performance!). However, the ISAAC algorithm is a 32 bit one (and the original implementation from the inventor meant that it was incorrect on 64-bit platforms; the fix is #6058 and is in bors' queue), which means that 64-bit computers are running at half capacity. I'm proposing to implement the ISAAC-64 algorithm (specified on the page above) which generates a random 64 bit number in the same time that ISAAC generates a 32 bit one (although, not surprisingly, the sequence of random numbers is different), and apparently has the same cryptographic properties, but I haven't been able to find any papers about it explicitly. Rust would default to using the 64 bit algorithm on 64 bit computers, but would provide a clear way to get a "consistent" RNG that gives the same sequence on both 32 and 64-bit platforms for a given initial seed (but not on different endiannesses, if I understand how the seeding works; but this is probably fixable, if it is deemed desirable). To get the full power of ISAAC-64, this would require adding a `next64() -> u64` method to the Rng trait. This change would double or triple throughput of random f64 generation on 64-bit platforms compared to using the 32-bit algorithm (and increase it 10-20x compared to calling the rng in the runtime, as is done now). On this note, f64s are generated by `a/max_u32 + b/max_u32^2 + c/max_u32^3`, where a, b, and c are random u32s, Many other languages just generate a single u64 and multiply by `1/max_u64` (e.g. http://hg.python.org/cpython/file/2.7/Lib/random.py#l809, this even uses 7 bytes, not 8), would this be an acceptable change? Lastly, I experimented with generating (so far) normal and exponential distributed random numbers using the Ziggurat algorithm (https://en.wikipedia.org/wiki/Ziggurat_algorithm). This works quite well, and can be extended to other distributions (with certain restrictions). Are these wanted in core/std? I'm proposing creating std::rand with these, possibly with a few extra traits e.g. "RandomDistribution". For reference the C++ stdlib contains a whole pile of distributions (http://www.cplusplus.com/reference/random/), as does the Python stdlib. (Is this wiki-bikeshed worthy?) If this is going to be added to the libraries, then there is a script that generates a file containing the tables required for the Ziggurat algorithm. Should this go in src/etc? Huon From graydon at mozilla.com Fri Apr 26 20:33:36 2013 From: graydon at mozilla.com (Graydon Hoare) Date: Fri, 26 Apr 2013 20:33:36 -0700 Subject: [rust-dev] Random number generation In-Reply-To: <517B2E49.5000302@gmail.com> References: <517B2E49.5000302@gmail.com> Message-ID: <517B4710.7000205@mozilla.com> On 26/04/2013 6:47 PM, Huon Wilson wrote: > This change would double or triple throughput of random f64 generation > on 64-bit platforms compared to using the 32-bit algorithm (and > increase it 10-20x compared to calling the rng in the runtime, as is > done now). On this note, f64s are generated by `a/max_u32 + > b/max_u32^2 + c/max_u32^3`, where a, b, and c are random u32s, Many > other languages just generate a single u64 and multiply by `1/max_u64` > (e.g. http://hg.python.org/cpython/file/2.7/Lib/random.py#l809, this > even uses 7 bytes, not 8), would this be an acceptable change? I'm not expert in this area and I'm not sure if any of us are; you might know better than anyone else here. I certainly don't object to adopting the ISAAC-64 algorithm if it's well understood by experts to be an improvement over the 32bit variant. If you'd be so kind as to survey the state of this sort of thing, document it and make changes to conform to what appears to be the best practice of other libraries (following our library-editing process[1] .. mostly just leave a paper trail for others), I would certainly appreciate it. > Lastly, I experimented with generating (so far) normal and exponential > distributed random numbers using the Ziggurat algorithm > (https://en.wikipedia.org/wiki/Ziggurat_algorithm). This works quite > well, and can be extended to other distributions (with certain > restrictions). Are these wanted in core/std? Yes. They can go in core::rand presently. We might refactor or move them if they seem too big, esoteric or arduous to maintain. > I'm proposing creating std::rand with these, possibly with a few extra > traits e.g. "RandomDistribution". For reference the C++ stdlib > contains a whole pile of distributions > (http://www.cplusplus.com/reference/random/), as does the Python > stdlib. (Is this wiki-bikeshed worthy?) Again, this feels like something where the library process of surveying, documenting and distilling might shed some light. I believe the recent work from C++11 is nearly state of the art, but I wouldn't be surprised if other languages have important contributions to the design space to be aware of also. > If this is going to be added to the libraries, then there is a script > that generates a file containing the tables required for the Ziggurat > algorithm. Should this go in src/etc? Yes please. Thanks for getting involved in this! Random numbers are often overlooked. -Graydon [1] https://github.com/mozilla/rust/wiki/Libs From ben.striegel at gmail.com Fri Apr 26 20:52:38 2013 From: ben.striegel at gmail.com (Benjamin Striegel) Date: Fri, 26 Apr 2013 23:52:38 -0400 Subject: [rust-dev] Random number generation In-Reply-To: <517B2E49.5000302@gmail.com> References: <517B2E49.5000302@gmail.com> Message-ID: Is it conceivable that this is a library that people would like to use outside of Rust itself? In other words, would it make sense to package this library in runtimeless/standalone format, and have Rust depend on it via submodule? On Fri, Apr 26, 2013 at 9:47 PM, Huon Wilson wrote: > Hi all, > > Recently I've been doing quite a bit of experimentation with random > number generation in Rust, and I've got a few > ideas/suggestions/experiments that I'd like feedback on before I clean > them up and open pull requests (or not). (I know that random numbers > are spectacularly easy to screw up, and can have bad consequences, so > I'm trying to be as careful and as explicit as possible with any > changes.) > > Some background: the main RNG that Rust currently uses is ISAAC > (http://burtleburtle.net/bob/**rand/isaacafa.html), > and is implemented > in the runtime, which core::rand calls into. The runtime calls are > quite slow, so I opened #6073 which is a pure Rust implementation of > it, which gives speeds comparable to the pure C version (yay for > performance!). > > However, the ISAAC algorithm is a 32 bit one (and the original > implementation from the inventor meant that it was incorrect on 64-bit > platforms; the fix is #6058 and is in bors' queue), which means that > 64-bit computers are running at half capacity. I'm proposing to > implement the ISAAC-64 algorithm (specified on the page above) which > generates a random 64 bit number in the same time that ISAAC generates > a 32 bit one (although, not surprisingly, the sequence of random > numbers is different), and apparently has the same cryptographic > properties, but I haven't been able to find any papers about it > explicitly. > > Rust would default to using the 64 bit algorithm on 64 bit computers, > but would provide a clear way to get a "consistent" RNG that gives the > same sequence on both 32 and 64-bit platforms for a given initial seed > (but not on different endiannesses, if I understand how the seeding > works; but this is probably fixable, if it is deemed desirable). To > get the full power of ISAAC-64, this would require adding a `next64() > -> u64` method to the Rng trait. > > This change would double or triple throughput of random f64 generation > on 64-bit platforms compared to using the 32-bit algorithm (and > increase it 10-20x compared to calling the rng in the runtime, as is > done now). On this note, f64s are generated by `a/max_u32 + > b/max_u32^2 + c/max_u32^3`, where a, b, and c are random u32s, Many > other languages just generate a single u64 and multiply by `1/max_u64` > (e.g. http://hg.python.org/cpython/**file/2.7/Lib/random.py#l809, > this > even uses 7 bytes, not 8), would this be an acceptable change? > > > Lastly, I experimented with generating (so far) normal and exponential > distributed random numbers using the Ziggurat algorithm > (https://en.wikipedia.org/**wiki/Ziggurat_algorithm). > This works quite > well, and can be extended to other distributions (with certain > restrictions). Are these wanted in core/std? > > I'm proposing creating std::rand with these, possibly with a few extra > traits e.g. "RandomDistribution". For reference the C++ stdlib > contains a whole pile of distributions > (http://www.cplusplus.com/**reference/random/), > as does the Python > stdlib. (Is this wiki-bikeshed worthy?) > > If this is going to be added to the libraries, then there is a script > that generates a file containing the tables required for the Ziggurat > algorithm. Should this go in src/etc? > > > Huon > ______________________________**_________________ > 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 andrei at ci.ufpb.br Fri Apr 26 22:28:08 2013 From: andrei at ci.ufpb.br (=?ISO-8859-1?Q?Andrei_de_Ara=FAjo_Formiga?=) Date: Sat, 27 Apr 2013 02:28:08 -0300 Subject: [rust-dev] Random number generation In-Reply-To: <517B2E49.5000302@gmail.com> References: <517B2E49.5000302@gmail.com> Message-ID: As I have some interest in using RNGs in Rust, I'd like to chime in on this. The extra traits like "RandomDistribution" would be a good thing, especially if it would be possible to "plug" a different, custom generator than the one provided and use the custom generator with code that simply calls rand(). For example for normal generation I might not want to use Ziggurat, or maybe I want a quasi-random uniform generator instead of a PRNG. (For normal generation I've been using Box Muller but it is a bit slow, Ziggurat may be slower when generating samples on the tails of the distribution, so maybe the ideal would be to use the inversion method over a good algorithm for generating quantiles, like R does, but this takes a bit more work). Also, if you're not already doing so I'd recommend running some statistical tests on the PRNG you're implementing, just to have a greater degree of confidence about them. The Diehard and Dieharder test suites are popular for testing the output of a PRNG. I may help with this if needed. 2013/4/26 Huon Wilson > Hi all, > > Recently I've been doing quite a bit of experimentation with random > number generation in Rust, and I've got a few > ideas/suggestions/experiments that I'd like feedback on before I clean > them up and open pull requests (or not). (I know that random numbers > are spectacularly easy to screw up, and can have bad consequences, so > I'm trying to be as careful and as explicit as possible with any > changes.) > > Some background: the main RNG that Rust currently uses is ISAAC > (http://burtleburtle.net/bob/**rand/isaacafa.html), > and is implemented > in the runtime, which core::rand calls into. The runtime calls are > quite slow, so I opened #6073 which is a pure Rust implementation of > it, which gives speeds comparable to the pure C version (yay for > performance!). > > However, the ISAAC algorithm is a 32 bit one (and the original > implementation from the inventor meant that it was incorrect on 64-bit > platforms; the fix is #6058 and is in bors' queue), which means that > 64-bit computers are running at half capacity. I'm proposing to > implement the ISAAC-64 algorithm (specified on the page above) which > generates a random 64 bit number in the same time that ISAAC generates > a 32 bit one (although, not surprisingly, the sequence of random > numbers is different), and apparently has the same cryptographic > properties, but I haven't been able to find any papers about it > explicitly. > > Rust would default to using the 64 bit algorithm on 64 bit computers, > but would provide a clear way to get a "consistent" RNG that gives the > same sequence on both 32 and 64-bit platforms for a given initial seed > (but not on different endiannesses, if I understand how the seeding > works; but this is probably fixable, if it is deemed desirable). To > get the full power of ISAAC-64, this would require adding a `next64() > -> u64` method to the Rng trait. > > This change would double or triple throughput of random f64 generation > on 64-bit platforms compared to using the 32-bit algorithm (and > increase it 10-20x compared to calling the rng in the runtime, as is > done now). On this note, f64s are generated by `a/max_u32 + > b/max_u32^2 + c/max_u32^3`, where a, b, and c are random u32s, Many > other languages just generate a single u64 and multiply by `1/max_u64` > (e.g. http://hg.python.org/cpython/**file/2.7/Lib/random.py#l809, > this > even uses 7 bytes, not 8), would this be an acceptable change? > > > Lastly, I experimented with generating (so far) normal and exponential > distributed random numbers using the Ziggurat algorithm > (https://en.wikipedia.org/**wiki/Ziggurat_algorithm). > This works quite > well, and can be extended to other distributions (with certain > restrictions). Are these wanted in core/std? > > I'm proposing creating std::rand with these, possibly with a few extra > traits e.g. "RandomDistribution". For reference the C++ stdlib > contains a whole pile of distributions > (http://www.cplusplus.com/**reference/random/), > as does the Python > stdlib. (Is this wiki-bikeshed worthy?) > > If this is going to be added to the libraries, then there is a script > that generates a file containing the tables required for the Ziggurat > algorithm. Should this go in src/etc? > > > Huon > ______________________________**_________________ > 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 lists at dhardy.name Sat Apr 27 01:18:54 2013 From: lists at dhardy.name (Diggory Hardy) Date: Sat, 27 Apr 2013 10:18:54 +0200 Subject: [rust-dev] Random number generation In-Reply-To: <517B4710.7000205@mozilla.com> References: <517B2E49.5000302@gmail.com> <517B4710.7000205@mozilla.com> Message-ID: <4343538.EWMZRilB1U@l10036> On Friday 26 April 2013 20:33:36 Graydon Hoare wrote: > On 26/04/2013 6:47 PM, Huon Wilson wrote: > > I'm proposing creating std::rand with these, possibly with a few extra > > traits e.g. "RandomDistribution". For reference the C++ stdlib > > contains a whole pile of distributions > > (http://www.cplusplus.com/reference/random/), as does the Python > > stdlib. (Is this wiki-bikeshed worthy?) > > Again, this feels like something where the library process of surveying, > documenting and distilling might shed some light. I believe the recent > work from C++11 is nearly state of the art, but I wouldn't be surprised > if other languages have important contributions to the design space to > be aware of also. Haven't had the chance to use the C++11 random library yet, but it looks good. Also worth mentioning is the GSL library, which despite its age is (AFAIAA) well regarded and very extensive: https://www.gnu.org/software/gsl/manual/html_node/ From lists at dhardy.name Sat Apr 27 01:24:19 2013 From: lists at dhardy.name (Diggory Hardy) Date: Sat, 27 Apr 2013 10:24:19 +0200 Subject: [rust-dev] continue and related keyword bikeshed [was Re: LL(1) problems] In-Reply-To: <517AB65F.9000709@mozilla.com> References: <51788FB2.3020103@mozilla.com> <517A9C2F.8090003@mozilla.com> <517AB65F.9000709@mozilla.com> Message-ID: <3346118.PkR6fr3BVq@l10036> What the... There's better things to innovate on than renaming 'continue'. Sometimes I think rules get taken too far. Perhaps the fact this has been such a long- running argument is evidence of a problem. On Friday 26 April 2013 10:16:15 Graydon Hoare wrote: > On 26/04/2013 8:24 AM, Felix S. Klock II wrote: > > (Felix-Hulk would appreciate it if further discussion on this fork of > > the thread had a subject line that reflected its content.) > > Tech-lead-graydon asks that we _not_ revisit 'loop', on this thread or > any other. We've been over it so many times that it makes me cry just to > see it on the list. It's been dormant for almost a year. Let it remain > dormant. I'd rather the language be proven LL(7) than entertain another > conversation about it. > > I will offer instead, as distraction, a short video about loops: > > http://www.youtube.com/watch?v=QER_yqTcmjM > > You can also re-read issue 2229 if you want to fall into a hall of > mirrors for a while and argue yourself into exhaustion: > > https://github.com/mozilla/rust/issues/2229 > > -Graydon > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From zack at z0w0.me Sat Apr 27 01:46:21 2013 From: zack at z0w0.me (Zack Corr) Date: Sat, 27 Apr 2013 18:46:21 +1000 Subject: [rust-dev] continue and related keyword bikeshed [was Re: LL(1) problems] In-Reply-To: <3346118.PkR6fr3BVq@l10036> References: <51788FB2.3020103@mozilla.com> <517A9C2F.8090003@mozilla.com> <517AB65F.9000709@mozilla.com> <3346118.PkR6fr3BVq@l10036> Message-ID: Agreed. I also personally think loop is more logical, anyway. Continue implies that the loop will actually stop until an explicit continue statement, IMO. Less keywords is good too. On 27 Apr 2013 18:24, "Diggory Hardy" wrote: > What the... > > There's better things to innovate on than renaming 'continue'. Sometimes I > think rules get taken too far. Perhaps the fact this has been such a long- > running argument is evidence of a problem. > > On Friday 26 April 2013 10:16:15 Graydon Hoare wrote: > > On 26/04/2013 8:24 AM, Felix S. Klock II wrote: > > > (Felix-Hulk would appreciate it if further discussion on this fork of > > > the thread had a subject line that reflected its content.) > > > > Tech-lead-graydon asks that we _not_ revisit 'loop', on this thread or > > any other. We've been over it so many times that it makes me cry just to > > see it on the list. It's been dormant for almost a year. Let it remain > > dormant. I'd rather the language be proven LL(7) than entertain another > > conversation about it. > > > > I will offer instead, as distraction, a short video about loops: > > > > http://www.youtube.com/watch?v=QER_yqTcmjM > > > > You can also re-read issue 2229 if you want to fall into a hall of > > mirrors for a while and argue yourself into exhaustion: > > > > https://github.com/mozilla/rust/issues/2229 > > > > -Graydon > > > > _______________________________________________ > > Rust-dev mailing list > > Rust-dev at mozilla.org > > https://mail.mozilla.org/listinfo/rust-dev > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From j.boggiano at seld.be Sat Apr 27 03:07:40 2013 From: j.boggiano at seld.be (Jordi Boggiano) Date: Sat, 27 Apr 2013 12:07:40 +0200 Subject: [rust-dev] Update on I/O progress In-Reply-To: <51785EE8.1000206@mozilla.com> References: <51785EE8.1000206@mozilla.com> Message-ID: <517BA36C.4000400@seld.be> Take my input with a grain of salt since I'm so new to the language, but here goes nothing: > I am particularly interested in making sure that common operations are > convenient and don't require a lot of boilerplate. To that end I've been > collecting [aspirational examples] of succinctly written Rust I/O code > using the hypothetical API. The goal will be to turn these into test > cases. I welcome additional examples. One fairly common (at least to me) case I would like addressed is TCP reads/writes with timeouts. It's quite common when writing anything network related that you need to handle timeouts to be able to kill the connection and retry or abort. If you don't you easily end up with zombie processes. In the current net::tcp it seems possible using the raw socket, but not if you use any of the convenience of TcpSocketBuf. I'm not sure how this would be best implemented, but I just wanted to raise the issue before it's too late and we have to write lots of boilerplate task monitoring to have timeouts. Which is ok but a bit hard on newcomers. > ## Error handling > > I've spent a lot of time thinking about - and talking to Patrick about - > how I/O should deal with errors (the old `io` doesn't have a consistent > strategy). The [error handling strategy] I'm proposing is intended to > eliminate boilerplate and allow efficient recovery from errors, but it > uses some uncommon patterns. This seems suboptimal still. Reading your [error handling] example, I wonder if this is really better than traditional exceptions that would break the execution after the failed `new` call. Now this might not be practical to implement in rust, so I'll skip over that and assume conditions are good. You say that both `new` and `write_line` will raise a condition in this case, but that means `error` at the end contains the second condition, which probably would have a message like "could not write in a null file" or something. While the message that interests us, for debugging or printing out to the user, is the first one "could not open file because of X". I fear that in the end to be able to handle and report errors properly one would have to write so much condition handling boilerplate that simply relying on multiple return values ? la Go might be best. [error handling] https://github.com/brson/rust/blob/io/src/libcore/rt/io/mod.rs#L155-164 > ## Close > > Do we need to have `close` methods or do we depend solely on RAII for > closing streams? I would say yes, because sometimes you really need to release a file to be able to do other things with it (especially on windows which likes to lock files for various reasons). > ## Constructor options > > I am considering defining `open` more like `fn open:(spec: > S)`, then implementing `OpenSpec` for e.g. `&str`, `Path`, `(Path, > FileFlags, FileAccess), `Url`, etc. > > Does this seem reasonable? Feels weird to have str implement something specific to another module, but if there is no other way it sounds more user friendly than a gazillion open_* methods. A few more comments on other things: - Streams are great, and the ability to register new stream protocol handler for "foo:..." urls would indeed be a big plus. - File vs FileStream, you could have a File (FileStream) and a FileInfo for the info stuff, since the latter is less commonly used. - open vs connect, I'd say open. Opening a connection sounds ok, connecting a file sounds awkward. Cheers -- Jordi Boggiano @seldaek - http://nelm.io/jordi From bruant.d at gmail.com Sat Apr 27 04:06:28 2013 From: bruant.d at gmail.com (David Bruant) Date: Sat, 27 Apr 2013 13:06:28 +0200 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517AF03A.3020704@mozilla.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> Message-ID: <517BB134.4040405@gmail.com> Le 26/04/2013 23:23, Brian Anderson a ?crit : > On 04/25/2013 10:42 PM, james wrote: >> On 24/04/2013 23:38, Brian Anderson wrote: >>> What I am focused on now is the design of a synchronous API for >>> sending and receiving streams of bytes, along with an implementation >>> built on an internal *asynchronous* I/O interface attached to the >>> scheduler event loop. This includes reading and writing files, TCP, >>> UDP, Unix sockets, stdio, pipes, adapters for string parsing, >>> compression, memory buffers, etc. >> >> This always concerns me - the design will tend towards having state >> on the stack etc and 'pull' processing rather than focussing on a >> clean design for a chain of state machines that handle 'push' of data >> coming from AIO completion events. >> >> Now I know that with say Erlang this is less concerning because >> processes are very lightweight there and you have process-specific >> GC, and I guess Rust has an ambition to be like that - but is it >> ready to handle this sort of IO framework in that way? > > I share your concern. It's likely that Rust tasks will never scale as > well as Erlang and I suspect that we will ultimately want an async API > that does not impose the expense of 1 task per I/O stream. I believe too this is doomed to happen. Firefox is under a huge struggle to remove as much as sync IO code as possible as part of the Snappy effort [1]. Tasks provide something easier to use than threads, so a browser in Rust can make things snappier by moving things to tasks, but allocation, de-allocating and scheduling have a cost. >> Specifically, will your IO framework be practical with 50,000 >> connections in reasonable memory (say a constrained 32 bit process) > I do think 50,000 I/O-performing tasks in a 32-bit process is within > our reach. Last year I demonstrated 500,000 simultaneous Rust tasks > (that did nothing but wait) in a 32-bit process, but there have been > severe regressions since. On Linux I think we can get the initial > allocation overhead for a single task into the ~2k range for sure. Still, one stack per I/O operation has a bad smell to it. Being forced to create a new task (even if "only" 2k) because the 49000 previous ones are sitting idle doesn't sound right. Not contacting the remote resource (disk, network) would be worse. To do efficient IO, there got to be a cheap way to start an IO and wait for it. Creating a task, doesn't sound cheap enough to work at scale. I'd like to encourage everyone reading to take the time to watch [2] (at least 10-15mins starting where I linked to). Graydon Hoare wrote: > If you want code to interleave, you put it in separate tasks. That > should be efficient enough to be practical. I believe it will be practical, but it imposes an unnecessary burden in the face of lots of concurrent I/O. > If it's not, the task model is not useful. I completely disagree. I've been working with Node.js for a year and a half now and non-blocking I/O makes my (single process) code fast enough by default so that I've never had to worry about it. My use case is that I'm writing a crawler service. It receives requests from the network, crawls a bunch of pages and sends back the result. There is some computation due to HTML parsing, finding links, etc. The single-threaded version is cool, but exploiting the X (often 4, but maybe 8 one day) cores in the production machine is super nice too. The service becomes X+1 process. One receives orders, delegates to the X actual crawlers and answers. The X other crawlers do the actual work. 2 things that were/are annoying in making my crawler service parallel: 1) In Node.js, you have to fork and create a new process to get parallelism. In Rust, create a task and you're done. A process is more heavy-weight than a task. 2) Communication between 2 things that run in parallel (process) requires copying memory. Inefficient as hell by comparison with Rust and communication with unique pointers. Even with single-threaded interleaving in Node.js, I envy the Rust task model as it makes parallelism both easy and efficient. My point here is that the task model is useful even if interleaving can happen within a task. David [1] https://wiki.mozilla.org/Performance/Snappy [2] https://www.youtube.com/watch?v=M-sc73Y-zQA&#t=289s -------------- next part -------------- An HTML attachment was scrubbed... URL: From leebraid at gmail.com Sat Apr 27 08:49:37 2013 From: leebraid at gmail.com (Lee Braiden) Date: Sat, 27 Apr 2013 16:49:37 +0100 Subject: [rust-dev] Simpler/more flexible condition handling was: Re: Update on I/O progress In-Reply-To: <517AB424.1010304@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <517AB424.1010304@mozilla.com> Message-ID: <517BF391.5040602@gmail.com> Hi all, This is going to be long, but I've tried to organise my thoughts clearly and as succinctly as possible. On 26/04/13 18:06, Patrick Walton wrote: > So here are my ideas. They are very worse-is-better at this point. > > * Failing to perform a basic I/O operation should result in a call to > the `io_error` condition (default behavior: fail task) and should set > an internal flag saying that this stream is dead. Agreed. > Stream constructors like `open` should return a dead stream. This would be a relatively ugly approach, to my way of thinking. Why should a dead stream be returned at all, if the code to create it failed? Why should I be able to call write() on something that could not be created? > Operations like read or write on dead streams should be no-ops. I think this should cause a task failure (maybe even a hard program assertion failure), rather than doing nothing, BUT, it should be almost impossible to cause, because nothing should return a bad stream, and code that "breaks" a stream should be forced to deal with it or be unwound, rather than simply continuing. > * Stream readers such as `read_uint` should be duplicated into two > methods for convenience: `read_uint` and `try_read_uint`. The former > just delegates to the latter with `.get()`. This is pretty bad, imho -- enough to spur me into writing long emails with alternatives ;) That system would cause a massive development burden for library writers/users, create much larger APIs, create too many similar functions, etc. It would mean code duplication, more bugs, more attack vectors, more confusion, and so on. I've used APIs like this, and they're not fun. Nor is working on a code base that uses them inconsistently. For instance, why should a try_read_uint exist, if you can: // assign a handler for read failures { read(); } // remove the handler AND have that handler code implemented just once, in a library? The only problems I can see are that: 1. Handlers for x() might be slow compared to a if try_x() statement. 2. The "do condition::cond.trap(handlerCode) actualcode" syntax is pretty unwieldy, and I'm not sure I like it being right at the top of the do block, potentially a long way from the code it affects. I think both of those should be addressed at a language/core level, rather than duplicating lots of functions in every module/lib. I tend to think, if a few developers can do something once, to save tens or hundreds or thousands of users doing the same thing, all in their own slightly different ways, with their own bugs, time loss, incompatibilities, etc., then it should be done right the first time. So, FWIW, since aspirational examples were mentioned, I would aim for something more like this: try { handle io::conditions::diskFull with io::handlers::purgeTempFiles; let fp = io::open(somePath, io::mode::write); fp.write(someBytes); } catch (cond : &io::Condition) { io::println(fmt!( "Some non-disk-full error (%?) occured, OR we couldn't purge disk space." "I don't know how to handle this. Rethrowing.", cond )); raise cond; } finally { // Restores the default handler state before we changed it above. // it might restore core::throwHandler as the handler, for example, // which just throws up the stack and unwinds, like other language's // exceptions would. // // NOTE: To reduce boilerplate, this should probably be implicit in // exiting the try block, rather than requiring a manual finally // block entry. handle io::cond::diskFull with super; } In other words, I'm imagining a language where: * You have Conditions, built by ConditionFactories. The casual user doesn't need to care, he just uses the API and handles its Conditions. * ConditionFactories interface with the call stack to allow building a stack of Handlers for the Condition. * Conditions are ALSO usable just like exceptions: they're /throwable/ & /catchable/, by naming the specific class you want to catch, or by naming a base class/trait. * The only real difference between catching a thrown Condition and handling one would be that: o In-place Condition handling is done with a closure or a function call o Thrown Conditions first use a special in-place Handler that unwinds the stack, passing the condition up the stack to a catch block, or, if no more catch blocks exist, to terminate() (or Rust's equivalent). * If you don't set a Handler, you get the default behaviour defined in that Condition class, or, if that is not set, the language/library default for /any/ Condition class, which is probably throwing, with the *option* of catching. * While a Condition can be caught by catch() {}, handled by a function, or handled by a closure, all three methods take a compatible argument: a Condition trait, or a variation. This allows code sharing, aids familiarity, etc. * Condition handling code ends by calling one of: cond.retry() To attempt to retry the code that raised the condition. I confess, I've little knowledge of how this works in Rust, but I imagine it's something like a guarded try block, with potential to become like STM. raise cond To throw the condition to a catch () block further up the stack * The Condition trait would support retrieving the stack frame, the file/line which the condition occurred at, etc., through methods. * In the case of catch blocks, some of that information would have been built up during the stack unwind, before the information was lost. * Conditions passed to in-place code where no stack unwinding is needed, would LOOK the same to the user, but they'd be FASTER, because: o The handling code would (interchangeably) be closures or functions. o That code would ideally be inlined whenever advantageous. o The Condition object would not be built up ahead of time, since it might not be needed, and all the information would be there in the current and previous stack frames anyway. There's no need to package all that information unless the Condition is thrown. *_Variations_*_ _ * Some kind of tracking of previously set handlers is needed. This could be as simple as setting tempory variables. However, it could be useful to allow a full stack of handlers, on a per-call-stack basis, so that raise cond in inline handlers calls the previous handler, until it reaches the throw handler, and then catch blocks take over. Using raise cond in those rethrows cond up the stack. * As a less invasive proposal, to avoid adding the handle keyword, this sort of syntax could be used: try { io::cond::diskFull.push_handler(io::handlers::purgeTempFiles) // some code } finally { io::cond::diskFull.pop_handler();// again, this could be implicit if pushes happen in the try block } This is closer to Rust's existing condition handling (if I've been looking at the latest version). However, I think it's less elegant, even if it does save keywords. IMHO, error handling is SUCH a big, frequent thing in languages, that it deserves a few keywords of its own. The full concept above would require only two new keywords: "handle", and "catch", along with some simple new statements. I'm not qualified to implement it in a compiler, but I believe it would be minimal effort, over the basic throwable exception model. With the alternative syntax, only "catch" would be new, and optional. To me, the extra keywords/work seem like a small price, for what we'd gain in clarity, elegance, and flexibility. We'd have the best of two popular error handling models, to choose from at will, with a nice syntax, too. -- Lee -------------- next part -------------- An HTML attachment was scrubbed... URL: From leebraid at gmail.com Sat Apr 27 09:10:09 2013 From: leebraid at gmail.com (Lee Braiden) Date: Sat, 27 Apr 2013 17:10:09 +0100 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517BB134.4040405@gmail.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> <517BB134.4040405@gmail.com> Message-ID: <517BF861.1000501@gmail.com> On 27/04/13 12:06, David Bruant wrote: > Le 26/04/2013 23:23, Brian Anderson a ?crit : >> I do think 50,000 I/O-performing tasks in a 32-bit process is within >> our reach. Last year I demonstrated 500,000 simultaneous Rust tasks >> (that did nothing but wait) in a 32-bit process, but there have been >> severe regressions since. On Linux I think we can get the initial >> allocation overhead for a single task into the ~2k range for sure. > Still, one stack per I/O operation has a bad smell to it. Being forced > to create a new task (even if "only" 2k) because the 49000 previous > ones are sitting idle doesn't sound right. Not contacting the remote > resource (disk, network) would be worse. To do efficient IO, there got > to be a cheap way to start an IO and wait for it. Creating a task, > doesn't sound cheap enough to work at scale. But we're not talking about creating a new task for every io operation as the io module's usual under-the-hood strategy, surely? It seems to me that, by default, what we'd want is a sync api which under the hood, creates one task per drive accessed, or maybe max(drives_in_use, number_of_cores). I think the OS will make them async with the drive hardware anyway, though, so number_of_cores doesn't matter. We wouldn't want to request 1000 different files (or seeks) at the same time, from one drive, though, right? I know there is command queuing on drives and all, but still... -- Lee -------------- next part -------------- An HTML attachment was scrubbed... URL: From danielmicay at gmail.com Sat Apr 27 09:19:53 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sat, 27 Apr 2013 12:19:53 -0400 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517BF861.1000501@gmail.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> <517BB134.4040405@gmail.com> <517BF861.1000501@gmail.com> Message-ID: On Sat, Apr 27, 2013 at 12:10 PM, Lee Braiden wrote: > On 27/04/13 12:06, David Bruant wrote: > > Le 26/04/2013 23:23, Brian Anderson a ?crit : > > I do think 50,000 I/O-performing tasks in a 32-bit process is within our > reach. Last year I demonstrated 500,000 simultaneous Rust tasks (that did > nothing but wait) in a 32-bit process, but there have been severe > regressions since. On Linux I think we can get the initial allocation > overhead for a single task into the ~2k range for sure. > > Still, one stack per I/O operation has a bad smell to it. Being forced to > create a new task (even if "only" 2k) because the 49000 previous ones are > sitting idle doesn't sound right. Not contacting the remote resource (disk, > network) would be worse. To do efficient IO, there got to be a cheap way to > start an IO and wait for it. Creating a task, doesn't sound cheap enough to > work at scale. > > > But we're not talking about creating a new task for every io operation as > the io module's usual under-the-hood strategy, surely? > > It seems to me that, by default, what we'd want is a sync api which under > the hood, creates one task per drive accessed, or maybe max(drives_in_use, > number_of_cores). I think the OS will make them async with the drive > hardware anyway, though, so number_of_cores doesn't matter. > > We wouldn't want to request 1000 different files (or seeks) at the same > time, from one drive, though, right? I know there is command queuing on > drives and all, but still... > > > -- > Lee You want to make all of the I/O requests you can at the same time and the OS I/O scheduler will schedule them in the way that minimizes the work required. That's why systemd takes 2 seconds to do a full boot instead of 15-20 seconds. Although the topic of the discussion is mostly networking where you absolutely don't want to queue them. From pwalton at mozilla.com Sat Apr 27 10:15:19 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 27 Apr 2013 10:15:19 -0700 Subject: [rust-dev] continue and related keyword bikeshed [was Re: LL(1) problems] In-Reply-To: <3346118.PkR6fr3BVq@l10036> References: <51788FB2.3020103@mozilla.com> <517A9C2F.8090003@mozilla.com> <517AB65F.9000709@mozilla.com> <3346118.PkR6fr3BVq@l10036> Message-ID: <517C07A7.7030202@mozilla.com> On 4/27/13 1:24 AM, Diggory Hardy wrote: > What the... > > There's better things to innovate on than renaming 'continue'. Sometimes I > think rules get taken too far. Perhaps the fact this has been such a long- > running argument is evidence of a problem. For what it's worth, I am still in favor of just calling it "continue". Patrick From pwalton at mozilla.com Sat Apr 27 10:30:08 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 27 Apr 2013 10:30:08 -0700 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517BB134.4040405@gmail.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> <517BB134.4040405@gmail.com> Message-ID: <517C0B20.1060908@mozilla.com> On 4/27/13 4:06 AM, David Bruant wrote: > I believe too this is doomed to happen. Firefox is under a huge struggle > to remove as much as sync IO code as possible as part of the Snappy > effort [1]. This is a completely misleading comparison. Firefox's sync I/O *blocks the entire main thread of the browser*, freezing up the UI in the process. That's why Firefox is removing it. Firefox doesn't have lightweight green threads. And Servo doesn't even have a "main thread". > Tasks provide something easier to use than threads, so a > browser in Rust can make things snappier by moving things to tasks, but > allocation, de-allocating and scheduling have a cost. There is a plan to cache aggressively, to avoid allocation and deallocation of stacks. Scheduling is very quick, just a context switch in userspace. > Still, one stack per I/O operation has a bad smell to it. Being forced > to create a new task (even if "only" 2k) because the 49000 previous ones > are sitting idle doesn't sound right. Not contacting the remote resource > (disk, network) would be worse. To do efficient IO, there got to be a > cheap way to start an IO and wait for it. Creating a task, doesn't sound > cheap enough to work at scale. I don't see any reason why not; the overhead of one userland context switch seems minuscule to me compared to the overhead of doing the I/O. Have you done benchmarks? > I'd like to encourage everyone reading to take the time to watch [2] (at > least 10-15mins starting where I linked to). If you're going to count allocation and deallocation of stacks against Rust's model, then why not count the allocation and deallocation of the callback closures and associated environments in node.js' model? It is *not* the case that node.js I/O allocation-free, as you're implying. If you're carrying around state per I/O request, and you have an unbounded number of I/O requests that can be in flight, you must incur an allocation to store that state. Whether that's part of a callback or part of a task's stack, it has to happen. Patrick From leebraid at gmail.com Sat Apr 27 10:39:49 2013 From: leebraid at gmail.com (Lee Braiden) Date: Sat, 27 Apr 2013 18:39:49 +0100 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517BA36C.4000400@seld.be> References: <51785EE8.1000206@mozilla.com> <517BA36C.4000400@seld.be> Message-ID: <517C0D65.9010702@gmail.com> Jordi Boggiano Wrote: > Feels weird to have str implement something specific to another module, > but if there is no other way it sounds more user friendly than a > gazillion open_* methods. > > > A few more comments on other things: > > - Streams are great, and the ability to register new stream protocol > handler for "foo:..." urls would indeed be a big plus. I agree; it's great that locations other than local file paths is being considered, especially in the context of general streams. BUT, I think the right thing would be to support URIs, rather than just URLs. For example, supporting URIs would also allow accessing URNs like:| | open(Uri("magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C")) "Get some data, identified by a SHA1 hash, from whichever data sources you have." For instance, this is popular on p2p networks, but is probably equally valid for, say, providing data from multiple key/value stores (say, MongoDB and LevelDB), in a database-independent way. open(Uri("urn:isbn:0451450523|"))| "Open the book with the given ISBN number." open(Uri("urn:issn:0167-6423")) "Open the Science of Computer Programming Journal." open(Uri("|urn:ietf:rfc:2648"|)) "Open IETF RFC 2648." My point is simply that there's more out there than just URLs, and if we're designing a stream API, it would be sensible to support the full range. > - open vs connect, I'd say open. Opening a connection sounds ok, > connecting a file sounds awkward. Yep. -- Lee -------------- next part -------------- An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sat Apr 27 10:51:03 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 27 Apr 2013 10:51:03 -0700 Subject: [rust-dev] Simpler/more flexible condition handling was: Re: Update on I/O progress In-Reply-To: <517BF391.5040602@gmail.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <517AB424.1010304@mozilla.com> <517BF391.5040602@gmail.com> Message-ID: <517C1007.9030504@mozilla.com> On 4/27/13 8:49 AM, Lee Braiden wrote: > This would be a relatively ugly approach, to my way of thinking. Why > should a dead stream be returned at all, if the code to create it > failed? Why should I be able to call write() on something that could > not be created? Two reasons: 1. If `open` returned a result type, you'd then have to call `.get()` on it to achieve task failure. A lot of people dislike this approach. 2. We have to have the concept of a "dead stream" or a "stream in the error state" already, because the OS and standard libraries have this concept. Given that, it seems simpler to just piggyback on that idea rather than bifurcating the I/O methods into two: ones that return a result and ones that set the error state on the stream. >> Operations like read or write on dead streams should be no-ops. > > I think this should cause a task failure (maybe even a hard program > assertion failure), rather than doing nothing By default that would cause a task failure. Only if you override it with a condition would it be possible to continue after this. > BUT, it should be almost > impossible to cause, because nothing should return a bad stream, and > code that "breaks" a stream should be forced to deal with it or be > unwound, rather than simply continuing. Due to the fact that we don't know how many aliases there are to a given stream, there's no way to force code that "breaks" a stream to deal with it in such a way that it relinquishes all references to the stream. (Actually, we could do it with unique types, but that would be quite a burden -- you couldn't straightforwardly have a `@FileStream`, for example.) > For instance, why should a try_read_uint exist, if you can: > > // assign a handler for read failures > { read(); } > // remove the handler > > AND have that handler code implemented just once, in a library? What does `read_uint` return if the handler wants to continue? > To me, the extra keywords/work seem like a small price, for what we'd > gain in clarity, elegance, and flexibility. We'd have the best of two > popular error handling models, to choose from at will, with a nice > syntax, too. This seems to basically just be exceptions. While I agree that exceptions are a nice model from the programmer's point of view (although Graydon strongly disagrees), I do have concerns about the performance model. Exceptions are expensive. As a language implementor, we basically have three, not very appealing, options: 1. Burden every call site of every function call with checking an error code, even if an exception was not thrown. 2. Burden every destructor with a call to `setjmp()`, even if an exception is not thrown. 3. Use table-driven unwinding, which makes exceptions extremely slow--so slow that programmers can't use them for simple "is there an integer here?" queries. To me (3) is the only realistic option for Rust, but it means that we can't use exceptions for "try to parse an integer". Or rather, it means that if we try, programmers will end up inventing `try_read_uint` themselves. The upshot of this, in my mind, is that `try_read_uint`-style methods are inevitable--if we don't provide them, programmers will. After talking with Brian some, though, I feel as though libraries should provide `try_foo` methods only if it makes sense to do so. For example, it probably doesn't make sense for HTTP parsing libraries to supply a `try_parse_http` method. You only provide a `try` method if both of these are true: 1. Programmers will want to recover extremely quickly from invalid input. 2. The function returns something other than unit. (Otherwise, a condition handler is fine.) Patrick From leebraid at gmail.com Sat Apr 27 11:36:23 2013 From: leebraid at gmail.com (Lee Braiden) Date: Sat, 27 Apr 2013 19:36:23 +0100 Subject: [rust-dev] Simpler/more flexible condition handling was: Re: Update on I/O progress In-Reply-To: <517C1007.9030504@mozilla.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <517AB424.1010304@mozilla.com> <517BF391.5040602@gmail.com> <517C1007.9030504@mozilla.com> Message-ID: <517C1AA7.2040304@gmail.com> On 27/04/13 18:51, Patrick Walton wrote: > On 4/27/13 8:49 AM, Lee Braiden wrote: >> This would be a relatively ugly approach, to my way of thinking. Why >> should a dead stream be returned at all, if the code to create it >> failed? Why should I be able to call write() on something that could >> not be created? > > Two reasons: > > 1. If `open` returned a result type, you'd then have to call `.get()` > on it to achieve task failure. A lot of people dislike this approach. Right, but this is why the (in this instance) exception model would be better. > 2. We have to have the concept of a "dead stream" or a "stream in the > error state" already, because the OS and standard libraries have this > concept. Given that, it seems simpler to just piggyback on that idea > rather than bifurcating the I/O methods into two: ones that return a > result and ones that set the error state on the stream. No argument there, except that it might be nice to have a higher-level API than the OS model. > By default that would cause a task failure. Ah, I see. > Due to the fact that we don't know how many aliases there are to a > given stream, there's no way to force code that "breaks" a stream to > deal with it in such a way that it relinquishes all references to the > stream. (Actually, we could do it with unique types, but that would be > quite a burden -- you couldn't straightforwardly have a `@FileStream`, > for example.) > > Only if you override it with a condition would it be possible to > continue after this > >> For instance, why should a try_read_uint exist, if you can: >> >> // assign a handler for read failures >> { read(); } >> // remove the handler >> >> AND have that handler code implemented just once, in a library? > > What does `read_uint` return if the handler wants to continue? Right, I was thinking that Rust had a transaction sort of model for retrying conditions, but it's just if worked else conditionhandler. In that model, the handler should either solve the problem and continue, or (eventually) throw. > >> To me, the extra keywords/work seem like a small price, for what we'd >> gain in clarity, elegance, and flexibility. We'd have the best of two >> popular error handling models, to choose from at will, with a nice >> syntax, too. > > This seems to basically just be exceptions. No, it addresses both, as well as your performance concerns below. > While I agree that exceptions are a nice model from the programmer's > point of view (although Graydon strongly disagrees), I do have > concerns about the performance model. Exceptions are expensive. As a > language implementor, we basically have three, not very appealing, > options: > > 1. Burden every call site of every function call with checking an > error code, even if an exception was not thrown. Right, horrible. > 2. Burden every destructor with a call to `setjmp()`, even if an > exception is not thrown. > >> 3. Use table-driven unwinding, which makes exceptions extremely >> slow--so slow that programmers can't use them for simple "is there an >> integer here?" queries. No. My point is that we can provide the best of both models -- exceptions AND local conditions, and avoid some of the speed issues. Iff we can provide inline, in-place condition code that either handles the problem without examining complex exception objects, then we can eliminate the performance costs, without exposing all the error handling to users. But iff that can't be handled locally, the handler could still throw, and allow a fallback to the exception model. I don't know how implementable it is in Rust, but the model I suggested, or something like it, would allow this optimisation, avoiding some of the stack unwinds etc., while still allowing that when necessary. It helps with things like "I'm trying to write data, and the disk is full, but there are all these temporary files lying around." It helps with parsing bad data in the sense that you could do a tight loop, dropping mpeg frames until you get one you can parse, for instance, or if you're re-reading a bad block up to N times before really throwing an error. If you have one character from a user or file, and it's as right as it will ever be, but is still wrong, then you probably need to handle that AS an error, then I can't see much option but to throw right back to the UI, and incur the performance issues associated with that. But what kind of future performance can you have, if your required input is screwed beyond repair? However, if you have a buffer of data, and you're guessing which encoding it uses (say, endianness), then it would make sense to quickly try the other encoding without throwing etc, but then still be able to throw, if neither method produces a valid checksum. The inline handler concept I talked about would allow that, with only performance costs in the "neither is valid" scenario, and minimal performance costs even then, if using the proxy approach I mentioned. Also, by thinking of it in terms of /setting/ handlers, and thinking of those handlers as reusable components, rather than closures coded each time, we can have a much more readable, standardised, less noisy syntax than the whole do condition.trap (|e| { code}) { real code } thing. > After talking with Brian some, though, I feel as though libraries > should provide `try_foo` methods only if it makes sense to do so. For > example, it probably doesn't make sense for HTTP parsing libraries to > supply a `try_parse_http` method. You only provide a `try` method if > both of these are true: > > 1. Programmers will want to recover extremely quickly from invalid input. > > 2. The function returns something other than unit. (Otherwise, a > condition handler is fine.) That's a sensible breakdown of when it's necessary in the given model, but I still think we should avoid the entire model, even if it requires language changes. -- Lee From pwalton at mozilla.com Sat Apr 27 11:50:42 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sat, 27 Apr 2013 11:50:42 -0700 Subject: [rust-dev] Simpler/more flexible condition handling was: Re: Update on I/O progress In-Reply-To: <517C1AA7.2040304@gmail.com> References: <51785EE8.1000206@mozilla.com> <51798B64.9020008@mozilla.com> <517AB424.1010304@mozilla.com> <517BF391.5040602@gmail.com> <517C1007.9030504@mozilla.com> <517C1AA7.2040304@gmail.com> Message-ID: <517C1E02.20008@mozilla.com> On 4/27/13 11:36 AM, Lee Braiden wrote: > On 27/04/13 18:51, Patrick Walton wrote: >> On 4/27/13 8:49 AM, Lee Braiden wrote: >>> This would be a relatively ugly approach, to my way of thinking. Why >>> should a dead stream be returned at all, if the code to create it >>> failed? Why should I be able to call write() on something that could >>> not be created? >> >> Two reasons: >> >> 1. If `open` returned a result type, you'd then have to call `.get()` >> on it to achieve task failure. A lot of people dislike this approach. > > Right, but this is why the (in this instance) exception model would be > better. > >> 2. We have to have the concept of a "dead stream" or a "stream in the >> error state" already, because the OS and standard libraries have this >> concept. Given that, it seems simpler to just piggyback on that idea >> rather than bifurcating the I/O methods into two: ones that return a >> result and ones that set the error state on the stream. > > No argument there, except that it might be nice to have a higher-level > API than the OS model. > >> By default that would cause a task failure. > > Ah, I see. > >> Due to the fact that we don't know how many aliases there are to a >> given stream, there's no way to force code that "breaks" a stream to >> deal with it in such a way that it relinquishes all references to the >> stream. (Actually, we could do it with unique types, but that would be >> quite a burden -- you couldn't straightforwardly have a `@FileStream`, >> for example.) >> > > > >> Only if you override it with a condition would it be possible to >> continue after this >> >>> For instance, why should a try_read_uint exist, if you can: >>> >>> // assign a handler for read failures >>> { read(); } >>> // remove the handler >>> >>> AND have that handler code implemented just once, in a library? >> >> What does `read_uint` return if the handler wants to continue? > > Right, I was thinking that Rust had a transaction sort of model for > retrying conditions, but it's just if worked else conditionhandler. What I mean is, what do these functions return? fn read_uint() -> uint { ... } fn read_int() -> int { ... } fn read_i8() -> i8 { ... } ... If the condition handler doesn't fail, the function has to return something. It could return the result of calling the condition, but that would result in a lot of conditions, since the return types are all incompatible. > No. My point is that we can provide the best of both models -- > exceptions AND local conditions, and avoid some of the speed issues. Ah, I see what you mean. This seems basically equivalent to what we have now, plus catchable failure and some syntax. In that case I'm personally OK with catchable failure, although not everybody on the core team is. Perhaps we could introduce a form which is like "spawn a task to catch an exception" from a data sharing view (i.e. it takes an ~fn and can't close over any `@` data) but is optimized to just call the closure and trap failure instead of actually spawning a whole new task. Regarding new syntax, I'm not sure we need it, as we have macros... Patrick From mikhail.zabaluev at gmail.com Sat Apr 27 12:29:29 2013 From: mikhail.zabaluev at gmail.com (Mikhail Zabaluev) Date: Sat, 27 Apr 2013 22:29:29 +0300 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517BF861.1000501@gmail.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> <517BB134.4040405@gmail.com> <517BF861.1000501@gmail.com> Message-ID: Hi Lee, 2013/4/27 Lee Braiden : > > But we're not talking about creating a new task for every io operation as > the io module's usual under-the-hood strategy, surely? > > It seems to me that, by default, what we'd want is a sync api which under > the hood, creates one task per drive accessed, or maybe max(drives_in_use, > number_of_cores). I think the OS will make them async with the drive > hardware anyway, though, so number_of_cores doesn't matter. This is similar to what GLib/GIO designers have achieved (and I am writing Rust bindings for it, so hopefully everybody can soon try that async I/O stack in Rust, too). Client operations are dispatched under the hood to a thread pool, and an implementation of a complex operation can choose to perform smaller steps synchronously in a task to avoid the async overhead for each constituent step. The client can pass a thread-safe cancellation handle to be able to cancel the whole operation on every step (thankfully not in the finicky POSIX way), with the theoretical granularity of every blocking call to the OS or a backend. In hope this information is useful, Mikhail From bruant.d at gmail.com Sat Apr 27 12:43:42 2013 From: bruant.d at gmail.com (David Bruant) Date: Sat, 27 Apr 2013 21:43:42 +0200 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517C0B20.1060908@mozilla.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> <517BB134.4040405@gmail.com> <517C0B20.1060908@mozilla.com> Message-ID: <517C2A6E.1080008@gmail.com> Le 27/04/2013 19:30, Patrick Walton a ?crit : > On 4/27/13 4:06 AM, David Bruant wrote: >> I believe too this is doomed to happen. Firefox is under a huge struggle >> to remove as much as sync IO code as possible as part of the Snappy >> effort [1]. > > This is a completely misleading comparison. Firefox's sync I/O *blocks > the entire main thread of the browser*, freezing up the UI in the > process. That's why Firefox is removing it. Firefox doesn't have > lightweight green threads. And Servo doesn't even have a "main thread". True. >> Tasks provide something easier to use than threads, so a >> browser in Rust can make things snappier by moving things to tasks, but >> allocation, de-allocating and scheduling have a cost. > > There is a plan to cache aggressively, to avoid allocation and > deallocation of stacks. Scheduling is very quick, just a context > switch in userspace. > >> Still, one stack per I/O operation has a bad smell to it. Being forced >> to create a new task (even if "only" 2k) because the 49000 previous ones >> are sitting idle doesn't sound right. Not contacting the remote resource >> (disk, network) would be worse. To do efficient IO, there got to be a >> cheap way to start an IO and wait for it. Creating a task, doesn't sound >> cheap enough to work at scale. > > I don't see any reason why not; the overhead of one userland context > switch seems minuscule to me compared to the overhead of doing the > I/O. Have you done benchmarks? I haven't. However, what I've read in this message and a couple of others [1][2] about the cost of tasks makes me more optimistic than I initially was. >> I'd like to encourage everyone reading to take the time to watch [2] (at >> least 10-15mins starting where I linked to). > > If you're going to count allocation and deallocation of stacks against > Rust's model, then why not count the allocation and deallocation of > the callback closures and associated environments in node.js' model? > It is *not* the case that node.js I/O allocation-free, as you're > implying. I'm was implying that sorry for the confusion. I'm not a libuv and Node.js expert, but I believe it could take as few as a file descriptor, a reference to the function to call when the request comes back and a message slot in the event loop message queue. The closure cost doesn't count as it's application memory. A Rust program would have an equivalent cost (forgetting that JS doesn't have a control on memory as efficient as Rust) In any case, the few things I enumerated don't seem to compare to the 2k/4k that's apparently necessary for a new task stack. I think the cost of tasks can be made only marginally bigger than an event loop if tasks are created lazily (which I believe is what is suggested in [2]). Creating them lazily would require a "queue" of tasks to create and run which would be the moral equivalent of the message queue in the event loop. > If you're carrying around state per I/O request, and you have an > unbounded number of I/O requests that can be in flight, you must incur > an allocation to store that state. Whether that's part of a callback > or part of a task's stack, it has to happen. Definitely. The point I was trying to make is that the current cost (2k/4k) seems disproportionate by comparison with what's needed in theory while waiting for an I/O request to come back (a file descriptor and a pointer to the function to call) Thanks for your answer, David [1] https://mail.mozilla.org/pipermail/rust-dev/2013-April/003829.html [2] https://mail.mozilla.org/pipermail/rust-dev/2013-April/003837.html From james at mansionfamily.plus.com Sun Apr 28 01:36:36 2013 From: james at mansionfamily.plus.com (james) Date: Sun, 28 Apr 2013 09:36:36 +0100 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517AA5EB.4090508@mozilla.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AA5EB.4090508@mozilla.com> Message-ID: <517CDF94.7020808@mansionfamily.plus.com> On 26/04/2013 17:06, Patrick Walton wrote: > On 4/25/13 10:42 PM, james wrote: >> If not, I wonder if there should be more effort on the AIO layer first, >> and then consider a synchronous shim on top. > > That's exactly what's being done. > > Patrick OK. It wasn't clear whether the AIO layer was primarily an internal implementation artifact, or exposed as the (primary) user-level IO API. You are saying the latter? James -------------- next part -------------- An HTML attachment was scrubbed... URL: From dbau.pp at gmail.com Sun Apr 28 04:10:31 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sun, 28 Apr 2013 21:10:31 +1000 Subject: [rust-dev] Random number generation In-Reply-To: <517B4710.7000205@mozilla.com> References: <517B2E49.5000302@gmail.com> <517B4710.7000205@mozilla.com> Message-ID: <517D03A7.70804@gmail.com> On 27/04/13 13:33, Graydon Hoare wrote: > On 26/04/2013 6:47 PM, Huon Wilson wrote: > >> This change would double or triple throughput of random f64 generation >> on 64-bit platforms compared to using the 32-bit algorithm (and >> increase it 10-20x compared to calling the rng in the runtime, as is >> done now). On this note, f64s are generated by `a/max_u32 + >> b/max_u32^2 + c/max_u32^3`, where a, b, and c are random u32s, Many >> other languages just generate a single u64 and multiply by `1/max_u64` >> (e.g. http://hg.python.org/cpython/file/2.7/Lib/random.py#l809, this >> even uses 7 bytes, not 8), would this be an acceptable change? > > I'm not expert in this area and I'm not sure if any of us are; you > might know better than anyone else here. I certainly don't object to > adopting the ISAAC-64 algorithm if it's well understood by experts to > be an improvement over the 32bit variant. If you'd be so kind as to > survey the state of this sort of thing, document it and make changes > to conform to what appears to be the best practice of other libraries > (following our library-editing process[1] .. mostly just leave a paper > trail for others), I would certainly appreciate it. > Page created: https://github.com/mozilla/rust/wiki/Lib-rand From a very brief initial survey, there doesn't seem to be much literature about ISAAC-64 specifically, but is extremely similar to ISAAC itself. I shall continue my investigation. From dbau.pp at gmail.com Sun Apr 28 05:46:07 2013 From: dbau.pp at gmail.com (Huon Wilson) Date: Sun, 28 Apr 2013 22:46:07 +1000 Subject: [rust-dev] Random number generation In-Reply-To: References: <517B2E49.5000302@gmail.com> Message-ID: <517D1A0F.70503@gmail.com> On 27/04/13 15:28, Andrei de Ara?jo Formiga wrote: > As I have some interest in using RNGs in Rust, I'd like to chime in on > this. > > The extra traits like "RandomDistribution" would be a good thing, > especially if it would be possible to "plug" a different, custom > generator than the one provided and use the custom generator with code > that simply calls rand(). For example for normal generation I might > not want to use Ziggurat, or maybe I want a quasi-random uniform > generator instead of a PRNG. (For normal generation I've been using > Box Muller but it is a bit slow, Ziggurat may be slower when > generating samples on the tails of the distribution, so maybe the > ideal would be to use the inversion method over a good algorithm for > generating quantiles, like R does, but this takes a bit more work). > > Also, if you're not already doing so I'd recommend running some > statistical tests on the PRNG you're implementing, just to have a > greater degree of confidence about them. The Diehard and Dieharder > test suites are popular for testing the output of a PRNG. I may help > with this if needed. > > The current organisation of core::rand means that the "raw" (P)RNG is pluggable; everything is parameterised over an Rng trait, and, at the moment, there is no obvious reason why this couldn't be maintained (I'll be making every effort to keep it this way: it gives a nice way of using (for example) both crypto-quality RNGs and simulation-speed RNGs without reimplementing everything). FWIW, the inversion method seems to be slower than Ziggurat for Exp(1) (logs are really slow!), and the sampling-from-tails step should only happen about 0.02% of the time for sampling from N(0,1), assuming I understand the algorithm correctly. (My current implementation uses Ziggurat with 256 slices, which means the tails start at +-3.654 for the normal distribution.) I would very much appreciate/need assistance, even if it is just adding some suggestions/links to the lib wiki page[1]. At the moment I'm visualising the key part of the distribution sampling as trait Distribution { fn sample(&self, rng: &R) -> Ret; } so that Normal can impl Distribution and Binomial can impl Distribution (for example). This keeps the raw rng separate from the distributions, so that all the rng needs to be able to do is generate a u32 or a u64 and then it should be able to be used to sample from any/all distributions. At least, that's how I've been thinking about doing it, but I haven't actually taken pen-to-paper/hands-to-keyboard to see if it is reasonable in practice, and I'll be trying to have a look at other languages to see how they do things, documenting them at [1]. (If anyone has an example of a nice random-number related library/paper/language etc, they should throw a link to it on that page. I've added GSL as Diggory Hardy suggested.) And yes, I agree that tests are important. I'm thinking it might even be worth including a check-rand target in the makefiles depending on how serious we are about making the rand module "perfect" (probably only run by hand though, since it may fail sometimes due to how randomness works). Again, suggestions and help are most definitely welcome and wanted: I've never architectured a random number heirachy before. :) Huon [1]: https://github.com/mozilla/rust/wiki/Lib-rand From pwalton at mozilla.com Sun Apr 28 10:38:35 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Apr 2013 10:38:35 -0700 Subject: [rust-dev] RFC: Rework generic paths Message-ID: <517D5E9B.6040800@mozilla.com> Hi everyone, The reactions to this bug on impls [1] have caused me to think that the current treatment of paths in generic type and trait implementations is something of a wart and perhaps should be reworked. Specifically, the problem is that this: impl MyType { fn new() -> MyType { ... } } Cannot be accessed (as you might expect) like so: MyType::::new::() But instead you must concatenate the type parameters like this: MyType::new::() This is highly unintuitive. Basically, all of this is an artifact of the fact that, internally, we treat a type implementation as essentially a module, and modules don't have type parameters. This fact also brings with it an unfortunate issue relating to typedefs, namely that you cannot call static methods through them. You might wish to write: type IntMyType = MyType::; MyIntType::new::() But you can't. In fact, you can't call static methods *at all* through typedefs, meaning that this doesn't work: impl MyOtherType { fn new() -> MyOtherType { ... } } type Alias = MyOtherType; Alias::new() // doesn't work This severely reduces the utility of typedefs. I've been thinking about ways we could fix this without severely complicating the compiler, and I think I've got the sketch of an idea that might work. I propose that we change type implementations (and traits) to be less module-like in the following ways: 1. Forbid `use` statements from importing from type implementations or traits. Having `use` statements take type parameters would severely complicate an already complex resolution pass, and might even require the name resolution and typechecking phases to be intertwined in an incoherent way. 2. Add a new type of `path` to the grammar: '::'? identifier ('::' identifier)* '::' '<' type_parameters '>' '::' identifier ('::' identifier)* ('::' '<' type_parameters '>')? This production admits paths like `MyType::::new::()`. 3. Internally, whenever the resolve pass sees one of these paths, or sees a component in a pass resolve to a typedef, it drops the type parameters and follows any typedefs to find the associated `impl` or trait. 4. When the typechecker sees such a path, it resolves the type portion of that path. If the type didn't resolve to a nominal monotype, it reports an error. Otherwise, it pulls the type parameters out of that nominal type and concatenates them with the type parameters supplied in the rest of the path, if any, to produce the "real" set of type parameters used by typechecking and translation. These semantics should allow all type parameters to be dropped if they can be inferred, as today, but should allow typedefs to "just work". Unless I'm missing something. :) This is not a backwards compatible change, but I don't expect much code to be impacted: I suspect `use` from a trait or type implementation is rare, and concatenated type parameters even more so. Thoughts? Patrick [1]: https://github.com/mozilla/rust/pull/6087 From pwalton at mozilla.com Sun Apr 28 10:45:04 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Apr 2013 10:45:04 -0700 Subject: [rust-dev] PSA: ~"string" is probably not what you want Message-ID: <517D6020.9080307@mozilla.com> Just thought I'd give the mailing list a heads up that ~"string", besides being ugly, is generally inefficient: it allocates a string on the heap and frees it when it goes out of scope. There are no optimizations that eliminate the allocation. If you need to compare a `~str` against a constant string, use .equiv(): use core::cmp::Equiv; fn main() { let x = ~"foo"; if "foo".equiv(&x) { println("yep"); } } This should admittedly be imported by default. Patrick From leebraid at gmail.com Sun Apr 28 10:57:38 2013 From: leebraid at gmail.com (Lee Braiden) Date: Sun, 28 Apr 2013 18:57:38 +0100 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517D6020.9080307@mozilla.com> References: <517D6020.9080307@mozilla.com> Message-ID: <517D6312.7030203@gmail.com> On 28/04/13 18:45, Patrick Walton wrote: > If you need to compare a `~str` against a constant string, use .equiv(): > > use core::cmp::Equiv; > > fn main() { > let x = ~"foo"; > if "foo".equiv(&x) { > println("yep"); > } > } > > This should admittedly be imported by default. Really? Strings can't just be compared with == ? To be honest, that alone is almost enough to put me off the language -- not only is it ugly and unwieldy, but it suggests a lot of limitations in the language's memory model / type system / operator overloading, which would also make my own code ugly and unwieldy. What's the problem with ==, or the difference with equiv(), exactly? Is there some way to make it just work, no matter what kind of strings you're comparing? Perhaps "foo" == (*x) would work, for example? -- Lee From pwalton at mozilla.com Sun Apr 28 11:14:13 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Apr 2013 11:14:13 -0700 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517D6312.7030203@gmail.com> References: <517D6020.9080307@mozilla.com> <517D6312.7030203@gmail.com> Message-ID: <517D66F5.1020703@mozilla.com> On 4/28/13 10:57 AM, Lee Braiden wrote: > Really? Strings can't just be compared with == ? To be honest, that > alone is almost enough to put me off the language -- not only is it ugly > and unwieldy, but it suggests a lot of limitations in the language's > memory model / type system / operator overloading, which would also make > my own code ugly and unwieldy. > > What's the problem with ==, or the difference with equiv(), exactly? The problem is that `&str` and `~str` are not the same type. We could change `Eq` so that it doesn't require the same type on the left-hand-side and the right-hand-side, but that would complicate the trait system quite a bit. Currently, overloaded operators do not borrow. I guess we could change overloaded operators (or maybe just `==` and `!=`?) to try to borrow the left hand side and/or right hand side to make the types match. I think this is *probably* OK. However, we need to be careful, because it's exactly the kind of thing that could have unforeseen consequences. "Strings should be comparable with `==` without allocating" is the kind of thing that is "obviously true", but trying to do it without thinking carefully about the ramifications of borrowing in overloaded operators is problematic. We already have quite complex method lookup semantics exactly to make things like this just work, and it has fallout when you start having to get picky about how many dereferences you do. To be honest, the tone of your message is a little frustrating, because you jumped on one thing that's not ideal (that the different types `~str` and `&str` cannot be compared with `==`), said something inaccurate (that strings cannot be compared with `==`), and extrapolated it to the idea that Rust's type system is "ugly and unwieldy". No, it's just that we need to think carefully about how to handle this one case. > Is > there some way to make it just work, no matter what kind of strings > you're comparing? Perhaps "foo" == (*x) would work, for example? That doesn't work, because it makes the dynamically sized `str` a type, which is incoherent. (It would lead to dynamically sized stack frames, or structs or enums with infinite size, and so on.) Patrick From danielmicay at gmail.com Sun Apr 28 11:35:40 2013 From: danielmicay at gmail.com (Daniel Micay) Date: Sun, 28 Apr 2013 14:35:40 -0400 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517D6312.7030203@gmail.com> References: <517D6020.9080307@mozilla.com> <517D6312.7030203@gmail.com> Message-ID: On Sun, Apr 28, 2013 at 1:57 PM, Lee Braiden wrote: > On 28/04/13 18:45, Patrick Walton wrote: >> >> If you need to compare a `~str` against a constant string, use .equiv(): >> >> use core::cmp::Equiv; >> >> fn main() { >> let x = ~"foo"; >> if "foo".equiv(&x) { >> println("yep"); >> } >> } >> >> This should admittedly be imported by default. > > > Really? Strings can't just be compared with == ? To be honest, that alone > is almost enough to put me off the language -- not only is it ugly and > unwieldy, but it suggests a lot of limitations in the language's memory > model / type system / operator overloading, which would also make my own > code ugly and unwieldy. > > What's the problem with ==, or the difference with equiv(), exactly? Is > there some way to make it just work, no matter what kind of strings you're > comparing? Perhaps "foo" == (*x) would work, for example? > > > -- > Lee Strings and vectors are special cased in the syntax, ~"foo" and ~("foo") aren't the same type. This issue is specific to the string/vector implementations included in the language, it's a non-issue with borrowed pointers or owned/shared boxes. Eq doesn't take a type parameter for the right-hand side parameter, so if ~"str" is on the left-hand side the right-hand side has to be ~"str" too. Although a ~str can be borrowed as a slice so "foo" == ~"foo" *will* work. Eq *could* take a type parameter like Add, Sub, etc. - it just doesn't right now. From james at mansionfamily.plus.com Sun Apr 28 12:12:32 2013 From: james at mansionfamily.plus.com (james) Date: Sun, 28 Apr 2013 20:12:32 +0100 Subject: [rust-dev] Update on I/O progress In-Reply-To: <517BF861.1000501@gmail.com> References: <51785EE8.1000206@mozilla.com> <517A13AD.8000705@mansionfamily.plus.com> <517AF03A.3020704@mozilla.com> <517BB134.4040405@gmail.com> <517BF861.1000501@gmail.com> Message-ID: <517D74A0.3050002@mansionfamily.plus.com> >It seems to me that, by default, what we'd want is a sync api which under the hood, creates one task per drive accessed, or maybe max(drives_in_use, number_of_cores). I think the OS will make them async with the drive hardware anyway, though, so number_of_cores doesn't matter. I don't think drive access is the issue; but 50k network clients is nothing unusual as a target for a concentrator process that's handling fan-out for a service that is being accessed by (say) engines in a large grid, or connected client applications - and if you have a target user community that might connect its a darn site easier to design for that than to scale horizontally (until you absolutely have to, anyway). From heri16 at gmail.com Sun Apr 28 12:45:01 2013 From: heri16 at gmail.com (heri16 at gmail.com) Date: Sun, 28 Apr 2013 12:45:01 -0700 (PDT) Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: Message-ID: <517d7c3d.2777420a.038e.4f7a@mx.google.com> An HTML attachment was scrubbed... URL: From pwalton at mozilla.com Sun Apr 28 12:49:01 2013 From: pwalton at mozilla.com (Patrick Walton) Date: Sun, 28 Apr 2013 12:49:01 -0700 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517d7c3d.2777420a.038e.4f7a@mx.google.com> References: <517d7c3d.2777420a.038e.4f7a@mx.google.com> Message-ID: <517D7D2D.8090102@mozilla.com> On 4/28/13 12:45 PM, heri16 at gmail.com wrote: > It is very easy to create a language that is unwieldy, but hard to > create something KISS simple that can be adopted, and that will be > praised for its cleanliness and elegance. > > If the basic things are not simple, a language will be relegated to > academia, and will not be as popular as hoped. > > We really need to take a look into this one, and come up with something > workable. That won't be easy considering what Patrick has mentioned. As Daniel pointed out, it isn't so bad. I didn't realize that we already borrow on the left hand side, so you can write: fn main() { let x = ~"foo"; if "foo" == x { println("yep"); } } We just need to borrow on the right hand side too, so that `x == "foo"` works. I can think of ways to do it; none are particularly pretty, but I suspect we could make it work. But the situation is not so dire now. Patrick From simon.sapin at exyr.org Sun Apr 28 13:08:51 2013 From: simon.sapin at exyr.org (Simon Sapin) Date: Sun, 28 Apr 2013 22:08:51 +0200 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517D7D2D.8090102@mozilla.com> References: <517d7c3d.2777420a.038e.4f7a@mx.google.com> <517D7D2D.8090102@mozilla.com> Message-ID: <517D81D3.6090904@exyr.org> Le 28/04/2013 21:49, Patrick Walton a ?crit : > As Daniel pointed out, it isn't so bad. I didn't realize that we already > borrow on the left hand side, so you can write: > > fn main() { > let x = ~"foo"; > if "foo" == x { > println("yep"); > } > } Using `if == ` rather than the reverse is sometimes called a "Yoda condition" and considered bad style, but that?s purely aesthetic. It?s still good that this works as expected. > We just need to borrow on the right hand side too, so that `x == "foo"` > works. I can think of ways to do it; none are particularly pretty, but I > suspect we could make it work. But the situation is not so dire now. Is there a reason that both sides of the == operator should not behave the same? Like many operators == seems like it should be "symmetric", ie. a == b are always the same for any a and b (and their types, presumably.) Cheers, -- Simon Sapin From lists at arctur.us Sun Apr 28 13:13:50 2013 From: lists at arctur.us (Mitch Skinner) Date: Sun, 28 Apr 2013 13:13:50 -0700 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517D6020.9080307@mozilla.com> References: <517D6020.9080307@mozilla.com> Message-ID: On Sun, Apr 28, 2013 at 10:45 AM, Patrick Walton wrote: > If you need to compare a `~str` against a constant string, use .equiv(): > I have some code where I'm trying to match an owned string against a set of constant strings, and it's not clear to me how to take your advice there. fn match_upper(to_match: &str) -> int { match to_match.to_ascii().to_upper().to_str_ascii() { ~"ABC" => 1, ~"DEF" => 2, ~"GHI" => 3, _ => 0 } } Does each call to this function heap-allocate all the owned strings in the match expression? If so, how could I avoid that? Is there a more idiomatic way to do what I'm trying to do? Thanks for the PSA, Mitch -------------- next part -------------- An HTML attachment was scrubbed... URL: From martindemello at gmail.com Sun Apr 28 13:39:28 2013 From: martindemello at gmail.com (Martin DeMello) Date: Sun, 28 Apr 2013 13:39:28 -0700 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517D7D2D.8090102@mozilla.com> References: <517d7c3d.2777420a.038e.4f7a@mx.google.com> <517D7D2D.8090102@mozilla.com> Message-ID: In which case, would special-casing == and !=, as you mentioned earlier, be a bad thing to do? (Sincere question; from a user pov it would make sense, but I don't know whether it would make operator overloading conceptually more ugly to have that special case in there) martin On Sun, Apr 28, 2013 at 12:49 PM, Patrick Walton wrote: > On 4/28/13 12:45 PM, heri16 at gmail.com wrote: >> >> It is very easy to create a language that is unwieldy, but hard to >> create something KISS simple that can be adopted, and that will be >> praised for its cleanliness and elegance. >> >> If the basic things are not simple, a language will be relegated to >> academia, and will not be as popular as hoped. >> >> We really need to take a look into this one, and come up with something >> workable. That won't be easy considering what Patrick has mentioned. > > > As Daniel pointed out, it isn't so bad. I didn't realize that we already > borrow on the left hand side, so you can write: > > fn main() { > let x = ~"foo"; > if "foo" == x { > println("yep"); > } > } > > We just need to borrow on the right hand side too, so that `x == "foo"` > works. I can think of ways to do it; none are particularly pretty, but I > suspect we could make it work. But the situation is not so dire now. > > Patrick > > > _______________________________________________ > Rust-dev mailing list > Rust-dev at mozilla.org > https://mail.mozilla.org/listinfo/rust-dev From jack at metajack.im Sun Apr 28 14:13:26 2013 From: jack at metajack.im (Jack Moffitt) Date: Sun, 28 Apr 2013 15:13:26 -0600 Subject: [rust-dev] PSA: ~"string" is probably not what you want In-Reply-To: <517D6312.7030203@gmail.com> References: <517D6020.9080307@mozilla.com> <517D6312.7030203@gmail.com> Message-ID: > Really? Strings can't just be compared with == ? To be honest, that alone > is almost enough to put me off the language -- not only is it ugly and > unwieldy, but it suggests a lot of limitations in the language's memory > model / type system / operator overloading, which would also make my own > code ugly and unwieldy. This kind of faux outrage isn't really constructive. Most systems languages don't let you compare strings with ==. In C you use str*cmp as == is pointer equality. This is also true in Java where you must write `if (foo.equals(bar))`. It would certainly be nice to follow in C++'s footsteps where std::strings are comparable with ==, but I'm not sure it nullifies Rust's goals if this condition can't be met. Equality always seems to be a mixed bag. In JavaScript you have == and ===. In Erlang you have == and =:=. In Java you have == and .equals(). In Clojure you have = and ==. Lisps have all kinds of things. In many cases you can end up with asymmetry that violates people's mathemeatical expectations of equality (Clojure's == is only commutative when used with two args, with 3 it gets slightly weird). jack. From palmercox at gmail.com Sat Apr 27 23:06:36 2013 From: palmercox at gmail.com (Palmer Cox) Date: Sun, 28 Apr 2013 02:06:36 -0400 Subject: [rust-dev] List comprehensions / Do notation Message-ID: Hi, Rust seems like a really excellent language. One feature that Rust doesn't seem to have is a built-in list-comprehension syntax. Wikipedia points out that macros can be used to simulate this feature, but the resulting syntax is a bit clunky. Are there plans to add such a syntax to the language? I'm also curious if there are plans to add a Haskell style do-notation syntax to the language? It seems that macros can also be used to simulate this, but the end result is even more clunky than using macros to simulate list-comprehensions. I would think that such a syntax might be very useful for working with the results from multiple tasks. Thanks, -Palmer Cox -------------- next part -------------- An HTML attachment was scrubbed... URL: From jack at metajack.im Sun Apr 28 14:27:10 2013 From: jack at metajack.im (Jack Moffitt) Date: Sun, 28 Apr 2013 15:27:10 -0600 Subject: [rust-dev] RFC: Rework generic paths In-Reply-To: <517D5E9B.6040800@mozilla.com> References: <517D5E9B.6040800@mozilla.com> Message-ID: > But you can't. In fact, you can't call static methods *at all* through > typedefs, meaning that this doesn't work: This has bitten me a few times already, so I'm definitely in favor of making it work if possible. The rest of your proposal sounds good to me, although I can't speak for how easy it is to implement or how it complicates the compiler. jack. From banderson at mozilla.com Sun Apr 28 14:46:34 2013 From: banderson at mozilla.com (Brian Anderson) Date: Sun, 28 Apr 2013 14:46:34 -0700 Subject: [rust-dev] RFC: Rework generic paths In-Reply-To: <517D5E9B.6040800@mozilla.com> References: <517D5E9B.6040800@mozilla.com> Message-ID: <517D98BA.3010503@mozilla.com> On 04/28/2013 10:38 AM, Patrick Walton wrote: > Hi everyone, > > The reactions to this bug on impls [1] have caused me to think that > the current treatment of paths in generic type and trait > implementations is something of a wart and perhaps should be reworked. > Specifically, the problem is that this: > > impl MyType { > fn new() -> MyType { ... } > } > > Cannot be accessed (as you might expect) like so: > > MyType::::new::() > > But instead you must concatenate the type parameters like this: > > MyType::new::() > > This is highly unintuitive. > > Basically, all of this is an artifact of the fact that, internally, we > treat a type implementation as essentially a module, and modules don't > have type parameters. This fact also brings with it an unfortunate > issue relating to typedefs, namely that you cannot call static methods > through them. You might wish to write: > > type IntMyType = MyType::; > > MyIntType::new::() > > But you can't. In fact, you can't call static methods *at all* through > typedefs, meaning that this doesn't work: > > impl MyOtherType { > fn new() -> MyOtherType { ... } > } > > type Alias = MyOtherType; > > Alias::new() // doesn't work > > This severely reduces the utility of typedefs. > > I've been thinking about ways we could fix this without severely > complicating the compiler, and I think I've got the sketch of an idea > that might work. I propose that we change type implementations (and > traits) to be less module-like in the following ways: > > 1. Forbid `use` statements from importing from type implementations or > traits. Having `use` statements take type parameters would severely > complicate an already complex resolution pass, and might even require > the name resolution and typechecking phases to be intertwined in an > incoherent way. > > 2. Add a new type of `path` to the grammar: > > '::'? identifier ('::' identifier)* '::' '<' type_parameters '>' > '::' identifier ('::' identifier)* ('::' '<' type_parameters '>')? > > This production admits paths like `MyType::::new::()`. > > 3. Internally, whenever the resolve pass sees one of these paths, or > sees a component in a pass resolve to a typedef, it drops the type > parameters and follows any typedefs to find the associated `impl` or > trait. > > 4. When the typechecker sees such a path, it resolves the type portion > of that path. If the type didn't resolve to a nominal monotype, it > reports an error. Otherwise, it pulls the type parameters out of that > nominal type and concatenates them with the type parameters supplied > in the rest of the path, if any, to produce the "real" set of type > parameters used by typechecking and translation. > > These semantics should allow all type parameters to be dropped if they > can be inferred, as today, but should allow typedefs to "just work". > Unless I'm missing something. :) > > This is not a backwards compatible change, but I don't expect much > code to be impacted: I suspect `use` from a trait or type > implementation is rare, and concatenated type parameters even more so. > > Thoughts? bjz's use cases are pretty compelling, but restricting `use` like that is very unfortunate, making 'uniform method syntax' not quite uniform. From jack at metajack.im Sun Apr 28 14:50:35 2013 From: jack at metajack.im (Jack Moffitt) Date: Sun, 28 Apr 2013 15:50:35 -0600 Subject: [rust-dev] Random number generation In-Reply-To: <517B2E49.5000302@gmail.com> References: <517B2E49.5000302@gmail.com> Message-ID: Kenji Rikitake did similar work in Erlang a few years ago, suggesting SIMD--oriented Fast Mersenne Twister (SFMT) as a replacement for the random number generator in Erlang. I believe he also worked on updating the old Wichmann-Hill generator code from a 1982 version of the algorithm to a newer 2006 version. He gave a talk[1] on PRNGs at Erlang Factory which was pretty good and might be useful here, there is also a paper[2] on the same topic. This kind of stuff was also discussed[3] quite a bit on the mailing list at the time as well. [1] http://www.erlang-factory.com/conference/SFBay2011/speakers/kenjirikitake [2] http://dl.acm.org/citation.cfm?id=2034669 [3] http://erlang.2086793.n4.nabble.com/Implementation-of-a-2006-version-of-Wichmann-Hull-random-number-generator-for-Erlang-OTP-td3055286.html jack. From robert at ocallahan.org Sun Apr 28 15:03:39 2013 From: robert at ocallahan.org (Robert O'Callahan) Date: Mon, 29 Apr 2013 10:03:39 +1200 Subject: [rust-dev] No range integer type? Saftey beyond memory? In-Reply-To: <517AAA18.3070200@mozilla.com> References: <1UToOa-000PkW-TJ@internal.tormail.org> <517562EE.4000303@mozilla.com> <5176C842.1060407@mozilla.com> <517850A6.7080409@mozilla.com> <517AAA18.3070200@mozilla.com> Message-ID: On Sat, Apr 27, 2013 at 4:23 AM, Graydon Hoare wrote: > I think it has to be opt-in, yeah. Sadly. I mean, I wish we were living in > the world of hardware garbage collection and tagged memory words too, and > hensel codes had won out over floating point, and all our languages had > well defined total functional subsets with industrial strength provers > attached to them that we were legally obliged to use. > I don't understand the relationship between those features and integer overflow checking. There are very strong reasons why those features haven't developed, and none of those reasons apply to integer overflow checking. > Definitely a Milestone 2 consideration ;) >> > > Maybe. At least consideration. I think any variant would have to be > additive (backwards compatible) simply because in languages like this, it's > _really_ not what people assume as the default. > In my experience the default assumption is that integer overflow doesn't happen. Just for fun I did "grep -F ' + '" and "grep -F ' - '" in some mozilla-central graphics, DOM and layout code: gfx/thebes/*.cpp gfx/cairo/cairo/src/*.c content/base/src/*.cpp content/html/content/src/*.cpp layout/generic/*.cpp and skimmed the results. I might have missed something, but I found only three occurrences of addition/subtraction operators where overflow seemed expected: two in hash functions in cairo-cache.c, and one in a hash function in cairo-misc.c. Based on that data and previous experience with this code, I'm certain that those occurrences are vastly outweighed by handwritten code that tries to detect/avoid integer overflows, and also by arithmetic operations that are still vulnerable to overflow bugs in spite of those checks. Furthermore, I wonder how many average C/C++ programmers know that overflow of unsigned values is defined but overflow of signed values is not. I expect that most people's assumptions are plain incorrect. So I contend that integer overflow checking is more likely to prevent unexpected behavior than to cause it, especially when it really matters: in shipped code that's being attacked. Once in a while someone writing a hash function or similar will trip over, but it will be easy