The H2 Wiki


Capabilities in Bluefin

The important property of capabilities, as Bluefin treats them, is that they are value-level entities that do not fundamentally differ from other program values (e.g. strings, numbers, …) and can be manipulated in just the same ways (e.g. passing them as arguments to functions, returning them from functions, putting them in tuples and records, closing over them in function definitions, …).


The notion of “purity”

As an aside, the notion of “purity” or “pure function” is awkward when applied to Haskell. Although computeFunction :: String -> Int could throw an exception or loop forever, if it doesn’t it seems reasonable to describe it as computing a pure, mathematical function that maps String to Int.


There is a misconception that “Haskell is a pure language”, implying that it “can’t do effects” and needs “something else”—specifically “monads” and particularly “the IO monad”—to allow it to “do effects”. This is false. Haskell implementations have always been able to do more than just calculate the result of mathematical functions, i.e. perform pure calculations. Rather than “pure”, I prefer to use “referentially transparent” to describe this aspect of Haskell. It is not possible for a program component written in a referentially transparent language to interact with an external environment without the possibility of that interaction being reflected in the type of the component.

The problem with IO is that it is “too big”.


Every Haskell program starts in main with the “I/O capability” as provided by the “IO monad”. Bluefin’s runEff function converts this into a Bluefin IOE capability:

runEff :: (forall e. IOE e -> Eff e r) -> IO r

From there, various other capabilities (reading and writing the filesystem, connecting to a database, making HTTP requests …) can be derived from IOE.


Migrating Bluefin’s terminology from “handle” to “terminology” is ongoing work. See Bluefin.Capability