Effect Oriented Programming • Bill Frasure, Bruce Eckel, James Ward & Andrew Harmel-Law • GOTO 2026

Authors Bill Frasure, Bruce Eckel, and James Ward discuss the core concepts of Effect-Oriented Programming. They explain how effects are composable operations that encapsulate side effects and defer execution, allowing developers to manage unpredictability with compiler-checked types. The conversation covers ZIO, the expansion of effect systems into languages like TypeScript and Kotlin, and their unique, constraint-driven writing process.

4 min read
Effect Oriented Programming • Bill Frasure, Bruce Eckel, James Ward & Andrew Harmel-Law • GOTO 2026
source: https://www.youtube.com/watch?v=Qds6rO9lxps

The Essence of Effect-Oriented Programming

Effect-Oriented Programming introduces a paradigm where effects are treated as first-class values. An effect is a composable operation that describes an interaction with the outside world, such as a database query, a network request, or writing to the console. The core principle is deferred execution: instead of an operation executing immediately, an effect creates a description of that operation. This description can then be composed with other effects to build a larger, more complex workflow. This encapsulation of side effects is what makes them robustly composable, addressing a long-standing challenge in software development.

This approach allows developers to build larger programs from smaller, verifiable pieces. The composition of two effects results in a new, larger effect, maintaining the same composable nature throughout the application.

Managing Unpredictability with the Compiler

A significant advantage of effect systems is their ability to manage the inherent unpredictability of side effects. The system doesn’t make non-deterministic operations (like network calls) deterministic, but it provides the necessary tools to handle their outcomes in a structured way. The compiler becomes a powerful ally in this process.

The authors highlight how the ZIO effect system, used as the primary example in their book, tracks three crucial pieces of information in its type signature for any given effect:

  1. Environment Type: The dependencies required to execute the effect. This could be a database connection, a system clock, or a random number generator.
  2. Failure Type: The specific errors that the effect can produce.
  3. Output Type: The value produced upon successful execution.

The compiler enforces that all possible failures are handled. If an effect can fail with a TimeoutException or a NetworkException, the compiler ensures that the calling code either handles both cases or explicitly declares that it will pass them up the call stack. This eliminates entire classes of runtime errors and forces developers to be deliberate about error handling. As a bonus, the compiler will also flag code that attempts to handle an error that cannot possibly occur.

A New Frontier for Testability

The explicit tracking of environmental dependencies revolutionizes testing. Because an effect declares what it needs to run, you can provide different implementations of those dependencies in different contexts.

  • For production, you provide the real system clock.
  • For testing, you can substitute a TestClock. This allows you to manipulate time within a unit test, simulating operations that take hours or weeks in a matter of milliseconds, making otherwise untestable logic easy to verify.

Similarly, if an effect requires random numbers, you can provide a predictable, “canned” sequence of numbers during testing to ensure your code behaves correctly under specific scenarios. This ability to replace real-world interactions with test-specific implementations makes it possible to write comprehensive, reliable tests for almost any part of an application.

The Collaborative Writing Process and Accessibility

The authors shared that their book, “Effect Oriented Programming,” was intentionally distilled from a much larger manuscript to its final, concise 100-page form. The goal was to lower the barrier to entry for a topic often perceived as intimidating. This was achieved through a highly collaborative process, often with all three authors working together in the same room.

To maximize accessibility, they established strict constraints:

  • A “forbidden words” list: To avoid alienating readers, they intentionally omitted complex functional programming jargon like “monad.” They emphasize that while the underlying systems are built on sound mathematical principles, one does not need to understand the math to reap the benefits.
  • A 47-character line limit: This constraint, enforced in their CI pipeline, forced simplification of code examples and ensured the entire book is comfortably readable in portrait mode on a mobile phone.

An Expanding Ecosystem

While the book uses Scala and ZIO, the concepts of effect-oriented programming are language-agnostic and are gaining traction across the industry.

  • TypeScript: A port of ZIO to TypeScript is rapidly gaining popularity, and the authors are working on a new version of their book using it.
  • Kotlin: The approach has inspired the design of new frameworks, such as a Kotlin AI framework from JetBrains.
  • New Languages: Emerging languages like Unison and Roc are building effect systems directly into their core, signaling a potential fundamental shift in language design.

This modern, type-safe approach is presented as the evolution of earlier attempts to manage complexity, such as Aspect-Oriented Programming (AOP) in frameworks like Spring. Instead of relying on annotations and “magic” that happens outside the type system, effects model these cross-cutting concerns as transparent, testable values in your code.

Share post

Stay In The Loop! Subscribe to Our Newsletter.

Get updates straight to your inbox. No spam, just useful content.

Recommended for You

SW Design, Architecture & Clarity at Scale • Sam Newman, Jacqui Read & Simon Rohrer • GOTO 2025

SW Design, Architecture & Clarity at Scale • Sam Newman, Jacqui Read & Simon Rohrer • GOTO 2025

A panel discussion with Sam Newman, Jacqui Read, and Simon Rohrer exploring the intersection of software design and architecture. The conversation delves into the critical role of communication, the practical application of Architecture Decision Records (ADRs), strategies for bridging the gap between architects and developers, and modern approaches to standardization through platform engineering and creating agile enterprise architectures.

Balancing Coupling in Software Design • Vlad Khononov & Sheen Brisals

Balancing Coupling in Software Design • Vlad Khononov & Sheen Brisals

Author Vlad Khononov discusses his book "Balancing Coupling in Software Design," explaining how a failed microservices project led him to rediscover timeless design principles from the 1970s. He explores the concepts of local vs. global complexity, the role of modularity as an antidote to complexity, and how managing coupling is crucial for building maintainable systems in any architectural style, from monoliths to cloud-native applications.