Reed

08. Oct 2026 23:18
What is this
A sustainable web career, for when all this blows over
07. Oct 2026 17:00
dbushell.com

For better or worse the web industry is going through a bit of a phase. The reasons are largely irrational. People still need the web, nothing has changed there. Regardless, the financials of this business are a struggle. Longterm career prospects are looking dicey. […]

On Git Refs
07. Oct 2026 02:00
matklad.github.io

I have recently improved my mental model of Git. Consider these two git commands:

A Terminal Protocol for Program Status (OSC 7501)
06. Oct 2026 02:00
mitchellh.com
Benchmark In Milliseconds
05. Oct 2026 02:00
matklad.github.io

How long should a micro benchmark run? My rule of thumb is to tweak the input size until the benchmark takes about 300ms, for the following reasons:

Friendship ended with Deno, now Node is my best friend
03. Oct 2026 17:00
dbushell.com

It’s finally time I go crawling back to Node! I’ve been using Node heavily this month on a SvelteKit client project. When did Node get so good‽ Deno has been my go-to runtime for so long I forgot how to Node. Now I’m back, I find all the ECMAScript† sugar is supported and the old annoying APIs have […]

Demoting i686 Windows targets to std-only
02. Oct 2026 02:00
blog.rust-lang.org
Announcing Rust 1.99.0
01. Oct 2026 02:00
blog.rust-lang.org
Shin honkaku
28. Sep 2026 17:00
dbushell.com

Shin honkaku is a sub-genre of Japanese detection fiction — and my new obsession! I’ve even designed my own book cover, scroll down to see… An intro to the genre “Shin honkaku” translates to “new orthodox” and pays homage to classic western authors of the early 20th century such as Poe, Queen, Van […]

Leaving them behind
28. Sep 2026 16:00
dbushell.com

Quick note before we begin: this is the first of two posts I’m publishing today. You’re welcome to skip ahead to: Shin honkaku — it’s far more fun! I’ve waited long enough! I’ve entertained one “wait six months” too many! The TL;DR for my updated AI policy has changed: The absolute vileness of the […]

Removing the fancy button
25. Sep 2026 17:00
dbushell.com

My blog is standard.site ready but I’m pausing full integration for now. I desperately wanted the fancy button but after its novelty wore off I’ve accepted the truth. The Bluesky button is bad UX. This has been widely complained about from day one. The problem is obvious for Bluesky users. […]

I said no and Apple said yes
22. Sep 2026 17:00
dbushell.com

The nice thing about keeping a blog is that I can say at precisely 9:51am, Wednesday 5th February 2025, I discovered that macOS 15.3 had enabled a feature that was phoning home every 15 minutes with personal data. And that I said “no” and turned it off. […]

Announcing a Maintainer in Residence: Scott Schafer for the Cargo team
22. Sep 2026 02:00
blog.rust-lang.org
GitHub Actions leaking secrets when Miri output is cached
21. Sep 2026 02:00
blog.rust-lang.org
Finding Bugs
19. Sep 2026 02:00
matklad.github.io

Are generative (randomized) tests significantly more effective than example-based unit-tests at discovering bugs? There's an interesting discussion about this on lobste.rs. One argument in favor of unit tests is, paraphrasing

“Programming” monitor
18. Sep 2026 17:00
dbushell.com

I’ve been rocking an LG monitor that has noticeable burn-in. The old dog takes a while to flicker into life too. I’ve had it around eight years (the Dell before it lasted ten). I think the monitor is too dumb to be spying on me but I’m due an upgrade anyway. […]

Be alert: targeted attacks on prominent Rustaceans
17. Sep 2026 02:00
blog.rust-lang.org
RSS Club #009: Domains
12. Sep 2026 17:00
dbushell.com

This is an RSS-only post, thank you for subscribing :) I keep buying domains! When will I ever learn? Domain prices are increasing (again) because why wouldn’t they? Sub-domains are free! Host your side project on a sub-domain! Then if you get bored, who cares? […]

CodePen: exposed!
08. Sep 2026 17:00
dbushell.com

