One common criticism of the work on ParallelJS is that the API itself does not guarantee parallel execution. Instead, our approach has been to offer methods whose definition makes parallel execution possible, but we have left it up to the engines to define the exact set of JavaScript that will be safe for parallel execution. Now, I definitely...
I’ve been doing a lot of thinking about Rust’s trait system lately. The current system is a bit uneven: it offers a lot of power, but the implementation is inconsistent and incomplete, and in some cases we haven’t thought hard enough about precisely what should be allowed and what should not. I’m going to write a series of posts looking at...
I want to finish my discussion of associated items by taking a look at how they are handled in Haskell, and what that might mean in Rust. These proposals have the same descriptive power as what I described before, but they are backwards compatible. This is nice. Object-oriented style name resolution In the object-oriented, C++-like version of...
While working on issue #5656 I encountered an interesting problem that I had not anticipated. The result is a neat little extension to the region type system that increases its expressive power. The change is completely internal to the type rules and involves no user-visible syntax or anything like that, though there are some (basically...
In my last post about ParallelJS, I discussed the ForkJoin() intrinsic and showed how it was used to implement the parallel map operation. Today I want to write about the high-level changes to IonMonkey that are needed to support ForkJoin(). IonMonkey, of course, is our JavaScript engine. Parallel execution mode To support ParallelJS, we...
Yesterday I realized that you can violate Rust’s memory safety guarantees by using “stack closures”, meaning closures that are allocated on the stack which have can refer to and manipulate the local variables of the enclosing stack frame. Such closures are ubiquitous in Rust, since every for loop makes use of them (and virtually every...
I want to look at an interesting topic: what subset of JavaScript do we intend to support for parallel execution, and how long will it take to get that working? As my dear and loyal readers already know, our current engine supports a simple subset of JavaScript but we will want to expand it and make the result more predictable. From my point of...
Recently, separate discussions with pnkfelix and graydon have prompted me to think a bit about “dynamically sized types” once again. Those who know Rust well know all about the sometimes annoying discrepancy between a type like ~T (owned pointer to T) and ~[S] (owned vector of S instances)—in particular, despite the visual similarity, there is no...
I realized today that there is an unfortunate interaction between the proposal for dynamically sized types and closure types. In particular, in the case of the recurring closure, I described the soundness issues that arise in our language when closures are able to recurse. My solution for this was to make the type system treat a &fn() value the...
I’ve been thinking about what I wrote in my last post regarding closures and I am beginning to change my opinion about the correct solution. fn~ just seems so unfortunate. So, besides writing fn~, what are the other options? I just thought I’d write down a few of the other ideas I’ve come up with for later reference. Not saying any of the ideas...
So, I didn’t actually mean to post that previous post, I had intended to think more on the idea. But oh well, cat’s out of the bag. In any case, I’ve been thinking about the “closures” vs “procedures” idea that I jotted down there and decided to try and elaborate on it a bit more, since I find it has a lot of appeal. In particular I think that...
We’ve been making a lot of conceptual progress with the PJS API that has not been written down anywhere, so I want to cover some of that work. This post focuses on the integration of parallel methods with the binary data API. It shows how the new API approach allows users to avoid allocation for higher efficiency. Methods, not types We are moving...
I’ve been thinking more about my proposal to split the current fn type into fn and proc. I have come to the conclusion that we just don’t need proc at all. I think we can get by with two types: fn(S) -> T: closures that always reference an enclosing scope extern "ABI" fn(S) -> t: raw function pointer, no environment Code that uses @fn or ~fn...
I have been thinking about my previous proposal for fn types. I wanted to offer some refinements and further thoughts. On Thunks I proposed a trait Task for encapsulating a function and the parameters it needs to run. I don’t like this name because this concept could be used in other places beyond just tasks. I was thinking that the proper name...
So Ben Blum has doing some investigation into the full implications of the Sized bound that I proposed as part of the dynamically sized types post. It’s clear that, if we change nothing else, the impact of Sized will be somewhat greater than I thought. He estimates somewhere around 40% of the files in libstd need at least one Sized bound; the...
As I alluded in the previous post, I have noticed an interesting connection between memory management and data-race freedom. I want to take a moment to elaborate on this, becaause the connection was not obvious to me at first, but it ultimately drives a lot of the Rust design decisions. First, I believe that if you want to guarantee data-race...
Rust currently has very strong support for concurrency in the form of actors which exchange messages and do not share memory. However, there are many tasks for which actors are not a good fit. The unbounded lifetime of actors means that they cannot safely access stack-allocated memory from another task, even if it is immutable. Actors cannot...
Today I had the honor of giving a presentation on Rust at the Northeastern University PL Seminar. It was a lot of fun, and I also had a lot of good conversations afterwards with some of the professors and PhD students there. For those who are interested, I am uploading the slides from my talk. The talk takes the same approach that I would like to...
Since the new version of PJS is going to be based on binary data, we are going to need to have a well-optimized binary data implementation. Nikhil Marathe has prepared an initial implementation, but it is limited to the interpreter. I am looking now at how to integrate binary data into the JIT. The goal is to have accesses get compiled to very...
Since I last wrote, we’ve made great progress with the work on the Parallel JS and Typed Objects (nee Binary Data) implementation. In particular, as of this morning, preliminary support for typed objects has landed in Mozilla Nightly, although what’s currently checked in is not fully conformant with the current version of the standard (for this...
As some of you may recall, the fate of function types in Rust has been somewhat uncertain. It all began when I realized that we could not soundly permit closures to recurse, which implies that closures must be tracked in a linear fashion. This caused interactions with the prior plans we had for dynamically sized types, and led to several...
Yesterday Dmitry Lomov and I had a discussion about the typed objects API. Much of the discussion revolved around the specific issue of handles. In this post I will summarize the issues we discussed and review the various design options. I’ll begin with a summary of what handles are and how they are used in current APIs; if this is familiar to...
The following is a draft proposal to support a form of single inheritance, similar to that found in object-oriented languages. The goal is to enable servo to efficiently support structures like the DOM. The proposal is not completely rounded out, but I wanted to put it up in its current form so as to gather any comments. In a nutshell, the...
OK, after writing the post on iterators that yield mutable references, and discussing with some folk on IRC, I remembered something I had forgotten. There is actually a way to phrase the mutable vector iterator differently such that it is safe. Actually, the end result still has some unsafe code, but it takes the form of a simple helper function,...
There is a known bug with the borrowck rules that causes it to be overly permissive. The fix is relatively simple but it unfortunately affects some of our Iterator implementations, specifically those iterators that iterate over &mut values. The short version is that while it is possible to expose a safe interface for iterating over &mut values,...
I think someone reading this blog would be forgiven for thinking that I must spend most of my energy thinking about Rust. In fact I spend a good part of my working hours hammering on PJS. I thought I’d try to write up a bit of a preview of the things we are working on. Parallel methods on arrays Right now, on Nightly Firefox builds, you can use...
I’ve been hard at work finishing up work on Rust’s “new” syntax for lifetimes – I put “new” in quotes because the syntax has been in use for some time, but in rustc itself the change was only half-baked. In effect, the new syntax was a kind of “bridge” to code that was designed for the older type system. This resulted in some artificial...
I want to optimize assignments to struct-typed fields in typed objects. This post is an effort to work through my optimization plan. The goal Imagine some code like this: var PointType = new StructType({x: int32, y: int32}); var LineType = new StructType({from: PointType, to: PointType}); var line = new LineType();...
I got a lot of feedback on my post about intermingled parameter lists – most of it negative – and I’ve been thinking about the issue over the weekend. Truth is, I wasn’t terribly fond of the proposal myself – making the position in the list significant feels wrong – but I felt it was the least bad of the various options. However, I’ve had a...
Some astute comments on a recent thread to rust-dev got me thinking about our approach to vectors. Until now, we have focused on having built-in support for vectors via the vector type (~[T]) and slice types (&[T]). However, another possible approach would be to move vector support out of the language (almost) entirely and into standard...
Alex Chrichton recently sent a message to the rust-dev mailing list discussing the fate of parameter coercion in Rust. I’ve been thinking about this for a while and feeling conflicted. As is my wont, I decided to try and write up a blog post explaining precisely what’s under debate and exporing the tradeoffs. Historical background In the interest...
There is currently some ongoing effort to implement the proposed JavaScript SIMD API in Firefox. The basic idea of the API is to introduce explicit vector value types called float32x4 and int32x4. These types fit into the typed objects hierarchy, so you can create arrays of them, embed them in structs, and so forth. The semantics of these vectors...
A quick follow-up to my previous post. The approach I suggested (“generate boxing instructions but bypass them when possible”) is in some sense pessimistic: we generate the instructions we need for the worst case and then cleanup. Like many problems in computer science, it has an optimistic dual. We could generate unboxed data and then insert...
In the past, I’ve been quite the champion of dynamically sized types (DST). Specifically what this means is that things like [T] and Trait would be “types” in the Rust type system. Lately I’ve been investing a lot of effort thinking through the ramifications of offering better support for smart pointers, and in particular how this interacts with...
After posting part 2 of my DST series, I realized that I had focusing too much on the pure “type system” aspect and ignoring some of the more…mundane semantics, and in particular the impact of monomorphization. I realize now that – without some further changes – we would not be able to compile and execute the second proposal (which I will dub...
In the previous post I elaborated a bit on DSTs and how they could be created and used. I want to look a bit now at an alternate way to support the combination of vector types and smart pointers (e.g., RC). This approach avoids the use of DSTs. We’ll see that it also addresses some of the rough patches of DST, but doesn’t work quite as well for...
Over the Thanksgiving break I’ve been devoting a lot of time to thinking about DST and Rust’s approach to vector and object types. As before, this is very much still churning in my mind so I’m just going to toss out some semi-structured thoughts. Brief recap Treating vectors like any other container. Some time back, I wrote up a post about how...
Dave Herman and I were tossing around ideas the other day for a revision of the typed object specification in which we remove nominal array types. The goal is to address some of the awkwardness that we have encountered in designing the PJS API due to nominal array types. I thought I’d try writing it out. This is to some extent a thought...
I believe I have come to the point where I am ready to make a final proposal for DST. Ironically, this proposal is quite similar to where I started, but somewhat more expansive. It seems to be one of those unusual cases where supporting more features actually makes things easier. Thanks to Eridius on IRC for pointing this out to me. I intend for...
I’ve been working on Issue #3511, which is an effort to rationalize the lifetimes of temporary values in Rust. This issue has been a thorn in the side of Rust users for a while, because the current lifetimes are rather haphazard and frequently too short. Some time ago, I did some thinking on this issue and then let it lie while other things took...
I have been working on making the borrow checker treat closures in a sound way. I hope to land this patch very soon. I want to describe the impact of these changes and summarize what we might do in the future. The high-level idea The basic idea is that the borrow checker will treat a closure as if it were constructing a record with one borrowed...
Today, if you do a mutable borrow of a local variable, you lose the ability to write to that variable except through the new reference you just created: let mut x = 3; let p = &mut x; x += 1; // Error *p += 1; // OK However, you retain the ability to read the original variable: let mut x = 3; let p = &mut x; print(x); // OK print(*p); // OK I...
In today’s Rust, there are a number of builtin traits (sometimes called “kinds”): Send, Freeze, Share, and Pod (in the future, perhaps Sized). These are expressed as traits, but they are quite unlike other traits in certain ways. One way is that they do not have any methods; instead, implementing a trait like Freeze indicates that the type has...
Here is the current state of my thinking with respect to value types and value objects. Some of you may have seen Brendan’s slides where he discusses value objects. This post is about the same topic, but it is focused on just the initial part of the work – what it means to be a value object and how we could define value types and integrate them...
I recently wrote up a paper describing the current version of the Typed Objects API. Anyone who is interested in the current state of the art in that specification should take a look. It’s not too long and intended to be an easy read. This is just a draft copy, and feedback is naturally very welcome – in particular, I expect that before we submit...
I’ve been thinking about an alternative way to factor the PJS API. Until now, we’ve had these methods like mapPar(), filterPar() and so forth. They work mostly like their sequential namesakes but execute in parallel. This API has the advantage of being easy to explain and relatively clear, but it’s also not especially flexible nor elegant....
Over time, I’ve become convinced that it would be better to drop the distinction between mutable and immutable local variables in Rust. Many people are highly skeptical, to say the least. I wanted to lay out my argument in public. I’ll give various motivations: a philosophical one, an eductional one, and a practical one, and also address the main...
This post withdrawn: it was posted by accident and was incomplete. +---+ +------+ +-----+ ^ +---+ | | & | ---------+ +---+ As you can see from the diagram, the &mut reference is a unique reference to the integer. That is, it can’t be copied, and it’s the only direct pointer to that integer. However, there are...
I am on vacation for a few weeks. I wanted to take some time to jot down an idea that’s been bouncing around in my head. I plan to submit an RFC at some point on this topic, but not yet, so I thought I’d start out by writing a blog post. Also, my poor blog has been neglected for some time. Consider this a draft RFC. Some important details about...
While on vacation, I’ve been working on an alternate type inference scheme for rustc. (Actually, I got it 99% working on the plane, and have been slowly poking at it ever since.) This scheme simplifies the code of the type inferencer dramatically and (I think) helps to meet our intutions (as I will explain). It is however somewhat less flexible...
A few weeks back pcwalton introduced a PR that aimed to move the attribute and macro syntax to use a leading @ sigil. This means that one would write macros like: @format("SomeString: {}", 22) or @vec[1, 2, 3] One would write attributes in the same way: @deriving(Eq) struct SomeStruct { } @inline fn foo() { ... } This proposal was controversial....
So for the end of last week, I was at Rust Belt Rust. This was awesome. And not only because the speakers and attendees at Rust Belt Rust were awesome, though they were. But also because it gave aturon, withoutboats, and I a chance to talk over a lot of stuff in person. We covered a lot of territory and so I wanted to do a series of blog posts...
Hello. This post is a continuation of my posts discussing the topic of associated type constructors (ATC) and higher-kinded types (HKT): The first post focused on introducing the basic idea of ATC, as well as introducing some background material. This post talks about some apparent limitations of associated type constructors, and shows how we can...
This post is a continuation of my posts discussing the topic of associated type constructors (ATC) and higher-kinded types (HKT): The first post focused on introducing the basic idea of ATC, as well as introducing some background material. The second post showed how we can use ATC to model HKT, via the “family” pattern. This post dives into what...
This post is a continuation of my posts discussing the topic of associated type constructors (ATC) and higher-kinded types (HKT): The first post focused on introducing the basic idea of ATC, as well as introducing some background material. The second post showed how we can use ATC to model HKT, via the “family” pattern. The third post did some...
This post is the (long awaited, or at least long promised) third post in my series on Rayon’s parallel iterators. The previous two posts were some time ago, but I’ve been feeling inspired to push more on Rayon lately, and I remembered that I had never finished this blog post series. Here is a list of the other posts in the series. If you haven’t...
While I was at POPL the last few days, I was reminded of an idea regarding how to bring more struture to the unsafe code guidelines process that I’ve been kicking around lately, but which I have yet to write about publicly. The idea is fresh on my mind because while at POPL I realized that there is an interesting opportunity to leverage the...
Over the last year or two (man, it’s scary how time flies), I’ve been doing quite a lot of thinking about Rust’s trait system. I’ve been looking for a way to correct a number of flaws and shortcomings in the current implementation, not the least of which is that it’s performance is not that great. But also, I’ve been wanting to get a relatively...
In a previous post, I talked about a proposed approach to drafting the unsafe code guidelines. Specifically, I want to the approach of having an executable specification of Rust with additional checks that will signal when undefined behavior has occurred. In this post, I want to try to dive into that idea a bit more and give some more specifics...
This last week we had the rustc compiler team design sprint. This was our second rustc compiler team sprint; the first one (last year) we simply worked on pushing various projects over the finish line (for example, in an epic effort, arielb1 completed dynamic drop during that sprint). This sprint was different: we had the goal of talking over...