All Posts

2 May 2024

Unwind considered harmful?

I’ve been thinking a wild thought lately: we should deprecate panic=unwind. Most production users I know either already run with panic=abort or use unwinding in a very limited fashion, basically just to run to cleanup, not to truly recover. Removing unwinding from most case meanwhile has a number of benefits, allowing us to extend the type system in interesting and potentially very impactful ways. It also removes a common source of subtle bugs.

read more →

23 April 2024

Sized, DynSized, and Unsized

Extern types have been blocked for an unreasonably long time on a fairly narrow, specialized question: Rust today divides all types into two categories — sized, whose size can be statically computed, and unsized, whose size can only be computed at runtime. But for external types what we really want is a third category, types whose size can never be known, even at runtime (in C, you can model this by defining structs with an unknown set of fields).

read more →

5 April 2024

Ownership in Rust

Ownership is an important concept in Rust — but I’m not talking about the type system. I’m talking about in our open source project. One of the big failure modes I’ve seen in the Rust community, especially lately, is the feeling that it’s unclear who is entitled to make decisions. Over the last six months or so, I’ve been developing a project goals proposal, which is an attempt to reinvigorate Rust’s roadmap process — and a key part of this is the idea of giving each goal an owner.

read more →

4 March 2024

Borrow checking without lifetimes

This blog post explores an alternative formulation of Rust’s type system that eschews lifetimes in favor of places. The TL;DR is that instead of having 'a represent a lifetime in the code, it can represent a set of loans, like shared(a.b.c) or mut(x). If this sounds familiar, it should, it’s the basis for polonius, but reformulated as a type system instead of a static analysis. This blog post is just going to give the high-level ideas. In follow-up posts I’ll dig into how we can use this to support interior references and other advanced borrowing patterns. In terms of implementation, I’ve mocked this up a bit, but I intend to start extending a-mir-formality to include this analysis.

read more →

3 January 2024

What I'd like to see for Async Rust in 2024 🎄

Well, it’s that time of year, when thoughts turn to…well, Rust of course. I guess that’s every time of year. This year was a pretty big year for Rust, though I think a lot of what happened was more in the vein of “setting things up for success in 2024”. So let’s talk about 2024! I’m going to publish a series of blog posts about different aspects of Rust I’m excited about, and what I think we should be doing. To help make things concrete, I’m going to frame the 2024 by using proposed project goals – basically a specific piece of work I think we can get done this year. In this first post, I’ll focus on async Rust.

read more →

7 December 2023

Being Rusty: Discovering Rust's design axioms

To your average Joe, being “rusty” is not seen as a good thing.1 But readers of this blog know that being Rusty – with a capitol R! – is, of course, something completely different! So what is that makes Rust Rust? Our slogans articulate key parts of it, like fearless concurrency, stability without stagnation, or the epic Hack without fear. And there is of course Lindsey Kuper’s epic haiku: “A systems language / pursuing the trifecta: / fast, concurrent, safe”. But I feel like we’re still missing a unified set of axioms that we can refer back to over time and use to guide us as we make decisions. Some of you will remember the Rustacean Principles, which was my first attempt at this. I’ve been dissatisfied with them for a couple of reasons, so I decided to try again. The structure is really different, so I’m calling it Rust’s design axioms. This post documents the current state – I’m quite a bit happier with it! But it’s not quite there yet. So I’ve also got a link to a repository where I’m hoping people can help improve them by opening issues with examples, counter-examples, or other thoughts.

read more →

28 November 2023

Project Goals

Lately I’ve been iterating on an idea I call project goals. Project goals are a new kind of RFC that defines a specific goal that a specific group of people hope to achieve in a specific amount of time – for example, “Rusty Spoon Corp proposes to fund 2 engineers full time to stabilize collections that support custom memory allocations by the end of 2023”.

Project goals would also include asks from various teams that are needed to complete the goal. For example, “Achieving this goal requires a dedicated reviewer from the compiler team along with an agreement from the language design team to respond to RFCs or nominated issues within 2 weeks.” The decision of whether to accept a goal would be up to those teams who are being asked to support it. If those teams approve the RFC, it means they agree with the goal, and also that they agree to commit those resources.

My belief is that project goals become a kind of incremental, rolling roadmap, declaring our intent to fix specific problems and then tracking our follow-through (or lack thereof). As I’ll explain in the post, I believe that a mechanism like project goals will help our morale and help us to get shit done, but I also think it’ll help with a bunch of other ancillary problems, such as providing a clearer path to get involved in Rust as well as getting more paid maintainers and contributors.

At the moment, project goals are just an idea. My plan is to author some sample goals to iron out the process and then an RFC to make it official.

read more →

20 October 2023

Idea: "Using Rust", a living document

A few years back, the Async Wg tried something new. We collaboratively authored an Async Vision Doc. The doc began by writing “status quo” stories, written as narratives from our cast of characters, that described how people were experiencing Async Rust at that time and then went on to plan a “shiny future”. This was a great experience. My impression was that authoring the “status quo” stories in particular was really helpful.

read more →

14 October 2023

Eurorust reflections

I’m on the plane back to the US from Belgium now and feeling grateful for having had the chance to speak at the EuroRust conference1. EuroRust was the first Rust-focused conference that I’ve attended since COVID (though not the first conference overall). It was also the first Rust-focused conference that I’ve attended in Europe since…ever, from what I recall.2 Since many of us were going to be in attendance, the types team also organized an in-person meetup which took place for 3 days before the conference itself3.

read more →

30 September 2023

Easing tradeoffs with profiles

Rust helps you to build reliable programs. One of the ways it does that is by surfacing things to your attention that you really ought to care about. Think of the way we handle errors with Result: if some operation can fail, you can’t, ahem, fail to recognize that, because you have to account for the error case. And yet often the kinds of things you care about depend on the kind of application you are building. A classic example is memory allocation, which for many Rust apps is No Big Deal, but for others is something to be done carefully, and for still others is completely verboten. But this pattern crops up a lot. I’ve heard and like the framing of designing for “what do you have to pay attention to” – Rust currently aims for a balance that errs on the side of paying attention to more things, but tries to make them easy to manage. But this post is about a speculative idea of how we could do better than that by allowing programs to declare a profile.

read more →

29 September 2023

Polonius revisited, part 2

In the previous Polonius post, we formulated the original borrow checker in a Polonius-like style. In this post, we are going to explore how we can extend that formulation to be flow-sensitive. In so doing, we will enable the original Polonius goals, but also overcome some of its shortcomings. I believe this formulation is also more amenable to efficient implementation. As I’ll cover at the end, though, I do find myself wondering if there’s still more room for improvement.

read more →

27 September 2023

Empathy in open source: be gentle with each other

Over the last few weeks I had been preparing a talk on “Inclusive Mentoring: Mentoring Across Differences” with one of my good friends at Amazon. Unfortunately, that talk got canceled because I came down with COVID when we were supposed to be presenting. But the themes we covered in the talk have been rattling in my brain ever since, and suddenly I’m seeing them everywhere. One of the big ones was about empathy — what it is, what it isn’t, and how you can practice it.

read more →

22 September 2023

Polonius revisited, part 1

lqd has been doing awesome work driving progress on polonius. He’s authoring an update for Inside Rust, but the TL;DR is that, with his latest PR, we’ve reimplemented the traditional Rust borrow checker in a more polonius-like style. We are working to iron out the last few performance hiccups and thinking about replacing the existing borrow checker with this new re-implementation, which is effectively a no-op from a user’s perspective (including from a performance perspective).

read more →

19 September 2023

New Layout, and now using Hugo!

Some time ago I wrote about how I wanted to improve how my blog works. I recently got a spate of emails about this – thanks to all of you! And a particular big thank you to Luna Razzaghipour, who went ahead and ported the blog over to use Hugo, cleaning up the layout a bit and preserving URLs. It’s much appreciated! If you notice something amiss (like a link that doesn’t work anymore), I’d be very grateful if you opened an issue on the babysteps github repo! Thanks!

read more →

18 September 2023

Stability without stressing the !@#! out

One of Rust’s core principles is “stability without stagnation”. This is embodied by our use of a “release train” model, in which we issue a new release every 6 weeks. Release trains make releasing a new release a “non-event”. Feature-based releases, in contrast, are super stressful! Since they occur infrequently, people try to cram everything into that release, which inevitably makes the release late. In contrast, with a release train, it’s not so important to make any particular release – if you miss one deadline, you can always catch the next one six weeks later.

read more →

12 June 2023

Higher-ranked projections (send bound problem, part 4)

I recently posted a draft of an RFC about Return Type Notation to the async working group Zulip stream. In response, Josh Triplett reached out to me to raise some concerns. Talking to him gave rise to a 3rd idea for how to resolve the send bound problem. I still prefer RTN, but I think this idea is interesting and worth elaborating. I call it higher-ranked projections. Idea part 1: Define T::Foo when T has higher-ranked bounds Consider a trait like this…

read more →

9 May 2023

Giving, lending, and async closures

In a previous post on async closures, I concluded that the best way to support async closures was with an async trait combinator. I’ve had a few conversations since the post and I want to share some additional thoughts. In particular, this post dives into what it would take to make async functions matchable with a type like impl FnMut() -> impl Future<Output = bool>. This takes us down some interesting roads, in particular the distinction between giving and lending traits; it turns out that the closure traits specifically are a bit of a special case in turns of what we can do backwards compatibly, due to their special syntax.

read more →

3 April 2023

Fix my blog, please

It’s well known that my blog has some issues. The category links don’t work. It renders oddly on mobile. And maybe Safari, too? The Rust snippets are not colored. The RSS feed is apparently not advertised properly in the metadata. It’s published via a makefile instead of some hot-rod CI/CD script, and it uses jekyll instead of whatever the new hotness is.1 Being a programmer, you’d think I could fix this, but I am intimidated by HTML, CSS, and Github Actions.

read more →

29 March 2023

Thoughts on async closures

I’ve been thinking about async closures and how they could work once we have static async fn in trait. Somewhat surprisingly to me, I found that async closures are a strong example for where async transformers could be an important tool. Let’s dive in! We’re going to start with the problem, then show why modeling async closures as “closures that return futures” would require some deep lifetime magic, and finally circle back to how async transformers can make all this “just work” in a surprisingly natural way.

read more →

16 March 2023

Must move types

Rust has lots of mechanisms that prevent you from doing something bad. But, right now, it has NO mechanisms that force you to do something good1. I’ve been thinking lately about what it would mean to add “must move” types to the language. This is an idea that I’ve long resisted, because it represents a fundamental increase to complexity. But lately I’m seeing more and more problems that it would help to address, so I wanted to try and think what it might look like, so we can better decide if it’s a good idea.

read more →

15 March 2023

Temporary lifetimes

In today’s lang team design meeting, we reviewed a doc I wrote about temporary lifetimes in Rust. The current rules were established in a blog post I wrote in 2014. Almost a decade later, we’ve seen that they have some rough edges, and in particular can be a common source of bugs for people. The Rust 2024 Edition gives us a chance to address some of those rough edges. This blog post is a copy of the document that the lang team reviewed.

read more →

12 March 2023

To async trait or just to trait

One interesting question about async fn in traits is whether or not we should label the trait itself as async. Until recently, I didn’t see any need for that. But as we discussed the question of how to enable “maybe async” code, we realized that there would be some advantages to distinguishing “async traits” (which could contain async functions) from sync traits (which could not). However, as I’ve thought about the idea more, I’m more and more of the mind that we should not take this step — at least not now.

read more →

3 March 2023

Trait transformers (send bounds, part 3)

I previously introduced the “send bound” problem, which refers to the need to add a Send bound to the future returned by an async function. This post continues my tour over the various solutions that are available. This post covers “Trait Transformers”. This proposal arose from a joint conversation with myself, Eric Holk, Yoshua Wuyts, Oli Scherer, and Tyler Mandry. It’s a variant of Eric Holk’s inferred async send bounds proposal as well as the work that Yosh/Oli have been doing in the keyword generics group.

read more →

13 February 2023

Return type notation (send bounds, part 2)

In the previous post, I introduced the “send bound” problem, which refers to the need to add a Send bound to the future returned by an async function. I want to start talking about some of the ideas that have been floating around for how to solve this problem. I consider this a bit of an open problem, in that I think we know a lot of the ingredients, but there is a bit of a “delicate balance” to finding the right syntax and so forth.

read more →

1 February 2023

Async trait send bounds, part 1: intro

Nightly Rust now has support for async functions in traits, so long as you limit yourself to static dispatch. That’s super exciting! And yet, for many users, this support won’t yet meet their needs. One of the problems we need to resolve is how users can conveniently specify when they need an async function to return a Send future. This post covers some of the background on send futures, why we don’t want to adopt the solution from the async_trait crate for the language, and the general direction we would like to go.

read more →

20 January 2023

Rust in 2023: Growing up

When I started working on Rust in 2011, my daughter was about three months old. She’s now in sixth grade, and she’s started growing rapidly. Sometimes we wake up to find that her clothes don’t quite fit anymore: the sleeves might be a little too short, or the legs come up to her ankles. Rust is experiencing something similar. We’ve been growing tremendously fast over the last few years, and any time you experience growth like that, there are bound to be a few rough patches.

read more →

22 September 2022

Rust 2024...the year of everywhere?

I’ve been thinking about what “Rust 2024” will look like lately. I don’t really mean the edition itself — but more like, what will Rust feel like after we’ve finished up the next few years of work? I think the answer is that Rust 2024 is going to be the year of “everywhere”. Let me explain what I mean. Up until now, Rust has had a lot of nice features, but they only work sometimes.

read more →

21 September 2022

Dyn async traits, part 9: call-site selection

After my last post on dyn async traits, some folks pointed out that I was overlooking a seemingly obvious possibility. Why not have the choice of how to manage the future be made at the call site? It’s true, I had largely dismissed that alternative, but it’s worth consideration. This post is going to explore what it would take to get call-site-based dispatch working, and what the ergonomics might look like.

read more →

19 September 2022

What I meant by the "soul of Rust"

Re-reading my previous post, I felt I should clarify why I called it the “soul of Rust”. The soul of Rust, to my mind, is definitely not being explicit about allocation. Rather, it’s about the struggle between a few key values — especially productivity and versatility1 in tension with transparency. Rust’s goal has always been to feel like a high-level but with the performance and control of a low-level one. Oftentimes, we are able to find a “third way” that removes the tradeoff, solving both goals pretty well.

read more →

18 September 2022

Dyn async traits, part 8: the soul of Rust

In the last few months, Tyler Mandry and I have been circulating a “User’s Guide from the Future” that describes our current proposed design for async functions in traits. In this blog post, I want to deep dive on one aspect of that proposal: how to handle dynamic dispatch. My goal here is to explore the space a bit and also to address one particularly tricky topic: how explicit do we have to be about the possibility of allocation?

read more →

18 August 2022

Come contribute to Salsa 2022!

Have you heard of the Salsa project? Salsa is a library for incremental computation – it’s used by rust-analyzer, for example, to stay responsive as you type into your IDE (we have also discussed using it in rustc, though more work is needed there). We are in the midst of a big push right now to develop and release Salsa 2022, a major new revision to the API that will make Salsa far more natural to use.

read more →

27 June 2022

Many modes: a GATs pattern

As some of you may know, on May 4th Jack Huey opened a PR to stabilize an initial version of generic associated types. The current version is at best an MVP: the compiler support is limited, resulting in unnecessary errors, and the syntax is limited, making code that uses GATs much more verbose than I’d like. Nonetheless, I’m super excited, since GATs unlock a lot of interesting use cases, and we can continue to smooth out the rough edges over time.

read more →

15 June 2022

What it feels like when Rust saves your bacon

You’ve probably heard that the Rust type checker can be a great “co-pilot”, helping you to avoid subtle bugs that would have been a royal pain in the !@#!$! to debug. This is truly awesome! But what you may not realize is how it feels in the moment when this happens. The answer typically is: really, really frustrating! Usually, you are trying to get some code to compile and you find you just can’t do it.

read more →

13 June 2022

Async cancellation: a case study of pub-sub in mini-redis

Lately I’ve been diving deep into tokio’s mini-redis example. The mini-redis example is a great one to look at because it’s a realistic piece of quality async Rust code that is both self-contained and very well documented. Digging into mini-redis, I found that it exemplifies the best and worst of async Rust. On the one hand, the code itself is clean, efficient, and high-level. On the other hand, it relies on a number of subtle async conventions that can easily be done wrong – worse, if you do them wrong, you won’t get a compilation error, and your code will “mostly work”, breaking only in unpredictable timing conditions that are unlikely to occur in unit tests.

read more →

17 April 2022

Coherence and crate-level where-clauses

Rust has been wrestling with coherence more-or-less since we added methods; our current rule, the “orphan rule”, is safe but overly strict. Roughly speaking, the rule says that one can only implement foreign traits (that is, traits defined by one of your dependencies) for local types (that is, types that you define). The goal of this rule was to help foster the crates.io ecosystem — we wanted to ensure that you could grab any two crates and use them together, without worrying that they might define incompatible impls that can’t be combined.

read more →

12 April 2022

Implied bounds and perfect derive

There are two ergonomic features that have been discussed for quite some time in Rust land: perfect derive and expanded implied bounds. Until recently, we were a bit stuck on the best way to implement them. Recently though I’ve been working on a new formulation of the Rust trait checker that gives us a bunch of new capabilities — among them, it resolved a soundness formulation that would have prevented these two features from being combined.

read more →

29 March 2022

dyn*: can we make dyn sized?

Last Friday, tmandry, cramertj, and I had an exciting conversation. We were talking about the design for combining async functions in traits with dyn Trait that tmandry and I had presented to the lang team on Friday. cramertj had an insightful twist to offer on that design, and I want to talk about it here. Keep in mind that this is a piece of “hot off the presses”, in-progress design and hence may easily go nowhere – but at the same time, I’m pretty excited about it.

read more →

9 February 2022

Dare to ask for more #rust2024

Last year, we shipped Rust 2021 and I have found the changes to be a real improvement in usability. Even though the actual changes themselves were quite modest, the combination of precise capture closure and simpler formatting strings (println!("{x:?}") instead of println!("{:?}", x)) is making a real difference in my “day to day” life.1 Just like NLL and the new module system from Rust 2018, I’ve quickly adapted to these new conventions.

read more →

27 January 2022

Panics vs cancellation, part 1

One of the things people often complain about when doing Async Rust is cancellation. This has always been a bit confusing to me, because it seems to me that async cancellation should feel a lot like panics in practice, and people don’t complain about panics very often (though they do sometimes). This post is the start of a short series comparing panics and cancellation, seeking after the answer to the question “Why is async cancellation a pain point and what should we do about it?

read more →

7 January 2022

Dyn async traits, part 7: a design emerges?

Hi all! Welcome to 2022! Towards the end of last year, Tyler Mandry and I were doing a lot of iteration around supporting “dyn async trait” – i.e., making traits that use async fn dyn safe – and we’re starting to feel pretty good about our design. This is the start of several blog posts talking about where we’re at. In this first post, I’m going to reiterate our goals and give a high-level outline of the design.

read more →

18 November 2021

Rustc Reading Club, Take 2

Wow! The response to the last Rustc Reading Club was overwhelming – literally! We maxed out the number of potential zoom attendees and I couldn’t even join the call! It’s clear that there’s a lot of demand here, which is great. We’ve decided to take another stab at running the Rustc Reading Club, but we’re going to try it a bit differently this time. We’re going to start by selecting a smaller group to do it a few times and see how it goes, and then decide how to scale up.

read more →

15 November 2021

CTCFT 2021-11-22 Agenda

The next “Cross Team Collaboration Fun Times” (CTCFT) meeting will take place next Monday, on 2021-11-22 at 11am US Eastern Time (click to see in your time zone). Note that this is a new time: we are experimenting with rotating in an earlier time that occurs during the European workday. This post covers the agenda. You’ll find the full details (along with a calendar event, zoom details, etc) on the CTCFT website.

read more →

5 November 2021

View types for Rust