I promise this post is not merely a comment on a Hacker News submission because good lord that would be desperate but that is where I’m starting: “They send all typed into editor input to codepen.dev almost immediately (you would see in 1-2 sec after you typed your secret that it appears in […]

Rust debugging survey 2026 results
07. Sep 2026 02:00
blog.rust-lang.org
Abattoirs of taste
04. Sep 2026 18:00
dbushell.com

I keep hearing this damned word pop up and it’s starting to annoy me. It’s fast-tracking its way to becoming the free space on buzzword bingo for magic 8 ball enjoyers. That word is “taste”. I’ll try to define “taste” in the context that prompt engineers — or whatever they’re calling themselves […]

Plagiarism ain’t cool bro :(
04. Sep 2026 17:00
dbushell.com

It’s not every day I read an email subject that makes my heart sink, only to find myself laughing out loud. Today I was told someone plagiarised my website! The snitch lol informant wishes to remain anonymous (they’ve obviously read my blog!) I wasn’t sure how to deal with this situation. […]

Announcing Rust 1.98.1
03. Sep 2026 02:00
blog.rust-lang.org
Static Allocation, Constant Work
02. Sep 2026 02:00
matklad.github.io

In reply to this email:

Announcing rustup 1.29.1
01. Sep 2026 02:00
blog.rust-lang.org
Cancelation Terminology
31. Aug 2026 02:00
matklad.github.io

A short note explaining the difference between synchronous cancelation, asynchronous cancelation, and graceful shutdown. I am not too attached to these specific three terms, but I want to call your attention to the three things behind them, which are important not to confuse with each other.

Announcing our first Maintainers in Residence
26. Aug 2026 02:00
blog.rust-lang.org
Enabling the next-generation trait solver on nightly
21. Aug 2026 02:00
blog.rust-lang.org
Rust Glancer
21. Aug 2026 02:00
matklad.github.io

Rust Glancer, a functional LSP server for Rust which uses two orders of magnitude less RAM, is incredibly cool. Go check it out! This post started as a comment on lobste.rs, but I figured it out that it's better to publish it somewhat more prominently. Don't expect polished writing though!

Better Batteries
20. Aug 2026 02:00
matklad.github.io

One of the eternal schisms in programming is over the question of whether the standard library should be minimal or encompassing. This is the wrong question to ask. The right one is:

Printing Lists
14. Aug 2026 02:00
matklad.github.io

To print a comma-separated list, a concise idiom is to optionally print the comma first, before the element:

Zig's Io.Threaded is Neat
06. Aug 2026 02:00
matklad.github.io

std.Io.Threaded is one of the implementations of Zig's new Io interface that enables concurrency. This is a boring just use threads impl. I personally find it neat though --- it does this weird thing that I wanted to do for ages, that to my knowledge no one else is doing properly, and implements it better than I thought to be possible.

Superlogical
29. Jul 2026 02:00
mitchellh.com
Everyone Should Know SIMD
22. Jul 2026 02:00
mitchellh.com
Memory Safety's Hardest Problem
20. Jul 2026 02:00
matklad.github.io

Uplifting a lobsters comment for easier reference.

Pledging Another $400,000 to the Zig Software Foundation
21. Jun 2026 02:00
mitchellh.com
Hi, I'm Sunny
04. May 2026 02:00
mcyoung.xyz
Ghostty Is Leaving GitHub
28. Apr 2026 02:00
mitchellh.com
Simdutf Can Now Be Used Without libc++ or libc++abi
15. Apr 2026 02:00
mitchellh.com
The Building Block Economy
07. Apr 2026 02:00
mitchellh.com
Breaking the Warranty with go:linkname
31. Mar 2026 02:00
mcyoung.xyz
My AI Adoption Journey
05. Feb 2026 01:00
mitchellh.com
Don't Trip[wire] Yourself: Testing Error Recovery in Zig
21. Jan 2026 01:00
mitchellh.com
Finding and Fixing Ghostty's Largest Memory Leak
10. Jan 2026 01:00
mitchellh.com
Optimization Countermeasures
15. Dec 2025 01:00
mcyoung.xyz
Ghostty Is Now Non-Profit
03. Dec 2025 01:00
mitchellh.com
Why SSA?
21. Oct 2025 02:00
mcyoung.xyz
Vibing a Non-Trivial Ghostty Feature
11. Oct 2025 02:00
mitchellh.com
Zig Builds Are Getting Faster
03. Oct 2025 02:00
mitchellh.com
Libghostty Is Coming
22. Sep 2025 02:00
mitchellh.com
You Have to Feel It
30. Aug 2025 02:00
mitchellh.com
Default Methods in Go
25. Aug 2025 02:00
mcyoung.xyz
Advice for Tech Non-Profits
20. Aug 2025 02:00
mitchellh.com
We Rewrote the Ghostty GTK Application
14. Aug 2025 02:00
mitchellh.com
Parsing Protobuf Like Never Before
16. Jul 2025 02:00
mcyoung.xyz
The Best C++ Library
14. Jul 2025 02:00
mcyoung.xyz
What's //go:nosplit for?
07. Jul 2025 02:00
mcyoung.xyz
Protobuf Tip #7: Scoping It Out
03. Jun 2025 02:00
mcyoung.xyz
Protobuf Tip #6: The Subtle Dangers of Enum Aliases
20. May 2025 02:00
mcyoung.xyz
Protobuf Tip #5: Avoid import public/weak
13. May 2025 02:00
mcyoung.xyz
Protobuf Tip #4: Accepting Mistakes We Can't Fix
29. Apr 2025 02:00
mcyoung.xyz
Protobuf Tip #3: Enum Names Need Prefixes
22. Apr 2025 02:00
mcyoung.xyz
Cheating the Reaper in Go
21. Apr 2025 02:00
mcyoung.xyz
Protobuf Tip #2: Compress Your Protos!
15. Apr 2025 02:00
mcyoung.xyz
What the Hell Is a Target Triple?
14. Apr 2025 02:00
mcyoung.xyz
Protobuf Tip #1: Field Names Are Forever
08. Apr 2025 02:00
mcyoung.xyz
The Art of Formatting Code
11. Mar 2025 01:00
mcyoung.xyz
"As Code"
04. Mar 2025 01:00
mitchellh.com
Welcoming Ghostty Subsystem Maintainers
07. Feb 2025 01:00
mitchellh.com
Ghostty: Reflecting on Reaching 1.0
26. Dec 2024 01:00
mitchellh.com
Go's Weird Little Iterators
16. Dec 2024 01:00
mcyoung.xyz
Things You Never Wanted To Know About Go Interfaces
12. Dec 2024 01:00
mcyoung.xyz
Nobody Gets Fired for Picking JSON, but Maybe They Should?
10. Dec 2024 01:00
mcyoung.xyz
Generators with UnpinCell
25. Oct 2024 02:00
without.boats

<p>In July, I described a way to make pinning <a href="https://without.boats/blog/pinned-places">more ergonomic</a> by integrating it more fully into the language. Last week, I develoepd that idea <a href="https://without.boats/blog/unpin-cell">further</a> with the notion of <code>UnpinCell</code>: a wrapper type that lets a user take an <code>&amp;pin mut UnpinCell&lt;T&gt;</code> and produce an <code>&amp;mut T</code>, similar to how other cells let a user take a shared reference to the cell and produce a mutable reference to its contents. I believe that this notion can also solve the biggest outstanding issues facing <a href="https://without.boats/blog/generators">generators</a>: the fact that the <code>Iterator</code> interface does not permit self-referential values.</p> <p>As I wrote in my <a href="https://without.boats/blog/pin">explanation</a> of Pin&rsquo;s design, the biggest advantage that Pin had over other design ideas was that it was a trivially backward compatible way of introducing a contract that an object will never be moved. But this meant that a trait could only opt into that contract using the new interface; traits that existed before Pin and don&rsquo;t opt into that contract cannot be implemented by types that have self-referential values. The most problematic trait here is <code>Iterator</code>, because generators (functions that evaluate to iterators in the same way async functions evaluate to futures) would ideally support self-referential values just like async functions do. So long as the interface for <code>Iterator</code> takes a mutable reference and not a pinned mutable reference, implementers must assume the iterator can be moved around and therefore can&rsquo;t be self-referential.</p>

Ghostty 1.0 is Coming
22. Oct 2024 02:00
mitchellh.com
UnpinCell
16. Oct 2024 02:00
without.boats

<p>A variation on my previous design for <a href="https://without.boats/blog/pinned-places">pinned places</a> has occurred to me that would be more consistent with Rust&rsquo;s existing feature set.</p> <p>The most outlandish aspect of the previous design was the notion of &ldquo;pinned fields,&rdquo; which support pinned projection. This is quite different from how field projection normally works in Rust: if you have a mutable reference to a struct, you can get a mutable reference to its field, period. (I know Niko Matsakis has recently explored ideas that would change this; this post won&rsquo;t go into any deep consideration of that proposal.) I&rsquo;ve come up with a design which would have similar properties, instead of introducing a kind of field marker.</p>

Pledging $300,000 to the Zig Software Foundation
01. Oct 2024 02:00
mitchellh.com
Tagged Union Subsets with Comptime in Zig
23. Sep 2024 02:00
mitchellh.com
Conditionally Disabling Code with Comptime in Zig
12. Sep 2024 02:00
mitchellh.com
Pinned places
23. Jul 2024 02:00
without.boats

<p>In the previous <a href="https://without.boats/blog/pin">post</a>, I described the goal of Rust&rsquo;s <code>Pin</code> type and the history of how it came to exist. When we were initially developing this API in 2018, one of our explicit goals was the limit the number of changes we would make to Rust, because we wanted to ship a &ldquo;minimum viable product&rdquo; of async/await syntax as soon as possible. This meant that <code>Pin</code> is a type defined in the standard library, without any syntactic or language support except for the ability to use it as a method receiver. As I wrote in my previous post, in my opinion this is the source of a &ldquo;complexity cliff&rdquo; when users have to interact with <code>Pin</code>.</p> <p>We knew when we made this choice that pinned references would be harder to use and more confusing than ordinary references, though I think we did underestimate just how much more challenging they would be for most users. Our initial hope was that with async/await, pinning would disappear into the background, because the <code>await</code> operator and the runtime&rsquo;s <code>spawn</code> function would pin your futures for you and you wouldn&rsquo;t have to encounter it directly. As things played out, there are still some cases where users must interact with pinned references, even when using async/await. And sometimes users do need to &ldquo;drop down&rdquo; into a lower-level <a href="https://without.boats/blog/the-registers-of-rust">register</a> to implement <code>Future</code> themselves; this is when they truly encounter a huge complexity cliff: both the essential complexity of implementing a state machine &ldquo;by hand&rdquo; and the additional complexity of understanding the APIs to do with <code>Pin</code>.</p> <p>My contention in my previous post was that the difficulties involved in this have very little to do with the complexity inherent in the pinned typestate as a concept, or in pinned references as a way of representing it, but instead arises from the fact that <code>Pin</code> is a pure library type without support from the language. Users who deal with <code>Pin</code> are almost always doing something that is totally memory safe, the problem is just that the idioms to do so with <code>Pin</code> are different from and less clear than the idioms for doing so with ordinary references.</p> <p>In this post, I want to propose a set of language changes - completely backward compatible with the language as it exists and the async ecosystem built on <code>Pin</code> - which will make interacting with pinned references much more similar to interacting with ordinary references.</p>

Pin
19. Jul 2024 02:00
without.boats

<p>The <code>Pin</code> type (and the concept of <em>pinning</em> in general) is a foundational building block on which the rest of the the Rust async ecosystem stands. Unfortunately, it has also been one of the least accessible and most misunderstood elements of async Rust. This post is meant to explain what <code>Pin</code> achieves, how it came to be, and what the current problem with <code>Pin</code> is.</p> <p>There was an interesting <a href="https://www.modular.com/blog/mojo-vs-rust-is-mojo-faster-than-rust">post</a> a few months ago on the blog of the company Modular, which is developing a new language called Mojo. In a brief section discussing <code>Pin</code> in Rust, I found that it very succinctly captured the zeitgeist of the public discussion of the subject:</p> <blockquote> <p>In Rust, there is no concept of value identity. For a self-referential struct pointing to its own member, that data can become invalid if the object moves, as it&rsquo;ll be pointing to the old location in memory. This creates a complexity spike, particularly in parts of async Rust where futures need to be self-referential and store state, so you must wrap Self with Pin to guarantee it&rsquo;s not going to move. In Mojo, objects have an identity so referring to self.foo will always return the correct location in memory, without any additional complexity required for the programmer.</p> </blockquote> <p>Some aspects of these remarks confuse me. The term &ldquo;value identity&rdquo; is not defined anywhere in this post, nor can I find it elsewhere in Mojo&rsquo;s documentation, so I&rsquo;m not clear on how Modular claims that Mojo solves the problem that <code>Pin</code> is meant to solve. Despite this, I do think the criticism of <code>Pin</code>&rsquo;s usability is well stated: there is indeed a &ldquo;complexity spike&rdquo; when a user is forced to interact with it. The phrase I would use is actually a &ldquo;complexity cliff,&rdquo; as in the user suddenly finds themself thrown off a cliff into a sea of complex, unidiomatic APIs they don&rsquo;t understand. This is a problem and it would be very valuable to Rust users if the problem were solved.</p> <p>As it happens, this little corner of Rust is my mess; adding <code>Pin</code> to Rust to support self-referential types was my idea. I have ideas of how this complexity spike could be resolved, which I will elaborate in a subsequent post. Before I can get there though I need to first try to explain, as efficiently as I know how, what <code>Pin</code> accomplishes, how it came to exist, and why it is currently difficult to use.</p>

Ownership
22. Jun 2024 02:00
without.boats

<p>This post is meant as an explainer about how substructural type theory can be applied in programming language design. Terms like &ldquo;substructural type theory&rdquo; tend to scare and confuse programmers who don&rsquo;t write Haskell on the weekends, so one thing programming language designers should do when thinking about how they will present their language is invent metaphors, even slightly misleading ones, to help more ordinary programmers understand how their language works. One such term is &ldquo;ownership.&rdquo;</p> <p>Not infrequently, objects in a program come to represent something outside of themselves; they are not &ldquo;pure data&rdquo; but some kind of resource with identity. A classic example of this might be a sort of handle granting exclusive access to a resource. For this to really work well you want to know that to get that object you had to execute certain code (a &ldquo;constructor&rdquo;), that when the object is no longer used some other code will be executed (a &ldquo;destructor&rdquo;), and that while the object is in scope, no concurrently executing code also has an object representing the same exclusive resource (that it is not &ldquo;aliased&rdquo;). This is what ownership (as presented in Rust, at least) is all about.</p> <p>I want to demystify ownership and substructural types in the hopes that this will become more common knowledge. Nothing in this post is really groundbreaking - if you&rsquo;re already &ldquo;in the know,&rdquo; it will contain no new information - but it does contain some notes on aspects of Rust&rsquo;s implementation that I think are incorrect (one of which would even be easy to change).</p>

References are like jumps
13. May 2024 02:00
without.boats

<blockquote> <p>In a high-level language, the programmer is deprived of the dangerous power to update his own program while it is running. Even more valuable, he has the power to split his machine into a number of separate variables, arrays, files, etc.; when he wishes to update any of these he must quote its name explicitly on the left of the assignment, so that the identity of the part of the machine subject to change is immediately apparent; and, finally, a high-level language can guarantee that all variables are disjoint, and that updating any one of them cannot possibly have any effect on any other.</p> <p>Unfortunately, many of these advantages are not maintained in the design of procedures and parameters in ALGOL 60 and other languages. But instead of mending these minor faults, many language designers have preferred to extend them throughout the whole language by introducing the concept of reference, pointer, or indirect address into the language as an assignable item of data. This immediately gives rise in a high-level language to one of the most notorious confusions of machine code, namely that between an address and its contents. Some languages attempt to solve this by even more confusing automatic coercion rules. Worst still, an indirect assignment through a pointer, just as in machine code, can update any store location whatsoever, and the damage is no longer confined to the variable explicitly named as the target of assignment&hellip;</p> <p>Unlike all other values (integers, strings, arrays, files, etc.) references have no meaning independent of a particular run of a program. They cannot be input as data, and they cannot be output as results. If either data or references to data have to be stored on files or backing stores, the problems are immense. And on many machines they have a surprising overhead on performance, for example they will clog up instruction pipelines, data lookahead, slave stores, and even paging systems. <strong>References are like jumps, leading wildly from one part of a data structure to another. Their introduction into high-level languages has been a step backward from which we may never recover.</strong></p> </blockquote> <p>— C.A.R. Hoare, <em>Hints on programming-language design</em> 1974</p> <p>How embarrassing it is for the practice of software development that, when it comes to the subject of references, we have spent half a century creating an enormous object proof that Sir Tony was correct. Null pointers may have been his <a href="https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/">billion dollar mistake</a>, but the decision to ignore his remarks about the problem of pointers in general was a trillion dollar mistake that everyone else made.</p> <p>What Tony Hoare was writing about when he said that references are like jumps was the problem of <em>mutable, aliased state.</em> If you have in a language the ability to alias two variables so that they refer to the same location in memory, and also the ability to assign values to variables as execution progresses, your ability to locally reason about the behavior of a component of your system becomes badly inhibited. Depriving the user of the ability to mutate aliased state by accident is critical to enabling the user to easily create correctly functioning systems.</p>

Coroutines and effects
20. Apr 2024 02:00
without.boats

<p>For the past few months I&rsquo;ve been mulling over some things that Russell Johnston made me realize about the relationship between effect systems and coroutines. You can read more of his thoughts on this subject <a href="https://www.abubalay.com/blog/2024/01/14/rust-effect-lowering">here</a>, but he made me realize that effect systems (like that found in Koka) and coroutines (like Rust&rsquo;s async functions or generators) are in some ways isomorphic to one another. I&rsquo;ve been pondering the differences between them, trying to figuring out the advantages and disadvantages of each.</p> <p>A few weeks ago, Will Crichton posted something on <a href="https://twitter.com/tonofcrates/status/1770560175835058573">Twitter</a> that helped bring the contrast into sharper focus for me:</p> <blockquote> <p>The entire field of PL right now: what if it was dynamically scoped&hellip;. but statically typed&hellip;&hellip;&hellip;&hellip;..? (effects, capabilities, contexts, metavariables&hellip;)</p> </blockquote> <p>I&rsquo;m just a humble language designer (and not a theorist of anything, especially not PL), so my focus is the difference in user experience and affordance. But this seems like a cutting insight and this property of effect handlers - static typing but dynamic scoping - seems to me to be a good jumping off point for understanding the difference between effect handlers and coroutines from a user perspective.</p>

The Rust Calling Convention We Deserve
17. Apr 2024 02:00
mcyoung.xyz
Joining Polar as an Advisor
04. Apr 2024 02:00
mitchellh.com
Iterators and traversables
13. Mar 2024 01:00
without.boats

<p>This is a brief note about the definition of <em>iterator</em>.</p>

Asynchronous clean-up
24. Feb 2024 01:00
without.boats

<p>One problem with the design of async Rust is what do about async clean-up code. Consider that you have a type representing some object or operation (like an async IO handle) and it runs clean up code when you are done using it, but that clean up code itself is also non-blocking and could yield control. Async Rust has no good way to handle this pattern today.</p> <p>The nicest solution seems to be to just use the mechanism that already exists: destructors. If only you could <code>await</code> inside a destructor, everything would seem to be solved. Alas, this would present several problems, and I personally do not believe it is realistic to imagine Rust gaining this feature in the same way that destructors work.</p> <p>The first problem is this: what happens if you drop the the value in a non-async scope? It&rsquo;s not possible to <code>await</code> there! There are two options: either the async destructor doesn&rsquo;t run (considered too easy a mistake to make), or there is a type-checking rule that prevents users from dropping values with async destructors in non-async scopes. The second solution reduces to undroppable types, which I will discuss later in this post: this rule is just undroppable types with an exception to allow them to be dropped in an async scope. What I can say with certainty is that undroppable types, even with an exception, would be very difficult to add to Rust.</p> <p>The second problem is the way that the state of the async destructor would impact the state of any future any containing it. This is actually a re-emergence of the problems with async methods, but now applied to any generic type (because you don&rsquo;t know of a generic type <code>T</code> has an async destructor). The first problem is that you have any trait object, when it drops, what happens if it has an async destructor? This introduces the same object safety issues as async methods: you have nowhere to store the future returned by the async destructor of a trait object. The second problem is that you want to send a value to a different thread, that state of its async destructor also needs to be <code>Send</code>. This is the same problem that motivated RTN, except that now its a problem for <em>every</em> generic type being moved to another thread, not only types on which you explicitly call an async method. I wrote about this problem years and years ago, but it seems to have been misunderstood and ignored since then.</p> <p>The third problem is that users are concerned about having implicit await points added to their future without them realizing it. Therefore there would need to be some restriction that not only doesn&rsquo;t allow these types to be dropped in a non-async scope, but also makes it so that they are destructed at an already explicit <code>await</code> point. This would make the rules around when their async destructors run very different from other destructors, if its even possible to make them coherent.</p> <p>The fourth problem, I believe maybe never raised before, is that it is not the ideal code generation to run async destructors sequentially no matter what. For example, if I have two values that I am asynchronously dropping, possibly I want to <code>join</code> the destructors so they run concurrently. But doing this implicitly would be very risky, because maybe I actually carefully expect one to run before the other.</p> <p>All of these problems hint at a different way to frame the problem of asynchronous clean-up: the problem is not that there is no async drop, but that destructors really only work when you can write a destructor function that returns <code>()</code>. Async clean-up is just a special case of clean-up which does not return <code>()</code>. In this case it returns a future, but there are also scenarios in which the issue is a lack of destructors that can return <code>Result</code>, for example.</p> <p>I want to explore the design space for asynchronous clean up and clean up code that returns values in general, without a focus on destructors specifically. The proposal I&rsquo;ve fleshed out here, based heavily on the work of others (especially Eric Holk and Tyler Mandry), combines two distinct features - async future cancellation and a <code>do</code> &hellip; <code>final</code> construct - to enable users to write asynchronous clean up code that is consistently called. I will also show how these constructs are required for any sort of &ldquo;linear type&rdquo; mechanism in Rust, so rather than seeing them as alternative to type-based async clean up code, they should be seen as prerequisites that can be implemented in the nearer term.</p>

FuturesUnordered and the order of futures
18. Feb 2024 01:00
without.boats

<p>In my <a href="https://without.boats/blog/let-futures-be-futures">previous post</a>, I wrote about the distinction between &ldquo;multi-task&rdquo; and &ldquo;intra-task&rdquo; concurrency in async Rust. I want to open this post by considering a common pattern that users encounter, and how they might implement a solution using each technique.</p> <p>Let&rsquo;s call this &ldquo;sub-tasking.&rdquo; You have a unit of work that you need to perform, and you want to divide that unit into many smaller units of work, each of which can be run concurrently. This is intentionally extremely abstract: basically every program of any significance contains an instance of this pattern at least once (often many times), and the best solution will depend on the kind of work being done, how much work there is, the arity of concurrency, and so on.</p> <ul> <li> <p>Using <strong>multi-task concurrency</strong>, each smaller of work would be its own task. The user would spawn each of these tasks onto an executor. The results of the task would be collected with a synchronization primitive like a <a href="https://tokio.rs/tokio/tutorial/channels">channel</a>, or the tasks would be awaited together with a <a href="https://docs.rs/tokio/latest/tokio/task/struct.JoinSet.html">JoinSet</a>.</p> </li> <li> <p>Using <strong>intra-task concurrency</strong>, each smaller unit will be a future run concurrently within the same task. The user would construct all of the futures and then use a concurrency primitive like <a href="https://docs.rs/tokio/latest/tokio/macro.join.html">join!</a> or <a href="https://docs.rs/tokio/latest/tokio/macro.select.html">select!</a> to combine them into a single future, depending on the exact access pattern.</p> </li> </ul> <p>Each of these approaches has its advantages and disadvantages. Spawning multiple tasks requires that each task be <code>'static</code>, which means they cannot borrow data from their parent task. This is often a very annoying limitation, not only because it might be costly to use shared ownership (meaning <code>Arc</code> and possibly <code>Mutex</code>), but also because even if it isn&rsquo;t going to be problematic in this context to use shared ownership, <span class="sidenote"> <label class="sidenote-label" for="1">the design of Rust will make it much more annoying to manage than borrowing.</label> <input class="sidenote-checkbox" type="checkbox" id="1"></input> <span class="sidenote-content">(I&rsquo;d love to see this change! Cheap shared ownership constructs like <code>Arc</code> and <code>Rc</code> should have non-affine semantics so you don&rsquo;t have to call clone on them.)</span> </span> </p> <p>When you join multiple futures, they <em>can</em> borrow from state outside of them within the same task, but as I wrote in the previous post, you can only join a static number of futures. Users that don&rsquo;t want to deal with shared ownership but have a dynamic number of sub-tasks they need to execute are left searching for another solution. Enter <a href="https://docs.rs/futures/latest/futures/stream/struct.FuturesUnordered.html">FuturesUnordered</a>.</p> <p><code>FuturesUnordered</code> is an odd duck of an abstraction from the futures library, which represents a collection of futures as a <code>Stream</code> (in std parlance, an <code>AsyncIterator</code>). This makes it a lot like tokio&rsquo;s <code>JoinSet</code> in surface appearance, but unlike <code>JoinSet</code> the futures you push into it are not spawned separately onto the executor, but are polled as the <code>FuturesUnordered</code> is polled. Much like spawning a task, every future pushed into <code>FuturesUnordered</code> is separately allocated, so representationally its very similar to multi-task concurrency. But because the <code>FuturesUnordered</code> is what polls each of these futures, they don&rsquo;t execute independently and they don&rsquo;t need to be <code>'static</code>. They can borrow surrounding state as long as the <code>FuturesUnordered</code> doesn&rsquo;t outlive that state.</p> <p>In a sense, <code>FuturesUnordered</code> is a sort of hybrid between intra-task concurrency and multi-task concurrency: you can borrow state from the same task like intra-task, but you can execute arbitrarily many concurrent futures like multi-task. So it seems like a natural fit for the use case I was just describing when the user wants that exact combination of features. But <code>FuturesUnordered</code> has also been a culprit in some of the more frustrating bugs that users encounter when writing async Rust. In the rest of this post, I want to investigate the reasons why that is.</p>

Ghostty Devlog 006
12. Feb 2024 01:00
mitchellh.com
Let futures be futures
03. Feb 2024 01:00
without.boats

<p>In the early-to-mid 2010s, there was a renaissance in languages exploring new ways of doing concurrency. In the midst of this renaissance, one abstraction for achieving concurrent operations that was developed was the &ldquo;future&rdquo; or &ldquo;promise&rdquo; abstraction, which represented a unit of work that will maybe eventually complete, allowing the programmer to use this to manipulate control flow in their program. Building on this, syntactic sugar called &ldquo;async/await&rdquo; was introduced to take futures and shape them into the ordinary, linear control flow that is most common. This approach has been adopted in many mainstream languages, a series of developments that has been controversial among practitioners.</p> <p>There are two excellent posts from that period which do a very good job of making the case for the two sides of the argument. I couldn&rsquo;t more strongly recommend reading each these posts in full:</p> <ul> <li><a href="https://monkey.org/~marius/futures-arent-ersatz-threads.html">Futures aren&rsquo;t ersatz threads</a> by Marius Eriksen <time>(April 2, 2013)</time> </li> <li><a href="https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/">What color is your function?</a> by Bob Nystrom <time>(February 1, 2015)</time> </li> </ul> <p>The thesis of Eriksen&rsquo;s post is that futures provide a fundamentally different model of concurrency from threads. Threads provide a model in which all operations occur &ldquo;synchronously,&rdquo; because the execution of the program is modeled as a stack of function calls, which block when they need to wait for concurrently executing operations to complete. In contrast, by representing concurrent operations as asynchronously completing &ldquo;futures,&rdquo; the futures model enabled several advantages cited by Eriksen. These are the ones I find particularly compelling:</p> <ol> <li>A function performing asynchronous operations has a different type from a &ldquo;pure&rdquo; function, because it must return a future instead of just a value. This distinction is useful because it lets you know if a function is performing IO or just pure computation, with far-reaching implications.</li> <li>Because they create a direct representation of the unit of work to be performed, futures can be composed in multiple ways, both sequentially and concurrently. Blocking function calls can only be composed sequentially without starting a new thread.</li> <li>Because futures can be composed concurrently, concurrent code can be written which more directly expresses the logic of what is occurring. Abstractions can be written which represent particular patterns of concurrency, allowing business logic to be lifted from the machinery of scheduling work across threads. Eriksen gives examples like a <code>flatMap</code> operator to chain many concurrent network requests after one initial network request.</li> </ol> <p>Nystrom takes the counter-position. He starts by imagining a language in which all functions are &ldquo;colored,&rdquo; either <code class="blue">BLUE</code> or <code class="red">RED</code> . In his imaginary language, the important difference between the two colors of function is that <code class="red">RED</code> functions can only be called from other <code class="red">RED</code> functions. He posits this distinction as a great frustration for users of the language, because having to track two different kinds of functions is annoying and in his language <code class="red">RED</code> functions must be called using an annoyingly baroque syntax. Of course, what he&rsquo;s referring to is the difference between synchronous functions and asynchronous functions. Exactly what Eriksen cites as an advantage of futures - that functions returning futures are different from functions that don&rsquo;t return futures - is for Nystrom it&rsquo;s greatest weakness.</p> <p>Some of the remarks Nystrom makes are not relevant to async Rust. For example, he says that if you call a function of one color as if it were a function of the other, dreadful things could happen:</p> <blockquote> <p>When calling a function, you need to use the call that corresponds to its color. If you get it wrong &hellip; it does something bad. Dredge up some long-forgotten nightmare from your childhood like a clown with snakes for arms hiding under your bed. That jumps out of your monitor and sucks out your vitreous humour.</p> </blockquote> <p>This is plausibly true of JavaScript, an untyped language with <a href="https://www.destroyallsoftware.com/talks/wat">famously ridiculous</a> semantics, but in a statically typed language like Rust, you&rsquo;ll get a compiler error which you can fix and move on.</p> <p>One of his main points is also that calling a <code class="red">RED</code> function is much more &ldquo;painful&rdquo; than calling a <code class="blue">BLUE</code> function. As Nystrom later elaborates in his post, he is referring to the callback-based API commonly used in JavaScript in 2015, and he says that async/await syntax resolves this problem:</p> <blockquote> <p>[Async/await] lets you make asynchronous calls just as easily as you can synchronous ones, with the tiny addition of a cute little keyword. You can nest <code>await</code> calls in expressions, use them in exception handling code, stuff them inside control flow.</p> </blockquote> <p>Of course, he also says this, which is the crux of the argument about the &ldquo;function coloring problem&rdquo;:</p> <blockquote> <p><em>But…</em> you still have divided the world in two. Those async functions are easier to write, but <em>they’re still async functions.</em></p> <p>You’ve still got two colors. Async-await solves annoying rule #4: they make red functions not much worse to call than blue ones. But all of the other rules are still there.</p> </blockquote> <p>Futures represent asynchronous operations differently from synchronous operations. For Eriksen, this provides additional affordances which are the key advantage of futures. For Nystrom, this is just an another hurdle to calling functions which return futures instead of blocking.</p> <p>As you might expect if you&rsquo;re familiar with this blog, I fall pretty firmly on the side of Eriksen. So it has not been easy on me to find that Nystrom&rsquo;s views have been much more popular with the sort of people who comment on Hacker News or write angry, over-confident rants on the internet. A few months ago I wrote a <a href="https://without.boats/blog/why-async-rust">post</a> exploring the history of how Rust came to have the futures abstraction and async/await syntax on top of that, as well as a follow-up <a href="https://without.boats/blog/a-four-year-plan">post</a> describing the features I would like to see added to async Rust to make it easier to use.</p> <p>Now I would like to take a step back and re-examine the design of async Rust in the context of this question about the utility of the futures model of concurrency. What has the use of futures actually gotten us in async Rust? I would like us to imagine that there could be a world in which the difficulties of using futures have been mitigated or resolved &amp; the additional affordances they provide make async Rust not only just as easy to use as non-async Rust, but actually a <em>better</em> experience overall.</p>

poll_progress
12. Dec 2023 01:00
without.boats

<p>Last week, Tyler Mandry published an interesting <a href="https://tmandry.gitlab.io/blog/posts/for-await-buffered-streams/">post</a> about a problem that the Rust project calls &ldquo;Barbara battles buffered streams.&rdquo; Tyler does a good job explaining the issue, but briefly the problem is that the buffering adapters from the futures library (<code>Buffered</code> and <code>BufferUnordered</code>) do not interact well with <code>for await</code> if the processing in the body is asynchronous (i.e. if it contains any <code>await</code> expressions).</p> <p>I think we can better understand the problem if we examine it visually. First, let&rsquo;s consider the control flow that occurs when a user processes a normal, non-asynchronous <code>Iterator</code> using a for loop:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"> ┌── SOME ────────────────┐ </span></span><span class="line"><span class="cl"> ╔═══════════════╗ ╔═══════▼═══════╗ </span></span><span class="line"><span class="cl"> ║ ║▐▌ ║ ║▐▌ </span></span><span class="line"><span class="cl"> ──────▶ NEXT ║▐▌ ║ LOOP BODY ║▐▌ </span></span><span class="line"><span class="cl"> ║ ║▐▌ ║ ║▐▌ </span></span><span class="line"><span class="cl"> ╚════════════▲══╝▐▌ ╚═══════════════╝▐▌ </span></span><span class="line"><span class="cl"> ▀▀│▀▀▀▀▀▀▀▀▀│▀▀▀▀▘ ▀▀▀▀▀▀▀│▀▀▀▀▀▀▀▀▀▘ </span></span><span class="line"><span class="cl"> │ └───────────────────┘ </span></span><span class="line"><span class="cl"> └── NONE ──────────────────────────────▶ </span></span></code></pre></div><p>The for loop first calls the iterator&rsquo;s <code>next</code> method, and then passes the resulting item (if there is one) to the loop body. When there are no more items, it exits the loop.</p>

Ghostty Devlog 005
06. Dec 2023 01:00
mitchellh.com
Three problems of pinning
30. Nov 2023 01:00
without.boats

<p>When we developed the <a href="https://doc.rust-lang.org/std/pin/struct.Pin.html">Pin</a> API, our vision was that &ldquo;ordinary users&rdquo; - that is, users using the &ldquo;high-level&rdquo; <a href="https://without.boats/blog/the-registers-of-rust/">registers</a> of Rust, would never have to interact with it. We intended that only users implementing Futures by hand, in the &ldquo;low-level&rdquo; register, would have to deal with that additional complexity. And the benefit that would accrue to all users is that futures, being immovable while polling, could store self-references in their state.</p> <p>Things haven&rsquo;t gone perfectly according to plan. The benefits of <code>Pin</code> have certainly been accrued - everyone is writing self-referential async functions all the time, and low-level concurrency primitives in all the major runtimes take advantage of <code>Pin</code> to implement intrusive linked lists internally. But <code>Pin</code> still sometimes rears its ugly head into &ldquo;high-level&rdquo; code, and users are unsurprisingly frustrated and confused when that happens.</p> <p>In my experience, there a three main ways that this happens. Two of them can be solved by better affordances for <code>AsyncIterator</code> (a part of why I have been pushing stabilizing this so hard!). The third is ultimately because of a mistake that we made when we designed <code>Pin</code>, and without a breaking change there&rsquo;s nothing we could about it. They are:</p> <ol> <li>Selecting a <code>Future</code> in a loop.</li> <li>Calling <code>Stream::next</code>.</li> <li>Awaiting a <code>Future</code> behind a pointer (e.g. a boxed future).</li> </ol>

Coroutines, asynchronous and iterative
29. Nov 2023 01:00
without.boats

<p>I wanted to follow up my <a href="https://without.boats/blog/poll-next">previous post</a> with a small note elaborating on the use of coroutines for asynchrony and iteration from a more abstract perspective. I realized the point I made about <code>AsyncIterator</code> being the product of <code>Iterator</code> and <code>Future</code> makes a bit more sense if you also consider the &ldquo;base case&rdquo; - a block of code that is neither asynchronous nor iterative.</p> <p>It&rsquo;s also an excuse to draw another fun ASCII diagram, and I&rsquo;ve got to put that Berkeley Mono license to good use.</p>

Designing a SIMD Algorithm from Scratch
27. Nov 2023 01:00
mcyoung.xyz
poll_next
27. Nov 2023 01:00
without.boats

<p>In my previous <a href="https://without.boats/blog/a-four-year-plan/">post</a>, I said that the single best thing the Rust project could do for users is stabilize <a href="https://doc.rust-lang.org/std/async_iter/trait.AsyncIterator.html">AsyncIterator</a>. I specifically meant the interface that already exists in the standard library, which uses a method called <code>poll_next</code>. Ideally this would have happened years ago, but the second best time would be tomorrow.</p> <p>The main thing holding up the <code>AsyncIterator</code> stabilization is a commitment by some influential contributors of the project to pursue an alternative design. This design, which I&rsquo;ll call the &ldquo;async next&rdquo; design, proposes to use an async method for the interface instead of the poll method of the &ldquo;poll next&rdquo; design implemented today. In my opinion, continuing to pursue this design is a mistake. I&rsquo;ve written about this <a href="https://without.boats/blog/async-iterator/">before</a>, but I don&rsquo;t have the sense my post was fully received by the Rust project.</p> <p>Yosh Wuyts, a leading contributor to the async working group, has written his own <a href="https://blog.yoshuawuyts.com/async-iterator-trait">post</a> about why the async next design is preferable to poll next. A lot of this is structured as an attempted refutation of points made by me and others about problems with the async next design. I do not find the argument in this post compelling, and my position about what the project should do is unchanged. I&rsquo;ve written this to attempt to express again, in more detail and more definitively, why I believe the project should accept the poll next design and stabilize <code>AsyncIterator</code> now.</p>

A four year plan for async Rust
07. Nov 2023 01:00
without.boats

<p>Four years ago today, the Rust async/await feature was released in version 1.39.0. The announcement <a href="https://blog.rust-lang.org/2019/11/07/Async-await-stable.html">post</a> says that &ldquo;this work has been a long time in development &ndash; the key ideas for zero-cost futures, for example, were first proposed by Aaron Turon and Alex Crichton in 2016&rdquo;. It&rsquo;s now been longer since the release of async/await than the time between the first design work on futures and the release of async/await syntax. Despite this, and despite the fact that async/await syntax was explicitly shipped as a &ldquo;minimum viable product,&rdquo; the Rust project has shipped almost no extensions to async/await in the four years since the MVP was released.</p> <p>This fact has been noticed, and I contend it is the primary controllable reason that async Rust has developed a negative reputation (other reasons, like its <a href="https://without.boats/blog/why-async-rust">essential complexity</a>, are not in the project&rsquo;s control). It&rsquo;s encouraging to see project leaders like Niko Matsakis <a href="https://smallcultfollowing.com/babysteps/blog/2023/10/14/eurorust-reflections/">recognize</a> the problem as well. I want to outline the features that I think async Rust needs to continue to improve its user experience. I&rsquo;ve organized these features into features that I think the project could ship in the short term (say, in the next 18 months), to those that will take longer (up to three years), and finally a section on a potential change to the language that I think would take years to plan and prepare for.</p>

Why async Rust?
15. Oct 2023 02:00
without.boats

<p>Async/await syntax in Rust was initially released to much fanfare and excitement. To quote <a href="https://news.ycombinator.com/item?id=21473418">Hacker News</a> at the time:</p> <blockquote> <p>This is going to open the flood gates. I am sure lot of people were just waiting for this moment for Rust adoption. I for one was definitely in this boat.</p> <p>Also, this has all the goodness: open-source, high quality engineering, design in open, large contributors to a complex piece of software. Truly inspiring!</p> </blockquote> <p>Recently, the reception has been a bit more mixed. To a quote a comment on <a href="https://news.ycombinator.com/item?id=37436413">Hacker News</a> again, discussing a recent blog post on the subject:</p> <blockquote> <p>I genuinely can&rsquo;t understand how anybody could look at the mess that&rsquo;s Rust&rsquo;s async and think that it was a good design for a language that already had the reputation of being very complicated to write.</p> <p>I tried to get it, I really did, but my god what a massive mess that is. And it contaminates everything it touches, too. I really love Rust and I do most of my coding in it these days, but every time I encounter async-heavy Rust code my jaw clenches and my vision blurs.</p> </blockquote> <p>Of course, neither of these comments are completely representative: even four years ago, some people had pointed concerns. And in the same thread as this comment about jaws clenching and vision blurring, there were many people defending async Rust with equal fervor. But I don&rsquo;t think I would be out of pocket to say that the nay-sayers have grown more numerous and their tone more strident as time has gone on. To some extent this is just the natural progression of the hype cycle, but I also think as we have become more distant from the original design process, some of the context has been lost.</p> <p>Between 2017 and 2019, I drove the design of async/await syntax, in collaboration with others and building on the work of those who came before me. Forgive me if I am put a bit off when someone says that they don&rsquo;t know how anyone could look at that &ldquo;mess&rdquo; and &ldquo;think that it was a good design,&rdquo; and please indulge me in this imperfectly organized and overly long explanation of how async Rust came to exist, what its purpose was, and why, in my opinion, for Rust there was no viable alternative. I hope that along the way I might shed more light on the design of Rust in a broader and deeper sense, at least slightly, and not merely regurgitate the justifications of the past.</p>

Thread-per-core
06. Oct 2023 02:00
without.boats

<p>I want to address a controversy that has gripped the Rust community for the past year or so: the choice by the prominent async &ldquo;runtimes&rdquo; to default to multi-threaded executors that perform work-stealing to balance work dynamically among their many tasks. Some Rust users are <a href="https://maciej.codes/2022-06-09-local-async.html">unhappy</a> with this decision, so unhappy that they use language I would characterize as melodramatic:</p> <blockquote> <p>The Original Sin of Rust async programming is making it multi-threaded by default. If premature optimization is the root of all evil, this is the mother of all premature optimizations, and it curses all your code with the unholy <code>Send + 'static</code>, or worse yet <code>Send + Sync + 'static</code>, which just <em>kills all the joy of actually writing Rust</em>.</p> </blockquote> <p>It&rsquo;s always off-putting to me that claims written this way can be taken seriously as a technical criticism, but our industry is rather unserious.</p>

Grapheme Clusters and Terminal Emulators
02. Oct 2023 02:00
mitchellh.com
Reorient GitHub Pull Requests Around Changesets
30. Sep 2023 02:00
mitchellh.com
What is a Matrix? A Miserable Pile of Coefficients!
29. Sep 2023 02:00
mcyoung.xyz
Ghostty Devlog 004
28. Sep 2023 02:00
mitchellh.com
Generic trait methods and new auto traits
20. Sep 2023 02:00
without.boats

<p>I want to wrap up my consideration of the idea of adding new auto traits to Rust with some notes from a conversation I had with Ariel Ben-Yehuda.</p> <p>You can read these two previous posts for context:</p> <ul> <li><a href="https://without.boats/blog/changing-the-rules-of-rust">Changing the rules of Rust</a></li> <li><a href="https://without.boats/blog/follow-up-to-changing-the-rules-of-rust">Follow up to &ldquo;Changing the rules of Rust&rdquo;</a></li> </ul>

Follow up to "Changing the rules of Rust"
18. Sep 2023 02:00
without.boats

<p>In <a href="https://without.boats/blog/changing-the-rules-of-rust">my previous post</a>, I described the idea of using an edition mechanism to introduce a new auto trait. I wrote that the compiler would need to create an &ldquo;unbreakable firewall&rdquo; to prevent using <code>!Leak</code> types from the new edition with code from the old edition that assumes values of all types can be leaked.</p> <p>The response has been pretty optimistic that ensuring this would be possible, even though I wrote in the post myself that I &ldquo;despair&rdquo; over how difficult it was. I&rsquo;ve received a great example from Ariel Ben-Yehuda which demonstrates how this problem is more difficult to solve than you would probably think.</p>

Changing the rules of Rust
17. Sep 2023 02:00
without.boats

<p>In Rust, there are certain API decisions about what is and isn&rsquo;t sound that impact all Rust code. That is, a decision was made to allow or not allow types which have certain safety requirements, and now all users are committed to that decision. They can&rsquo;t just use a different API with different rules: <em>all</em> APIs must conform to these rules.</p> <p>These rules are determined through certain &ldquo;marker&rdquo; traits. If a safe API could do something to a value of a type which some types don&rsquo;t support, the API must be bound by that marker trait, so that users can not pass values of those types which don&rsquo;t support that behavior to that API. In contrast, if Rust allows APIs to perform that behavior on any type, without any sort of marker trait bound, then types which don&rsquo;t support that behavior cannot exist.</p> <p>I&rsquo;m going to give three examples to show what I mean, each of which Rust has considered at different points, though only the first one actually exists in Rust.</p>

Talk: Introducing Ghostty and Some Useful Zig Patterns
12. Sep 2023 02:00
mitchellh.com
Ghostty Devlog 003
24. Aug 2023 02:00
mitchellh.com
I Wrote A String Type
09. Aug 2023 02:00
mcyoung.xyz
Ghostty Devlog 002
05. Aug 2023 02:00
mitchellh.com
A Gentle Introduction to LLVM IR
01. Aug 2023 02:00
mcyoung.xyz
Ghostty Devlog 001
13. Jul 2023 02:00
mitchellh.com
My Approach to Building Large Technical Projects
01. Jun 2023 02:00
mitchellh.com
A governance system, if you can keep it
27. May 2023 02:00
without.boats

<p>One of the most famous anecdotes that forms the basis of the United States&rsquo; political self-identity is the story of an interaction between Benjamin Franklin and Elizabeth Willing Powel after the Constitutional Convention of 1787, which established the United States&rsquo; present form of government. Powel asked Franklin what sort of government the U.S. was to have, to which he replied: <strong>&ldquo;a republic, if you can keep it.&rdquo;</strong></p> <p>Given the self-conscious references to &ldquo;constitutions&rdquo; and &ldquo;checks and balances&rdquo; in the Rust project&rsquo;s recent <a href="https://github.com/rust-lang/rfcs/pull/3392">governance RFC</a> and the discourse around it, some further reflection on this quote and its implications about governance as such might now be appropriate for the project and its community.</p>

Integrating Zig and SwiftUI
27. May 2023 02:00
mitchellh.com
Single Abstract Method Traits
11. May 2023 02:00
mcyoung.xyz
Iterator, Generator
06. May 2023 02:00
without.boats

<p>I have been devoting a lot of my free time in the past month to thinking about structured concurrency, and a blog post about that is coming soon, but first I want to revisit iterators and generators.</p> <p>In <a href="https://without.boats/blog/generators">a previous post</a>, I wrote about one of the hardest problems for generators: self-referential generators. Unlike the Future trait when we were designing async functions, the Iterator trait is already stable, and it does not take a pinned reference to itself. This means an Iterator cannot be self-referential.</p>

Prompt Engineering is for Transactional Prompting
24. Apr 2023 02:00
mitchellh.com
Using Nix with Dockerfiles
23. Apr 2023 02:00
mitchellh.com
Prompt Engineering vs. Blind Prompting
14. Apr 2023 02:00
mitchellh.com
The Scoped Task trilemma
08. Apr 2023 02:00
without.boats

<p>This is the first post in a series of posts about concurrency in Rust, and the different APIs that can exist to support it. Unlike my recent series on control-flow effects, this series isn’t driving toward any particular vision of what I think the Rust project should do. Instead, I am just trying to publicly explore the problem space and build tools for thinking about the issues involved. I’m not sure what the “right” concurrency API is.</p>

Better Trait Resolution in Rust
04. Apr 2023 02:00
mcyoung.xyz
Growth of AI Through a Cloud Lens
04. Apr 2023 02:00
mitchellh.com
Atomicless Concurrency
29. Mar 2023 02:00
mcyoung.xyz
Generators
26. Mar 2023 01:00
without.boats

<p>One of the main emphases of my recent posts has been that I believe shipping generators would solve a lot of user problems by making it easy to write imperative iterative code, and especially to make that iterative code interact well with asynchrony and fallibility as well. One thing that frustrates me about the situation is that generators have been nearly ready to ship for years now, but very little visible progress has been made. In particular, the core compiler transform to take a generator and produce a state machine already exists, because it’s exactly how async functions are implemented.</p>

The AsyncIterator interface
22. Mar 2023 01:00
without.boats

<p>In <a href="https://without.boats/blog/the-registers-of-rust">a previous post</a>, I established the notion of “registers” - code in Rust can be written in different registers, and it’s important to adequately support all registers. I specifically discussed the low-level interface of the AsyncIterator trait, about which there is currently a debate. The interface it currently has is a method called <code>poll_next</code>, which is a “poll” method like <code>Future::poll</code>. Poll methods are very “low-level” and are harder to write correctly than async functions. Some people would like to see <code>AsyncIterator</code> shifted to have an async next method, simply the “asyncified” <code>Iterator</code> trait.</p>

Const as an auto trait
16. Mar 2023 01:00
without.boats

<p>The previous two posts in this series tried to discuss the design of Rust through the lens of some higher level language concepts:</p> <ul> <li>First, the notion that programming languages have different <a href="https://without.boats/blog/the-registers-of-rust">registers</a></li> <li>Second, the idea that not all <a href="https://without.boats/blog/patterns-and-abstractions">patterns</a> should be made into abstractions</li> </ul> <p>This post does not introduce any such high-minded concept. It is entirely down in the weeds. That’s partly because it is based on content I removed from the previous post so that post could focus on the higher point.</p>

Patterns & Abstractions
14. Mar 2023 01:00
without.boats

<p>This is the second post in an informal series commenting on the design of async Rust in 2023. In <a href="https://without.boats/blog/the-registers-of-rust">my previous post</a>, after a discussion of the “registers” in which control-flow effects could be handled in Rust, I promised to turn my attention to recent proposals around a concept called “keyword generics.” For reference, there are two posts by the current design team of Rust that are my reference point for this commentary:</p> <ul> <li><strong><a href="https://blog.rust-lang.org/inside-rust/2023/02/23/keyword-generics-progress-report-feb-2023.html">Keyword Generics Progress Report: February 2023</a></strong>, a status update from the group working on “keyword generics”</li> <li><strong><a href="https://smallcultfollowing.com/babysteps/blog/2023/03/03/trait-transformers-send-bounds-part-3/">Trait transformers (send bounds, part 3)</a></strong>, a blog post about a related idea by Niko Matsakis</li> </ul> <p>I’m not going to reiterate these blog posts at length, but in brief “keyword generics” is a proposal to introduce a new kind of abstraction to Rust, to allow types to be abstracted over certain effects. The examples have focused on <code>async</code> and <code>const</code> as the effects, but there is sometimes discussion of <code>try</code> as well. Astute readers will notice this is an overlapping but not identical set of effects to the effects I identified in my last post; I did not mention <code>const</code> as an effect, and as far as I know the keyword generics working group has not devoted much or any time to considering iteration as an effect.</p>

My Startup Banking Story
14. Mar 2023 01:00
mitchellh.com
The registers of Rust
08. Mar 2023 01:00
without.boats

<p>It’s been nearly two and half years since I was an active contributor to the Rust project. There are some releases that I’ve been very excited about since then, and I’m heartened by <a href="http://smallcultfollowing.com/babysteps/blog/2023/01/20/rust-in-2023-growing-up/">Niko’s recent blog post</a> emphasizing stability and polish over grand new projects. But I’ve also felt a certain apprehension at a lot of the directions the project has taken, which has often occupied my thoughts. From that preoccupation this blog post has emerged, hopefully the first in a series over the next few weeks outlining my thoughts on the design of Rust in 2023, especially in connection to async, and I hope its impact will be chiefly positive.</p>

3Hz Computer, Hold the Transistors
24. Jul 2022 02:00
mcyoung.xyz
std::tuple the Hard Way
13. Jul 2022 02:00
mcyoung.xyz
The Alkyne GC
07. Jun 2022 02:00
mcyoung.xyz
Contributing to Complex Projects
13. Mar 2022 01:00
mitchellh.com
Zig Build System Internals
24. Feb 2022 01:00
mitchellh.com
Zig Sema: ZIR => AIR
13. Feb 2022 01:00
mitchellh.com
Zig AstGen: AST => ZIR
12. Feb 2022 01:00
mitchellh.com
Zig Parser
11. Feb 2022 01:00
mitchellh.com
Zig Tokenizer
10. Feb 2022 01:00
mitchellh.com
Move Constructors Revisited
19. Dec 2021 01:00
mcyoung.xyz
Understanding Assembly Part I: RISC-V
29. Nov 2021 01:00
mcyoung.xyz
Everything You Never Wanted To Know About Linker Script
01. Jun 2021 02:00
mcyoung.xyz
The Taxonomy of Pointers
24. May 2021 02:00
mcyoung.xyz
Move Constructors in Rust: Is it possible?
26. Apr 2021 02:00
mcyoung.xyz
Ringbahn III: A deeper dive into drivers
01. Oct 2020 02:00
without.boats

<p>In <a href="../ringbahn-ii">the previous post</a> in this series, I wrote about how the core state machine of <a href="https://github.com/ringbahn/ringbahn">ringbahn</a> is implemented. In this post I want to talk about another central concept in ringbahn: <strong>&ldquo;drivers&rdquo;</strong>, external libraries which determine how ringbahn schedules IO operations over an io-uring instance.</p>

Revisiting a 'smaller Rust'
30. Sep 2020 02:00
without.boats

<p>A bit over a year ago, I wrote some <a href="../notes-on-a-smaller-rust">notes on a &ldquo;smaller Rust&rdquo;</a> - a higher level language that would take inspiration from some of Rust&rsquo;s type system innovations, but would be simpler by virtue of targeting a domain with less stringent requirements for user control and performance. During my time of unemployment this year, I worked on sketching out what a language like that would look like in a bit more detail. I wanted to write a bit about what new conclusions I&rsquo;ve come to during that time.</p>

iou version 0.3 released
22. Sep 2020 02:00
without.boats

<p>Today I made a new release of the <a href="https://github.com/ringbahn/iou">iou</a> library, which contains idiomatic Rust bindings to the <a href="https://github.com/axboe/liburing">liburing</a> library. This library allows users to manipulate the new <a href="https://kernel.dk/io_uring.pdf">io-uring</a> interface for asynchronous IO on Linux. For more context, you can read <a href="https://without.boats/blog/iou">my previous post on the first release of iou last year</a>.</p> <p>This new release greatly expands the API of iou, introduces some valuable improvements, and contains some breakages. I figured I would let this blog post serve as some basic release notes.</p>

Propane: an experimental generator syntax for Rust
06. Aug 2020 02:00
without.boats

<p>I&rsquo;ve just released a new crate called <a href="https://crates.io/crates/propane">propane</a>, which is a library for writing <strong>generator functions</strong>. It can only run on nightly:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="cp">#![feature(generators, generator_trait, try_trait)]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[propane::generator]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span> <span class="nf">fizz_buzz</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nb">String</span> <span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">..</span><span class="mi">101</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mi">3</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="mi">5</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kr">yield</span><span class="w"> </span><span class="nb">String</span>::<span class="n">from</span><span class="p">(</span><span class="s">&#34;FizzBuzz&#34;</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kr">yield</span><span class="w"> </span><span class="nb">String</span>::<span class="n">from</span><span class="p">(</span><span class="s">&#34;Fizz&#34;</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kr">yield</span><span class="w"> </span><span class="nb">String</span>::<span class="n">from</span><span class="p">(</span><span class="s">&#34;Buzz&#34;</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="kr">yield</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div>

Shipping Const Generics in 2020
16. Jul 2020 02:00
without.boats

<p>It&rsquo;s hard to believe that its been more than 3 years since I opened <a href="https://github.com/rust-lang/rfcs/pull/2000">RFC 2000</a>, which defined the const generics for Rust. At the same time, reading the RFC thread, there&rsquo;s also been a huge amount of change in this area: for one thing, at the time the RFC was written, const fns weren&rsquo;t stable, and consts weren&rsquo;t even being evaluated using miri yet. There&rsquo;s been a lot of work over the years on the const generics feature, but still nothing has shipped. However, I think we have defined a very useful subset of const generics which is stable enough to ship in the near term.</p>

Ringbahn II: the central state machine
02. Jul 2020 02:00
without.boats

<p><a href="../ringbahn">Last time</a> I wrote about <a href="https://github.com/withoutboats/ringbahn">ringbahn</a>, a safe API for using io-uring from Rust. I wrote that I would soon write a series of posts about the mechanism that makes ringbahn work. In the first post in that series, I want to look at the core state machine of ringbahn which makes it memory safe. The key types involved are the <a href="https://docs.rs/ringbahn/0.0.0-experimental.3/ringbahn/struct.Ring.html">Ring</a> and <a href="https://docs.rs/crate/ringbahn/0.0.0-experimental.3/source/src/completion.rs">Completion</a> types.</p>

Two Memory Bugs From Ringbahn
10. Jun 2020 02:00
without.boats

<p>While implementing <a href="https://github.com/withoutboats/ringbahn">ringbahn</a>, I introduced at least two bugs that caused memory safety errors, resulting in segfaults, allocator aborts, and bizarre undefined behavior. I&rsquo;ve fixed both bugs that I could find, and now I have no evidence that there are more memory safety issues in the current codebase (though that doesn&rsquo;t mean there aren&rsquo;t, of course). I wanted to write about both of these bugs, because they had an interesting thing in common: they were both caused by destructors.</p>

Futures and Segmented Stacks
08. Jun 2020 02:00
without.boats

<p>This is just a note on getting the best performance out of an async program.</p> <p>The point of using async IO over blocking IO is that it gives the user program more control over handling IO, on the premise that the user program can use resources more effectively than the kernel can. In part, this is because of the inherent cost of context switching between the userspace and the kernel, but in part it is also because the user program can be written with more specific understanding of its exact requirements.</p>

Ringbahn: a safe, ergonomic API for io-uring in Rust
27. May 2020 02:00
without.boats

<p>In <a href="../io-uring">my previous post,</a> I discussed the new io-uring interface for Linux, and how to create a safe API for using io-uring from Rust. In the time since that post, I have implemented a prototype of such an API. The crate is called <a href="https://github.com/withoutboats/ringbahn"><strong>ringbahn</strong></a>, and it is intended to enable users to perform IO on io-uring without any risk of memory unsafety.</p>

Notes on io-uring
06. May 2020 02:00
without.boats

<p>Last fall I was working on a library to make a safe API for driving futures on top of an an io-uring instance. Though I released bindings to liburing called <a href="https://github.com/withoutboats/iou">iou</a>, the futures integration, called ostkreuz, was never released. I don&rsquo;t know if I will pick this work up again in the future but several different people have started writing other libraries with similar goals, so I wanted to write up some notes on what I learned working with io-uring and Rust&rsquo;s futures model. This post assumes some level of familiarity with the io-uring API. A high level overview is provided in <a href="https://kernel.dk/io_uring.pdf">this document</a>.</p>

The problem of effects in Rust
13. Apr 2020 02:00
without.boats

<p>In <a href="https://without.boats/blog/why-ok-wrapping/">a previous post</a>, I shortly discussed the concept of &ldquo;effects&rdquo; and the parallels between them. In an unrelated post since then, <a href="https://blog.yoshuawuyts.com/fallible-iterator-adapters/">Yosh Wuyts</a> writes about the problem of trying to write fallible code inside of an iterator adapter that doesn&rsquo;t support it. In a <a href="https://internals.rust-lang.org/t/idea-non-local-control-flow/11976">previous discussion</a>, the users of the Rust Internals forum hotly discuss the notion of closures which would maintain the so-called <a href="https://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html">&ldquo;Tennant&rsquo;s Correspondence Principle&rdquo;</a> - that is, closures which support breaking to scopes outside of the closure, inside of the function they are in (you can think of this is closures capturing their control flow environment in addition to capturing variables).</p> <p>I think it may not be obvious, but these discussions are all deeply related. They all arise from what is, in my opinion, one of the biggest problems with the design of the Rust language: its failure at 1.0 to give good support for handling common effects related to program control flow.</p>

A brief apology of Ok-Wrapping
07. Apr 2020 02:00
without.boats

<p>I&rsquo;ve <em>long</em> been a proponent of having some sort of syntax in Rust for writing functions which return results which &ldquo;ok-wrap&rdquo; the happy path. This is has also always been a feature with very vocal, immediate, and even emotional opposition from many of our most enthusiastic users. I want to write, in one place, why I think this feature would be awesome and make Rust much better.</p> <p>I don&rsquo;t want to get into the details too much of the specific proposal, but here&rsquo;s a sketch of one way this <em>could</em> work (there are a number of variables). We would add a syntactic modifier to the signature of a function, like this:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="nc">throws</span><span class="w"> </span><span class="n">io</span>::<span class="n">Error</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">//.. </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div><p>This function returns <code>Result&lt;usize, io::Error&gt;</code>, but internally the <code>return</code> expressions return a value of type <code>usize</code>, not the Result type. They are &ldquo;Ok-wrapped&rdquo; into being <code>Ok(usize)</code> automatically by the language. If users wish to throw an error, a new <code>throw</code> expression is added which takes the error side (the type after <code>throws</code> in the signature). The <code>?</code> operator would behave in this context the same way it behaves in a function that returns <code>Result</code>.</p>

From failure to Fehler
06. Apr 2020 02:00
without.boats

About two and a half years ago I wrote a Rust library called failure, which quickly became one of the most popular error handling libraries in Rust. This week, its current maintainer decided to deprecate it, a decision I strongly support. This week, I also released a new and very different error-handling library, called fehler. I wanted to discuss these two libraries briefly. A brief history of failure When I released failure, the most popular error handling library by far was error-chain.

What constitutes a vulnerability?
01. Apr 2020 02:00
without.boats

This is just a post about something that grinds my gears a bit more than it reasonably should: I think the habit of applying for CVEs for Rust (and Rust ecosystem libraries) is silly at best and harmful at worst. I think it muddies the waters about what a vulnerability is, and paints an overly negative picture of Rust&rsquo;s security situation that can only lead people to make inaccurate evaluations when contrasting it with other languages like C/C++.

waitmap - an async awaitable map
12. Mar 2020 01:00
without.boats

I&rsquo;ve just released a new crate called waitmap. This is a concurrent hash map (built on top of dashmap) intended for use as a concurrency primitive with async/await. It extends the API of dashmap by having an additional wait method. The wait future looks up an entry in the map and suspends this task if the entry was not present when wait was called. The task will be woken whenever a value is inserted under that key.

Global Executors
14. Nov 2019 01:00
without.boats

One of the big sources of difficulty on the async ecosystem is spawning tasks. Because there is no API in std for spawning tasks, library authors who want their library to spawn tasks have to depend on one of the multiple executors in the ecosystem to spawn a task, coupling the library to that executor in undesirable ways. Ideally, many of these library authors would not need to spawn tasks at all.

iou: Rust bindings for liburing
08. Nov 2019 01:00
without.boats

Today I&rsquo;m releasing a library called iou. This library provides idiomatic Rust bindings to the C library called liburing, which itself is a higher interface for interacting with the io_uring Linux kernel interface. Here are the answers to some questions I expect that may provoke. What is io_uring? io_uring is an interface added to the Linux kernel in version 5.1. Concurrent with that, the primary maintainer of that interface has also been publishing a library for interacting with it called liburing.

Asynchronous Destructors
16. Oct 2019 02:00
without.boats

The first version of async/await syntax is in the beta release, set to be shipped to stable in 1.39 on November 7, next month. There are a wide variety of additional features we could add to async/await in Rust beyond what we&rsquo;re shipping in that release, but speaking for myself I know that I&rsquo;d like to pump the breaks on pushing forward big ticket items in this space. Let&rsquo;s let the ecosystem develop around what we have now before we start sprinting toward more big additions to the language.

Notes on a smaller Rust
17. Jul 2019 02:00
without.boats

<p>Many people who use Rust for a bit - especially those who like the language but do not fall in love with it - feel a sense that there must be a smaller, simpler variation on the same theme which would maybe be a little less powerful, but would also be much easier to use. I agree with them, but I think they are almost always wrong about what would need to change. Here are some notes on where I would start to create that smaller Rust.</p>

Update on await syntax
28. May 2019 02:00
without.boats

In my previous post I said that the lang team would be making our final decision about the syntax of the await operator in the May 23 meeting. That was last Thursday, and we did reach a decision. In brief, we decided to go forward with the preliminary proposal I outlined earlier: a postfix dot syntax, future.await. For more background, in addition the previous post on my blog, you can read this write up about some of the trade offs from April.

Zero Cost Abstractions
16. May 2019 02:00
without.boats

The idea of a zero cost abstraction is very important to certain programming languages, like Rust and C++, which intend to enable users to write programs with excellent performance profiles with relatively little effort. Since this idea is fundamental to the design of Rust and my work, I want to investigate, for a moment, what exactly a zero cost abstraction even is. The idea is summarized in its original by Bjarne Stroustrup, the original developer of C++:

A final proposal for await syntax
06. May 2019 02:00
without.boats

This is an announcement regarding the resolution of the syntax for the await operator in Rust. This is one of the last major unresolved questions blocking the stabilization of the async/await feature, a feature which will enable many more people to write non-blocking network services in Rust. This post contains information about the timeline for the final decision, a proposal from the language team which is the most likely syntax to be adopted, and the justification for this decision.

for await loops (Part I)
15. Apr 2019 02:00
without.boats

The biggest unresolved question regarding the async/await syntax is the final syntax for the await operator. There&rsquo;s been an enormous amount of discussion on this question so far; a summary of the present status of that discussion and the positions within the language team is coming soon. Right now I want to separately focus on one question which impacts that decision but hasn&rsquo;t been considered very much yet: for loops which process streams.

Generators II: The Question Mark Problem
18. Feb 2019 01:00
without.boats

This is my second post on the design of generators. In the first post, I outlined what an MVP of the feature would look like. In this post, I want to take a look at the first design issue for the feature: how it integrates with the ? operator. To explain exactly what I mean, let&rsquo;s start with a specific motivating example: // This generator yields the number of alphanumeric characters in every line // in some io::Read&#39;able data // exact sign function declaration syntax left unspecified on purpose |data| { let mut buffered_data = BufReader::new(data); let mut string = String::new(); while buffered_data.

Generators I: Toward a minimum viable product
11. Feb 2019 01:00
without.boats

We&rsquo;re still not finished with the design of async/await, but it&rsquo;s already become clear that it&rsquo;s time to get the next phases of the feature into the pipeline. There are two extensions to the minimal async/await feature we&rsquo;ve currently got that seem like the clear high priority: Async methods: allowing async fn to be used in traits. Generators: allowing imperative control flow to create Iterators and Streams the same way async fn allows imperative control flow to create a Future.

The Waker API II: waking across threads
11. Jan 2019 01:00
without.boats

In the previous post, I provided a lot of background on what the waker API is trying to solve. Toward the end, I touched on one of the tricky problems the waker API has: how do we handle thread safety for the dynamic Waker type? In this post, I want to look at that in greater detail: what we&rsquo;ve been doing so far, and what I think we should do.

The Waker API I: what does a waker do?
07. Jan 2019 01:00
without.boats

Work on supporting async/await in Rust continues to progress rapidly. I&rsquo;m hoping to write a retrospective on everything that happened in 2018 in a few weeks. Right now we&rsquo;re closing in on an important milestone: stabilizing the futures API that will be used to interact programmatically with asynchronous computations. The biggest remaining area of work is the design of the waker API, an essential but somewhat opaque part of how our asynchronous programming system works.

Organizational Debt
16. Dec 2018 01:00
without.boats

We all know that classic aphorism: Year comes to an end, Rust blog post press send. This is mine. There are lots of cool technical improvements to Rust that I want the project to achieve this year, and a few in particular that I&rsquo;m definitely going to be putting a lot of time into. But this blog post is going to talk about none of them. Instead, I want to talk about organizational debt, and how badly the Rust project needs to deal with it in 2019.

Wherefore art thou Romio?
05. Dec 2018 01:00
without.boats

This blog post is about a project called Romio that I&rsquo;ve been working on over the past two or three weeks. Romio is a port of a small part of the Tokio project to the newer futures APIs. I started the project to get some experience porting code from the old futures API to the new API. However, we realized that this code could also be useful to other people who want to experiment with networking code using the new async/await syntax, so with the help of others we polished it up during the RustFest Rome &ldquo;impl days&rdquo; and now its being released for people to experiment with.

Making progress in await syntax
08. Nov 2018 01:00
without.boats

One thing we&rsquo;ve left as an unresolved question so far in the matter of async/await syntax is the exact final syntax for the await operation. In the current implementation, awaits are written using a compiler plugin: async fn foo() { await!(bar()); } This is not because of any technical limitation: the reason we have done this is that we have not decided on the precise, final syntax for the await operation.

Anchored and Uniform Paths
02. Nov 2018 01:00
without.boats

Rust 2018 is almost out the door, but there is one big decision the language team has yet to make. It has to do with the modules and paths system, so of course it is a very easy decision that no one has a strong opinion about. ;-) In Rust 2018, we&rsquo;ll be making some big changes to how paths work to try to create a more consistent experience. The &ldquo;lodestar&rdquo; (if you will) of these changes is an idea we call &ldquo;1path:&rdquo; the idea no matter where you are in your project, whether in a use statement or normal code, a path is interpreted the same way.

Shifgrethor IV: Tracing
31. Oct 2018 01:00
without.boats

The post before this one covered how shifgrethor handles rooting: how we track for the garbage collector that this object is alive. That isn&rsquo;t sufficient for implementing a tracing garbage collector though: the idea of a tracing garbage collector is that we can trace from rooted objects through all of the objects they reference. That way, instead of having to root everything you use, you can only root a few objects from which all of the live objects can be traced.

Shifgrethor III: Rooting
24. Oct 2018 02:00
without.boats

After the digression in the previous post, it&rsquo;s time to get back to what I promised in the first post: a look at how shifgrethor handles rooting. Shifgrethor&rsquo;s solution is somewhat novel and takes advantage of some of Rust&rsquo;s specific features, so I want to start by looking briefly at some of the other options. How to root a GC&rsquo;d object There are two broad categories of rooting strategies that are common among precise, tracing garbage collectors:

Shifgrethor II: Notes on tracing garbage collectors
22. Oct 2018 02:00
without.boats

In the previous post I said that in the second post in the series we&rsquo;d talk about how rooting works. However, as I sat down to write that post, I realized that it would be a good idea to back up and give an initial overview of how a tracing garbage collector works - and in particular, how the underlying garbage collector in shifgrethor is implemented. In the abstract, we can think of the memory of a Rust program with garbage collection as being divided into three sections: the stack, the &ldquo;unmanaged&rdquo; heap, and the &ldquo;managed&rdquo; heap.

Shifgrethor I: Garbage collection as a Rust library
16. Oct 2018 02:00
without.boats

I&rsquo;m really excited to share with you an experiment that I&rsquo;ve been working on for the past 5 or 6 weeks. It&rsquo;s a Rust library called shifgrethor. shifgrethor implements a garbage collector in Rust with an API I believe to be properly memory safe. I&rsquo;ll be going through all of the technical details in future blog posts, so I want to kick this series off with a high level overview of the project&rsquo;s purpose and design decisions.

The hard parts of talking about open source
16. Oct 2018 02:00
without.boats

<p><a href="https://twitter.com/czaplic">Evan Czaplicki</a>, the creator and maintainer of the <a href="https://elm-lang.org/">Elm project</a> (a project that I love by the way) gave a great talk at Strange Loop last month called &ldquo;The Hard Parts of Open Source.&rdquo; I really enjoyed and valued this talk, and I encourage everyone who is involved in open source to watch it. You can find on YouTube <a href="https://www.youtube.com/watch?v=o_4EX4dPppA">here</a>.</p> <p>In particular, I got a lot of value out of his identification of three specific harmful patterns of behavior in the open source community, and of his geneological work tracing the origins of those behaviors through the history of the &ldquo;hacker&rdquo; subculture. I think I&rsquo;m going to be utilising these patterns a lot when trying to understand unpleasant interactions I have in connection with my open source work.</p> <p>In case some readers decide not to watch Evan&rsquo;s talk, I want to highlight those three patterns here:</p> <ol> <li><strong>&ldquo;Why don&rsquo;t you just..&rdquo;</strong> People sometimes propose solutions to problems that are very obvious, but have nuanced and non-obvious problems. Often, these proposals are made with an intonation that the project maintainers - who have thought about the domain a great deal more than the person making the proposal - have completely overlooked this obvious solution.</li> <li><strong>&ldquo;On whose authority?&rdquo;</strong> People sometimes will attempt to subvert and undermine the authority of project leadership. Sometimes they go as far as suggesting ulterior, untoward motivation for decision-making (usually having to do with the project&rsquo;s financial sponsor). Sometimes they undermine the competence and capabilities of people leading the project.</li> <li><strong>&ldquo;All discussion is constructive.&rdquo;</strong> While the previous two patterns were forms of outright attack on project maintainers, this pattern is more subtle. It is the attitude which ignores the negative externalities of discussion, the way that producing more discussion content can be harmful to the project&rsquo;s goals. Sometimes it goes so far as to say that discussion containing negative behavioral patterns is still constructivebecause behind the attacks there might be good ideas.</li> </ol> <p>As I&rsquo;ve said, I think Evan&rsquo;s talk is quite good and worth watching, but I do have an objection, which is why I&rsquo;ve written out this whole blog post. In the final segment of the talk, it shifts from disecting these social phenomena into a sketch of a proposed discussion platform designed with the goal of producing more positive discussions.</p>

New crate: pin-cell
09. Oct 2018 02:00
without.boats

Today I realized a new crate called pin-cell. This crate contains a type called PinCell, which is a kind of cell that is similar to RefCell, but only can allow pinned mutable references into its interior. Right now, the crate is nightly only and no-std compatible. How is the API of PinCell different from RefCell? When you call borrow_mut on a RefCell, you get a type back that implements DerefMut, allowing you to mutate the interior value.

Thinking about names, as well as scuba diving
10. Sep 2018 02:00
without.boats

There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors. Naming a project, tool, or concept that you want other people to use is a very hard problem. The most important thing, of course, is that the name sounds cool. Then, significantly less important, but still quite important, is that the name convey useful information to your users. This is where things get tricky. There are tons of different kinds of cool birds and sharks and reptiles we can name our projects after, but only some of those names also convey information to our users.

Another look at the pinning API
22. Aug 2018 02:00
without.boats

A few months ago we introduced the concept of &ldquo;pinned&rdquo; references - pointers which &ldquo;pin&rdquo; the data they refer to in a particular memory location, guaranteeing that it will never move again. These are an important building block for certain patterns that had previously been hard for Rust to handle, like self-referential structs and intrusive lists, and we&rsquo;ve in the process of considering stabilizing the API. One thing has always nagged about the API we have right now though: the proliferation of different reference types that it implies.

My experience with the Rust 2018 preview
24. Jul 2018 02:00
without.boats

Recently, I wrote a little a side project to sign git commits without gpg. When I did this, I decided to use the Rust 2018 edition. I also transitioned an existing library from Rust 2015 to Rust 2018 to see how that tooling worked. I thought I&rsquo;d write a blog post about my experience using the Rust 2018 preview and the state of things right now. Module changes The main thing I noticed vividly was the new experience of the module system.

Signing my git commits without GPG
23. Jul 2018 02:00
without.boats

Unlike most git users, I try to sign my commits. Unfortunately, the only way to do this right now is to use PGP signatures, because that is all that git is able to integrate with. This has meant that in practice I have to use GPG if I want to sign my commits, an experience I do not relish. Last week, I wrote a program to replace GPG for that purpose.

Async Methods II: object safety
04. Jun 2018 02:00
without.boats

Last time, we introduced the idea of async methods, and talked about how they would be implemented: as a kind of anonymous associated type on the trait that declares the method, which corresponds to a different, anonymous future type for each implementation of that method. Starting this week we&rsquo;re going to look at some of the implications of that. The first one we&rsquo;re going to look at is object safety.

Async Methods I: generic associated types
31. May 2018 02:00
without.boats

Async/await continues to move along swimmingly. We&rsquo;ve accepted an RFC describing how the async/await syntax will work in Rust, and work is underway on implementing support for it in the compiler. We&rsquo;re hopeful that users will be able to start experimenting with the syntax on nightly by early July. The RFC for async/await didn&rsquo;t address one important thing: async methods. It is very important for people defining libraries to be able to define traits that contain async functions, like this:

Async & Await in Rust: a full proposal
06. Apr 2018 02:00
without.boats

<p>I&rsquo;m really excited to announce the culmination of much of our work over the last four months: a pair of RFCs for supporting async &amp; await notation in Rust. This will be very impactful for Rust in the network services space. The change is proposed as two RFCs:</p> <ul> <li><strong><a href="https://github.com/rust-lang/rfcs/pull/2394">RFC #2394:</a></strong> which adds async &amp; await notation to the language.</li> <li><strong><a href="https://github.com/rust-lang/rfcs/pull/2395">RFC #2395:</a></strong> which moves a part of the futures library into std to support that syntax.</li> </ul> <p>These RFCs will enable basic async &amp; await syntax support with the full range of Rust features - including borrowing across yield points. The rest of this blog post just covers the answers to some anticipated frequently asked questions; for more details see the two RFCs.</p>

Async/Await VI: 6 weeks of great progress
20. Mar 2018 01:00
without.boats

It&rsquo;s hard to believe its been almost 6 weeks since the last post I made about async/await in Rust. So much has happened that these last several weeks have flown by. We&rsquo;ve made exceptionally good progress on solving the problem laid out in the first post of this series, and I want to document it all for everyone. Future and the pinning API Last month I wrote an RFC called &ldquo;Standard library API for immovable types&rdquo;.

Failure 1.0.0 on March 15
22. Feb 2018 01:00
without.boats

I&rsquo;m planning to release a 1.0.0 version of failure on March 15. Once this happens, I don&rsquo;t plan to release any further breaking changes to the failure crate (though maybe someday in the distant future). Breaking changes in 1.0 failure is in a somewhat unique position as being a significant part of the public API of other libraries that depend on it. Whether they use the Error struct or derive Fail for a custom error type, this becomes a part of the API they expose to other users.

Async/Await V: Getting back to the futures
08. Feb 2018 01:00
without.boats

Two posts ago I proposed a particular interface for shipping self-referential generators this year. Immediately after that, eddyb showed me a better interface, which I described in the next post. Now, to tie everything together, its time to talk about how we can integrate this into the futures ecosystem. Starting point: this Generator API To begin, I want to document the generator API I&rsquo;ll be using in this post, which is roughly what followed from my previous post:

Async/Await IV: An Even Better Proposal
07. Feb 2018 01:00
without.boats

I did not plan to write this blog post. I thought that the fourth post in my series would explain how we could go from the generator API in my previous post to a futures API in which you don&rsquo;t have to heap allocate every async call. But eddyb surprised me, and now I have to revisit the API in the previous post, because we can implement everything we need from immovability with a safe interface afterall.

Async/Await III: Moving Forward with Something Shippable
04. Feb 2018 01:00
without.boats

In the first post, we looked at the relationship between generators and a more general notion of self-references. In the second post, we narrowed down exactly what problem we need to solve to make generators work, and talked about some solutions that we&rsquo;ve considered but don&rsquo;t feel like we could ship in the near future. In the original post, I promised that I would have a near term solution by the end of this series.

Async/Await II: Narrowing the Scope of the Problem
31. Jan 2018 01:00
without.boats

Last time we talked about the broader problem that generators with references across yield points represent: self-referential structs. This time, I want to narrow in on the specific problem that needs to be solved to make generators work, and also discuss some ideas for solutions that I think are false starts. (I still don&rsquo;t have a proposal about what to do in this post, but it will come soon enough!)

Async/Await I: Self-Referential Structs
25. Jan 2018 01:00
without.boats

This is the first in a series of blog posts about generators, async &amp; await in Rust. By the end of this series, I will have a proposal for how we could expediently (within the next 12 months) bring generators, async &amp; await to stable Rust, and resolve some of the most difficult ergonomics problems in the futures ecosystem. But that proposal is still several posts away. Before we can get to a concrete proposition, we need to understand the scope &amp; nature of the problem we need to solve.

Announcing a new project: configure
18. Jan 2018 01:00
without.boats

Hi :) I&rsquo;ve been working on a project called configure, which is intended to create a uniform way to load configuration variables from the environment of the program. Specifically, the goal is to create something that libraries can rely on to allow applications to delegate decisions about how configuration is loaded to applications, without those applications having to write a lot of bespoke configuration management glue. Storing configuration in the environment &ldquo;The 12 Factor App&rdquo; has this very good advice about managing configuration:

