
(stdin,stdout,stderr) seem to naturally have this scope (assuming you don't use freopen). There needs to be only one Handle created for each of these because otherwise the buffering won't work properly. Global <- initializers seem like the right thing here.
I think I would rather have them passed to 'main' as arguments... Afterall, what if somone calls hClose on one? The fact that a function may fail (on a closed handle) due to an action taken in another function (closing the handle) is not nice... Passing the handles explicitly might make things more obvious. A more functional way would be to reference count the handle, and only really close it then the last reference is closed or goes out of scope. I guess you wouldn't want a huge number of arguments to main, so a record would let you have all the 'environment' in one variable.
Are there any others?
The fact that the concept of 'one program' is artificial (created by the loading process used by the OS), it would suggest that OS variables associated with the process (IE process-ID, or anything stored in the OS's process-table may have a natural lifetime of one process - although these days most of these things tend to be associated with threads instead (thread-id etc...) and many threads can start and end in the life of a program. I cannot think of any library that could not be written in a multiple reference way - if it wasn't dependant on some legacy code. Even a library to manage a single physical piece of hardware (say a special encryption chip) would be better written allowing more than one chip to be supported - even if current hardware does not allow this - some future system might, and you don't want to have to change the software-architecture because of this... Far better to allow multiple threads to independantly open multiple devices - and limit the number of devices to 1 for now. In this case the OS would need to manage the device-counter. A nice way to do this would be to use the FFI to get the operating system to manage this. You could use an OS semaphore or a unix-socket. If you use the PID as part of the socket name, then only the first call to open-socket would succeed. This suggests that a nice library to make this sort of thing easy would be a 'namedChannel' library, where read and write ends of a channel could be opened independantly and the address would be an arbitrary string. Keean.