Adrian Hey wrote:
Jules Bean wrote:
I've pretty much convinced it's wrong. There should be one and only
one "main" from which all subsequent IO activity derives. But creating
internal state in the form of mutable data structures is not an IO
activity. It just so happens that at the moment the only way to do this
is newIORef :: a -> IO(IORef a), but this need not be so (readIORef and
writeIORef are IO activities, but newIORef isn't).
I find this point rather slippery. 'newIORef' is a
unique-name-provider, but 'unique over what'? When a module is
imported twice, should it not create new unique names?
No, it's just binding a name to a value, same as any other binding.
The difference is unlike normal top level bindings, that name is not
"equal to" any other expression. It just "is", if you get what I mean
(I'm sure you do). That's why the proposed syntax borrows the <- from
do expressions.
That's not my point. newIORef creates unique names (references). The
whole job of newIORef is to create unique names; unique names which
"refer to" little tiny bits of state parcelled up somewhere in that
mysterious IO monad. It is the scope of this uniqueness I'm talking
about: do libraries need these unique names to be unique over each
importer, over each thread, over each subprocess: consider a haskell
application server or a haskell OS... what is the correct domain of
uniqueness?
A large proportion of
libraries in fact *can* be written as "reentrant" in this sense, and
truly are parameterisable by their state.
I can't help being sceptical about this. AFAICS it doesn't matter how
many explicit state handles you tack on to the left of the
"-> IO Whatever", the fact that the whole lot ends in "-> IO Whatever"
means there's almost certainly some state left unaccounted for and
unparameterised (calls the OS are missing an OS state handle for
example).
Also, I don't really understand what you mean by "reentrant" in this
context. Are you talking about thread safety? (I guess not) Are you
implying that APIs of IO libs that mutate Haskell "global" state are
some how different from other IO APIs which mutate other "global" state
(such as OS state or "world state")? Are they deficient in some way?
If so, how can you tell the difference?
'reentrant' is not the right word, although it's a related notion. I was
talking about libraries which can safely be initialised more than once,
for multiple clients, and they keep around 'separate' state for each
client/each time they are initialised. This kind of design is often a
precondition for being thread-safe; and it's often plain good design,
unless some external 'real world' uniqueness makes it impossible.
Jules
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe