Steve Klabnik

“The most violent element in society is ignorance.” - Emma Goldman

Page 2

What’s next for SemVer

On December 18, 20091, the Semantic Versioning specification was announced. More commonly known as SemVer, it provided guidance for developers regarding software versions:

I propose a simple set of rules and requirements that dictate how version numbers are assigned and incremented. For this system to work, you first need to declare a public API. This may consist of documentation or be enforced by the code itself. Regardless, it is important that this API be clear and precise. Once you identify your public API, you communicate changes to it with specific increments to your version number. Consider a version format of X.Y.Z (Major.Minor.Patch). Bug fixes not affecting the API increment the patch version, backwards compatible API additions/changes increment the minor version, and backwards incompatible API changes increment the major version.

I call this system “Semantic Versioning.”...

Continue reading →

thank u, next

I started working at 15, when I took a job as a pizza cook. Over the next seven years, I moved up the ranks, to a driver, shift manager, and then as part of the “new store opening team.” The franchise was growing, and we needed to help new franchisees open their new stores. I’d travel to where the new store was a week before they would open, help train the new staff, and then work their opening weekend. It was really fulfilling work; if pizza paid as well as tech, I’d seriously consider doing it forever.

One time, somewhere in Maryland, I got a bit ill. It wasn’t a good idea for me to work the rest of the week, but the company’s top brass would usually visit to cut the ribbon on the store. It was about a four hour drive back to home, and our COO graciously agreed to let me come back to the ‘burgh with him, so I could recover at home. On the drive, I asked him what he did before working...

Continue reading →

Thoughts on Rust in 2019

Each year, we ask the community to write blog posts about what they want to see on Rust’s roadmap for the next year. This is my post for Rust in 2019.

Rust 2021: Maturity

This year is also a bit special; in 2018, we introduced “editions” to Rust, on a roughly three-year schedule. So now is not just a good time to think about 2019, but about 2020 and 2021 as well. Rust 2015 was about “stability”. Rust 2018 was about “productivity.” I’d like Rust 2021 to be about “maturity.”

In order to get there, here’s what we need in 2019.

No new features

Emphasis on “new” here. What do I mean by this? Well, there are a few features that are in the pipeline that I do think should land:

  • async/await
  • GATs
  • const generics

And possibly

  • Specialization

None of these features are new; we’ve got their basic designs in place. These features are also significant and foundational; we need async/await...

Continue reading →

Six years with Rust

Today is six years since I first heard of Rust. I wrote a post last year about it.

This past year was… intense. Rust 1.31 was basically Rust 2.0, at least in the marketing sense. I burned myself out getting the first edition of the book together for Rust 1.0, and I burned myself out getting the edition shipped.

Let’s talk about the bad and the good. Bad first so we end on the high notes.

The Bad

This year, the docs team sort of… died. Not entirely, but it’s… different now. We used to have a single docs team that handled most everything docs related. The core of that for the past few years has been me and two others. But early this year, we split the sub-teams into fewer individual teams. The old docs team became the docs team, the rustdoc team, the Rust By Example team, and the Reference team. But we didn’t really attract many more people. We did to some degree! The reference team...

Continue reading →

Clojure’s stability: lessons learned

There’s been some Programming Language Discourse lately, and I have some thoughts. It’s mostly centered around a comment on the orange website:

I would put it simply: Clojure was designed by a thinker, who creates when he is away from the keyboard, not in front of it. When one releases and breaks the code in his head first, very few breaking changes are left for the public releases.

I think, regardless of this person being right or wrong, there’s an interesting question here. Let’s look at the comment this is ultimately responding to:

From the perspective of a (fairly large-scale at this point) app developer: I find it great that Clojure places such emphasis on backwards compatibility. In general, migration to newer Clojure versions is completely painless.

The language has been designed by experienced and mature people and doesn’t go through “let’s throw everything out and start...

Continue reading →

Rust has a static garbage collector

There’s a fairly common argument that pops up on programming forums, and it’s about the nature of what “garbage collection” means. In the research world, this is what GC means:

Garbage collection (GC), also known as automatic memory management, is the automatic recycling of dynamically allocated memory(2). Garbage collection is performed by a garbage collector which recycles memory that it can prove will never be used again. Systems and languages which use garbage collection can be described as garbage-collected.

Historically, there has been two major forms of GC: reference counting, and tracing. The argument happens because, with the rise of tracing garbage collectors in many popular programming languages, for many programmers, “garbage collection” is synonymous with “tracing garbage collection.” For this reason, I’ve been coming around to the term “automatic memory management”, as it...

Continue reading →

Who authors the most popular crates on

I had a question this morning: who authors the most popular crates on

First, we have to figure out what we mean by “most popular.” My first guess was “top 100 by recent downloads”, so I looked at Once I got to 100, I found that even the next few crates were ones that I heard of and would think are used often. I decided to keep going until I felt the results were more tenuous. This is obviously pretty subjective, but I also realized something: I felt like the data got a bit more noisy when I got to the 100k download mark. Sorting by this and removing a few outliers (the rustc-ap-* crates don’t count, IMHO), I had a list of 264 crates in a text file.

Furthermore, how do I determine ‘crate authorship’? Many crates, especially popular ones, are worked on by more than one person. I’m trying to come up with some really rough numbers here, so I decided to go with the...

Continue reading →

Should you learn C to “learn how the computer works”?

I’ve often seen people suggest that you should learn C in order to learn how computers work. Is this a good idea? Is this accurate? I’m going to start with my conclusion right upfront, just to be crystal clear about what I’m saying here:

  • C is not “how the computer works.”
  • I don’t think most people mean this phrase literally, so that is sort of irrelevant.
  • Understanding the context means that learning C for this reason may still be a good idea for you, depending on your objectives.

I plan on making two follow-up posts as well, exploring more implications of this idea, but this is already quite a lot. I’ll update this post with links to them when I make them.

I’ve often seen people suggest this:

By learning C, you can learn how computers work.

I think that this idea is not inherently wrong, but does come with some caveats. As long as you keep those caveats in mind, I think this...

Continue reading →

You can’t “turn off the borrow checker” in Rust

Every once in a while, someone will talk about unsafe in Rust, and how it “turns off the borrow checker.” I think this framing leads to misconceptions about unsafe and how it interacts with safe code.

Here’s some code that causes a borrow checker error:

fn main() {
    let mut x = 5;

    let y = &x;
    let z = &mut x;

    println!("{}", y);

And the error:

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
 --> src/
4 |     let y = &x;
  |              - immutable borrow occurs here
5 |     let z = &mut x;
  |                  ^ mutable borrow occurs here
6 | }
  | - immutable borrow ends here

Rust won’t let us have a &T and a &mut T to the same T at the same time.

If unsafe “turned off the borrow checker, we’d expect this code to work:

fn main() {
    let mut x = 5;

    unsafe {
        let y = &x;
        let z = &mut x;

Continue reading →

Is WebAssembly the return of Java Applets & Flash?

In my last post on WebAssembly, I made the following claim:

Some have compared WebAssembly to Java applets; in some ways, they’re very right, but in some ways, they’re very wrong. Eventually I’ll write a post about the wrong, but for now, the right: in some sense, WebAssembly is a different way of accomplishing what the JVM set out to do: it’s a common virtual machine that can be used to build very cross-platform software.

A lot of people expressed interest in me elaborating, so let’s get to it! For this post, I’m going to make three comparisons: to Flash, to Java Applets, and occasionally to PNaCL. Secondly, this post is going to focus on the web use-case for WebAssembly, even though the previous post was about non-web uses. We’ll make that comparison in the next post. Finally, this post is kind of like eating tapas, there’s a bunch of little sections. I feel like it’s a bit short...

Continue reading →