The topic that got most votes at functional programming study group was effect systems. I was a little unsure if a seemingly-advanced topic would get people talking. In the true spirit of RC, what ensued was a group exploration.
Prior to SICP, I thought about programming languages as being static vs dynamic, compiled vs interpreted, with vs without garbage collection. Reading SICP I was (more formally) introduced to functional vs imperative, eager vs lazy evaluation.
With functional vs imperative, I thought about the latter as allowing functions to have side effects. Since pure functions in the former don’t allow for side effects, enabling side effects (like reading a file or printing to the screen) in a language like Haskell requires a little bit of ‘ceremony’ through monads.
I’m still wrapping my head around monads. My understanding is monads allows side effects in a controlled way, performed when explicitly triggered rather than being triggered automatically by the evaluation of a function.
The problem with monads is composability, as the composition of two monads may not be a monad. In other words, care is needed when monads are composed together as the desired effect may be different vs what was intended when considering each monad individually.
Having an effect system offers an alternative to using monads. Koka is an experimental language that introduces effect types and handlers. Reading about the different effect types, there’s a ‘continuum’ and thus not simply a pure vs effectful function distinction.
Why bother? This beginner-friendly post has examples of algebraic effects allowing a more flexible or generalized form of try-except. Instead of simply catching the error, we could perform arbitrary operations and then ‘go back’ to the function that raised the error. It’s also worth nothing that having handlers allows for this in an ergonomic way, which also avoids having to ‘color’ functions.
Haskell has the `freer-simple` library that enables an extensible effect system. Where effects can have a major impact is enabling ergonomic concurrency in OCaml (c.f. Haskell which has better multicore primitives). This has been in the works for close to a decade and is currently an experimental feature in OCaml 5.
The discussion is timely. Earlier in the week we watched Simon Peyton-Jones present on the Verse language. Verse has an effect system instead of using monads, slide 6 here. The study group got curious about logic programming (Verse is a functional logic language) so we’ll be discussing this next week!
Special thanks to Sam Eisenhandler for seeding the discussion on effect systems.