Re: Suggestion for module system (to get rid of many uses of unsafePerformIO)

2007-05-24 Thread Adrian Hey

Stephen Dolan wrote:


At the moment,
we have the situation of modules using unsafePerformIO newIORef, which
influences program behaviour without being referenced by main.


Not really. Even with things as they currently are, if we have at the
top level..

resultOfSomething = unsafePerformIO doSomething

.. laziness will ensure that nothing will happen unless the value
resultOfSomething is demanded (by main ultimately).

Of course, this does not imply the above hack is at all safe.

Regards
--
Adrian Hey


___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Suggestion for module system (to get rid of many uses of unsafePerformIO)

2007-05-24 Thread oleg

Stephen Dolan wrote:
 unsafePerformIO is possibly the most ugly feature of Haskell, yet is
 necessary to do many things which should be possible without it, such
 as reading configuration from a file at startup or creating global
 IORefs

There is a considerable debate about global mutable state even in
imperative languages. As to reading data from a configuration file --
which should be immutable for the rest of the computation -- one
solution has been proposed back in 2002:

Pure File Reading (was: Dealing with configuration data)
http://www.haskell.org/pipermail/haskell/2002-September/010519.html

The problem essentially is of separate compilation and dynamic linking --
both of which are far simpler now than it was in 2002, with GHC API and
hs-plugins.
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: Suggestion for module system (to get rid of many uses of unsafePerformIO)

2007-05-23 Thread Adrian Hey

Stephen Dolan wrote:


Would this be useful, useless, or just downright silly?


The silence is deafening :-)

I think what you're describing seems to be so completely different
from Haskell as it is now that that people either don't understand
it, or they do understand it and do think it's downright silly, but
are just too polite to say that. Maybe you should try writing it up
in a more comprehensible form on a Haskell wiki page.

I would say that I get worried when people talk about module
initialisation and/or (potentially) side effecting imports. I'm
not sure if this is a problem with what you're proposing, but
I think it's important that we don't get into a situation where
the mere presence or absence of some definition in a module can
influence program behaviour, even if it isn't referenced by main
somehow.

Regards
--
Adrian Hey






___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: Suggestion for module system (to get rid of many uses of unsafePerformIO)

2007-05-23 Thread Stephen Dolan

I think what you're describing seems to be so completely different
from Haskell as it is now that that people either don't understand
it, or they do understand it and do think it's downright silly, but
are just too polite to say that. Maybe you should try writing it up
in a more comprehensible form on a Haskell wiki page.


Yeah, that certainly wasn't my most readable piece of writing.



I would say that I get worried when people talk about module
initialisation and/or (potentially) side effecting imports. I'm
not sure if this is a problem with what you're proposing, but
I think it's important that we don't get into a situation where
the mere presence or absence of some definition in a module can
influence program behaviour, even if it isn't referenced by main
somehow.


No, the point of what I was proposing was that, when a module requires
side-effecting initialisation, it would have to be imported inside a
do block like any other side-effecting piece of code. At the moment,
we have the situation of modules using unsafePerformIO newIORef, which
influences program behaviour without being referenced by main. If the
import statement was inside a do block, it would be clear when the
side-effects are taking place.

Regards,
Stephen Dolan
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Suggestion for module system (to get rid of many uses of unsafePerformIO)

2007-05-20 Thread Stephen Dolan

unsafePerformIO is possibly the most ugly feature of Haskell, yet is
necessary to do many things which should be possible without it, such
as reading configuration from a file at startup or creating global
IORefs, e.g

module Main where
import Data.IORef
a = unsafePerformIO $ newIORef 42
fac n = product [1..n]
main = do
val - readIORef a
putStrLn $ show (fac val)

This can be avoided by putting everything in the monad in main, i.e.
module Main where
import Data.IORef
main = do
a - unsafePerformIO $ newIORef 42
let fac n = product [1..n]
let mainFunc = do
val - readIORef a
putStrLn $ show (fac val)
mainFunc

However, this approach does not work for modules which need to do
their own initialisation with the current module system.

I propose that it be legal to write things like this:
MyModule.hs:
fac n = product [1..n]
do
ref - newIORef 42
module MyModule (ref, fac)

and then, in a different file, write this:
module Main where
main = do
import qualified MyModule as M -- implies evaluating newIORef
val - readIORef M.ref
putStrLn $ show (M.fac val)

The statement module name [(exported symbols)] would,
informally, give a value of type Module. This would not be a
first-class type, so it can't be passed around or bound to a variable.
So,
do
ref - newIORef 42
module MyModule (ref, fac)
writeIORef ref 43
would be illegal, since if you expand the do-notation, it is trying to
pass around an object of type IO Module. So, in the previous
example, Main :: Module and MyModule :: IO Module. The only valid
operation you can perform on a module is to import it, so while import
Main would be valid anywhere, import MyModule would only be valid in
the IO monad, and would cause the line ref - newIORef 42 to be run
when the IO action was executed. Following lexical scoping rules, its
symbols would only be accessible in the do-block it was imported into,
so the IORef ref could never escape from the IO monad.

This would also mean that if main were run twice, each run would see a
different IORef for ref, since the call to newIORef has, in effect,
been included into main. If the module were imported in two different
places, both places would see different values for ref, since the
evaluation of newIORef has been done twice.

Would this be useful, useless, or just downright silly?
Thanks,
Stephen Dolan
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime