Hammers and Immutability by Emil Hernvall

February 22, 2023

In the Hammers and Immutability presentation by Emil Hernvall, discusses his belief in the power of immutability in programming, using the metaphor of a hammer to illustrate its transformative effect. He shares his experiences implementing immutability in various projects, including an IRC server, and argues for its practical value. Emil also discusses passing state between parts of a program without sharing it, using channels as a foundational primitive, and shares his experience developing a physics-based game. He faced challenges rendering bubbles around a hexagon shape, which resulted in a complex state, but ultimately solved the problem by making the entire game state immutable. Emil also shares a past experience developing a custom photo-sharing application, where he encountered challenges with Rust’s borrow checker and mutable access restrictions, and eventually learned the benefits of immutability for performance and simpler programming.

Hammers and Immutability: A comprehensive overview

The immutability hammer: A tool for every problem

Emil Hernvall began his presentation by likening immutability to a hammer — an essential tool in a programmer’s toolkit. Just as a hammer makes every problem seem like a nail, immutability can turn complex, stateful issues into more manageable ones. He recounted his initial experiences with implementing immutability in various projects, including an IRC server. Initially, he thought a “state mode knob” would be necessary to handle the protocol’s statefulness and side effects. However, he soon realized that embracing immutability provided a simpler and more effective solution.

 

Building an immutable server

One of the practical examples Emil discussed was the structure of a server built with immutable data structures. In this server, the main function initializes the state — a map of users and channels — and then starts a green thread to process events. Instead of updating the state in place, the server creates new user objects and spawns threads to handle specific events. This approach leverages Haskell’s immutable data structures, where changes are represented by new data rather than modifying existing structures. This method not only ensures consistency but also simplifies the reasoning about the state.

 

Passing state without sharing: Channels and event loops

Emil highlighted the concept of passing state between program components without sharing it, using channels as a foundational primitive. This approach, similar to the event loop in Rust and emphasized in the book Java Concurrency in Practice, helps prevent common concurrency issues. He illustrated this concept through his work on a JavaScript game called Bubble Spinner. The game involved complex physics concepts like moment of inertia and angular momentum, and Emil’s implementation maintained state immutability to manage these complexities effectively.

 

The challenges of immutable game development

Developing a physics-based game presented its own set of challenges, particularly in rendering bubbles around a hexagon shape. Emil detailed the difficulties of managing the game’s state, which involved intricate calculations and multiple variables for each bubble. The solution lay in making the entire game state immutable, allowing for more straightforward tracking and debugging. This decision underscored the power of immutability in simplifying complex logic and reducing potential errors.

 

Concurrency and immutability in a photo-sharing app

Another significant project Emil discussed was a custom photo-sharing application he developed for his wife. This app ran on a home server, monitoring a folder for new images and rescaling them in the background. Initially, Emil struggled with Rust’s borrow checker and mutable access restrictions, leading to performance issues due to lock contention. However, by adopting immutability and atomic reference counters, he achieved concurrent access without sacrificing consistency or performance. This experience highlighted immutability’s advantages in concurrent systems, offering a simpler and more efficient alternative to traditional locking mechanisms.

 

Conclusion: The enduring value of immutability

In his concluding remarks, Emil reflected on the broader implications of immutability in software development. He noted that while the concept might initially seem counterintuitive, especially to those used to imperative programming, it offers significant benefits. These include easier reasoning about state, reduced potential for bugs, and often better performance. Emil’s experiences, ranging from game development to building concurrent systems, demonstrate that immutability is not just a theoretical concept but a practical tool that can lead to cleaner and more robust software.

Emil’s talk serves as a compelling case for incorporating immutability into more aspects of software design. Whether you’re dealing with complex state management, concurrency, or just looking for ways to simplify your code, immutability can be a powerful “hammer” in your programming toolkit. For those interested in exploring these concepts further, Emil encourages diving into resources like “Java Concurrency in Practice” and experimenting with immutability in various projects.

 

Additional resources

Check out more from the MeetUp Func Prog Sweden. Func Prog Sweden is the community for anyone interested in functional programming. At the MeetUps the community explore different functional languages like Erlang, Elixir, Haskell, Scala, Clojure, OCaml, F# and more.