July 5th, 2024

Synchronous Core, Asynchronous Shell

A software architecture concept, "Synchronous Core, Asynchronous Shell," combines functional and imperative programming for clarity and testing. Rust faces challenges integrating synchronous and asynchronous parts, prompting suggestions for a similar approach.

Read original articleLink Icon
Synchronous Core, Asynchronous Shell

In a software architecture concept called "Synchronous Core, Asynchronous Shell," inspired by Gary Bernhardt's work, the idea is to use functional programming for the core logic and imperative programming for side effects. This approach aims to enhance understanding, testing, and modifying the logic without the complexities of fully functional programs. Recently, discussions have arisen regarding the ergonomic challenges of Rust's async functionality, particularly the difficulties in integrating synchronous and asynchronous parts due to different execution models. The concept of function coloring has been highlighted as a limitation, where asynchronous functions can call synchronous ones but not vice versa easily. The author suggests employing a synchronous core, asynchronous shell pattern in Rust services, aligning with Gary's original idea but with a direct mapping of synchronous and asynchronous code. This pattern helps maintain advantages of the original concept and prevents synchronous code from calling asynchronous code directly. The author also proposes using the command pattern to trigger side effects from the core, emphasizing the benefits of function coloring as a safeguard against unintended side effects.

Related

Download Accelerator – Async Rust Edition

Download Accelerator – Async Rust Edition

This post explores creating a download accelerator with async Rust, emphasizing its advantages over traditional methods. It demonstrates improved file uploads to Amazon S3 and provides code for parallel downloads.

The Inconceivable Types of Rust: How to Make Self-Borrows Safe

The Inconceivable Types of Rust: How to Make Self-Borrows Safe

The article addresses Rust's limitations on self-borrows, proposing solutions like named lifetimes and inconceivable types to improve support for async functions. Enhancing Rust's type system is crucial for advanced features.

I Probably Hate Writing Code in Your Favorite Language

I Probably Hate Writing Code in Your Favorite Language

The author critiques popular programming languages like Python and Java, favoring Elixir and Haskell for immutability and functional programming benefits. They emphasize personal language preferences for hobby projects, not sparking conflict.

Spending too much time optimizing for loops

Spending too much time optimizing for loops

Researcher Octave Larose discussed optimizing Rust interpreters, focusing on improving performance for the SOM language. They highlighted enhancing loop efficiency through bytecode and primitives, addressing challenges like Rust limitations and complex designs. Despite performance gains, trade-offs between efficiency and code elegance persist.

Exploring biphasic programming: a new approach in language design

Exploring biphasic programming: a new approach in language design

Biphasic programming introduces new language design trends like Zig's "comptime" for compile-time execution, React Server Components for flexible rendering, and Winglang's phase-specific code for cloud applications.

Link Icon 2 comments
By @zogrodea - 3 months
I follow the same principle in my code, but doesn't the "functional core, imperative shell" pattern already push the async stuff out of the core?

What would be an example of an async operation that doesn't perform a side-effect (thereby needing a place in the imperative shell rather than the functional core)?

I think pushing async to the shell is really a subset of pushing imperative code to the shell.