-- -*- encoding: utf-8; fill-column: 95 -*-
-----------------------------------------------------------------------------------------------
--
-- Module : Data.Global
-- Creation Date : 2011-09-01
-- Authors : Jean-Marie Gaillourdet <jmg@gaillourdet.net>
-- License : BSD-style
-- Portability : all
--
--
-----------------------------------------------------------------------------------------------
-- | 'Data.Global' provides a global namespace of 'IORef's, 'MVar's and 'TVar's. This namespace
-- may be accessed in pure code. Yet reading and writing to those 'IORef's, 'MVar's and 'TVar's
-- happens still in their respective monads.
--
-- 'Data.Global' is designed to meet the following use cases:
--
-- * Simplify the declaration of top-level mutable variables, by avoiding any pragmas as well
-- as 'unsafePerformIO'.
--
-- * Avoid having to pass references explicitly throughout the program in order to let
-- distant parts communicate.
--
-- * Enable a communication by convention scheme, where e.g. different libraries may
-- communicate without code dependencies.
--
-- * Simplify the "configuration problem" - at least for code in the IO monad.
--
-- Note, that this library does not encourage sloppy software design by re-introducing all bad
-- effects of global variables. Nevertheless, sometimes global variables are a suitable
-- solution to a problem. In that case 'Data.Global' simplifies and extends their handling
-- significantly.
module Data.Global (
-- * Introductory Example
-- $intro
-- * The Namespace of Global Variables
-- $namespace
-- * Initialization
-- $init
-- * Reference of Variable Declaration Functions
declareIORef
, declareMVar
, declareTVar
) where
import Data.Global.Registry
-- $intro
--
-- The most simple usage of 'Data.Global' is as follows:
--
-- Let there be an 'IORef'!
--
-- >>> let ref = declareIORef \"some-cool-variable\" 17
--
-- Use @ref@ like any other 'IORef'.
--
-- >>> readIORef ref
-- 17
--
-- You can do the same with 'MVar's and 'TVar's.
-- $namespace
-- The types of variables: @'IORef' a@, @'MVar' a@, and @'TVar' a@ create separate
-- namespaces. I.e. A variable of type @'IORef' 'Int'@ and one of type @'MVar' 'Int'@ can both
-- exist with the same name.
-- $init
-- References / variables returned by any of the @declare...@ functions are initialized
-- as needed with the value provided to @declare...@. Have a look at this example.
--
-- @
-- someVar1, someVar2 :: IORef Int
-- someVar1 = declareIORef \"my-global-var\" 0
-- someVar2 = declareIORef \"my-global-var\" 1
-- @
--
-- @someVar1@ and @someVar2@ are guaranteed to always denote the exact same 'IORef', but it is
-- unspecified whether the first read access to that 'IORef' returns @0@ or @1@. It can even
-- have any other initial value if it is also accessed from some other part of the program.