Synchronous Core, Asynchronous Shell

submited by
Style Pass
2024-07-05 03:30:16

A bit over a decade ago, Gary Bernhardt published Functional Core, Imperative Shell. His proposed software architecture uses functional programming style, especially immutable data, for the bulk of the logic, and an outer shell that uses imperative programming style for side effects such as I/O. This makes it easier to understand, test, and change the logic without imposing the difficulties of entirely functional programs. Gary also presented an expansion of this idea in his talk Boundaries later that same year. I personally like and use this pattern, and think it is much more universally useful than for example pure functional or object-oriented styles.

More recently there has been a lot of discussion about the ergonomics of Rust's async functionality, with many participants expression frustration about the boundary between synchronous and asynchronous parts of the language. A common complaint references function colors, the idea that asynchronous parts don't compose well with synchronous parts due to their different execution model. Specifically, asynchronous functions can call synchronous ones, but not the other way around, at least not without additional ceremony.

Looking at most real world Rust services1I also work on a decent amount of embedded and desktop applications, which are often entirely synchronous, though with Embassy even embedded software is getting an asynchronous shell. I work on these days, a lot of them perform asynchronous I/O using Tokio, especially interactions over the network such as data stores and other services. It struck me that I tend to follow a synchronous core, asynchronous shell pattern, which uses the same ideas as Gary laid out earlier, but additionally directly maps synchronous and asynchronous code into the core and shell, respectively. This comes with all the same advantages of the original, and avoids a situation where synchronous code calls asynchronous code, as the core does not call the shell.

Leave a Comment