My Goals for Rust in 2018
09. Jan 2018 01:00
without.boats

The Rust project has requested blog posts about the project&rsquo;s goals for 2018. I found myself in pretty much complete agreement with Nick Cameron&rsquo;s post, so I thought instead I would write about my own personal goals for Rust in 2018. I am fortunate enough to work on Rust full-time; modulated by the work that needs to get done to accomplish larger team goals, these are some things that I&rsquo;m individually very motivated to make progress on in 2018.

Unsafe Abstractions
04. Jan 2018 01:00
without.boats

Unsafety in Rust is often discussed in terms the primitive operations that can only be performed inside of unsafe blocks (such as dereferencing raw pointers and accessing mutable statics). I want to look at it from a different angle from these primitive operations, and instead focus on the capability to produce unsafe abstractions. The general concept of unsafe abstractions An unsafe abstraction is a new abstraction which requires the unsafe keyword to apply to some context (this is an intentionally &ldquo;abstract&rdquo; definition, because as we will see there are several highly divergent forms of unsafe abstraction supported in Rust).

Not Explicit
27. Dec 2017 01:00
without.boats

Oftentimes when I am conversing about the design of Rust with other users - as on RFCs or the internals forum - I witness a peculiar remark about &ldquo;explicitness.&rdquo; It usually goes something like this: I do not like Feature Design X because it is too implicit. Magic is okay in Other Language Y, but Rust is supposed to be an explicit language, so we should go with Feature Design Z instead.