I wanted to write about an idea that’s been kicking around in the back of my mind for some time. I call it view types. The basic idea is to give a way for an &mut or & reference to identify which fields it is actually going to access. The main use case for this is having “disjoint” methods that don’t interfere with one another. This is not a proposal (yet?

read more →

28 October 2021

Rustc Reading Club

Ever wanted to understand how rustc works? Me too! Doc Jones and I have been talking and we had an idea we wanted to try. Inspired by the very cool Code Reading Club, we are launching an experimental Rustc Reading Club. Doc Jones posted an announcement on her blog, so go take a look! The way this club works is pretty simple: every other week, we’ll get together for 90 minutes and read some part of rustc (or some project related to rustc), and talk about it.

read more →

15 October 2021

Dyn async traits, part 6

A quick update to my last post: first, a better way to do what I was trying to do, and second, a sketch of the crate I’d like to see for experimental purposes. An easier way to roll our own boxed dyn traits In the previous post I covered how you could create vtables and pair the up with a data pointer to kind of “roll your own dyn”. After I published the post, though, dtolnay sent me this Rust playground link to show me a much better approach, one based on the erased-serde crate.

read more →

14 October 2021

Dyn async traits, part 5

If you’re willing to use nightly, you can already model async functions in traits by using GATs and impl Trait — this is what the Embassy async runtime does, and it’s also what the real-async-trait crate does. One shortcoming, though, is that your trait doesn’t support dynamic dispatch. In the previous posts of this series, I have been exploring some of the reasons for that limitation, and what kind of primitive capabilities need to be exposed in the language to overcome it.

read more →

13 October 2021

CTCFT 2021-10-18 Agenda

The next “Cross Team Collaboration Fun Times” (CTCFT) meeting will take place next Monday, on 2021-10-18 (in your time zone)! This post covers the agenda. You’ll find the full details (along with a calendar event, zoom details, etc) on the CTCFT website. Agenda The theme for this meeting is exploring ways to empower and organize contributors. (5 min) Opening remarks 👋 (nikomatsakis) (5 min) CTCFT update (angelonfira) (20 min) Sprints and groups implementing the async vision doc (tmandry) (15 min) rust-analyzer talk (TBD) The rust-analyzer project aims to succeed RLS as the official language server for Rust.

read more →

7 October 2021

Dyn async traits, part 4

In the previous post, I talked about how we could write our own impl Iterator for dyn Iterator by adding a few primitives. In this post, I want to look at what it would take to extend that to an async iterator trait. As before, I am interested in exploring the “core capabilities” that would be needed to make everything work. Start somewhere: Just assume we want Box In the first post of this series, we talked about how invoking an async fn through a dyn trait should to have the return type of that async fn be a Box<dyn Future> — but only when calling it through a dyn type, not all the time.

read more →

6 October 2021

Dyn async traits, part 3

In the previous “dyn async traits” posts, I talked about how we can think about the compiler as synthesizing an impl that performed the dynamic dispatch. In this post, I wanted to start explore a theoretical future in which this impl was written manually by the Rust programmer. This is in part a thought exercise, but it’s also a possible ingredient for a future design: if we could give programmers more control over the “impl Trait for dyn Trait” impl, then we could enable a lot of use cases.

read more →

1 October 2021

Dyn async traits, part 2

In the previous post, we uncovered a key challenge for dyn and async traits: the fact that, in Rust today, dyn types have to specify the values for all associated types. This post is going to dive into more background about how dyn traits work today, and in particular it will talk about where that limitation comes from. Today: Dyn traits implement the trait In Rust today, assuming you have a “dyn-safe” trait DoTheThing , then the type dyn DoTheThing implements Trait.

read more →

30 September 2021

Dyn async traits, part 1

Over the last few weeks, Tyler Mandry and I have been digging hard into what it will take to implement async fn in traits. Per the new lang team initiative process, we are collecting our design thoughts in an ever-evolving website, the async fundamentals initiative. If you’re interested in the area, you should definitely poke around; you may be interested to read about the MVP that we hope to stabilize first, or the (very much WIP) evaluation doc which covers some of the challenges we are still working out.

read more →

16 September 2021

Rustacean Principles, continued

RustConf is always a good time for reflecting on the project. For me, the last week has been particularly “reflective”. Since announcing the Rustacean Principles, I’ve been having a number of conversations with members of the community about how they can be improved. I wanted to write a post summarizing some of the feedback I’ve gotten. The principles are a work-in-progress Sparking conversation about the principles was exactly what I was hoping for when I posted the previous blog post.

read more →

15 September 2021

CTCFT 2021-09-20 Agenda

The next “Cross Team Collaboration Fun Times” (CTCFT) meeting will take place next Monday, on 2021-09-20 (in your time zone)! This post covers the agenda. You’ll find the full details (along with a calendar event, zoom details, etc) on the CTCFT website. Agenda Announcements Interest group panel discussion We’re going to try something a bit different this time! The agenda is going to focus on Rust interest groups and domain working groups, those brave explorers who are trying to put Rust to use on all kinds of interesting domains.

read more →

8 September 2021

Rustacean Principles

As the web site says, Rust is a language empowering everyone to build reliable and efficient software. I think it’s precisely this feeling of empowerment that people love about Rust. As wycats put it recently to me, Rust makes it “feel like things are possible that otherwise feel out of reach”. But what exactly makes Rust feel that way? If we can describe it, then we can use that description to help us improve Rust, and to guide us as we design extensions to Rust.

read more →

30 August 2021

Next CTCFT Meeting: 2021-09-20

Hold the date! The next Cross Team Collaboration Fun Times meeting will be 2021-09-20. We’ll be using the “Asia-friendly” time slot of 21:00 EST. What will the talks be about? A detailed agenda will be announced in a few weeks. Current thinking however is to center the agenda on Rust interest groups and domain working groups, those brave explorers who are trying to put Rust to use on all kinds of interesting domains, such as game development, cryptography, machine learning, formal verification, and embedded development.

read more →

12 July 2021

CTCFT 2021-07-19 Agenda

The next “Cross Team Collaboration Fun Times” (CTCFT) meeting will take place one week from today, on 2021-07-19 (in your time zone)! What follows are the abstracts for the talks we have planned. You’ll find the full details (along with a calendar event, zoom details, etc) on the CTCFT website. Mentoring Presented by: doc-jones The Rust project has a number of mechanisms for getting people involved in the project, but most are oriented around 1:1 engagement.

read more →

14 June 2021

CTCFT 2021-06-21 Agenda

The second “Cross Team Collaboration Fun Times” (CTCFT) meeting will take place one week from today, on 2021-06-21 (in your time zone)! This post describes the main agenda items for the meeting; you’ll find the full details (along with a calendar event, zoom details, etc) on the CTCFT website. Afterwards: Social hour After the CTCFT this week, we are going to try an experimental social hour. The hour will be coordinated in the #ctcft stream of the rust-lang Zulip.

read more →

26 May 2021

Edition: the song

You may have heard that the Rust 2021 Edition is coming. Along with my daughter Daphne, I have recorded a little song in honor of the occasion! The full lyrics are below – if you feel inspired, please make your own version!1 Enjoy! Video Lyrics (Spoken) Breaking changes where no code breaks. Sounds impossible, no? But in the Rust language, you might say that we like to do impossible things. It isn’t easy.

read more →

14 May 2021

CTCFTFTW

This Monday I am starting something new: a monthly meeting called the “Cross Team Collaboration Fun Times” (CTCFT)1. Check out our nifty logo2: The meeting is a mechanism to help keep the members of the Rust teams in sync and in touch with one another. The idea is to focus on topics of broad interest (more than two teams): Status updates on far-reaching projects that could affect multiple teams; Experience reports about people trying new things (sometimes succeeding, sometimes not); “Rough draft” proposals that are ready to be brought before a wider audience.

read more →

1 May 2021

[AiC] Vision Docs!

The Async Vision Doc effort has been going now for about 6 weeks. It’s been a fun ride, and I’ve learned a lot. It seems like a good time to take a step back and start talking a bit about the vision doc structure and the process. In this post, I’m going to focus on the role that I see vision docs playing in Rust’s planning and decision making, particularly as compared to RFCs.

read more →

26 April 2021

Async Vision Doc Writing Sessions VII

My week is very scheduled, so I am not able to host any public drafting sessions this week – however, Ryan Levick will be hosting two sessions! When Who Wed at 07:00 ET Ryan Fri at 07:00 ET Ryan If you’re available and those stories sound like something that interests you, please join him! Just ping me or Ryan on Discord or Zulip and we’ll send you the Zoom link. If you’ve already joined a previous session, the link is the same as before.

read more →

19 April 2021

Async Vision Doc Writing Sessions VI

Ryan Levick and I are going to be hosting more Async Vision Doc Writing Sessions this week. We’re not organized enough to have assigned topics yet, so I’m just going to post the dates/times and we’ll be tweeting about the particular topics as we go. When Who Wed at 07:00 ET Ryan Wed at 15:00 ET Niko Fri at 07:00 ET Ryan Fri at 14:00 ET Niko If you’ve joined before, we’ll be re-using the same Zoom link.

read more →

12 April 2021

Async Vision Doc Writing Sessions V

This is an exciting week for the vision doc! As of this week, we are starting to draft “shiny future” stories, and we would like your help! (We are also still working on status quo stories, so there is no need to stop working on those.) There will be a blog post coming out on the main Rust blog soon with all the details, but you can go to the “How to vision: Shiny future” page now.

read more →

7 April 2021

Async Vision Doc Writing Sessions IV

My week is very scheduled, so I am not able to host any public drafting sessions this week – however, Ryan Levick will be hosting two sessions! When Who Topic Thu at 07:00 ET Ryan The need for Async Traits Fri at 07:00 ET Ryan Challenges from cancellation If you’re available and those stories sound like something that interests you, please join him! Just ping me or Ryan on Discord or Zulip and we’ll send you the Zoom link.

read more →

2 April 2021

My "shiny future"

I’ve been working on the Rust project for just about ten years. The language has evolved radically in that time, and so has the project governance. When I first started, for example, we communicated primarily over the rust-dev mailing list and the #rust IRC channel. I distinctly remember coming into the Mozilla offices1 one day and brson excitedly telling me, “There were almost a dozen people on the #rust IRC channel last night!

read more →

29 March 2021

Async Vision Doc Writing Sessions III

Ryan Levick and I are hosting a number of public drafting sessions scheduled this week. Some of them are scheduled early to cover a wider range of time zones. When Who Topic Tue at 14:30 ET Niko wrapping C++ async APIs in Rust futures and other tales of interop Wed at 10:00 ET Niko picking an HTTP library and similar stories Wed at 15:00 ET Niko structured concurrency and parallel data processing Thu at 07:00 ET Ryan debugging and getting insights into running services Fri at 07:00 ET Ryan lack of a polished common implementations of basic async helpers Fri at 14:30 ET Niko bridging sync and async If you’re available and those stories sound like something that interests you, please join us!

read more →

25 March 2021

Async Vision Doc Writing Sessions II

I’m scheduling two more public drafting sessions for tomorrow, Match 26th: On March 26th at 10am ET (click to see in your local timezone), we will be working on writing a story about the challenges of writing a library that can be reused across many runtimes (rust-lang/wg-async-foundations#45); On March 26th at 2pm ET (click to see in your local tomezone), we will be working on writing a story about the difficulty of debugging and interpreting async stack traces (rust-lang/wg-async-foundations#69).

read more →

22 March 2021

Async Vision Doc Writing Sessions

Hey folks! As part of the Async Vision Doc effort, I’m planning on holding two public drafting sessions tomorrow, March 23rd: March 23rd at noon ET (click to see in your local timezone) March 23rd at 5pm ET (click to see in your local tomezone) During these sessions, we’ll be looking over the status quo issues and writing a story or two! If you’d like to join, ping me on Discord or Zulip and I’ll send you the Zoom link.

read more →

30 December 2020

The more things change...

I’ve got an announcement to make. As of Jan 4th, I’m starting at Amazon as the tech lead of their new Rust team. Working at Mozilla has been a great experience, but I’m pretty excited about this change. It’s a chance to help shape what I hope to be an exciting new phase for Rust, where we grow from a project with a single primary sponsor (Mozilla) to an industry standard, supported by a wide array of companies.

read more →

18 December 2020

Looking back on 2020

I wanted to write a post that looks back over 2020 from a personal perspective. My goal here is to look at the various initiatives that I’ve been involved in and try to get a sense for how they went, what worked and what didn’t, and also what that means for next year. This post is a backdrop for a #niko2021 post that I plan to post sometime before 2021 actually starts, talking about what I expect to be doing in 2021.

read more →

11 December 2020

Rotating the compiler team leads

Since we created the Rust teams, I have been serving as lead of two teams: the compiler team and the language design team (I’ve also been a member of the core team, which has no lead). For those less familiar with Rust’s governance, the compiler team is focused on the maintenance and implementation of the compiler itself (and, more recently, the standard library). The language design team is focused on the design aspects.

read more →

30 April 2020

Async interviews: my take thus far

The point of the async interview series, in the end, was to help figure out what we should be doing next when it comes to Async I/O. I thought it would be good then to step back and, rather than interviewing someone else, give my opinion on some of the immediate next steps, and a bit about the medium to longer term. I’m also going to talk a bit about what I see as some of the practical challenges.

read more →

9 April 2020

Library-ification and analyzing Rust

I’ve noticed that the ideas that I post on my blog are getting much more “well rounded”. That is a problem. It means I’m waiting too long to write about things. So I want to post about something that’s a bit more half-baked – it’s an idea that I’ve been kicking around to create a kind of informal “analysis API” for rustc. The problem statement I am interested in finding better ways to support advanced analyses that “layer on” to rustc.

read more →

10 March 2020

Async Interview #7: Withoutboats

Hello everyone! I’m happy to be posting a transcript of my async interview with withoutboats. This particularly interview took place way back on January 14th, but the intervening months have been a bit crazy and I didn’t get around to writing it up till now. Video You can watch the video on YouTube. I’ve also embedded a copy here for your convenience: Next steps for async Before I go into boats’ interview, I want to talk a bit about the state of async-await in Rust and what I see as the obvious next steps.

read more →

11 February 2020

Async Interview #6: Eliza Weisman

Hello! For the latest async interview, I spoke with Eliza Weisman (hawkw, mycoliza on twitter). Eliza first came to my attention as the author of the tracing crate, which is a nifty crate for doing application level tracing. However, she is also a core maintainer of tokio, and she works at Buoyant on the linkerd system. linkerd is one of a small set of large applications that were build using 0.

read more →

20 January 2020

Async Interview #5: Steven Fackler

Hello! For the latest async interview, I spoke with Steven Fackler (sfackler). sfackler has been involved in Rust for a long time and is a member of the Rust libs team. He is also the author of a lot of crates, most notably tokio-postgres. I particularly wanted to talk to sfackler about the AsyncRead and AsyncWrite traits. These traits are on everybody’s list of “important things to stabilize”, particularly if we want to create more interop between different executors and runtimes.

read more →

13 January 2020

Async Interview #4: Florian Gilcher

Hello! For the latest async interview, I spoke with Florian Gilcher (skade). Florian is involved in the async-std project, but he’s also one of the founders of Ferrous Systems, a Rust consulting firm that also does a lot of trainings. In that capacity, he’s been teaching people to use async Rust now since Rust’s 1.0 release. Video You can watch the video on YouTube. I’ve also embedded a copy here for your convenience:

read more →

9 January 2020

Towards a Rust foundation

In my #rust2020 blog post, I mentioned rather off-handedly that I think the time has come for us to talk about forming a Rust foundation. I wanted to come back to this topic and talk in more detail about what I think a Rust foundation might look like. And, since I don’t claim to have the final answer to that question by any means, I’d also like to talk about how I think we should have this conversation going forward.

read more →

23 December 2019

Async Interview #3: Carl Lerche

Hello! For the latest async interview, I spoke with Carl Lerche (carllerche). Among many other crates1, Carl is perhaps best known as one of the key authors behind tokio and mio. These two crates are quite widely used through the async ecosystem. Carl and I spoke on December 3rd. Video You can watch the video on YouTube. I’ve also embedded a copy here for your convenience: Background: the mio crate One of the first things we talked about was a kind of overview of the layers of the “tokio-based async stack”.

read more →

11 December 2019

Async Interview #2: cramertj, part 3

This blog post is continuing my conversation with cramertj. This will be the last post. In the first post, I covered what we said about Fuchsia, interoperability, and the organization of the futures crate. In the second post, I covered cramertj’s take on the Stream, AsyncRead, and AsyncWrite traits. We also discused the idea of attached streams and the imporance of GATs for modeling those. In this post, we’ll talk about async closures.

read more →

10 December 2019

Async Interview #2: cramertj, part 2

This blog post is continuing my conversation with cramertj. In the first post, I covered what we said about Fuchsia, interoperability, and the organization of the futures crate. This post covers cramertj’s take on the Stream trait as well as the AsyncRead and AsyncWrite traits. You can watch the video on YouTube. The need for “streaming” streams and iterators Next, cramertj and I turned to discussing some of the specific traits from the futures crate.

read more →

9 December 2019

Async Interview #2: cramertj

For the second async interview, I spoke with Taylor Cramer – or cramertj, as I’ll refer to him. cramertj is a member of the compiler and lang teams and was – until recently – working on Fuchsia at Google. He’s been a key player in Rust’s Async I/O design and in the discussions around it. He was also responsible for a lot of the implementation work to make async fn a reality.

read more →

3 December 2019

AiC: Improving the pre-RFC process

I want to write about an idea that Josh Triplett and I have been iterating on to revamp the lang team RFC process. I have written a draft of an RFC already, but this blog post aims to introduce the idea and some of the motivations. The key idea of the RFC is formalize the steps leading up to an RFC, as well as to capture the lang team operations around project groups.

read more →

2 December 2019

Rust 2020

Technically speaking, it’s past the deadline for #rust2020 posts, but I’m running late this year, and I’m going to post something anyway. In this post, I am focusing on what I see as the “largest scale” issues, and not on technical initiatives. If I have time, I will try to post a follow-up talking about some of the key technical initiatives that I think we should focus on as well.

read more →

28 November 2019

Async Interview #1: Alex and Nick talk about async I/O and WebAssembly

Hello from Iceland! (I’m on vacation.) I’ve just uploaded [the first of the Async Interviews][video] to YouTube. It is a conversation with Alex Crichton (alexcrichton) and Nick Fitzgerald (fitzgen) about how WebAssembly and Rust’s Async I/O system interact. When you watch it, you will probably notice two things: First, I spent a lot of time looking off to the side! This is because I had the joint Dropbox paper document open on my side monitor and I forgot how strange that would look.

read more →

22 November 2019

Announcing the Async Interviews

Hello all! I’m going to be trying something new, which I call the “Async Interviews”. These interviews are going to be a series of recorded video calls with various “luminaries” from Rust’s Async I/O effort. In each one, I’m going to be asking roughly the same question: Now that the async-await MVP is stable, what should we be doing next? After each call, I’ll post the recording from the interview, along with a blog post that leaves a brief summary.

read more →

26 October 2019

why async fn in traits are hard

After reading boat’s excellent post on asynchronous destructors, I thought it might be a good idea to write some about async fn in traits. Support for async fn in traits is probably the single most common feature request that I hear about. It’s also one of the more complex topics. So I thought it’d be nice to do a blog post kind of giving the “lay of the land” on that feature – what makes it complicated?

read more →

11 September 2019

AiC: Shepherds 3.0

I would like to describe an idea that’s been kicking around in my head. I’m calling this idea “shepherds 3.0” – the 3.0 is to distinguish it from the other places we’ve used the term in the past. This proposal actually supplants both of the previous uses of the term, replacing them with what I believe to be a preferred alternative (more on that later). Caveat This is an idea that has been kicking around in my head for a while.

read more →

10 July 2019

AiC: Unbounded queues and lang design

I have been thinking about how language feature development works in Rust1. I wanted to write a post about what I see as one of the key problems: too much concurrency in our design process, without any kind of “back-pressure” to help keep the number of “open efforts” under control. This setup does enable us to get a lot of things done sometimes, but I believe it also leads to a number of problems.

read more →

8 July 2019

Async-await status report #2

I wanted to give an update on the status of the “async-await foundations” working group. This post aims to cover three things: the “async await MVP” that we are currently targeting; how that fits into the bigger picture; and how you can help, if you’re so inclined; Current target: async-await MVP We are currently working on stabilizing what we call the async-await MVP – as in, “minimal viable product”. As the name suggests, the work we’re doing now is basically the minimum that is needed to “unlock” async-await.

read more →

26 April 2019

AiC: Language-design team meta working group

On internals, I just announced the formation of the language-design team meta working group. The role of the meta working group is to figure out how other language-design team working groups should work. The plan is to begin by enumerating some of our goals – the problems we aim to solve, the good things we aim to keep – and then move on to draw up more details plans. I expect this discussion will intersect the RFC process quite heavily (at least when it comes to language design changes).

read more →

22 April 2019

AiC: Collaborative summary documents

In my previous post, I talked about the idea of mapping the solution space: When we talk about the RFC process, we always emphasize that the point of RFC discussion is not to select the best answer; rather, the point is to map the solution space. That is, to explore what the possible tradeoffs are and to really look for alternatives. This mapping process also means exploring the ups and downs of the current solutions on the table.

read more →

19 April 2019

AiC: Adventures in consensus

In the talk I gave at Rust LATAM, I said that the Rust project has always emphasized finding the best solution, rather than winning the argument. I think this is one of our deepest values. It’s also one of the hardest for us to uphold. Let’s face it – when you’re having a conversation, it’s easy to get attached to specific proposals. It’s easy to have those proposals change from “Option A” vs “Option B” to “my option” and “their option”.

read more →

15 April 2019

More than coders

Lately, the compiler team has been changing up the way that we work. Our goal is to make it easier for people to track what we are doing and – hopefully – get involved. This is an ongoing effort, but one thing that has become clear immediately is this: the compiler team needs more than coders. Traditionally, when we’ve thought about how to “get involved” in the compiler team, we’ve thought about it in terms of writing PRs.

read more →

1 March 2019

Async-await status report

I wanted to post a quick update on the status of the async-await effort. The short version is that we’re in the home stretch for some kind of stabilization, but there remain some significant questions to overcome. Announcing the implementation working group As part of this push, I’m happy to announce we’ve formed a async-await implementation working group. This working group is part of the whole async-await effort, but focused on the implementation, and is part of the compiler team.

read more →

22 February 2019

Rust lang team working groups

Now that the Rust 2018 edition has shipped, the language design team has been thinking a lot about what to do in 2019 and over the next few years. I think we’ve got a lot of exciting stuff on the horizon, and I wanted to write about it. Theme for this edition In 2015, our overall theme was stability. For the 2018 Edition, we adopted productivity. For Rust 20211, we are thinking of maturity as the theme.

read more →

29 January 2019

Salsa: Incremental recompilation

So for the last couple of months or so, I’ve been hacking in my spare time on this library named salsa, along with a number of awesome other folks. Salsa basically extracts the incremental recompilation techniques that we built for rustc into a general-purpose framework that can be used by other programs. Salsa is developing quickly: with the publishing of v0.10.0, we saw a big step up in the overall ergonomics, and I think the current interface is starting to feel very nice.

read more →

21 January 2019

Polonius and the case of the hereditary harrop predicate

In my previous post about Polonius and subregion obligations, I mentioned that there needs to be a follow-up to deal with higher-ranked subregions. This post digs a bit more into what the problem is in the first place and sketches out the general solution I have in mind, but doesn’t give any concrete algorithms for it. The subset relation in Polonius is not enough In my original post on Polonius, I assumed that when we computed a subtype relation T1 <: T2 between two types, the result was either a hard error or a set of subset relations between various regions.

read more →

17 January 2019

Polonius and region errors

Now that NLL has been shipped, I’ve been doing some work revisiting the Polonius project. Polonius is the project that implements the “alias-based formulation” described in my older blogpost. Polonius has come a long way since that post; it’s now quite fast and also experimentally integrated into rustc, where it passes the full test suite. However, polonius as described is not complete. It describes the core “borrow check” analysis, but there are a number of other checks that the current implementation checks which polonius ignores:

read more →

7 January 2019

Rust in 2019: Focus on sustainability

To me, 2018 felt like a big turning point for Rust, and it wasn’t just the edition. Suddenly, it has become “normal” for me to meet people using Rust at their jobs. Rust conferences are growing and starting to have large number of sponsors. Heck, I even met some professional Rust developers amongst the parents at a kid’s birthday party recently. Something has shifted, and I like it. At the same time, I’ve also noticed a lot of exhaustion.

read more →

10 November 2018

After NLL: Moving from borrowed data and the sentinel pattern

Continuing on with my “After NLL” series, I want to look at another common error that I see and its solution: today’s choice is about moves from borrowed data and the Sentinel Pattern that can be used to enable them. The problem Sometimes when we have &mut access to a struct, we have a need to temporarily take ownership of some of its fields. Usually what happens is that we want to move out from a field, construct something new using the old value, and then replace it.

read more →

8 November 2018

Splash 2018 Mid-Week Report

This week I’ve been attending SPLASH 2018. It’s already been quite an interesting week, and it’s only just begun. I thought I’d write up a quick report on some of the things that have been particularly interesting to me, and some of the ideas that they’ve sparked off. Teaching programming (and Rust!) I really enjoyed this talk by Felienne Hermans entitled “Explicit Direct Instruction in Programming Education”. The basic gist of the talk was that, when we teach programming, we often phrase it in terms of “exploration” and “self-expression”, but that this winds up leaving a lot of folks in the cold and may be at least partly responsible for the lack of diversity in computer science today.

read more →

1 November 2018

After NLL: Interprocedural conflicts

In my previous post on the status of NLL, I promised to talk about “What is next?” for ownership and borrowing in Rust. I want to lay out the various limitations of Rust’s ownership and borrowing system that I see, as well as – where applicable – current workarounds. I’m curious to get feedback on which problems affect folks the most. The first limitation I wanted to focus on is interprocedural conflicts.

read more →

31 October 2018

MIR-based borrowck is almost here

Now that the final Rust 2018 Release Candidate has shipped, I thought it would be a good idea to do another update on the state of the MIR-based borrow check (aka NLL). The last update was in June, when we were still hard at work on getting things to work. Rust 2018 will use NLL now Let’s get the highlights out of the way. Most importantly, Rust 2018 crates will use NLL by default.

read more →

27 September 2018

October Office Hour Slots

Just a quick note that the October 2018 office hour slots are now posted. If you’re having a problem with Rust, or have something you’d like to talk out, please sign up!

read more →

24 September 2018

Office Hours #1: Cyclic services

This is a report on the second “office hours”, in which we discussed how to setup a series of services or actors that communicate with one another. This is a classic kind of problem in Rust: how to deal with cyclic data. Usually, the answer is that the cycle is not necessary (as in this case). The setup To start, let’s imagine that we were working in a GC’d language, like JavaScript.

read more →

21 September 2018

Office Hours #0: Debugging with GDB

This is a report on the first “office hours”, in which we discussed debugging Rust programs with gdb. I’m very grateful to Ramana Venkata for suggesting the topic, and to Tom Tromey, who joined in. (Tom has been doing a lot of the work of integrating rustc into gdb and lldb lately.) This blog post is just going to be a quick summary of the basic workflow of using Rust with gdb on the command line.

read more →

12 September 2018

Rust office hours

Hello, all! Beginning this Friday (in two days)1, I’m going to start an experiment that I call Rust office hours. The idea is simple: I’ve set aside a few slots per week to help people work through problems they are having learning or using Rust. My goal here is both to be of service but also to gain more insight into the kinds of things people have trouble with. No problem is too big or too small!

read more →

2 September 2018

Rust pattern: Iterating an over a Rc<Vec<T>>

This post examines a particular, seemingly simple problem: given ownership of a Rc<Vec<u32>>, can we write a function that returns an impl Iterator<Item = u32>? It turns out that this is a bit harder than it might at first appear – and, as we’ll see, for good reason. I’ll dig into what’s going on, how you can fix it, and how we might extend the language in the future to try and get past this challenge.

read more →

13 August 2018

Never patterns, exhaustive matching, and uninhabited types (oh my!)

One of the long-standing issues that we’ve been wrestling with in Rust is how to integrate the concept of an “uninhabited type” – that is, a type which has no values at all. Uninhabited types are useful to represent the “result” of some computation you know will never execute – for example, if you have to define an error type for some computation, but this particular computation can never fail, you might use an uninhabited type.

read more →

20 June 2018

Proposal for a staged RFC process

I consider Rust’s RFC process one of our great accomplishments, but it’s no secret that it has a few flaws. At its best, the RFC offers an opportunity for collaborative design that is really exciting to be a part of. At its worst, it can devolve into bickering without any real motion towards consensus. If you’ve not done so already, I strongly recommend reading aturon’s excellent blog posts on this topic.

read more →

15 June 2018

MIR-based borrow check (NLL) status update

I’ve been getting a lot of questions about the status of “Non-lexical lifetimes” (NLL) – or, as I prefer to call it these days, the MIR-based borrow checker – so I wanted to post a status update. The single most important fact is that the MIR-based borrow check is feature complete and available on nightly. What this means is that the behavior of #![feature(nll)] is roughly what we intend to ship for “version 1”, except that (a) the performance needs work and (b) we are still improving the diagnostics.

read more →

27 April 2018

An alias-based formulation of the borrow checker

Ever since the Rust All Hands, I’ve been experimenting with an alternative formulation of the Rust borrow checker. The goal is to find a formulation that overcomes some shortcomings of the current proposal while hopefully also being faster to compute. I have implemented a prototype for this analysis. It passes the full NLL test suite and also handles a few cases – such as #47680 – that the current NLL analysis cannot handle.

read more →

24 April 2018

Rust pattern: Precise closure capture clauses

This is the second in a series of posts about Rust compiler errors. Each one will talk about a particular error that I got recently and try to explain (a) why I am getting it and (b) how I fixed it. The purpose of this series of posts is partly to explain Rust, but partly just to gain data for myself. I may also write posts about errors I’m not getting – basically places where I anticipated an error, and used a pattern to avoid it.

read more →

16 April 2018

Rust pattern: Rooting an Rc handle

I’ve decided to do a little series of posts about Rust compiler errors. Each one will talk about a particular error that I got recently and try to explain (a) why I am getting it and (b) how I fixed it. The purpose of this series of posts is partly to explain Rust, but partly just to gain data for myself. I may also write posts about errors I’m not getting – basically places where I anticipated an error, and used a pattern to avoid it.

read more →

9 February 2018

Maximally minimal specialization: always applicable impls

So aturon wrote this beautiful post about what a good week it has been. In there, they wrote: Breakthrough #2: @nikomatsakis had a eureka moment and figured out a path to make specialization sound, while still supporting its most important use cases (blog post forthcoming!). Again, this suddenly puts specialization on the map for Rust Epoch 2018. Sheesh I wish they hadn’t written that! Now the pressure is on. Well, here goes nothing =).

read more →

1 February 2018

In Rust, ordinary vectors are values

I’ve been thinking a lot about persistent collections lately and in particular how they relate to Rust, and I wanted to write up some of my observations.1 What is a persistent collection? Traditionally, persistent collections are seen as this “wildly different” way to setup your collection. Instead of having methods like push, which grow a vector in place: vec.push(element); // add element to `vec` you have a method like add, which leaves the original vector alone but returns a new vector that has been modified:

read more →

31 January 2018

An on-demand SLG solver for chalk

In my last Chalk post, I talked about an experimental, SLG-based solver that I wrote for Chalk. That particular design was based very closely on the excellent paper “Efficient top-down computation of queries under the well-founded semantics”, by W. Chen, T. Swift, and D. Warren. It followed a traditional Prolog execution model: this has a lot of strengths, but it probably wasn’t really suitable for use in rustc. The single biggest reason for this was that it didn’t really know when to stop: given a query like exists<T> { T: Sized }, it would happily try to enumerate all sized types in the system.

read more →

9 January 2018

#Rust2018

As part of #Rust2018, I thought I would try to writeup my own (current) perspective. I’ll try to keep things brief. First and foremost, I think that this year we have to finish what we started and get the “Rust 2018” release out the door. We did good work in 2017: now we have to make sure the world knows it and can use it. This primarily means we have to do stabilization work, both for the recent features added in 2017 as well as some, ahem, longer-running topics, like SIMD.

read more →

5 January 2018

Lessons from the impl period

So, as you likely know, we tried something new at the end of 2017. For roughly the final quarter of the year, we essentially stopped doing design work, and instead decided to focus on implementation – what we called the “impl period”. We had two goals for the impl period: (a) get a lot of high-value implementation work done and (b) to do that by expanding the size of our community, and making it easy for new people to get involved.

read more →

21 October 2017

Chalk meets SLG

For the last month or so, I’ve gotten kind of obsessed with exploring a new evaluation model for Chalk. Specifically, I’ve been looking at adapting the SLG algorithm, which is used in the XSB Prolog engine. I recently opened a PR that adds this SLG-based solver as an alternative, and this blog post is an effort to describe how that PR works, and explore some of the advantages and disadvantages I see in this approach relative to the current solver that I described in my previous post.

read more →

12 September 2017

Cyclic queries in chalk

In my last post about chalk queries, I discussed how the query model in chalk. Since that writing, there have been some updates, and I thought it’d be nice to do a new post covering the current model. This post will also cover the tabling technique that scalexm implemented for handling cyclic relations and show how that enables us to implement implied bounds and other long-desired features in an elegant way.

read more →

11 July 2017

Non-lexical lifetimes: draft RFC and prototype available

I’ve been hard at work the last month or so on trying to complete the non-lexical lifetimes RFC. I’m pretty excited about how it’s shaping up. I wanted to write a kind of “meta” blog post talking about the current state of the proposal – almost there! – and how you could get involved with helping to push it over the finish line. TL;DR What can I say, I’m loquacious! In case you don’t want to read the full post, here are the highlights:

read more →

25 May 2017

Query structure in chalk

For my next post discussing chalk, I want to take kind of a different turn. I want to talk about the general struct of chalk queries and how chalk handles them right now. (If you’ve never heard of chalk, it’s sort of “reference implementation” for Rust’s trait system, as well as an attempt to describe Rust’s trait system in terms of its logical underpinnings; see this post for an introduction to the big idea.

read more →

2 May 2017

gnome-class: Integrating Rust and the GNOME object system

I recently participated in the GNOME / Rust “dev sprint” in Mexico City. (A thousand thanks to Federico and Joaquin for organizing!) While there I spent some time working on the gnome-class plugin. The goal of gnome-class was to make it easy to write GObject implementations in Rust which would fully interoperate with C code. Roughly speaking, my goal was that you should be able to write code that looked and felt like Vala code, but where the method bodies (and types, and so forth) are in Rust.

read more →

23 April 2017

Unification in Chalk, part 2

In my previous post, I talked over the basics of how unification works and showed how that “mathematical version” winds up being expressed in chalk. I want to go a bit further now and extend that base system to cover associated types. These turn out to be a pretty non-trival extension. What is an associated type? If you’re not a Rust programmer, you may not be familiar with the term “associated type” (although many langages have equivalents).

read more →

6 April 2017

Rayon 0.7 released

We just released Rayon 0.7. This is a pretty exciting release, because it marks the official first step towards Rayon 1.0. In addition, it marks the first release where Rayon’s parallel iterators reach “feature parity” with the standard sequential iterators! To mark the moment, I thought I’d post the release notes here on the blog: This release marks the first step towards Rayon 1.0. For best performance, it is important that all Rayon users update to at least Rayon 0.

read more →

25 March 2017

Unification in Chalk, part 1

So in my first post on chalk, I mentioned that unification and normalization of associated types were interesting topics. I’m going to write a two-part blog post series covering that. This first part begins with an overview of how ordinary type unification works during compilation. The next post will add in associated types and we can see what kinds of mischief they bring with them. What is unification? Let’s start with a brief overview of what unification is.

read more →

17 March 2017

The Lane Table algorithm

For some time now I’ve been interested in better ways to construct LR(1) parsers. LALRPOP currently allows users to choose between the full LR(1) algorithm or the LALR(1) subset. Neither of these choices is very satisfying: the full LR(1) algorithm gives pretty intuitive results but produces a lot of states; my hypothesis was that, with modern computers, this wouldn’t matter anymore. This is sort of true – e.g., I’m able to generate and process even the full Rust grammar – but this results in a ton of generated code.

read more →

1 March 2017

Nested method calls via two-phase borrowing

In my previous post, I outlined a plan for non-lexical lifetimes. I wanted to write a follow-up post today that discusses different ways that we can extend the system to support nested mutable calls. The ideas here are based on some the ideas that emerged in a recent discussion on internals, although what I describe here is a somewhat simplified variant. If you want more background, it’s worth reading at least the top post in the thread, where I laid out a lot of the history here.

read more →

21 February 2017

Non-lexical lifetimes using liveness and location

At the recent compiler design sprint, we spent some time discussing non-lexical lifetimes, the plan to make Rust’s lifetime system significantly more advanced. I want to write-up those plans here, and give some examples of the kinds of programs that would now type-check, along with some that still will not (for better or worse). If you were at the sprint, then the system I am going to describe in this blog post will actually sound quite a bit different than what we were talking about.

read more →

17 February 2017

Project idea: datalog output from rustc

I want to have a tool that would enable us to answer all kinds of queries about the structure of Rust code that exists in the wild. This should cover everything from synctactic queries like “How often do people write let x = if { ... } else { match foo { ... } }?” to semantic queries like “How often do people call unsafe functions in another module?” I have some ideas about how to build such a tool, but (I suspect) not enough time to pursue them.

read more →

12 February 2017

Compiler design sprint summary

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 many of the big design challenges that we’d like to tackle in the upcoming year and making sure that the compiler team was roughly on board with the best way to implement them.

read more →

1 February 2017

Unsafe code and shared references

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 of the approach I have in mind. I’m going to focus on this post on the matter of the proper use of shared references &T – I’ll completely ignore &mut T for now, since those are much more complicated (because they require a notion of uniqueness).

read more →

26 January 2017

Lowering Rust traits to logic

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 clear, normative definition of how the trait system works, so that we can better judge possible extensions.

read more →

22 January 2017

Assigning blame to unsafe code

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 “blame” calculation techniques from gradual typing research.

read more →

14 November 2016

Parallel iterators, part 3: Consumers

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 read them, or don’t remember them, you will want to do so before reading this one:

read more →

9 November 2016

Associated type constructors, part 4: Unifying ATC and HKT

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 exploration into what it would mean to support HKT directly in the language, instead of modeling them via the family pattern.

read more →

4 November 2016

Associated type constructors, part 3: What higher-kinded types might look like

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 it would mean to support HKT directly in the language, instead of modeling them via the family pattern.

read more →

3 November 2016

Associated type constructors, part 2: family traits

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 overcome them by making use of a design pattern that I call “family traits”. Along the way, we introduce the term higher-kinded type for the first time, and show (informally) that family traits are equally general.

read more →

2 November 2016

Associated type constructors, part 1: basic concepts and introduction

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 trying to write down some of the things we were thinking so as to get other people’s input.

read more →

1 November 2016

Switching to Jekyll

If you visit the site today, you’ll notice it looks quite a bit different. I’ve decided to switch from my old antiquated Octopress to a plain Jekyll-based one. The most immediate of this is that Rust code highlighting looks much better, and I get access to modern Github-flavored markdown. =) Since I understand plain Jekyll a bit more, I’ll hopefully also be able to customize the appearance somewhat – but for now I’m just going with the basic theme.

read more →

24 October 2016

Supporting blanket impls in specialization

In my previous post, I talked about how we can separate out specialization into two distinct concepts: reuse and override. Doing so makes because the conditions that make reuse possible are more stringent than those that make override possible. In this post, I want to extend this idea to talk about a new rule for specialization that allow overriding in more cases. These rules are a big enabler for specialization, allowing it to accommodate many use cases that we couldn’t handle before.

read more →

2 October 2016

Observational equivalence and unsafe code

I spent a really interesting day last week at Northeastern University. First, I saw a fun talk by Philip Haller covering LaCasa, which is a set of extensions to Scala that enable it to track ownership. Many of the techniques reminded me very much of Rust (e.g., the use of “spores”, which are closures that can limit the types of things they close over); if I have time, I’ll try to write up a more detailed comparison in some later post.

read more →

30 September 2016

Announcing intorust.com

For the past year or so, I and a few others have been iterating on some tutorial slides for learning Rust. I’ve given this tutorial here at the local Boston Rust Meetup a few times, and we used the same basic approach at RustConf; I’ve been pretty happy with the results. But until now it’s been limited to “in person” events. That’s why I’m so happy to announce a new site, Into Rust.

read more →

29 September 2016

Distinguishing reuse from override

In my previous post, I started discussing the idea of intersection impls, which are a possible extension to specialization. I am specifically looking at the idea of making it possible to add blanket impls to (e.g.) implement Clone for any Copy type. We saw that intersection impls, while useful, do not enable us to do this in a backwards compatible way. Today I want to dive a bit deeper into specialization.

read more →

24 September 2016

Intersection Impls

As some of you are probably aware, on the nightly Rust builds, we currently offer a feature called specialization, which was defined in RFC 1210. The idea of specialization is to improve Rust’s existing coherence rules to allow for overlap between impls, so long as one of the overlapping impls can be considered more specific. Specialization is hotly desired because it can enable powerful optimizations, but also because it is an important component for modeling object-oriented designs.

read more →

12 September 2016

Thoughts on trusting types and unsafe code

I’ve been thinking about the unsafe code guidelines a lot in the back of my mind. In particular, I’ve been trying to think through what it means to “trust types” – if you recall from the Tootsie Pop Model (TPM) blog post, one of the key examples that I was wrestling with was the RefCell-Ref example. I want to revisit a variation on that example now, but from a different angle.

read more →

18 August 2016

'Tootsie Pop' Followup

A little while back, I wrote up a tentative proposal I called the “Tootsie Pop” model for unsafe code. It’s safe to say that this model was not universally popular. =) There was quite a long and fruitful discussion on discuss. I wanted to write a quick post summarizing my main take-away from that discussion and to talk a bit about the plans to push the unsafe discussion forward. The importance of the unchecked-get use case For me, the most important lesson was the importance of the “unchecked get” use case.

read more →

27 May 2016

The 'Tootsie Pop' model for unsafe code

In my previous post, I spent some time talking about the idea of unsafe abstractions. At the end of the post, I mentioned that Rust does not really have any kind of official guidelines for what kind of code is legal in an unsafe block and what is not.What this means in practice is that people wind up writing what “seems reasonable” and checking it against what the compiler does today.

read more →

23 May 2016

Unsafe abstractions

The unsafe keyword is a crucial part of Rust’s design. For those not familiar with it, the unsafe keyword is basically a way to bypass Rust’s type checker; it essentially allows you to write something more like C code, but using Rust syntax. The existence of the unsafe keyword sometimes comes as a surprise at first. After all, isn’t the point of Rust that Rust programs should not crash? Why would we make it so easy then to bypass Rust’s type system?

read more →

9 May 2016

Non-lexical lifetimes: adding the outlives relation

This is the third post in my series on non-lexical lifetimes. Here I want to dive into Problem Case #3 from the introduction. This is an interesting case because exploring it is what led me to move away from the continuous lifetimes proposed as part of RFC 396. Problem case #3 revisited As a reminder, problem case #3 was the following fragment: fn get_default<'m,K,V:Default>(map: &'m mut HashMap<K,V>, key: K) -> &'m mut V { match map.

read more →

4 May 2016

Non-lexical lifetimes based on liveness

In my previous post I outlined several cases that we would like to improve with Rust’s current borrow checker. This post discusses one possible scheme for solving those. The heart of the post is two key ideas: Define a lifetime as a set of points in the control-flow graph, where a point here refers to some particular statement in the control-flow graph (i.e., not a basic block, but some statement within a basic block).

read more →

27 April 2016

Non-lexical lifetimes: introduction

Over the last few weeks, I’ve been devoting my free time to fleshing out the theory behind non-lexical lifetimes (NLL). I think I’ve arrived at a pretty good point and I plan to write various posts talking about it. Before getting into the details, though, I wanted to start out with a post that lays out roughly how today’s lexical lifetimes work and gives several examples of problem cases that we would like to solve.

read more →

2 March 2016

Nice errors in LALRPOP

For the last couple of weeks, my mornings have been occupied with a pretty serious revamping of LALRPOP’s error message output. I will probably wind up doing a series of blog posts about the internal details of how it works, but I wanted to write a little post to advertise this work. Typically when you use an LR(1) parser generator, error messages tend to be written in terms of the LR(1) state generation algorithm.

read more →

25 February 2016

Parallel Iterators Part 2: Producers

This post is the second post in my series on Rayon’s parallel iterators. The goal of this series is to explain how parallel iterators are implemented internally, so I’m going to be going over a lot of details and giving a lot of little code examples in Rust. If all you want to do is use parallel iterators, you don’t really have to understand any of this stuff. I’ve had a lot of fun designing this system, and I learned a few lessons about how best to use Rust (some of which I cover in the conclusions).

read more →

19 February 2016

Parallel Iterators Part 1: Foundations

Since giving a talk about Rayon at the Bay Area Rust meetup, I’ve been working off and on on the support for parallel iterators. The basic idea of a parallel iterator is that I should be able to take an existing iterator chain, which operates sequentially, and easily convert it to work in parallel. As a simple example, consider this bit of code that computes the dot-product of two vectors:

read more →

18 December 2015

Rayon: data parallelism in Rust

Over the last week or so, I’ve been working on an update to Rayon, my experimental library for data parallelism in Rust. I’m pretty happy with the way it’s been going, so I wanted to write a blog post to explain what I’ve got so far. Rayon’s goal is to make it easy to add parallelism to your sequential code – so basically to take existing for loops or iterators and make them run in parallel.

read more →

8 October 2015

Virtual Structs Part 4: Extended Enums And Thin Traits

So, aturon wrote this interesting post on an alternative “virtual structs” approach, and, more-or-less since he wrote it, I’ve been wanting to write up my thoughts. I finally got them down. Before I go any further, a note on terminology. I will refer to Aaron’s proposal as the Thin Traits proposal, and my own previous proposal as the Extended Enums proposal. Very good. (OK, I lied, one more note: starting with this post, I’ve decided to disable comments on this blog.

read more →

14 September 2015

LALRPOP

Around four years ago, when I had first decided to start at Mozilla research, I had planned to write an LR(1) parser generator. It seemed like a good way to get to know Rust. However, I found that newborns actually occupy somewhat more time than anticipated (read: I was lucky to squeeze in a shower), and hence that never came to pass. Well, I’m happy to say that, four years later, I’ve finally rectified that.

read more →

20 August 2015

Virtual Structs Part 3: Bringing Enums and Structs Together

So, in previous posts, I discussed the pros and cons of two different approaches to modeling variants: Rust-style enums and C++-style classes. In those posts, I explained why I see Rust enums and OO-style class hierarchies as more alike than different (I personally credit Scala for opening my eyes to this, though I’m sure it’s been understood by others for much longer). The key points were as follows: Both Rust-style enums and C++-style classes can be used to model the idea of a value that be one of many variants, but there are differences in how they work at runtime.

read more →

29 May 2015

Virtual Structs Part 2: Classes strike back

This is the second post summarizing my current thoughts about ideas related to “virtual structs”. In the last post, I described how, when coding C++, I find myself missing Rust’s enum type. In this post, I want to turn it around. I’m going to describe why the class model can be great, and something that’s actually kind of missing from Rust. In the next post, I’ll talk about how I think we can get the best of both worlds for Rust.

read more →

5 May 2015

Virtual Structs Part 1: Where Rust's enum shines

One priority for Rust after 1.0 is going to be incorporating some kind of support for “efficient inheritance” or “virtual structs”. In order to motivate and explain this design, I am writing a series of blog posts examining how Rust’s current abstractions compare with those found in other languages. The way I see it, the topic of “virtual structs” has always had two somewhat orthogonal components to it. The first component is a question of how we can generalize and extend Rust enums to cover more scenarios.

read more →

30 April 2015

A few more remarks on reference-counting and leaks

So there has been a lot of really interesting discussion in response to my blog post. I wanted to highlight some of the comments I’ve seen, because I think they raise good points that I failed to address in the blog post itself. My comments here are lightly edited versions of what I wrote elsewhere. Isn’t the problem with objects and leak-safe types more general? Reem writes: I posit that this is in fact a problem with trait objects, not a problem with Leak; the exact same flaw pointed about in the blog post already applies to the existing OIBITs, Send, Sync, and Reflect.

read more →

29 April 2015

On reference-counting and leaks

What’s a 1.0 release without a little drama? Recently, we discovered that there was an oversight in one of the standard library APIs that we had intended to stabilize. In particular, we recently added an API for scoped threads – that is, child threads which have access to the stack frame of their parent thread. The flaw came about because, when designing the scoped threads API, we failed to consider the impact of resource leaks.

read more →

6 April 2015

Modeling graphs in Rust using vector indices

After reading nrc’s blog post about graphs, I felt inspired to write up an alternative way to code graphs in Rust, based on vectors and indicates. This encoding has certain advantages over using Rc and RefCell; in particular, I think it’s a closer fit to Rust’s ownership model. (Of course, it has disadvantages too.) I’m going to describe a simplified version of the strategy that rustc uses internally. The actual code in Rustc is written in a somewhat dated “Rust dialect”.

read more →

14 January 2015

Little Orphan Impls

We’ve recently been doing a lot of work on Rust’s orphan rules, which are an important part of our system for guaranteeing trait coherence. The idea of trait coherence is that, given a trait and some set of types for its type parameters, there should be exactly one impl that applies. So if we think of the trait Show, we want to guarantee that if we have a trait reference like MyType : Show, we can uniquely identify a particular impl.

read more →

26 November 2014

Purging proc

The so-called “unboxed closure” implementation in Rust has reached the point where it is time to start using it in the standard library. As a starting point, I have a pull request that removes proc from the language. I started on this because I thought it’d be easier than replacing closures, but it turns out that there are a few subtle points to this transition. I am writing this blog post to explain what changes are in store and give guidance on how people can port existing code to stop using proc.

read more →

14 November 2014

Allocators in Rust

There has been a lot of discussion lately about Rust’s allocator story, and in particular our relationship to jemalloc. I’ve been trying to catch up, and I wanted to try and summarize my understanding and explain for others what is going on. I am trying to be as factually precise in this post as possible. If you see a factual error, please do not hesitate to let me know. The core tradeoff The story begins, like all interesting design questions, with a trade-off.

read more →

30 September 2014

Multi- and conditional dispatch in traits

I’ve been working on a branch that implements both multidispatch (selecting the impl for a trait based on more than one input type) and conditional dispatch (selecting the impl for a trait based on where clauses). I wound up taking a direction that is slightly different from what is described in the trait reform RFC, and I wanted to take a chance to explain what I did and why. The main difference is that in the branch we move away from the crate concatenability property in exchange for better inference and less complexity.

read more →

11 September 2014

Attribute and macro syntax

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. This debate has been sitting for a week or so.

read more →

9 July 2014

An experimental new type inference scheme for Rust

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 than the existing inference scheme, though all of rustc and all the libraries compile without any changes.

read more →

6 July 2014

Implied bounds

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 references are omitted and will come in a follow-up blog post.

read more →

14 May 2014

Follow up to Focusing on Ownership

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 multiple paths to the &mut itself. That’s not the fault of the &mut, it’s just that uniqueness is a global property.

read more →

13 May 2014

Focusing on ownership

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 defense of the current system. (Note: I considered submitting this as a Rust RFC, but decided that the tone was better suited to a blog post, and I don’t have the time to rewrite it now.

read more →

24 April 2014

Parallel pipelines for JS

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. Lately, I’ve been prototyping an alternate design that I call parallel pipelines (that’s just a working title; I expect the name to change).

read more →

1 April 2014

Typed Objects Status Report

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 it, the implementation section will change, since it will be much further along.

read more →

1 April 2014

Value types in JavaScript

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 into the standard. I am not going to discuss new syntax or operators yet.

read more →

28 February 2014

Rust RFC: Opt-in builtin traits

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 certain properties (defined below). The biggest difference, though, is that these traits are not implemented manually by users.

read more →

25 February 2014

Rust RFC: Stronger guarantees for mutable borrows

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 would like to change the borrow checker rules so that both writes and reads through the original path x are illegal while x is mutably borrowed.

read more →

4 February 2014

Closures and the borrow checker

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 pointer for each variable mentioned in the closure.

read more →

9 January 2014

Rvalue lifetimes in Rust

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 priority. Part of the reason that this issue has lasted so long is that the current trans cleanup scheme is very inflexible.

read more →

5 January 2014

DST, Take 5

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 this post to stand alone, so I’m going to start from the beginning in the description.

read more →

12 December 2013

Structural arrays in Typed Objects

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 experiment. Description by example I’ve had a hard time trying to identify the best way to present the idea, because it is at once so similar and so unlike what we have today.

read more →

2 December 2013

Thoughts on DST, Part 4

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 we could treat vectors like any other container, which would (to some extent) avoid the need for DST.

read more →

27 November 2013

Thoughts on DST, Part 2

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<[uint]>). 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 object types.

read more →

27 November 2013

Thoughts on DST, Part 3

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 statically sized typed (SST) from here on out). Let me first explain the problem and then show how my first thoughts on how it might be addressed.

read more →

26 November 2013

Thoughts on DST, Part 1

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 dynamically sized types, and I am no longer persuaded that DST offer the best way forward.

read more →

22 November 2013

Optimizing SIMD, part 2

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 boxes where needed. In fact, we have an existing mechanism for doing that, called the type policies.

read more →

21 November 2013

Optimizing SIMD

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 types is designed to make it possible for JIT engines to detect and optimize their use.

read more →

20 November 2013

Parameter coercion in Rust

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 of clarity, I wanted to briefly explain some terminology and precisely what the rules are.

read more →

14 November 2013

Treating vectors like any other container

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 libraries. I wanted to write out a post exploring this idea; I find it brings some simplifications and reduces the need for DST.

read more →

4 November 2013

Intermingled parameter lists, take 2

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 change of heart, and thus have a new “least bad” proposal.

read more →

4 November 2013

Optimizing complex typed object assignments

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(); line.to = {x: 22, y: 44}; The last line in particular is the one I am interested in. Today we execute this in the most naive way.

read more →

29 October 2013

Intermingled parameter lists

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 limitations: for example, types could only have a single lifetime parameter, and it had to be named 'self.

read more →

29 October 2013

PJS Roadmap

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 the parallel methods mapPar, filterPar, and reducePar on normal JS arrays.

read more →

24 October 2013

Iterators yielding mutable references

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, it is not possible to implement such iterators without an unsafe block. After giving this quite a bit of thought, I have come to the conclusion that we have three options:

read more →

24 October 2013

Iterators yielding mutable references, take 2

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, and it’s quite plausible to imagine that code becoming safe eventually.

read more →

24 October 2013

Single inheritance

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 proposal is to: Enable structs to extend other structs, meaning that the substruct inherits all fields of the superstruct, and also enabling a subtyping relationship between borrowed pointers.

read more →

18 October 2013

Typed object handles

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 you (cough Dave Herman cough) you may want to skip ahead to the section “Subtle points”.

read more →

10 October 2013

Fn types in Rust, take 3

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 alternative proposals. The most radical involved keeping only one closure type for borrowed closures and then using macros and object types to represent all other use cases.

read more →

3 September 2013

Type specifications in Parallel JS

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 reason, support is limited to Nightly and not available in Aurora or Beta builds).

