Re: [rust-dev] Deprecating rustpkg
I also agree on the task force proposal, it's the right way to capitalize on past failure and success. For me, rust-pkg will not success if it doesn't have a proper centralized repository. That's a debate, the current version explicitely specify the URL where to download stuff. But things changes, developers changes, URL get broken, or a new developer forks a project or continue it on another repository. I have quite a good experience (I think) on dependency management, mostly on C++ (QT/Linux projects and embedded) and now python (that's why I love the simplicity and power of pipy!) so I would be glad to be associated with such task force. For me you have two approach: enough for major use case, things like pipy that do the job for most use case, and exhaustive approach where you end up with complicated but extremely powerful do-it-all tools like maven but that get eventually dropped because it's too complex to use. That is also joining the build system thread, where also rustpkg appeared :) But I push to split them appart: the dependency management tool should trigger a build system and not do everything - Gaetan 2014-01-28 Huon Wilson dbau...@gmail.com On 28/01/14 19:36, György Andrasek wrote: I never quite understood the problem `rustpkg` was meant to solve. For building Rust code, `rustc --out-dir build` is good enough. For running tests and benchmarks, `rustc` is good enough. For downloading things, I still need to feed it a github address, which kinda takes away any value it could have over `git clone` or git submodules. rustpkg (theoretically) manages fetching and building dependencies (with the appropriate versions), as well as making sure those dependencies can be found (i.e. what the -L flag does for rustc). What I would actually need from a build system, i.e. finding {C,C++,Rust} libraries, building {C,C++,Rust} libraries/executables and linking them to said {C,C++,Rust} libraries, it doesn't do. It also doesn't bootstrap rustc. rustpkg is unfinished and has several bugs, so describing its current behaviour/usage as if it were its intended behaviour/usage is not correct. I believe it was designed to handle native (non-Rust) dependencies to some degree. Huon [Disclaimer: I've never quite got a rustpkg workflow going. It's probably awesome, but completely overshadowed by `rustc`.] On 01/28/2014 09:02 AM, Tim Chevalier wrote: On Mon, Jan 27, 2014 at 10:20 PM, Val Markovic v...@markovic.io wrote: On Jan 27, 2014 8:53 PM, Jeremy Ong jeremyc...@gmail.com wrote: I'm somewhat new to the Rust dev scene. Would anybody care to summarize roughly what the deficiencies are in the existing system in the interest of forward progress? It may help seed the discussion for the next effort as well. I'd like to second this request. I haven't used rustpkg myself but I've read its reference manual ( https://github.com/mozilla/rust/blob/master/doc/rustpkg.md) and it sounds like a reasonable design. Again, since I haven't used it, I'm sure I'm missing some obvious flaws. Thirded. I implemented rustpkg as it's currently known, and did so in the open, detailing what I was thinking about in a series of exhaustively detailed blog posts. Since few people seemed very interested in providing feedback on it as I was developing it (with the exception of Graydon, who also worked on the initial design), I assumed that it was on the right track. I rewrote rustpkg because there was a perception that the initial design of rustpkg was not on the right track, nor was cargo, but obviously simply rewriting the whole system from scratch in the hopes that it would be better didn't work, since people are talking about throwing it out. So, before anybody embarks on a third rewrite in the hopes that *that* will be better, I suggest that a working group form to look at what went wrong in the past 2 or 3 attempts at implementing a build system / package system for Rust, so that those mistakes can be learned from. Perhaps all that needs to be done differently is that someone more central to the community needs to write it, but if that's what it takes, it seems preferable to the wasted time and effort that I imagine will ensue from yet another rewrite for the sake of throwing out code. Cheers, Tim ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Deprecating rustpkg
Rubygems is, in my opinion, one of the best examples of package managers for a programming language out there. I don't use ruby currently but I recall liking it much more than the competition, at least as of a few years ago. In no particular order, it features: - central repository - optionally specify alternative urls on a per package basis - hard and soft version requirements - local bundles (so you can have multiple versions of the same package and switch seamlessly from project to project) - dependency calculation - dependency groups (i.e. ability to group a number of deps in a test group which can be switched on or off) - local or systemwide install of libraries and executables - easy to write a package and publish it (very easy) - gem signing - plugin system that allowed extensions to be written (an example plugin was something that allowed a gem to be compiled with specific ruby versions iirc) - with the bundler gem, an easy way to at a glance, examine all dependencies of a given project and fetch them all (the Gemfile). This had implications to deploy processes too (gemfile.lock). This isn't a comprehensive list but it evidently made an impression on me. I'm sure there are tons of other things I'm missing. Other systems that I've worked with I found critically lacking in isolating the dependencies of one project from another or failing to resolve dependency trees satisfactorily. Most importantly, the ease with which packages could be downloaded and used immediately were immense. As mentioned before, getting this right is crucial to establishing a vibrant developer ecosystem (see rubygems and npm). On Tue, Jan 28, 2014 at 1:33 AM, Lee Braiden leebr...@gmail.com wrote: On 28/01/14 08:36, György Andrasek wrote: I never quite understood the problem `rustpkg` was meant to solve. For building Rust code, `rustc --out-dir build` is good enough. For running tests and benchmarks, `rustc` is good enough. For downloading things, I still need to feed it a github address, which kinda takes away any value it could have over `git clone` or git submodules. What I would actually need from a build system, i.e. finding {C,C++,Rust} libraries, building {C,C++,Rust} libraries/executables and linking them to said {C,C++,Rust} libraries, it doesn't do. It also doesn't bootstrap rustc. I agree with this. What I'd want is much more like apt (add repositories, update lists of available packages from those repositories, manage priorities between repositories, say that one repository should be preferred over another for a particular package, working in specific prefixes (/usr/local, /usr, /, ~/Projects/something-requiring-old-libs), but rust-specific and platform independent. -- Lee ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Deprecating rustpkg
On 01/28/2014 10:33 AM, Lee Braiden wrote: I agree with this. What I'd want is much more like apt (add repositories, update lists of available packages from those repositories, manage priorities between repositories, say that one repository should be preferred over another for a particular package, working in specific prefixes (/usr/local, /usr, /, ~/Projects/something-requiring-old-libs), but rust-specific and platform independent. What you actually want is Paludis[0], which installs from source. I'd propose it as a standard Rust package manager, but it does have some serious flaws for that purpose: - Designed as the package manager for a full Linux distro, so it wants to handle everything by itself. If you give it a build dependency on gcc, it'll want to maintain the entire toolchain. - No Windows support. - Hard dependency on `bash`. That said, it has solved a serious number of PM problems we should learn from: - Completely build system agnostic. All tooling is done in bash libraries called `exheres`, with an infinite number of customization hooks from patching to post-install. Can build everything from glibc to xmonad. - Separate set of build and run dependencies, with configurable install root: you can (probably) bootstrap an embedded Linux with it. - Metadata lives in a number of git repos you can cherry-pick. Creating your own is *easy*. - Some support for external package sources, like Hackage. - Fast[1] dependency handling including cycles and both global and local keywords: `doc` pulls in the doc build tools, `bash_completion` installs relevant extra files, `texture-float` enables patented code in mesa. - Installing from source control. - All user-facing configuration is done in /etc/paludis, where you can apply keywords, CFLAGS, mirrors, scm options, mask/unmask packages etc. on a per-package per-version basis with globs and stuff. tl;dr If you want to design a package manager, bootstrap an Exherbo[2] first. [0]: http://paludis.exherbo.org/overview/features.html [2]: http://exherbo.org/ [1]: ``` # time cave resolve world --everything Done: 2501 steps snip Executing pretend actions: 265 of 265 * You have 6 unread news items (use 'eclectic news' to read) real0m16.108s user0m12.706s sys 0m1.643s ``` ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Deprecating rustpkg
On 01/28/2014 04:33 AM, Lee Braiden wrote: On 28/01/14 08:36, György Andrasek wrote: I never quite understood the problem `rustpkg` was meant to solve. For building Rust code, `rustc --out-dir build` is good enough. For running tests and benchmarks, `rustc` is good enough. For downloading things, I still need to feed it a github address, which kinda takes away any value it could have over `git clone` or git submodules. What I would actually need from a build system, i.e. finding {C,C++,Rust} libraries, building {C,C++,Rust} libraries/executables and linking them to said {C,C++,Rust} libraries, it doesn't do. It also doesn't bootstrap rustc. I agree with this. What I'd want is much more like apt (add repositories, update lists of available packages from those repositories, manage priorities between repositories, say that one repository should be preferred over another for a particular package, working in specific prefixes (/usr/local, /usr, /, ~/Projects/something-requiring-old-libs), but rust-specific and platform independent. Have you ever used Composer https://getcomposer.org/? I know that Jordi Boggiano, one of the authors, has been involved with the Rust community in the past. Some Composer features that I think are critical for the new Rust package manager include: - Tags and branches are automatically recognized from git to create versions. - Version specifiers aren't just limited to this version exactly, but allow you to match on a range of versions (though Semantic Versioning is encouraged). - Packages have vendor prefixes (like rust/flate or leafstorm/mycoollibrary) to help avoid name conflicts and allow for forking, but these aren't linked to the way packages are retrieved. - There's a central repository, but it's really easy to add random git repositories to the composer.json, or to create your own repositories for internal use. - It automatically generates a lock file that allows you to reinstall exactly the same versions of the dependencies across machines. - Everything is installed per-project, so no conflicts across projects. (Though the new rustpkg may want to not do this exactly because of compile times.) If I had more time and more Rust experience, I would be interested in implementing a Composer-like package manager for Rust. Unfortunately I have little of both. :-( -- Thanks, Matthew Frazier http://leafstorm.us ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: Future-proof for unboxed closures
On Mon, Jan 27, 2014 at 08:33:57PM +0100, Gábor Lehel wrote: I think this question has a more general form, namely: when should I pass by value and when using move/my? I expect this will come up quite a bit if we add the latter. Yes, I agree. The main reason to use `move/my` is to permit moves of dynamically sized types. In the case of once closures, that is a trait type. Given that, I have wondered if we can do without it, and instead say that (e.g.) passing a DST as a by value argument is legal. Without a region, though, we'd need some other rules to prevent that DST from leaking. For example, you can pass a DST as an input parameter, but you cannot have a local variable, field, or return type of DST type. The last time I thought this through, those rules (or something like them) seemed onerous, but now they seem quite reasonable to me. (More or less the same as our old reference mode parameters.) They support the important use case of passing in a (unboxed) `OnceFn` object and permitting it to be called. Niko ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Deprecating rustpkg
On 01/27/2014 11:53 PM, Jeremy Ong wrote: I'm somewhat new to the Rust dev scene. Would anybody care to summarize roughly what the deficiencies are in the existing system in the interest of forward progress? It may help seed the discussion for the next effort as well. I can only speak for myself, but here are some reasons why I abandoned rustpkg and switched to CMake. Firstly, and overarchingly, it was the attitude of the project development with respect to issues. As a comparison, let me consider Rust the language. It is a pain to make my code pass the borrow check sometimes, the lifetimes are perhaps the most frustrating aspect of Rust. I put up with them however, because they solve a gigantic problem and are the keystone of Rust's safety-without-GC story. rustpkg also has many incredibly frustrating aspects, but they are there (in my opinion) arbitrarily and not as a solution to any real problem. When I hit them, I do not get the same sense of purposeful sacrifice I get with Rust's difficult points. Let me outline the specific issues I personally hit (I know of other ones, but I haven't encountered them personally). Conflation of package id and source. That fact combined with the fact that to depend on some external package you have to write extern mod = pkgid meant that you needed to create bizarre directory structures to depend on locally developed packages (e.g. you'd have to put your locally developed project in a directory tree like so: github.com/SiegeLord/Project). This is not something I was going to do. The package dependencies are written in the source file, which makes it onerous to switch between versions/forks. A simple package script would have solved it, but it wasn't present by design. My repositories have multiple crates, and rustpkg is woefully under-equipped to handle that case. You cannot build them without dealing with pkg.rs, and using them from other projects seemed impossible too (the extern mod syntax wasn't equipped to handle multiple crates per package). This is particularly vexing when you have multiple example programs alongside your library. I was not going to split my repository up just because rustpkg wasn't designed to handle that case. All of those points would be solved by having an explicit package description file/script which was THE overarching design non-goal of rustpkg. After that was made clear to me, I just ditched it and went to C++ style package management and a CMake build system. -SL ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Today's Rust contribution ideas
On Mon, Jan 27, 2014 at 11:41 PM, Sebastian Sylvan sebastian.syl...@gmail.com wrote: On Mon, Jan 27, 2014 at 9:33 AM, Matthieu Monrocq matthieu.monr...@gmail.com wrote: On Mon, Jan 27, 2014 at 3:39 AM, Brian Anderson bander...@mozilla.comwrote: Consensus is that the `do` keyword is no longer pulling its weight. Remove all uses of it, then remove support from the compiler. This is a 1.0 issue. # Experiment with faster hash maps (#11783) Rust's HashMap uses a cryptographically secure hash, and at least partly as a result of that it is quite slow. HashMap continues to show up very, very high in performance profiles of a variety of code. It's not clear what the solution to this is, but it is clear that - at least sometimes - we need a much faster hash map solution. Figure out how to create faster hash maps in Rust, potentially sacrificing some amount of DOS-resistance by using weaker hash functions. This is fairly open-ended and researchy, but a solution to this could have a big impact on the performance of rustc and other projects. You might be interested by a serie of articles by Joaquín M López Muñoz who maintains the Boost.MultiIndex library. He did a relatively comprehensive overview of the hash-maps implementation of Dirkumware (MSVC), libstdc++ and libc++ on top of Boost.MultiIndex, and a lot of benchmarks showing the performance for insertion/removal/search in a variety of setup. One of the last articles: http://bannalia.blogspot.fr/2014/01/a-better-hash-table-clang.html Let me also plug this blog post from a while back: http://sebastiansylvan.com/2013/05/08/robin-hood-hashing-should-be-your-default-hash-table-implementation/. There's also a followup on improving deletions*, which makes the final form the fastest hash map I know of. It's also compact (95% load factor, 32 bits overhead per element, but you can reduce that to 2 bits per element if you sacrifice some perf.), and doesn't allocate (other than doubling the size of the table when you hit the load factor). For a benchmark with lots of std::strings it was 23%, 66% and 25% faster for insertions deletions and lookups (compared to MSVC unordered_map), it also uses 30% less memory in that case. Seb * the basic form has an issue where repeated deletes gradually increases the probe count. In pathological cases this can reduce performance by a lot. The fix is to incrementally fix up the table on each delete (you could also do it in batch every now and then). It's still faster in all cases, and the probe-length as well as probe-length-variance remains low even in the most pathological circumstances. Thanks for the link, I should have mentioned that the C++ Standard version is constrained by a memory stability requirement which may or may not apply to Rust (thanks to borrow checks, it should be possible to know statically whether an element is borrowed or not). This memory stability requirement as well as some other requirements such as relative stability of items within the same equivalence class during insert/erase several constrain the design; and indeed if the requirements can be lifted it the designs proposed on bannalia will be suboptimal. -- Matthieu ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Deprecating rustpkg
Lots of good points in this thread, but I wanted to request deprecation, but not removal until a better alternative is documented and made available. Rustpkg works for my needs - I use it every day - but it definitely needs some TLC. Thanks! -- Ian On Tue, Jan 28, 2014 at 11:46 AM, SiegeLord slab...@aim.com wrote: On 01/27/2014 11:53 PM, Jeremy Ong wrote: I'm somewhat new to the Rust dev scene. Would anybody care to summarize roughly what the deficiencies are in the existing system in the interest of forward progress? It may help seed the discussion for the next effort as well. I can only speak for myself, but here are some reasons why I abandoned rustpkg and switched to CMake. Firstly, and overarchingly, it was the attitude of the project development with respect to issues. As a comparison, let me consider Rust the language. It is a pain to make my code pass the borrow check sometimes, the lifetimes are perhaps the most frustrating aspect of Rust. I put up with them however, because they solve a gigantic problem and are the keystone of Rust's safety-without-GC story. rustpkg also has many incredibly frustrating aspects, but they are there (in my opinion) arbitrarily and not as a solution to any real problem. When I hit them, I do not get the same sense of purposeful sacrifice I get with Rust's difficult points. Let me outline the specific issues I personally hit (I know of other ones, but I haven't encountered them personally). Conflation of package id and source. That fact combined with the fact that to depend on some external package you have to write extern mod = pkgid meant that you needed to create bizarre directory structures to depend on locally developed packages (e.g. you'd have to put your locally developed project in a directory tree like so: github.com/SiegeLord/Project). This is not something I was going to do. The package dependencies are written in the source file, which makes it onerous to switch between versions/forks. A simple package script would have solved it, but it wasn't present by design. My repositories have multiple crates, and rustpkg is woefully under-equipped to handle that case. You cannot build them without dealing with pkg.rs, and using them from other projects seemed impossible too (the extern mod syntax wasn't equipped to handle multiple crates per package). This is particularly vexing when you have multiple example programs alongside your library. I was not going to split my repository up just because rustpkg wasn't designed to handle that case. All of those points would be solved by having an explicit package description file/script which was THE overarching design non-goal of rustpkg. After that was made clear to me, I just ditched it and went to C++ style package management and a CMake build system. -SL ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Deprecating rustpkg
Keeping it around means maintaining it, and it means tempting people to use it even though it's deprecated. My suggestion would be, if you really need rustpkg, then extract it into a separate repo and maintain it there. But get it out of the mozilla/rust tree. -Kevin On Jan 28, 2014, at 11:28 AM, Ian Daniher explodingm...@gmail.com wrote: Lots of good points in this thread, but I wanted to request deprecation, but not removal until a better alternative is documented and made available. Rustpkg works for my needs - I use it every day - but it definitely needs some TLC. Thanks! -- Ian On Tue, Jan 28, 2014 at 11:46 AM, SiegeLord slab...@aim.com wrote: On 01/27/2014 11:53 PM, Jeremy Ong wrote: I'm somewhat new to the Rust dev scene. Would anybody care to summarize roughly what the deficiencies are in the existing system in the interest of forward progress? It may help seed the discussion for the next effort as well. I can only speak for myself, but here are some reasons why I abandoned rustpkg and switched to CMake. Firstly, and overarchingly, it was the attitude of the project development with respect to issues. As a comparison, let me consider Rust the language. It is a pain to make my code pass the borrow check sometimes, the lifetimes are perhaps the most frustrating aspect of Rust. I put up with them however, because they solve a gigantic problem and are the keystone of Rust's safety-without-GC story. rustpkg also has many incredibly frustrating aspects, but they are there (in my opinion) arbitrarily and not as a solution to any real problem. When I hit them, I do not get the same sense of purposeful sacrifice I get with Rust's difficult points. Let me outline the specific issues I personally hit (I know of other ones, but I haven't encountered them personally). Conflation of package id and source. That fact combined with the fact that to depend on some external package you have to write extern mod = pkgid meant that you needed to create bizarre directory structures to depend on locally developed packages (e.g. you'd have to put your locally developed project in a directory tree like so: github.com/SiegeLord/Project). This is not something I was going to do. The package dependencies are written in the source file, which makes it onerous to switch between versions/forks. A simple package script would have solved it, but it wasn't present by design. My repositories have multiple crates, and rustpkg is woefully under-equipped to handle that case. You cannot build them without dealing with pkg.rs, and using them from other projects seemed impossible too (the extern mod syntax wasn't equipped to handle multiple crates per package). This is particularly vexing when you have multiple example programs alongside your library. I was not going to split my repository up just because rustpkg wasn't designed to handle that case. All of those points would be solved by having an explicit package description file/script which was THE overarching design non-goal of rustpkg. After that was made clear to me, I just ditched it and went to C++ style package management and a CMake build system. -SL ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] rustpkg error: Package ____ depends on ____, but I don't know how to find it
Any info or idea? I update from the master and now all my project have the same issue. If I use rustc I have no problem. I see the thread about rustpkg, perhaps I should migrate to rustc and cmake? Philippe Le 26/01/2014 16:25, Philippe Delrieu a écrit : Hi, I have the same problem since 2 or 3 days with the portmidi project. Philippe Le 26/01/2014 14:06, Cadence Marseille a écrit : Hi, I am seeing a new build error and I am not sure what is causing it. rust-pcre https://github.com/cadencemarseille/rust-pcre, libpcre bindings for Rust, is set up to use Travis and Rust CI http://rust-ci.org/. The latest build is failing with: rustpkg install pcre WARNING: The Rust package manager is experimental and may be unstable error: Package pcre depends on extra, but I don't know how to find it task 'unnamed' failed at 'explicit failure', /build/buildd/rust-nightly-201401260405~897a0a3~precise/src/librustpkg/util.rs:531 http://util.rs:531 task 'main' failed at 'receiving on a closed channel', /build/buildd/rust-nightly-201401260405~897a0a3~precise/src/libstd/comm/mod.rs:743 http://mod.rs:743 task 'unnamed' failed at 'Error running custom build command', /build/buildd/rust-nightly-201401260405~897a0a3~precise/src/librustpkg/lib.rs:517 http://lib.rs:517 make: *** [install] Error 65 See https://travis-ci.org/cadencemarseille/rust-pcre/builds/17643218 I looked at some other Rust CI-enabled projects and found a similar error: https://travis-ci.org/eholk/rust-opencl/builds/17491630 https://travis-ci.org/erickt/rust-zmq/builds/16353359 https://travis-ci.org/erickt/rust-mustache/builds/16059551 https://travis-ci.org/bjz/gl-rs/builds/16126945 https://travis-ci.org/bjz/sax-rs/builds/16405581 What is causing this error and how do I fix it? Cadence ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] static mut and owning pointers
Hi all! I’m not sure is it an error or static mut variables misunderstanding from my side. The source: struct MyStruct { val: int } static mut global_data: Option~MyStruct = None; fn test_call() { unsafe { match global_data { Some(data) = { println!(We have data {:?}, data);} None = { println!(We don't have data);} } } } fn main() { unsafe { global_data = Some(~MyStruct{val: 42}); } test_call(); test_call(); } and output: We have data ~MyStruct{val: 42} We don't have data But if I’m changing global_data from Option~MyStruct to OptionMyStruct output is changed also: We have data ~MyStruct{val: 42} We have data ~MyStruct{val: 42} Is it normal behaviour and owning pointers cannot be stored in global variables or an error?___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] static mut and owning pointers
Your code is moving the contents of Option~MyStruct into the match arm. It just so happens that this seems to be zeroing out the original pointer in memory, and that happens to be the same representation that None does for the type Option~MyStruct (since ~ pointers are non-nullable), so the act of moving the value just happens to be transforming it into a None. Normally you couldn't do this, but mutable statics are weird (which is why you need the unsafe block to access it). When you remove the ~, the lines end up printing the same because MyStruct is implicitly copyable, so your match arm is now copying instead of moving. The correct fix here is to use `Some(ref data)` instead of `Some(data)`. This will take a reference to the data instead of moving it, and the static will remain unchanged. -Kevin On Jan 28, 2014, at 11:48 AM, Alexander Stavonin a.stavo...@gmail.com wrote: Hi all! I’m not sure is it an error or static mut variables misunderstanding from my side. The source: struct MyStruct { val: int } static mut global_data: Option~MyStruct = None; fn test_call() { unsafe { match global_data { Some(data) = { println!(We have data {:?}, data);} None = { println!(We don't have data);} } } } fn main() { unsafe { global_data = Some(~MyStruct{val: 42}); } test_call(); test_call(); } and output: We have data ~MyStruct{val: 42} We don't have data But if I’m changing global_data from Option~MyStruct to OptionMyStruct output is changed also: We have data ~MyStruct{val: 42} We have data ~MyStruct{val: 42} Is it normal behaviour and owning pointers cannot be stored in global variables or an error? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Function shipping
On Tuesday, January 28, 2014, Noah Watkins jayh...@cs.ucsc.edu wrote: It would be particularly useful to be able to ship a closure to be executed remotely. The only language I've seen do this well is Erlang, and it still requires both nodes have the same version of the same module loaded at the same time. -- Tony Arcieri ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] static mut and owning pointers
damned, my gmail client was not up to date, you've got a better answer already (I got the ref keyword right at least ;)) On Tue, Jan 28, 2014 at 1:00 PM, François-Xavier Bourlet bomb...@gmail.com wrote: match global_data { Some(data) = You should be able to do: Some(ref data) Which will take a reference instead of moving the owned pointer. In the second case (no owned pointer) you are actually copying the struct everything. Using ref data would safe a copy as well. I might be wrong, I am a newcomer on rust :) On Tue, Jan 28, 2014 at 11:48 AM, Alexander Stavonin a.stavo...@gmail.com wrote: Hi all! I'm not sure is it an error or static mut variables misunderstanding from my side. The source: struct MyStruct { val: int } static mut global_data: Option~MyStruct = None; fn test_call() { unsafe { match global_data { Some(data) = { println!(We have data {:?}, data);} None = { println!(We don't have data);} } } } fn main() { unsafe { global_data = Some(~MyStruct{val: 42}); } test_call(); test_call(); } and output: We have data ~MyStruct{val: 42} We don't have data But if I'm changing global_data from Option~MyStruct to OptionMyStruct output is changed also: We have data ~MyStruct{val: 42} We have data ~MyStruct{val: 42} Is it normal behaviour and owning pointers cannot be stored in global variables or an error? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Compile-time function evaluation in Rust
It sounds like you're proposing that arbitrary functions may be eligible for CTFE if they happen to meet all the requirements, without any special annotations. This seems like a bad idea to me. I understand why it's attractive, but it means that seemingly harmless changes to a function's implementation (but not its signature) can cause compiler errors in other modules, or even other crates if the AST for the function happens to be made extern. A more conservative approach would be to require the #[ctfe] annotation, which then imposes all the given restrictions on the function. The downside is such a function then is restricted to only calling other CTFE functions, so we'd have to go in to the standard libraries and add this annotation whenever we think it's both useful and possible. This approach mirrors the approach being used by C++11/C++14. -Kevin On Jan 28, 2014, at 2:15 PM, Pierre Talbot ptal...@hyc.io wrote: Hi, The Mozilla foundation proposes research internships [1] and the CTFE optimization in the Rust compiler seems to be a really exciting project. I wrote a proposal [2] that I'll send with my application and so I'd like to share it with you and discuss about bringing CTFE inside Rust. Here a non-exhaustive summary of key points in my proposal. First of all, we need to establish when CTFE is triggered, I found two contexts (denoted as a hole []): * Inside a immutable static variable (static ident ’:’ type ’=’ [] ’;’). * In a vector expression (’[’ expr ’,’ .. [] ’]’). Next in a similar way than with inline attributes we might want to add these new attributes: * #[ctfe] hints the compiler to perform CTFE. * #[ctfe(always)] asks the compiler to always perform CTFE resulting in a compiler error if it’s impossible. * #[ctfe(never)] asks the compiler to never perform CTFE resulting in a compiler error if this function is called in a CTFE context. The rational behind this is that some functions might want to disallow CTFE, for example if they manipulate machine-dependent data (such as playing with endianness). Some might want to be designed only for compile-time and so we want to disable run-time execution. Finally others might hints the compiler to try to optimize whenever you can, of course if the function contains infinite loop for some input, the compilation might not terminate. I propose some requirements on function eligible for CTFE (see the proposal for references to the Rust manual): 1. Its parameters are evaluable at compile-time. 2. It isn’t a diverging function. 3. It isn’t an unsafe function. 4. It doesn’t contain unsafe block. 5. It doesn’t perform I/O actions. 6. The function source code is available to the compiler. It mustn’t be in an external block, however it can be an extern function. In this proposal, you'll also find a pseudo-coded algorithm, related work (in D and C++), and much more :-) If you have any suggestions or corrections, do not hesitate. Also, feel free to ask questions. Regards, Pierre Talbot [1] https://careers.mozilla.org/en-US/position/oZO7XfwB [2] http://hyc.io/rust-ctfe-proposal.pdf ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Compile-time function evaluation in Rust
Out of that list of requirements, #5 (doesn't perform I/O actions) is the one that strikes me as least well-defined. Could you elaborate on how you would enforce it? Cheers, Josh On 28 January 2014 14:15, Pierre Talbot ptal...@hyc.io wrote: Hi, The Mozilla foundation proposes research internships [1] and the CTFE optimization in the Rust compiler seems to be a really exciting project. I wrote a proposal [2] that I'll send with my application and so I'd like to share it with you and discuss about bringing CTFE inside Rust. Here a non-exhaustive summary of key points in my proposal. First of all, we need to establish when CTFE is triggered, I found two contexts (denoted as a hole []): * Inside a immutable static variable (static ident ':' type '=' [] ';'). * In a vector expression ('[' expr ',' .. [] ']'). Next in a similar way than with inline attributes we might want to add these new attributes: * #[ctfe] hints the compiler to perform CTFE. * #[ctfe(always)] asks the compiler to always perform CTFE resulting in a compiler error if it's impossible. * #[ctfe(never)] asks the compiler to never perform CTFE resulting in a compiler error if this function is called in a CTFE context. The rational behind this is that some functions might want to disallow CTFE, for example if they manipulate machine-dependent data (such as playing with endianness). Some might want to be designed only for compile-time and so we want to disable run-time execution. Finally others might hints the compiler to try to optimize whenever you can, of course if the function contains infinite loop for some input, the compilation might not terminate. I propose some requirements on function eligible for CTFE (see the proposal for references to the Rust manual): 1. Its parameters are evaluable at compile-time. 2. It isn't a diverging function. 3. It isn't an unsafe function. 4. It doesn't contain unsafe block. 5. It doesn't perform I/O actions. 6. The function source code is available to the compiler. It mustn't be in an external block, however it can be an extern function. In this proposal, you'll also find a pseudo-coded algorithm, related work (in D and C++), and much more :-) If you have any suggestions or corrections, do not hesitate. Also, feel free to ask questions. Regards, Pierre Talbot [1] https://careers.mozilla.org/en-US/position/oZO7XfwB [2] http://hyc.io/rust-ctfe-proposal.pdf ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Compile-time function evaluation in Rust
On 01/28/2014 11:24 PM, Kevin Ballard wrote: It sounds like you're proposing that arbitrary functions may be eligible for CTFE if they happen to meet all the requirements, without any special annotations. This seems like a bad idea to me. I understand why it's attractive, but it means that seemingly harmless changes to a function's implementation (but not its signature) can cause compiler errors in other modules, or even other crates if the AST for the function happens to be made extern. A more conservative approach would be to require the #[ctfe] annotation, which then imposes all the given restrictions on the function. The downside is such a function then is restricted to only calling other CTFE functions, so we'd have to go in to the standard libraries and add this annotation whenever we think it's both useful and possible. This approach mirrors the approach being used by C++11/C++14. -Kevin I understand your point of view but adding #[ctfe] doesn't solve the problem either, the library designer could remove this annotation, isn't it? I didn't precise it, but I gave a different semantic to #[ctfe] than what you understood. Let me rephrase it: * #[ctfe] hints the compiler that performing CTFE outside of the contexts (as specified) is safe. It means that for any input this function will terminate [in a reasonable amount of time and memory]. We should keep in mind the drawbacks of the constexpr semantic: 1. Force the library designer to think about CTFE, the user might be in a better position since he knows well which parameters he'll give to this function. 2. Annotate functions means more maintenance, more changes and more errors. Moreover, the C++11 constexpr only allow a subset of the language, which is practical for the compiler implementor but not for the library designer. In D, they specify when a function is *not* eligible. Thanks for comments! On Jan 28, 2014, at 2:15 PM, Pierre Talbot ptal...@hyc.io wrote: Hi, The Mozilla foundation proposes research internships [1] and the CTFE optimization in the Rust compiler seems to be a really exciting project. I wrote a proposal [2] that I'll send with my application and so I'd like to share it with you and discuss about bringing CTFE inside Rust. Here a non-exhaustive summary of key points in my proposal. First of all, we need to establish when CTFE is triggered, I found two contexts (denoted as a hole []): * Inside a immutable static variable (static ident ’:’ type ’=’ [] ’;’). * In a vector expression (’[’ expr ’,’ .. [] ’]’). Next in a similar way than with inline attributes we might want to add these new attributes: * #[ctfe] hints the compiler to perform CTFE. * #[ctfe(always)] asks the compiler to always perform CTFE resulting in a compiler error if it’s impossible. * #[ctfe(never)] asks the compiler to never perform CTFE resulting in a compiler error if this function is called in a CTFE context. The rational behind this is that some functions might want to disallow CTFE, for example if they manipulate machine-dependent data (such as playing with endianness). Some might want to be designed only for compile-time and so we want to disable run-time execution. Finally others might hints the compiler to try to optimize whenever you can, of course if the function contains infinite loop for some input, the compilation might not terminate. I propose some requirements on function eligible for CTFE (see the proposal for references to the Rust manual): 1. Its parameters are evaluable at compile-time. 2. It isn’t a diverging function. 3. It isn’t an unsafe function. 4. It doesn’t contain unsafe block. 5. It doesn’t perform I/O actions. 6. The function source code is available to the compiler. It mustn’t be in an external block, however it can be an extern function. In this proposal, you'll also find a pseudo-coded algorithm, related work (in D and C++), and much more :-) If you have any suggestions or corrections, do not hesitate. Also, feel free to ask questions. Regards, Pierre Talbot [1] https://careers.mozilla.org/en-US/position/oZO7XfwB [2] http://hyc.io/rust-ctfe-proposal.pdf ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] static mut and owning pointers
Probably this should yield an error -- I tend to think we should only permit moves that we cannot enforce from `*` pointers, just to add an extra barrier. Niko On Tue, Jan 28, 2014 at 12:12:23PM -0800, Kevin Ballard wrote: Your code is moving the contents of Option~MyStruct into the match arm. It just so happens that this seems to be zeroing out the original pointer in memory, and that happens to be the same representation that None does for the type Option~MyStruct (since ~ pointers are non-nullable), so the act of moving the value just happens to be transforming it into a None. Normally you couldn't do this, but mutable statics are weird (which is why you need the unsafe block to access it). When you remove the ~, the lines end up printing the same because MyStruct is implicitly copyable, so your match arm is now copying instead of moving. The correct fix here is to use `Some(ref data)` instead of `Some(data)`. This will take a reference to the data instead of moving it, and the static will remain unchanged. -Kevin On Jan 28, 2014, at 11:48 AM, Alexander Stavonin a.stavo...@gmail.com wrote: Hi all! I’m not sure is it an error or static mut variables misunderstanding from my side. The source: struct MyStruct { val: int } static mut global_data: Option~MyStruct = None; fn test_call() { unsafe { match global_data { Some(data) = { println!(We have data {:?}, data);} None = { println!(We don't have data);} } } } fn main() { unsafe { global_data = Some(~MyStruct{val: 42}); } test_call(); test_call(); } and output: We have data ~MyStruct{val: 42} We don't have data But if I’m changing global_data from Option~MyStruct to OptionMyStruct output is changed also: We have data ~MyStruct{val: 42} We have data ~MyStruct{val: 42} Is it normal behaviour and owning pointers cannot be stored in global variables or an error? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Compile-time function evaluation in Rust
That's what I figured. Forbidding unsafe is definitely a good way to keep things simple starting out. Compile time evaluation can always be extended later on. On Tue, Jan 28, 2014 at 3:21 PM, Pierre Talbot ptal...@hyc.io wrote: On 01/28/2014 11:26 PM, Eric Reed wrote: Looks pretty reasonable to me at first glance. Out of curiosity, what's the rationale behind forbidding unsafe functions/blocks? In the reference manual we can read things such as: Mutating an immutable value/reference, if it is not marked as non-freeze. This would be impossible at compile-time. But I'm agree that we could relax this constraint and specify more precisely in which cases we disallow this.| | On Tue, Jan 28, 2014 at 2:15 PM, Pierre Talbot ptal...@hyc.io mailto: ptal...@hyc.io wrote: Hi, The Mozilla foundation proposes research internships [1] and the CTFE optimization in the Rust compiler seems to be a really exciting project. I wrote a proposal [2] that I'll send with my application and so I'd like to share it with you and discuss about bringing CTFE inside Rust. Here a non-exhaustive summary of key points in my proposal. First of all, we need to establish when CTFE is triggered, I found two contexts (denoted as a hole []): * Inside a immutable static variable (static ident ':' type '=' [] ';'). * In a vector expression ('[' expr ',' .. [] ']'). Next in a similar way than with inline attributes we might want to add these new attributes: * #[ctfe] hints the compiler to perform CTFE. * #[ctfe(always)] asks the compiler to always perform CTFE resulting in a compiler error if it's impossible. * #[ctfe(never)] asks the compiler to never perform CTFE resulting in a compiler error if this function is called in a CTFE context. The rational behind this is that some functions might want to disallow CTFE, for example if they manipulate machine-dependent data (such as playing with endianness). Some might want to be designed only for compile-time and so we want to disable run-time execution. Finally others might hints the compiler to try to optimize whenever you can, of course if the function contains infinite loop for some input, the compilation might not terminate. I propose some requirements on function eligible for CTFE (see the proposal for references to the Rust manual): 1. Its parameters are evaluable at compile-time. 2. It isn't a diverging function. 3. It isn't an unsafe function. 4. It doesn't contain unsafe block. 5. It doesn't perform I/O actions. 6. The function source code is available to the compiler. It mustn't be in an external block, however it can be an extern function. In this proposal, you'll also find a pseudo-coded algorithm, related work (in D and C++), and much more :-) If you have any suggestions or corrections, do not hesitate. Also, feel free to ask questions. Regards, Pierre Talbot [1] https://careers.mozilla.org/en-US/position/oZO7XfwB [2] http://hyc.io/rust-ctfe-proposal.pdf ___ Rust-dev mailing list Rust-dev@mozilla.org mailto:Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] static mut and owning pointers
Our discussion in a recent meeting concluded that statics will not be allowed to contain types with destructors, and you also won't be able to move out of static items: https://github.com/mozilla/rust/issues/10577#issuecomment-32294407 On Tue, Jan 28, 2014 at 3:34 PM, Kevin Ballard ke...@sb.org wrote: At first glance it seems reasonable to prohibit moving out of a mutable static, but I'm not sure it really makes sense to try and put restrictions on mutable statics when we can't make them safe. -Kevin On Jan 28, 2014, at 3:26 PM, Niko Matsakis n...@alum.mit.edu wrote: Probably this should yield an error -- I tend to think we should only permit moves that we cannot enforce from `*` pointers, just to add an extra barrier. Niko On Tue, Jan 28, 2014 at 12:12:23PM -0800, Kevin Ballard wrote: Your code is moving the contents of Option~MyStruct into the match arm. It just so happens that this seems to be zeroing out the original pointer in memory, and that happens to be the same representation that None does for the type Option~MyStruct (since ~ pointers are non-nullable), so the act of moving the value just happens to be transforming it into a None. Normally you couldn't do this, but mutable statics are weird (which is why you need the unsafe block to access it). When you remove the ~, the lines end up printing the same because MyStruct is implicitly copyable, so your match arm is now copying instead of moving. The correct fix here is to use `Some(ref data)` instead of `Some(data)`. This will take a reference to the data instead of moving it, and the static will remain unchanged. -Kevin On Jan 28, 2014, at 11:48 AM, Alexander Stavonin a.stavo...@gmail.com wrote: Hi all! I'm not sure is it an error or static mut variables misunderstanding from my side. The source: struct MyStruct { val: int } static mut global_data: Option~MyStruct = None; fn test_call() { unsafe { match global_data { Some(data) = { println!(We have data {:?}, data);} None = { println!(We don't have data);} } } } fn main() { unsafe { global_data = Some(~MyStruct{val: 42}); } test_call(); test_call(); } and output: We have data ~MyStruct{val: 42} We don't have data But if I'm changing global_data from Option~MyStruct to OptionMyStruct output is changed also: We have data ~MyStruct{val: 42} We have data ~MyStruct{val: 42} Is it normal behaviour and owning pointers cannot be stored in global variables or an error? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Compile-time function evaluation in Rust
The way it is implemented in Rust is by using the libc, but the requirement #6 says we can't call external function, so implicitly the problem is solved. I'm agree that it isn't formal, but I can't come up with a better solution for now. You made me think of another requirements (so basic that I forgot to mention it): * A function is eligible for CTFE if every function calls inside this function are themselves eligible. On 01/28/2014 11:27 PM, Josh Matthews wrote: Out of that list of requirements, #5 (doesn’t perform I/O actions) is the one that strikes me as least well-defined. Could you elaborate on how you would enforce it? Cheers, Josh On 28 January 2014 14:15, Pierre Talbot ptal...@hyc.io mailto:ptal...@hyc.io wrote: Hi, The Mozilla foundation proposes research internships [1] and the CTFE optimization in the Rust compiler seems to be a really exciting project. I wrote a proposal [2] that I'll send with my application and so I'd like to share it with you and discuss about bringing CTFE inside Rust. Here a non-exhaustive summary of key points in my proposal. First of all, we need to establish when CTFE is triggered, I found two contexts (denoted as a hole []): * Inside a immutable static variable (static ident ’:’ type ’=’ [] ’;’). * In a vector expression (’[’ expr ’,’ .. [] ’]’). Next in a similar way than with inline attributes we might want to add these new attributes: * #[ctfe] hints the compiler to perform CTFE. * #[ctfe(always)] asks the compiler to always perform CTFE resulting in a compiler error if it’s impossible. * #[ctfe(never)] asks the compiler to never perform CTFE resulting in a compiler error if this function is called in a CTFE context. The rational behind this is that some functions might want to disallow CTFE, for example if they manipulate machine-dependent data (such as playing with endianness). Some might want to be designed only for compile-time and so we want to disable run-time execution. Finally others might hints the compiler to try to optimize whenever you can, of course if the function contains infinite loop for some input, the compilation might not terminate. I propose some requirements on function eligible for CTFE (see the proposal for references to the Rust manual): 1. Its parameters are evaluable at compile-time. 2. It isn’t a diverging function. 3. It isn’t an unsafe function. 4. It doesn’t contain unsafe block. 5. It doesn’t perform I/O actions. 6. The function source code is available to the compiler. It mustn’t be in an external block, however it can be an extern function. In this proposal, you'll also find a pseudo-coded algorithm, related work (in D and C++), and much more :-) If you have any suggestions or corrections, do not hesitate. Also, feel free to ask questions. Regards, Pierre Talbot [1] https://careers.mozilla.org/en-US/position/oZO7XfwB [2] http://hyc.io/rust-ctfe-proposal.pdf ___ Rust-dev mailing list Rust-dev@mozilla.org mailto:Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Compile-time function evaluation in Rust
On 29/01/14 10:45, Kevin Ballard wrote: On Jan 28, 2014, at 3:16 PM, Pierre Talbot ptal...@hyc.io wrote: On 01/28/2014 11:24 PM, Kevin Ballard wrote: It sounds like you're proposing that arbitrary functions may be eligible for CTFE if they happen to meet all the requirements, without any special annotations. This seems like a bad idea to me. I understand why it's attractive, but it means that seemingly harmless changes to a function's implementation (but not its signature) can cause compiler errors in other modules, or even other crates if the AST for the function happens to be made extern. A more conservative approach would be to require the #[ctfe] annotation, which then imposes all the given restrictions on the function. The downside is such a function then is restricted to only calling other CTFE functions, so we'd have to go in to the standard libraries and add this annotation whenever we think it's both useful and possible. This approach mirrors the approach being used by C++11/C++14. -Kevin I understand your point of view but adding #[ctfe] doesn't solve the problem either, the library designer could remove this annotation, isn't it? I didn't precise it, but I gave a different semantic to #[ctfe] than what you understood. Let me rephrase it: * #[ctfe] hints the compiler that performing CTFE outside of the contexts (as specified) is safe. It means that for any input this function will terminate [in a reasonable amount of time and memory]. We should keep in mind the drawbacks of the constexpr semantic: 1. Force the library designer to think about CTFE, the user might be in a better position since he knows well which parameters he'll give to this function. 2. Annotate functions means more maintenance, more changes and more errors. Moreover, the C++11 constexpr only allow a subset of the language, which is practical for the compiler implementor but not for the library designer. In D, they specify when a function is *not* eligible. Yes, I was using #[ctfe] to mean something slightly different than you were. In my case, it meant mark this function as eligible for CTFE, and impose all the CTFE restrictions. And it does fix the problem I mentioned, because #[ctfe] would be considered part of the function signature, not the function implementation. Everyone is already used to the idea that modifying the function signature may cause compiler errors at the call site. But the only example I can think of right now for when changing a function's _implementation_ causes call site compiler errors is when you're using C++ templates. FWIW, `transmute` causes such errors in Rust. e.g. `fn errorsT(x: T) { unsafe { std::cast::transmute::T, int(x); } }` will fail to compile when passed u16, but not when passed uint, and this isn't encoded in the type signature. Huon Not only that, but with your approach, changing the implementation of one function could accidentally cause a whole host of other functions to become ineligible for CTFE. And the farther apart the actual source of the problem, and the resulting error, the harder it is to diagnose and fix such errors. That said, I was not aware that D already takes this approach, of allowing CTFE by default. I'm curious how it works for them, and how they handle these problems. -Kevin ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] Faster communication between tasks
A small update: I've gotten a resizable version of my disruptor implementation working, and the performance looks pretty good so far. I still have a few loose ends to tie up before I push out the changes. I should have the updated code on GitHub hopefully within a couple of weeks, depending on how much time I find to work on it. On Sat, Nov 9, 2013 at 2:13 PM, Simon Ruggier simo...@gmail.com wrote: Hi all, I've tentatively come up with a design that would allow the sender to reallocate the buffer as necessary, with very little added performance cost. The sending side would bear the cost of reallocation, and there would be an extra test that receivers would have to make every time they process an item (no extra atomic operations needed). However, it may be a few weeks or more before I have a working implementation to demonstrate, so I figured it might be worthwhile to mention now that I'll be working on this. Also, I think it would be interesting to investigate doing something like the Linux kernel's deadlock detection[1], but generalized to apply to bounded queues, and implemented as a static check. I know little about this, but even so, I can see how it would be an enormous amount of work. On the other hand, I would have thought the same thing about the memory safety rules that Rust enforces. I'm hopeful that this will eventually be possible as well. [1] https://www.kernel.org/doc/Documentation/lockdep-design.txt On Wed, Oct 30, 2013 at 12:55 AM, Simon Ruggier simo...@gmail.com wrote: On Tue, Oct 29, 2013 at 3:30 PM, Brian Anderson bander...@mozilla.comwrote: On 10/28/2013 10:02 PM, Simon Ruggier wrote: Greetings fellow Rustians! First of all, thanks for working on such a great language. I really like the clean syntax, increased safety, separation of data from function definitions, and freedom from having to declare duplicate method prototypes in header files. I've been working on an alternate way to communicate between tasks in Rust, following the same approach as the LMAX Disruptor.[1] I'm hoping to eventually offer a superset of the functionality in the pipes API, and replace them as the default communication mechanism between tasks. Just as with concurrency in general, my main motivation in implementing this is to improve performance. For more information about the disruptor approach, there's a lot of information linked from their home page, in a variety of formats. This is really exciting work. Thanks for pursuing it. I've been interested in exploring something like Disruptor in Rust. The current channel types in Rust are indeed slow, and fixing them is the topic of https://github.com/mozilla/rust/issues/8568. I'll start paying attention to that. The Morrison Afek 2013 paper looks like something I should read. This is my first major contribution of new functionality to an open-source project, so I didn't want to discuss it in advance until I had a working system to demonstrate. I currently have a very basic proof of concept that achieves almost two orders of magnitude better performance than the pipes API. On my hardware[2], I currently see throughput of about 27 million items per second when synchronizing with a double-checked wait condition protocol between sender and receivers, 80+ million items with no blocking (i.e. busy waiting), and anywhere from 240,000 to 600,000 when using pipes. The LMAX Disruptor library gets up to 110 million items per second on the same hardware (using busy waiting and yielding), so there's definitely still room for significant improvement. Those are awesome results! Thanks! When I first brought it up, it was getting about 14 million with the busy waiting. Minimizing the number of atomic operations (even with relaxed memory ordering) makes a big difference in performance. The 2/3 drop in performance with the blocking wait strategy comes from merely doing a read-modify-write operation on every send (it currently uses atomic swap, I haven't experimented with others yet). To be fair, the only result I can take credit for is the blocking algorithm. The other ideas are straight from the original disruptor. I've put the code up on GitHub (I'm using rustc from master).[3] Currently, single and multi-stage pipelines of receivers are supported, while many features are missing, like multiple concurrent senders, multiple concurrent receivers, or mutation of the items as they pass through the pipeline. However, given what I have so far, now is probably the right time to start soliciting feedback and advice. I'm looking for review, suggestions/constructive criticism, and guidance about contributing this to the Rust codebase. I'm not deeply familiar with Disruptor, but I believe that it uses bounded queues. My general feeling thus far is that, as the general 'go-to' channel type, people should not be using bounded queues that block the sender when full because of the potential for