Failure 0.1.1 released
30. Nov 2017 01:00
without.boats

I&rsquo;ve just published failure 0.1.1 to crates.io. It&rsquo;s mostly some incremental improvements to failure that have been suggested since the first release two weeks ago. Improvements to the derive A big change in version 0.1.1 is that the derive can be used without depending on the failure_derive crate separately. All that needs to be done is tagging the extern crate statement with #[macro_use]: // No direct dependency on `failure_derive` #[macro_use] extern crate failure; #[derive(Fail, Debug)] #[fail(display = &#34;An error occurred.

Announcing Failure
16. Nov 2017 01:00
without.boats

I&rsquo;m really excited to announce a new crate I&rsquo;ve been working on, called failure, and which I&rsquo;ve just released to crates.io. Failure is a Rust library intended to make it easier to manage your error types. This library has been heavily influenced by learnings we gained from previous iterations in our error management story, especially the Error trait and the error-chain crate. The Fail trait The core abstraction in failure is the Fail trait, a replacement for the existing std::error::Error trait.

Alternative Registries
23. Oct 2017 23:10
without.boats

cargo gained a new feature this week! You can now download dependencies from alternative registries, alongside the dependencies you download from crates.io. This is an important step in enabling organizations to distribute their internal libraries through cargo without requiring them to upload those libraries to a public registry. This feature will be available on nightly only, and it is gated behind the alternative-registries feature gate. We&rsquo;ve used feature gates to iterate on new and unstable features in rustc since the 1.