read more →

19 July 2013

Integrating binary data and type inference in SpiderMonkey

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 efficient generated code. In this blog post, I specifically want to cover the plan for integrating our type inference with binary data.

read more →

18 July 2013

Rust presentation at Northeastern

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 use for the next Rust paper.

read more →

11 June 2013

Data Parallelism in Rust

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 share memory except through the relatively clumsy (and somewhat expensive) mechanism of Arc structures (which stands for “atomic reference count”), meaning that if there are large data structures they can be a pain to access.

read more →

11 June 2013

On the connection between memory management and data-race freedom

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 freedom, and you want to support the cheap transfer of mutable state between tasks, then you must have a garbage-collector-free subset of your language.

read more →

6 June 2013

Reducing DST Annotation

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 actual number may wind up being somewhat higher.

read more →

3 June 2013

More on fns

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 is probably Thunk. I quote Wikipedia for the definition of Thunk: “In computer science, a thunk (also suspension, suspended computation or delayed computation) is a parameterless closure created to prevent the evaluation of an expression until forced at a later time.

read more →

30 May 2013

Removing procs

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 today could be rewritten to either use a boxed trait or to use a pair of a user-data struct and an extern fn.

read more →

29 May 2013

Integrating binary data and PJs

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 away from a ParallelArray type and into methods that will be offered on existing array types.

