Reference. Doo bee doo bee doo
We explore the design and implementation of Frank, a strict functional programming language with a bidirectional effect type system designed from the ground up around a novel variant of Plotkin and Pretnar’s effect handler abstraction. Effect handlers provide an abstraction for modular effectful programming: a handler acts as an interpreter for a collection of commands whose interfaces are statically tracked by the type system. However, Frank eliminates the need for an additional effect handling construct by generalising the basic mechanism of functional abstraction itself. A function is but the special case of a Frank operator that interprets no commands. Moreover, Frank’s operators can be multihandlers which simultaneously interpret commands from several sources at once, without disturbing the direct style of functional programming with values. Effect typing in Frank employs a novel form of effect polymorphism which avoids mentioning effect variables in source code. This is achieved by propagating an ambient ability inwards, rather than accumulating unions of potential effects outwards. With the ambient ability describing the effects that are available at a certain point in the code, it can become necessary to reconfigure access to the ambient ability. A primary goal is to be able to encapsulate internal effects, eliminating a phenomenon we call effect pollution . Moreover, it is sometimes desirable to rewire the effect flow between effectful library components. We propose adaptors as a means for supporting both effect encapsulation and more general rewiring. Programming with effects and handlers is in its infancy. We contribute an exploration of future possibilities, particularly in combination with other forms of rich type systems.
Cite
Cited by (3)
Yarrow: Reconciling Effect Handlers and Region-Based Memory Management mathiasen-2026-yarrow
We present a new ML-like programming language Yarrow with algebraic effects and region-based memory management. Reconciling these programming language features into one language is challenging: the non-local control flow of algebraic effects break the stack discipline of function calls and returns that region-based memory management relies on, and multi-shot effect handlers break the invariant that regions can be exited at most once. We present a program logic, called Yarrow Logic (YL), that supports safe and modular reasoning about regions in the presence of one-shot and multi-shot effect handlers. We prove the logic sound w.r.t. the operational semantics of Yarrow which is inspired by the runtime of OCaml but refined for regions. We use YL to prove correctness of a number of case studies with algebraic effects, including checkpointing, asynchronous computation and a LIFO data structure implementation. Since all memory locations used in these case studies are allocated in regions, these case studies avoid using the less efficient garbage collected heap memory. We have formalized Yarrow’s operational semantics, the Yarrow program logic, and all our case studies using the Iris separation logic framework on top of the Rocq Prover.
Live Pattern Matching with Typed Holes yuan-2023-live
Several modern programming systems, including GHC Haskell, Agda, Idris, and Hazel, support typed holes . Assigning static and, to varying degree, dynamic meaning to programs with holes allows program editors and other tools to offer meaningful feedback and assistance throughout editing, i.e. in a live manner. Prior work, however, has considered only holes appearing in expressions and types. This paper considers, from type theoretic and logical first principles, the problem of typed pattern holes. We confront two main difficulties, (1) statically reasoning about exhaustiveness and irredundancy when patterns are not fully known, and (2) live evaluation of expressions containing both pattern and expression holes. In both cases, this requires reasoning conservatively about all possible hole fillings. We develop a typed lambda calculus, Peanut, where reasoning about exhaustiveness and redundancy is mapped to the problem of deriving first order entailments. We equip Peanut with an operational semantics in the style of Hazelnut Live that allows us to evaluate around holes in both expressions and patterns. We mechanize the metatheory of Peanut in Agda and formalize a procedure capable of deciding the necessary entailments. Finally, we scale up and implement these mechanisms within Hazel, a programming environment for a dialect of Elm that automatically inserts holes during editing to provide static and dynamic feedback to the programmer in a maximally live manner, i.e. for every possible editor state. Hazel is the first maximally live environment for a general-purpose functional language.
Effect handlers via generalised continuations hillerstrom-2020-effect
Plotkin and Pretnar’s effect handlers offer a versatile abstraction for modular programming with user-defined effects. This paper focuses on foundations for implementing effect handlers, for the three different kinds of effect handlers that have been proposed in the literature: deep, shallow, and parameterised. Traditional deep handlers are defined by folds over computation trees and are the original construct proposed by Plotkin and Pretnar. Shallow handlers are defined by case splits (rather than folds) over computation trees. Parameterised handlers are deep handlers extended with a state value that is threaded through the folds over computation trees. We formulate the extensions both directly and via encodings in terms of deep handlers and illustrate how the direct implementations avoid the generation of unnecessary closures. We give two distinct foundational implementations of all the kinds of handlers we consider: a continuation-passing style (CPS) transformation and a CEK-style abstract machine. In both cases, the key ingredient is a generalisation of the notion of continuation to accommodate stacks of effect handlers. We obtain our CPS translation through a series of refinements as follows. We begin with a first-order CPS translation into untyped lambda calculus which manages a stack of continuations and handlers as a curried sequence of arguments. We then refine the initial CPS translation by uncurrying it to yield a properly tail-recursive translation and then moving towards more and more intensional representations of continuations in order to support different kinds of effect handlers. Finally, we make the translation higher order in order to contract administrative redexes at translation time. Our abstract machine design then uses the same generalised continuation representation as the CPS translation. We have implemented both the abstract machine and the CPS transformation (plus extensions) as backends for the Links web programming language.
Cites 76 works (7 here)
With notes (7)
Effect handlers via generalised continuations hillerstrom-2020-effect
Plotkin and Pretnar’s effect handlers offer a versatile abstraction for modular programming with user-defined effects. This paper focuses on foundations for implementing effect handlers, for the three different kinds of effect handlers that have been proposed in the literature: deep, shallow, and parameterised. Traditional deep handlers are defined by folds over computation trees and are the original construct proposed by Plotkin and Pretnar. Shallow handlers are defined by case splits (rather than folds) over computation trees. Parameterised handlers are deep handlers extended with a state value that is threaded through the folds over computation trees. We formulate the extensions both directly and via encodings in terms of deep handlers and illustrate how the direct implementations avoid the generation of unnecessary closures. We give two distinct foundational implementations of all the kinds of handlers we consider: a continuation-passing style (CPS) transformation and a CEK-style abstract machine. In both cases, the key ingredient is a generalisation of the notion of continuation to accommodate stacks of effect handlers. We obtain our CPS translation through a series of refinements as follows. We begin with a first-order CPS translation into untyped lambda calculus which manages a stack of continuations and handlers as a curried sequence of arguments. We then refine the initial CPS translation by uncurrying it to yield a properly tail-recursive translation and then moving towards more and more intensional representations of continuations in order to support different kinds of effect handlers. Finally, we make the translation higher order in order to contract administrative redexes at translation time. Our abstract machine design then uses the same generalised continuation representation as the CPS translation. We have implemented both the abstract machine and the CPS transformation (plus extensions) as backends for the Links web programming language.
On the expressive power of user-defined effects: Effect handlers, monadic reflection, delimited control forster-2019-on
We compare the expressive power of three programming abstractions for user-defined computational effects: Plotkin and Pretnar’s effect handlers, Filinski’s monadic reflection, and delimited control. This comparison allows a precise discussion about the relative expressiveness of each programming abstraction. It also demonstrates the sensitivity of the relative expressiveness of user-defined effects to seemingly orthogonal language features. We present three calculi, one per abstraction, extending Levy’s call-by-push-value. For each calculus, we present syntax, operational semantics, a natural type-and-effect system, and, for effect handlers and monadic reflection, a set-theoretic denotational semantics. We establish their basic metatheoretic properties: safety, termination, and, where applicable, soundness and adequacy. Using Felleisen’s notion of a macro translation, we show that these abstractions can macro express each other, and show which translations preserve typeability. We use the adequate finitary set-theoretic denotational semantics for the monadic calculus to show that effect handlers cannot be macro expressed while preserving typeability either by monadic reflection or by delimited control. Our argument fails with simple changes to the type system such as polymorphism and inductive types. We supplement our development with a mechanised Abella formalisation.
Do be do be do lindley-2017-do
Productive coprogramming with guarded recursion atkey-2013-productive
Complete and easy bidirectional typechecking for higher-rank polymorphism dunfield-2013-complete
Handlers in action kammar-2013-handlers
Applicative programming with effects mcbride-2008-applicative
In this article, we introduce Applicative functors – an abstract characterisation of an applicative style of effectful programming, weaker than Monads and hence more widespread. Indeed, it is the ubiquity of this programming pattern that drew us to the abstraction. We retrace our steps in this article, introducing the applicative pattern by diverse examples, then abstracting it to define the Applicative type class and introducing a bracket notation that interprets the normal application syntax in the idiom of an Applicative functor. Furthermore, we develop the properties of applicative functors and the generic operations they support. We close by identifying the categorical structure of applicative functors and examining their relationship both with Monads and with Arrow.
External (69)
- Effekt: Capability-passing style for type- and effect-safe, extensible effect handlers in Scala (2020)
- Binders by day, labels by night: Effect instances via lexically scoped handlers (2020)
- Abstracting algebraic effects (2019)
- Abstraction-safe effect handlers via tunneling (2019)
- Monad transformers and modular algebraic effects: what binds them together (2019)
- Typed Equivalence of Effect Handlers and Delimited Control (2019)
- Defined Algebraic Operations (PhD thesis) (2019)
- Effect handlers for the masses (2018)
- Handle with care: Relational interpretation of algebraic effects and handlers (2018)
- JEff: objects for effect (2018)
- Algebraic Effect Handlers with Resources and Deep Finalization (2018)
- On the expressive power of user-defined effects: Effect handlers, monadic reflection, delimited control (2017)
- Effekt: extensible algebraic effects in Scala (short paper) (2017)
- Fibred Computational Effects (2017)
- Enhancing a Modular Effectful Programming Language (MSc thesis) (2017)
- Type directed compilation of row-typed algebraic effects (2016)
- Liberating effects with rows and handlers (2016)
- Compilation of Effect Handlers and their Applications in Concurrency (MSc(R) thesis) (2016)
- Programming with algebraic effects and handlers (2015)
- Freer monads, more extensible effects (2015)
- Turing-Completeness Totally Free (2015)
- Fusion for Free (2015)
- An Algebraic Approach to Typechecking and Elaboration (blog post) (2015)
- Effective concurrency through algebraic effects (2015)
- Handlers for Algebraic Effects in Links (MSc thesis) (2015)
- Trifecta (1.5.2) (2015)
- Parsec (3.1.9) (2015)
- Inferring Algebraic Effects (2014)
- An Effect System for Algebraic Effects and Handlers (2014)
- Koka: Programming with Row Polymorphic Effect Types (2014)
- Effect handlers in scope (2014)
- Indentation-sensitive parsing for Parsec (2014)
- Reflection without remorse (2014)
- Algebraic effects and effect handlers for idioms and arrows (2014)
- Heuristics Entwined with Handlers Combined (2014)
- Handling Algebraic Effects (2013)
- Extensible effects (2013)
- Idris, a general-purpose dependently typed programming language: Design and implementation (2013)
- Programming and reasoning with algebraic effects and dependent types (2013)
- Wellfounded recursion with copatterns (2013)
- Type inference, Haskell and dependent types (2013)
- Frank (0.3) (2012)
- Lightweight monadic programming in ML (2011)
- Kleisli arrows of outrageous fortune (2011)
- Modular rollback through control logging: A pair of twin functional pearls (2011)
- Type inference in context (2010)
- Monads in action (2010)
- The Logic and Handling of Algebraic Effects (PhD thesis) (2009)
- Data types à la carte (2008)
- Links: Web Programming Without Tiers (2007)
- How might effectful programs look? (2007)
- Programming interfaces and basic topology (2005)
- Programming with Arrows (2005)
- Call-By-Push-Value: A Functional/Imperative Synthesis (2004)
- Algebraic Operations and Generic Effects (2003)
- Notions of Computation Determine Monads (2002)
- Semantics for Algebraic Operations (2001)
- Adequacy for Algebraic Effects (2001)
- Local type inference (2000)
- Representing layered monads (1999)
- The Zipper (1997)
- The reflexive CHAM and the join-calculus (1996)
- The Type and Effect Discipline (1994)
- The essence of functional programming (1992)
- How to make ad-hoc polymorphism less ad hoc (1989)
- Polymorphic effect systems (1988)
- Modules for standard ML (1984)
- Mindstorms: Children, Computers, and Powerful Ideas (1980)
- PASCAL User Manual and Report (1975)