Blogging With GitLab and Hugo
28. Sep 2017 02:00
without.boats

Previously, I attempted to maintain a blog using GitHub Pages. I was very unsuccessful at actually producing blog posts, though. I don&rsquo;t care a lot about the appearance or maintenance of my blog site. What I want from the experience is the same experience I have writing Rust RFCs (because I have a lot of experience doing that): I write some markdown. I commit and push. Other people can read it.

Handshake Patterns
21. Jan 2017 01:00
without.boats

The problem: defining a &lsquo;handshake&rsquo; protocol between two traits You have a problem that decomposes in this way: you want any type which implements trait Alpha to be composable with any type which implements trait Omega&hellip; That is, if Foo and Bar are both Alphas and Baz and Quux are both Omegas, you can compose Foo with Baz or Quux, and the same with Bar, and so on. This is not a trivial problem.

The Rust module system is too confusing
04. Jan 2017 01:00
without.boats

A while ago I was considering an idea, so I wrote a tweet to ask what folks thought about it. A very spirited discussion followed about the Rust module system and what the pain points with it were (indeed - whether or not there were pain points at all). Depending on your skill at navigating Twitter&rsquo;s UI, you may or may not be able to read the whole discussion by following the link above.

Comparing Filesystem Performance in Virtual Machines
10. Jan 2014 01:00
mitchellh.com
Packer
28. Jun 2013 02:00
mitchellh.com
The Tao of Vagrant
18. Jun 2013 02:00
mitchellh.com
Automation Obsessed
06. Jun 2013 02:00
mitchellh.com
Abandoning Rubygems
21. Mar 2013 01:00
mitchellh.com
APPLE: My Key to Success
04. Mar 2013 01:00
mitchellh.com
The New Normal
21. Jan 2013 01:00
mitchellh.com
404 Page Not Found
01. Jan 0001 01:22
without.boats

…In that Empire, the Art of Cartography attained such Perfection that the map of a single Province occupied the entirety of a City, and the map of the Empire, the entirety of a Province. In time, those Unconscionable Maps no longer satisfied, and the Cartographers Guilds struck a Map of the Empire whose size was that of the Empire, and which coincided point for point with it. The following Generations, who were not so fond of the Study of Cartography as their Forebears had been, saw that that vast Map was Useless, and not without some Pitilessness was it, that they delivered it up to the Inclemencies of Sun and Winters.