read more →

14 May 2013

Procedures, continued

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 the current collection of closure types is addressing too many distinct use cases and the result is confusing.

read more →

13 May 2013

Mutable fn alternatives

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 in this post are good yet.

read more →

13 May 2013

Recurring closures and dynamically sized types

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 same way it treats &mut T pointers: they would be non-copyable, and when you invoke them, that would be effectively like a “mutable borrow”, meaning that for the duration of the call the original value would become inaccessible.

read more →

30 April 2013

Dynamically sized types, revisited

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 type [S], so ~[S] is not an instance of ~T for any T. This design was the outcome of a lot of back-and-forth and I think it has generally served us well, but I’ve always had this nagging feeling that we can do better.

read more →

30 April 2013

Parallelizable JavaScript Subset

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 view, the subset below includes basically all the JavaScript syntax that I ever use.

read more →

30 April 2013

The Case of the Recurring Closure

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 higher-order function). Luckily, this hole can be fixed with (I think) very little pain—in fact, I think fixing it can also help us make other analyses a little less strict.

read more →

4 April 2013

A tour of the Parallel JS implementation (Part 2)

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 introduce a second mode of compilation called parallel execution mode. JavaScript compiled in this mode produces executable code that is suitable to be run in parallel.

read more →

4 April 2013

