[Haskell] Re: Global Variables and IO initializers

Benjamin Franksen benjamin.franksen at bessy.de
Thu Nov 4 11:12:13 EST 2004


On Thursday 04 November 2004 16:16, Koen Claessen wrote:
> The problem with John's approach is that it breaks
> modularity. It does this in two ways:
>
> (1) Whenever a module uses an implicit parameter like that,
> it has to have a name that is different from all implicit
> parameters used by any other (future) module. (Yes, implicit
> paramers cannot be quantified by a module name.) This is
> difficult to ensure.

I haven't thought of this before. It is a drawback, indeed. Is there any 
convincing technical reason why implicit parameters cannot be "quantified by 
a module name" (whatever that may mean exactly).

> (2) Having the implicit parameter breaks the abstraction
> barrier. I might want to re-implement a module that does not
> make use of global variables, into one that uses a cache or
> hash-table or whatever (think BDD library), and not change
> the interface of the functions that are provided.
>
>  | What I've been asking myself is: Wouldn't it be possible
>  | for the compiler to silenty add the implicit parameter
>  | type constraints behind the scenes?
>
> You would be back at square 1, since your program will still
> look and behave exactly the same as a program that
> implicitly executes all initializations; the only difference
> is implementation.

No, not at all. "behind the scenes" refered only to adding appropriate *type 
annotations* (i.e. implicit parameter constraints). You would still need to 
perform all initialization explicitly inside main.

If this were possible, at least your critique point 2 would no longer apply.

Ben Rudiak-Gould explained very clearly what I meant.

> I have a different proposal.
>
> Imagine a commutative monad, CIO. Commutative monads have
> the property that it does not matter in what order actions
> are performed, they will have the same effect. In other
> words, for all m1 :: CIO A, m2 :: CIO B, k :: A -> B -> CIO
> C, it should hold that:
>
>   do a <- m1             do b <- m2
>      b <- m2     ===        a <- m1
>      k a b                  k a b
>
> Now, one could imagine an extension X of Haskell98, in which
> modules are allowed to contain definitions of the form:
>
>   p <- m
>
> Here, p is a (monomorphic) pattern, and m is of type CIO A,
> for some type A. CIO is an (abstract) monad provided in a
> library module, just like IO is today.
>
> One could wonder where the primitive actions in the monad
> CIO come from? Well, library providers (compilers) could
> provide these. For example:
>
>   newIORefCIO     :: a -> CIO (IORef a)
>   newEmptyMVarCIO :: CIO (MVar a)
>
> And so on.
>
> The implementer of these functions has to guarantee that the
> actions do not destroy the commutativity of the CIO monad.
> This is done in the same way as today, compiler writers and
> users of the FFI guarantee that certain primitive operations
> such as + on Ints are pure.
>
> The FFI could even adapt CIO as a possible result type
> (instead of having just pure functions or IO functions in
> the FFI).

This proposal is very elegant and beautiful. There is one caveat, however.

Commutativity is a property of the Monad in itself. Inside the CIO monad 
everything commutes, but does that mean actions inside CIO always commute 
with all other actions in IO?

Instead of just being a commutative sub monad of IO, CIO would need to be a 
sub-monad in IO that has the property that its actions commute with every IO 
action. Only then would the order of execution be irrelevant.

CIO would surely contain actions to create MVars and IORefs. Are there other 
primitive IO actions that belong to (this) CIO?

***

On a different note, I remember that Eiffel (an imperative OO language) lacks 
global variables, too. As a replacement Eiffel has so called 'once' routines. 
These are executed only once per program run -- later calls just return the 
memoized result from the first time.

This smells a lot like the unsafePerformIO+{- NoInline-} aproach to me.

Ben


More information about the Haskell mailing list