Nested lifetimes

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 nonsensical) programs that will no longer compile. Anyway I found it interesting and thought I would share.

read more →

3 April 2013

Associated items continued

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 associated items that I introduced before, the names of associated items and methods were resolved relative to a type.

read more →

2 April 2013

Associated items

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 various aspects of the trait system and trying to suss out what we should be doing in each case.

read more →

21 March 2013

Guaranteeing parallel execution

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 think it is a good idea to clearly define the subset of JavaScript that our engine will be able to execute in parallel.

read more →

20 March 2013

A tour of the Parallel JS implementation (Part 1)

I am going to write a series of blog posts giving a tour of the current Parallel JS implementation in SpiderMonkey. These posts are intended to serve partly as documentation for the code. The plan is to begin high level and work my way down to the nitty gritty details, so here we go! I will start my discussion at the level of the intrinsic ForkJoin() function. As an intrinsic function, ForkJoin() is not an API intended for use by end-users.

read more →

20 March 2013

Parallel JS lands

The first version of our work on ParallelJS has just been promoted to mozilla-central and thus will soon be appearing in a Nightly Firefox build near you. I find this pretty exciting. In honor of the occassion, I wanted to take a moment to step back and look both at what has landed now, what we expect to land soon, and the overall trajectory we are aiming for. What is available now Once Nightly builds are available, users will be able to run what is essentially a “first draft” of Parallel JS.

read more →

26 February 2013

Splitting the PJs API

Lately, I’ve been thinking about the ParallelJS API that we want to expose. In particular, I’ve been considering offering methods on the normal array type for basic parallel operations. I think this opens up some interesting doors. Note: To give credit where credit is due, I should note that a lot of the ideas in this post originate with other members of the Parallel JS team (Shu-yu Guo, Dave Herman, Felix Klock).

read more →

22 February 2013

Interfacing with C functions in Rust

One of the things that I’ve been working on for some time now is the proper integration of C functions. As with virtually every other facet of the design of Rust, we’ve been slowly moving from a model where Rust tried to hide low-level details for you to one where Rust offers tight control over what’s going on, with the type system intervening only as needed to prevent segfaults or other strange behavior.

read more →

17 January 2013

Destructors and finalizers in Rust

Rust features destructors and, as of this moment, they are simply not sound with respect to many other features of the language, such as borrowed and managed pointers. The problem is that destructors are granted unlimited access to arbitrary data, but the type system and runtime do not take that into account. I propose to fix this by limiting destructors to owned types, meaning types that don’t contain borrowed or managed pointers.

read more →

16 January 2013

Revised for loop protocol

In Rust today, there is a special for syntax designed to support interruptible loops. Since we introduced it, this has proven to be a remarkable success. However, I think we can improve it very slightly. Current for protocol The current “for protocol” is best explained by giving an example of how to implement it for slices: fn each<E>(v: &[E], f: &fn(&E) -> bool) { let mut i = 0; let n = v.

read more →

15 January 2013

Lifetime notation redux

In a previous post I outlined some of the options for updating our lifetime syntax. I want to revist those examples after having given the matter more thought, and also after some discussions in the comments and on IRC. My newest proposal is that we use <> to designate lifetime parameters on types and we lean on semantic analysis (the resolve pass, more precisely) to handle the ambiguity between a lifetime name and a type name.

read more →

3 January 2013

The case FOR deterministic results

In my last post, I made the case against having a deterministic semantics. I’ve gotten a fair amount of feedback saying that, for a Web API, introducing nondeterminism is a very risky idea. Certainly the arguments are strong. Therefore, I want to take a moment and make the case for determinism. Why determinism? All things being equal, it’s clear that deterministic execution semantics are preferable. They’re easier to debug and they avoid the question of browser incompatibilities.

read more →

2 January 2013

Deterministic or not?

One of the interesting questions with respect to Parallel JS is what the semantics ought to be if you attempt a parallel operation with a kernel function that has side-effects. There are basically three reasonable options: Deterministic results where possible: The function behaves “as if” it executed sequentially, executing the kernel from 0 to n, just like Array.map. Error: An exception is thrown. Non-determinstic results: The function behaves “as if” it executed sequentially, but the items were mapped in an unspecified order.

read more →

30 December 2012

Lifetime notation

I’ve been thinking for a while that our lifetime notation has too many defaults which can be more confusing than helpful. A recent spate of e-mails on rust-dev brought this back to my mind. I’ve been wanting to take a look at these defaults for a while, so I thought I’d write up a quick exploration of the “syntactic space”. A warning: this is not really an exciting post to read.

read more →

6 December 2012

Improving our parallel intrinsic

I mentioned in my previous post that we are using a single primitive parallel operation to implement PJs. It turns out that I am not very satisfied with what we currently have and I have been thinking about some alternatives. In this post I’ll describe briefly how things are setup, what problems I see, and then sketch out how I think we could improve it. How things work now: %ParallelBuildArray() The current intrinsic is %ParallelBuildArray(length, func, args.

read more →

5 December 2012

Self-hosted Parallel JS

The blog has been silent for a while. The reason is that I’ve been hard at work on Parallel JS. It’s come a long way: in fact, the goal is to land an initial version in the next couple weeks! One of the very exciting developments has been that we switched to a self-hosting implementation. Self-hosting is a very cool new direction for the SpiderMonkey engine being introduced by Till Schneidereit.

read more →

18 November 2012

Imagine never hearing the phrase 'aliasable, mutable' again

I’ve been thinking of a radical change we could make to the treatment of mutability and borrowed pointers in Rust. The goal is to eliminate all of the error messages about “aliasable, mutable data” that the borrow checker currently issues. The idea is somewhat inspired by writing a recent paper on Rust’s current system—writing a paper on something never fails to get me thinking about how to improve it, though it sometimes fails to stimulate ideas which are actually good—and also somewhat inspired by recent conversations on IRC and in person.

read more →

24 October 2012

Purity in Parallel JavaScript

I can’t believe I’m saying this, but I’ve started to think that Parallel JS (nee Rivertrail) should not demand pure callbacks to functions like map() and so forth. Rather it should just accept arbitrary functions. Previously, I thought that it was important that ParallelArray methods should only accept functions which, at least in a perfect world, would be safely parallelizable. But I am no longer so sure why that is an important goal.

read more →

24 October 2012

Restrict pointers

I am considering whether we should add a way to borrow something but retain uniqueness. This would address a shortcoming of the borrowing system that has been bothering me for some time, and it would enable a few patterns that are difficult or awkward today. The Problem I described the problem in this paper review I wrote, but I will repeat it here, because it’s relevant, and perhaps people don’t read and remember every single word that I write.

read more →

23 October 2012

Function and object types

My big goal for 0.5 is to straighten out our function types (yet again). I’ve been tossing the design for these over in my head since the summer and I wanted to lay out my plan. This is a variation of something that Ben Blum and I sketched out on a whiteboard. Closure type The closure type will be described something like so. Beware, it’s got a lot of options. It turns out that there is a very large variety of things one might want to use closures for, and supporting them requires a fair number of knobs.

read more →

12 October 2012

Extending the definition of purity in Rust

In this post I propose an extension of Rust’s purity rules. The short version is that pure functions would be allowed to mutate data owned by their &mut parameters. This extends the current Rust purity rules which allow pure functions to invoke impure closures so long as they are an argument to the function. The principle is the same: pure functions are functions whose side-effects can be completely determined by examining their parameters (for the more formally minded among you, this is effectively an effect-parametric system with very lightweight notation).

read more →

10 October 2012

Rivertrail

I have started work on implementing Rivertrail, Intel’s proposal for data parallelism in JS. I am excited about this project, it seems like it’s going to be great fun. The initial version that we produce is going to be focused on Intel’s specification, but I hope we can eventually combine it with the more general stuff I’ve been doing as part of PJs. There is an awful lot of overlap between the two, though also a few minor differences that will need to be ironed out.

read more →

5 October 2012

Termination of trait matching

So, the condition that was supposed to ensure termination in my previous post is most certainly wrong. The idea was to prevent tautological impls like the following: impl<A: Foo> A: Foo { ... } Such impls, given a naive algorithm, would loop infinitely trying to decide if a type T implemented Foo. You can imagine: it would ask, “does T implement Foo? Well, if I map A to T then this impl applies, but only if T implements Foo.

read more →

4 October 2012

A postscript on traits and impls

I was thinking more about type classes as I walked down the street. In my prior post I wrote that the rules I proposed resulted in a system where traits loosely fit the following Haskell template: class C self a ... z | self -> a ... z where ... However, I gave two caveats. The first was that due to subtyping we cannot say that one type precisely determines another, but only that it puts a bound.

read more →

4 October 2012

Refining traits and impls

Currently, the Rust compiler accepts all manner of trait, impl, and bound declarations. In fact, it accepts plenty of declarations that later phases of the compiler are not sophisticated enough to handle. In other words, the syntax is writing checks the semantics can’t cash. (An aside: I just love saying that phrase for some perverse reason. I really wish however that checks, like rotary dial telephones, were something that younger people vaguely understood but which no longer had relevance in the modern era.

read more →

1 October 2012

Moves based on type

I have been trying to come up with a reasonable set of rules for deciding when a pattern binding ought to be a move and when it ought to be a copy and utterly failing. Simultaneously, pcwalton, brson, and I kind of simultaneously arrived at an alternate design that tries to simplify the copy/move distinction. I think that it also solves the question of when to copy/move pattern bindings in a nice way.

read more →

26 September 2012

Type system for borrowing permissions

Well, I have not done too well with my goal of reading a research paper a day on the train (actually my initial goal was two papers, but seeing as how I’ve failed so spectacularly, I’ve dialed it back some). However, I’ve decided to give it another go. I’ve bought a printer now so I can print papers out (double-sided, no less!) at home (I had initially planned to buy an iPad or something, but a decent printer is only $100, and paper is still nicer to read and write notes on…you do the math).

read more →

15 September 2012

Rvalue lifetimes

We need to clarify our story on rvalue lifetimes. This is related to issue #3387 and also various recent and not-so-recent discussions on IRC. The basic question is how long an rvalue lives when the program creates pointers into it. To understand the rough issues, first consider this program: let x = foo(); match x { Some(ref y) => {...} None => {...} } Here, the result of foo() is stored into a local variable.

read more →

24 August 2012

Datasort refinements

One of the things that is sometimes frustrating in Rust is the inability to define a type that indicates some subset of enum variants. For example, it is very common to have a pattern like this: match an_expr { expr_call(*) => process_call(an_expr) ... } fn process_call(a_call_expr: @ast::expr) { ... } But as you can see, the type of a_call_expr does not reflect the fact that this expression is a call. This is frustrating.

read more →

30 July 2012

Type inference in Spidermonkey

I’ve been slowly learning how type inference works in SpiderMonkey. As I understand it, SpiderMonkey’s type inference scheme is the brain child of one Brian “Hack-it”, coder extraordinaire. You may have seen a recent PLDI publication on the topic. You may, like me, have read that publication. You may, also like me, have walked away thinking, “um, I don’t really understand how that works.” In that case, dear reader, this blog post is for you.

read more →

24 July 2012

Generalizing inherited mutability

I have been working on a change to the definition of mutability in Rust. This is a much smaller change than my previous thought experiments, which were aimed at achieving better parameterization (those are still percolating; I think the best approach is a modified version of the latest proposal where not all types have mutability but type parameters do…but that’s a problem for another day with many complications). The goal of these changes is to enable operations like “freeze” and “thaw”.

read more →

19 July 2012

Yet another tutorial on borrowed pointers

Here is my latest stab at a tutorial on borrowed pointers. I know, I know, enough with the borrowed pointer tutorials already! Hopefully this will be my last post in this vein for a while. I am much happier with this version. It is still too long to serve as a chapter in the general Rust tutorial, but I think it’s more approachable than the previous attempt, which was more of a reference document.

read more →

17 July 2012

About that 'tutorial'...

One thing I didn’t make clear regarding my last post: I am not especially satisfied with the way the “tutorial” was turning out. I use scare quotes here because I think it resembles a reference manual more than a tutorial. Nonetheless I think there are some sections that are quite good; and a document like it probably ought to exist. So I figured I’d post it anyhow and I can mine it for material later.

read more →

17 July 2012

Borrowed pointer tutorial

Here is a (much) more complete draft of the tutorial on borrowed pointers. It is becoming more in-depth than I intended. I hope to later extract a much shorter subset. But I thought I’d post what I’ve got so far. Borrowed pointers Borrowed pointers are one of the more flexible and powerful tools available in Rust. A borrowed pointer can be used to point anywhere: into the shared and exchange heaps, into the stack, and even into the interior of another data structure.

read more →

13 July 2012

Concurrent maps

I had a very interesting discussion with Sriram and Terrence (of Kilim and ANTLR fame, respectively—two smart dudes) yesterday. One of the things we talked about was adapting shared-memory data structures like concurrent hash maps into an actor setting. One thing we’ve found when working on Servo is that the temptation to cheat is enormous. Most of the papers you read about things like parallel layout just assume a shared memory setting and blithely make use of data strutures like concurrent hash maps.

read more →

12 July 2012

Fn types

I am trying to mop up some of the remaining work for regions now. One of the big remaining areas is dealing with function and iface types. This proposal is certainly influenced by my previous proposals. However, we have backed away from the idea of dynamically-sized types for vectors and so I will do the same here. The design My current design includes the following kinds of function types (written as I expect them to commonly be written; some details are omitted):

read more →

10 July 2012

Borrowed Pointer Tutorial

This is a draft of (the first section of) a new Rust tutorial on borrowed pointers (the official name for “regions”). Comments welcome. UPDATE: I added a section “Why borrowed?” Borrowed pointers Borrowed pointers are one of the more flexible and powerful tools available in Rust. A borrowed pointer can be used to point anywhere: into the shared and exchange heaps, into the stack, and even into the interior of another data structure.

read more →

11 June 2012

HotPar

Last Thursday and Friday I had the good fortune of presenting a paper of mine at HotPar 2012. The paper is called Parallel Closures: A New Twist on an Old Idea; it basically describes what has evolved to become the PJs (Parallel JavaScript) model, though it does so in the context of a static checker built in Java. I really enjoyed the workshop: the presenters were generally very good and the audience was lively.

read more →

10 June 2012

Unifying patterns in alts and lets

This is a proposal to unify the mechanics of alt and destructuring assignment. It was born out of discussion between erickt, pcwalton, and I amidst various bugs in the bug tracker but I wanted to float it around to a larger audience. I’d like to discuss this on Tuesday, because one of the logical next steps for the regions work is to begin deciding precisely what to do about the types of identifiers in alts.

read more →

31 May 2012

Mutability

OK, I’ve been thinking more about the mutability issue and I think I have found a formulation that I am happy with. The basic idea is that we refactor types like so: T = M T | X | @T | ~T | [T] | {(f:T)*} | int | uint | ... M = mut | const | imm This no doubt looks similar to some of my other permutations. The key difference is that before I separated qualified and unqualified types.

read more →

30 May 2012

Mutability idea retracted

I have been thinking a bit more about the approach to mutability I recently discussed. It seemed a bit too good to be true (too clean) and I think I’ve realized a problem. The problem derives from my definition of types: T = Q U Q = mut | const | imm U = [T] | @T | &T | { (f : T)* } | X | int | uint | .

read more →

29 May 2012

Simple effect system

Currently, Rust has an effect system but refuses to admit it. In an effort to broaden the set of things that can be safely done in the face of extant aliases into the heap, I have been experimenting with a lightweight extension to Rust’s system. So far I think it is promising but also no magic bullet. Background For those who aren’t familiar with the term, an “effect system” is basically just a fancy name for tagging functions with some extra information beyond the types of their arguments and their return type.

read more →

28 May 2012

Moving mutability into the type

I am dissatisfied with how mutability is treated in the Rust type system. The current system is that a type is not prefixed mutable; rather, lvalues are. That is, a type T is defined like so: T = [M T] | @ M T | & M T | { (M f : T)* } | int | uint | ... M = mut | const | (imm) Note that there is no type mut int (a mutable integer).

read more →

14 May 2012

Vectors, slices, and functions, oh my!

I wanted to bring together the various ideas around vectors and function types into one post. The goals of these changes are to achieve orthogonality of the pointer types, so that leading &, @, and ~ sigils are the only way to indicate the kind of pointer that is in use; to help pare down on the proliferation of subtle variantions on types, such as the 5 different function types currently available.

read more →

8 May 2012

Iface types

Yesterday I wrote about my scheme for paring down our set of function types to one type, fn:kind(S) -> T. When I finished writing the post, I was feeling somewhat uncertain about the merits of the idea, but I’m feeling somewhat better about it today. I really like the idea that top-level items have the type fn:kind(S) -> T and that you therefore give them an explicit sigil to use them in an expression; this allows us to remove the “bare function” type altogether without any complex hacks in the inference scheme.

read more →

7 May 2012

Fn types

As you loyal readers know, I am on a quest to make the Rust type system more orthogonal with respect to the kind of pointer in use, by which I mean that I want to have the three pointer sigils (@, &, and ~) indicate where memory is located and the other types indicate what value is to be found at that memory. Right now there are a few cases where we conflate the two things into one type.

read more →

5 May 2012

Borrowing errors

I implemented a simple, non-flow-sensitive version of the reference checker which I described in my previous post. Of course it does not accept the Rust codebase; however, the lack of flow-sensitivity is not the problem, but rather our extensive use of unique vectors. I thought I’d write a post first showing the problem that you run into and then the various options for solving it. Errors The single most common error involves vec:len().

read more →

1 May 2012

Borrowing

I’ve been working for the last few days on the proper safety conditions for borrowing. I am coming into a situation where I am not sure what would be the best approach. The question boils down to how coarse-grained and approximate our algorithm ought to be: in particular, ought it to be flow sensitive? But let me back up a bit, first, and provide a bit of background. Background Rust bucks the “new language” trend by not having a purely garbage-collected model.

read more →

27 April 2012

In favor of types of unknown size

I’m still thinking about vector and string types in Rust and I think I’ve decided what I feel is the best approach. I thought I’d summarize it here and make the case for it. If you don’t know what I’m talking about, see this post for more background. I’ll forward this to the mailing list as well; I’m sorry if it seems like I’m harping on this issue. I just think vectors and strings are kind of central data structures so we want them to be as nice as possible, both in terms of what you can do with them and in terms of the notations we use to work with them.

read more →

25 April 2012

Permission regions for race-free parallelism

I’ve been making a point of reading academic papers on the train as I ride home. It’s so easy to get behind with the sheer quantity of work that is being produced. Anyway, it occurred to me that I ought to try and summarize the papers I read on this blog so that I can I remember my reactions to them. I’ll start with “Permission Regions for Race-Free Parallelism”, by Westbrook, Zhao, Budimilic, and Sarkar.

read more →

25 April 2012

References

I want to do an introduction to the regions system I’ve been working on. This is work-in-progress, so some of the details are likely to change. Also, I’m going to try some new terminology on for size: although it has a long history in the literature, I think the term “region” is not particularly accurate, so I am going to use the term “lifetime” or “pointer lifetime” and see how it fits.

read more →

23 April 2012

On types and type schemes

After my recent dalliance in Matters of a Truly Trivial Nature, I’d like to return to Matters Most Deep and Profound. I’m running up against an interesting question with regions that has to do with the nature of function types like fn(&int): up until now, I’ve assumed that this refers to a function that takes an integer pointer in some region that is specified by the caller. That is, it is a kind of shorthand for a type that might be written like fn<r>(&r.

read more →

23 April 2012

Vectors, strings, and slices

We’ve been discussing a lot about how to manage vectors and strings in Rust. Graydon sent out an excellent proposal which allows for a great number of use cases to be elegant handled. However, I find the syntax somewhat misleading. I’ve proposed one alternative on the mailing list, but I now find I don’t like it, so I thought I’d brainstorm a bit and try to find something better. There are really three use cases:

read more →

15 April 2012

Syntax matters...?

For a long time, it was considered fairly obvious, I think, that syntax didn’t really matter. It was just the surface skin over the underlying ideas. In recent times, though, the prevailing wisdom has reversed, and it is now quite common to hear people talk about how “syntax matters”. While I don’t exactly disagree, I think that the importance of trivial syntactic matters is generally overemphasized. It is not a matter of life and death whether or not semicolons are required to end a line, for example, or whether parentheses are required in making a call.

read more →

11 April 2012

DOA: Don't overabstract

I’d like to propose a term for code that has been “over-DRY’d” (dessicated?). I occasionally run across some method which just seems horribly complex. Reading it closer, it usually turns out that what happened is that two or three independent operations got collected into one subroutine. Perhaps they started out as doing almost the same thing—but before long, they diverged, and now the subroutine has grown a hundred parameters and has a control-flow path that requires a whiteboard and a ultra-super-fine-point marker to follow.

read more →

10 April 2012

Declared vs duckish typing

One of the questions in our object system is what precisely how “declared” we want things to be when it comes to interfaces and implementations. In a discussion on IRC, graydon suggested it’d be nice to have terms like “duck-typing” defined more precisely in a Rust syntax, and he is correct. So here is my effort. The current setup Currently, implementations must declare precisely what types they implement. For example, it looks like this:

read more →

9 April 2012

Rust's object system

On the rust-dev mailing list, someone pointed out another “BitC retrospective” post by Jonathon Shapiro concerning typeclasses. The Rust object system provides interesting solutions to some of the problems he raises. We also manage to combine traditional class-oriented OOP with Haskell’s type classes in a way that feels seamless to me. I thought I would describe the object system as I see it in a post. However, it turns out that this will take me far too long to fit into a single blog post, so I’m going to do a series.

read more →

6 April 2012

For loops

First off, I want to welcome Brian Anderson to the Rust blog-o-sphere (which so far consists primarily of myself). His first post does a great job of explaining how to use the new for syntax that was recently added to Rust: this syntax allows for break, ret, and cont from within user-defined loops, which is very nice. Reading some of the Hacker News comments (this one in particular), I wanted to clarify one thing.

read more →

28 March 2012

Avoiding region explosion in Rust

pcwalton and I (but mostly pcwalton) have been hard at work implementing regions in Rust. We are hoping to use regions to avoid a lot of memory allocation overhead in the compiler—the idea is to use memory pools (a.k.a. arenas) so that we can cheaply allocate the data needed to process a given function and then release it all in one shot. It is well known that arenas are great fit for the memory allocation patterns of a compiler, which tend to produce a lot of data that lives for the duration of a pass but is not needed afterwards.

read more →

28 March 2012

Servo design

Yesterday we had a hackathon/meeting to discuss the overarching design of Servo, the project to build a next-generation rendering engine. We didn’t ultimately do much hacking (though we did a little), but mostly we tried to hammer out the big picture so that we can actually get to writing code. I wanted to try and write up what I understood as the consensus (for the moment, anyway). The big picture There will be (at least) three large components.

read more →

3 March 2012

Progress on inlining

Cross-crate inlining has come a long way and is now basically functional (I have yet to write a comprehensive test suite, so I’m sure it will fail when exercising various corners of the language). Just for fun, I did some preliminary micro-benchmarks. The results are not that surprising: removing method call overhead makes programs run faster! But it’s still nice to see things go faster. We’ll look at the benchmarks, see the results, and then dive into the generated assembly.

read more →

25 February 2012

Serialization without type information via impls

My current implementation of the auto-serialization code generator requires full type information. This is a drag. First, macros and syntax extension currently run before the type checker, so requiring full type information prevents the auto-serialization code from being implemented in the compiler, as it should be. At first I wanted to change how the compiler works to provide type information, but after numerous discussions with pcwalton and dherman, I’ve come to the conclusion that this is a bad idea: it requires exposing an API for the AST and for type information and introduces numerous other complications.

read more →

22 February 2012

Regions tradeoffs

In the last few posts I’ve been discussing various options for regions. I’ve come to see region support as a kind of continuum, where the current system of reference modes lies at one end and a full-blown region system with explicit parameterized types and user-defined memory pools lies at the other. In between there are various options. To better explore these tradeoffs, I wrote up a document that outlines various possible schemes and also details use cases that are enabled by these schemes.

read more →

18 February 2012

Versioning considered OK

Marijn pointed out to me that our current setup should avoid the worst of the versioning problems I was afraid of. In the snapshot, we package up a copy of the compiler along with its associated libraries, and use this compiler to produce the new compiler. The new compiler can then compilers its own target libraries, thus avoiding the need to interact with libraries produced by the snapshot. Of course, I should have known this, since I have relied on this so that I can changed the metadata format without worrying about backwards compatibility.

read more →

17 February 2012

CCI and versioning

I’ve been busily implementing the Cross-Crate Inlining stuff, but one area I haven’t looked at much is versioning. In particular, if we are going to be serializing the AST, we need a plan for what to do when the AST changes. Actually, if inlining were only to be used for performance, we wouldn’t really need to have a plan: we could just not inline when the AST appeared to be stored in some form we don’t understand.

read more →

16 February 2012

Returning refs

One commonly requested feature for regions is the ability to return references to the inside of structures. I did not allow that in the proposal in my previous post because I did not want to have any region annotations beyond a simple &. I think, however, that if you want to allow returning references to the interior of a parameter, you need a way for the user to denote region names explicitly.

read more →

15 February 2012

Regions-lite...ish

I was talking to brson today about the possibility of moving Rust to a regions system. He pointed out that the complexity costs may be high. I was trying to make a slimmer version where explicit region names were never required. This is what I came up with. The truth is, it’s not that different from the original: adding back region names wouldn’t change much. But I’m posting it anyway because it includes a description of how to handle regions in types and I think it’s the most complete and correct proposal at the moment.

read more →

14 February 2012

Using futures in the task API

Brian pointed out to me a nice solution to the Task API problem that I have overlooked, though it’s fairly obvious. Basically, I had rejected a “builder” style API for tasks because there is often a need for the child task to be able to send some data back to its parent after it has been spawned, and a builder API cannot easily accommodate this. Brian’s idea was to encapsulate these using futures.

read more →

13 February 2012

Task API

One of the thorny API problems I’ve been thinking about lately is the task API for Rust. I originally had in mind this fancy and very flexible aproach based on bind. When I spelled it out I found it was very powerful and flexible but also completely unworkable in practice. So here is a more limited proposal. There is a core task API that looks something like this: enum task = uint; // wrap the task ID or whatever type opts = { .

read more →

9 February 2012

Auto-serialization in Rust

I’ve been working on implementing Cross-Crate Inlining. The major task here is to serialize the AST. This is conceptually trivial but in practice a major pain. It’s an interesting fact that the more tightly you type your data, the more of a pain it (generally) is to work with in a generic fashion. Of functional-ish languages that I’ve used, Scala actually makes things relatively easy by using a combination of reflection and dynamic typing (interfaces like Product come to mind).

read more →

2 February 2012

Breaking out is hard to do

One of the things I’d like to do for the iteration library is settle on a convention for breaking and continuing within loops. There is a bug on this issue (#1619) and it seems like the general approach is clear but some of the particulars are less so. So I thought I’d try to enumerate how code will look under the various alternatives and then maybe we can settle on one: they’re all fairly similar.

read more →

2 February 2012

Cross-crate inlining

Cross-crate inlining (CCI) refers to the ability to inline a function across crate boundaries. In Rust, a “crate” is the unit of compilation, rather than an individual file as in C or C++. A crate basically corresponds to a single library or executable, but it may contain any number of modules and source files internally. CCI is important for performance due to the ubiquitous use of small methods like vec::iter() in our source code.

read more →

1 February 2012

Update

It’s been a while since I wrote anything on the blog! A lot has been going on in the meantime, both in Rust, parallel JavaScript, and personally…I hate to write a big update post but I gotta’ catch up somehow! Rust First, we made our 0.1 release, which is great. We are now planning for 0.2. The goal is to make frequent, relatively regular releases. We’re still in such an early phase that it doesn’t seem to make sense to literally release every few months, but at the same time we don’t plan to wait long.

read more →

11 January 2012

Proposed JS parallelism vs actors

In one of the comments on yesterday’s post, Tushar Pokle asked why I would champion my model over an Erlang model of strict data separation. There are several answers to this question. The simplest answer is that Web Workers already provide an actors model, though they do not make tasks particularly cheap (it’s possible to work around this by creating a fixed number of workers and sending tasks for them to execute).

read more →

9 January 2012

Parallel Javascript

Lately the ideas for a parallel, shared memory JavaScript have begun to take shape. I’ve been discussing with various JavaScript luminaries and it seems like a design is starting to emerge. This post serves as a documentation of the basic ideas; I’m sure the details will change as we go along. User Model The model is that a JavaScript worker (the “parent”) may spawn a number of child tasks (the “children”).

read more →

29 December 2011

Block sugar in expressions

UPDATE: I found some more complications. Updates inline. I have been working on and off on allowing block sugar to appear in Rust expressions and not only statements. For those who do not know what I am talking about, let me give a bit of context. At the moment, one can write the following in Rust: vec::iter(v) { |e| ... } which is sugar for the function call: vec::iter(v, { |e| .

read more →

29 December 2011

Composing blocks

The original Rust design included iterators very similar to Python’s generators. As I understand it, these were stripped out in favor of Ruby-esque blocks, partially because nobody could agree on the best way to implement iterators. I like blocks, but it seems like it’s more natural to compose iterators, so I wanted to think a bit about how one might use blocks to achieve similar things. I’m sure this is nothing new; there must be hundreds of libraries in Haskell that do the same things I’m talking about here.

read more →

21 December 2011

Tone and criticism

So, I worry that my various posts about Rust give the impression that I’m dissatisfied with the language. It’s true that there are several things I’d like to change—and those are what I’ve focused on—but I want to clarify that I quite like Rust the way it is and I find the overall feel of the language to be very good. When it comes to the big decisions, I think Rust gets it right:

read more →

20 December 2011

Dynamic race detection

In the context of thinking about parallelism for Rust, I have been reminded of an older idea I had for a lightweight, predictable dynamic race detection monitoring system based around block-scoped parallelism. I should think this would be suitable for (an extended version of) a dynamic language like Python, JavaScript, or Lua. I will write in a Python-like syntax since I know it best, but I am debating about exploring this for JavaScript.

read more →

16 December 2011

Implementing unique closures

I landed a preliminary version of unique closures (which I am currently calling sendable fns) on the trunk last night. I wanted to briefly document what I did to alter the design of closures to get this working (of course there is a comment in the code too, but who reads that?). Closures in Rust are represented as two words. The first is the function pointer and the second is a pointer to the closure, which is the captured environment that stores the data that was closed over.

read more →

13 December 2011

Const vs Mutable

I keep thinking about parallel blocks although I know I probably shouldn’t; but so long as I write these notes while rustc builds, everybody wins, right? Anyhow, pcwalton and dherman yesterday pointed out to me that const is not exactly one of the most beloved features of C++: “const-ification” is no fun, and if we’re not careful, Rust could walk right down that path. To some extent my reaction is, “Well, something’s gotta’ give.

read more →

13 December 2011

Partially ordered unique closures

On a call with other Rust developers, I realized that I was thinking about unique closures all wrong. I had in mind a total ordering: fn[send] <: fn <: block but of course this is not necessary. What is desirable is a partial ordering: fn[send] <: block fn <: block just as ~ and @ pointers can both be aliased using a reference. Ironically, this is precisely what I proposed in my list of possible solutions, but I did so using region terminology.

read more →

12 December 2011

Challengines implementing unique closures

Update: See the recent post addressing the solution to this problem. I have been trying to implement unique closures—or sendable functions, as I prefer to call them—but I realized that there is a fundamental problem that I hadn’t thought of before. The problem stems from two contradictory design goals: Sendable functions should be movable to another task without copying The various function types should have a subtyping relationship The first requirement really demands that the sendable function’s environment be stored with a unique pointer.

read more →

9 December 2011

Pure blocks

I’ve been thinking a lot about “parallel blocks” recently and I am beginning to think they can be made to work very simply. The main thing that is needed is a type qualifier const that means “read-only”. This would be a type prefix with very low precedence, just like immutable and shared in D. The type const T would refer to an instance of T that cannot be modified. This is a deep property, so, given some record types defined like:

read more →

8 December 2011

Sendable functions

One of the last remaining tasks for Rust 0.1 is to find a way to address issues #1128 and #1038. The key problem is that, right now, we can only spawn a task with a bare function, which is to say a function that carries no closure or environment. Due to the way that Rust is implemented, this even excludes generic functions. I have been wanting to lift this restriction but have been stymied by trying to make it accessible.

read more →

8 December 2011

Why not modes?

Marijn asked me what it is that I dislike about parameter modes. I thought I might as well explain here. For background, today in Rust a function can declare each parameter in one of several modes: By value (++): No pointer is used but the value is not owned by the callee. Therefore, the callee does not need to free it, for example, or decrement a ref count. By immutable reference (&&): a pointer to the variable in the caller’s stack frame is passed, but the callee cannot use it to make changes.

read more →

7 December 2011

Rust usability problems

I recently implemented a new hashtable module for Rust. This was actually the first piece of code written in Rust which I started from scratch. I ran into some difficulties. Some of these are just things you have to get used to; some might be worth trying to correct. Just not entirely sure which problem falls into which category yet. Cyclic types Due to Rust’s structural types, types cannot reference themselves.

read more →

6 December 2011

Coroutines for Rust

I have been thinking about unique closures, one of the last blocker items for the Rust 0.1 release. The original idea of a unique closure was that it should be a closure that can only access uniquely owned state, and which can therefore be sent to other tasks. However, I’ve come to have my doubts about this idea. In particular, a unique closure, like any closure, is a function, and can therefore be invoked many times: but this imposes some limits on what such a closure can safely do.

read more →

5 December 2011

Statement-level parallelism

The primary means of parallel programming in Rust is tasks. Our task support is good: as good or better than any other language I’ve seen (good support for unique types and unique closures) but we have virtually no support for intra-task parallelism. The classic example is iterating over an array and processing each element in parallel. To be fair, this is a hard problem. For my PhD, I worked on a language called Harmonic.

read more →

3 December 2011

Rust without implicit copies

I just posted a draft of a proposal for Rust that aims to eliminate implicit copies. At the moment, it is not the final version; there are some flaws I need to correct. For one thing, I need to address implicit capturing of variables by lambdas. From the introduction: This is a proposal for Rust whose purpose is to eliminate implicit copies of aggregate types, while preserving most other aspects of the language.

read more →

2 December 2011

Why case classes are better than variant types

One of the better features from functional programming languages are variant types (a.k.a. algebraic data types). Basically they are a way of enumerating a small set of possibilities and then making sure that you handle every possible case. However, in real world use variant types tend to run into a few annoying problems. While working on the Harmonic compiler, I found that Scala’s case classes addressed some of these shortcomings.

read more →