Module Initialisation? (was Re: [Haskell] (no subject))
Wolfgang Thaller
wolfgang.thaller at gmx.net
Sat Oct 16 23:45:44 EDT 2004
Adrian Hey wrote:
> I'm puzzled about this idea of "module init action" in a declarative
> language. Perhaps, if it's desirable to have some module initialisation
> applied to a module if anything from it is used, the way to do this
> would
> be to have a reserved identifier specially for the purpose, like
> "main", but at the module level. (Though this idea still seems a
> bit strange to me).
I don't see what's so strange about that. At least, it's not any
stranger than on-demand execution of IO actions in a pure functional
language. And the toplevel "<-" is definitely a natural syntax for
that.
> I've interpreted this correctly this means that someAction will always
> get executed, whether or not foo (or anything dependent on foo) is used
> elsewhere? This seems like a bad thing to me.
It's a feature. I'd actually _want_ to use that one independently.
> It may be harmless enough
> if all it does is create a few IORefs which are then promptly garbage
> collected, but in some situations it could involve quite complex
> and expensive initialisation operations on foreign libraries
> (for example).
Well if you want those IO operations to be lazily interleaved with the
rest of the program (or not executed at all), you can use
valueToBeInitedLazily <- unsafeInterleaveIO $ do
blah
... which explicitly says what you are doing that might be slightly
unsafe.
> Since a lot of the concerns expressed about this seem to centre
> around possible abuse of arbitrary IO operations in these top
> level constructions, maybe the problem could be addressed by
> insisting that a restricted monad was used, call it SafeIO say.
You're taking away a feature I want to use.
1) Initialising global IORefs is a good thing, no matter when it's
actually done.
2) Being able to initialize things at program startup is a good thing,
even if they're
not explicitly referred to.
3) Lazy, on-demand initialization of things is a good thing, if you
know what you're doing.
4) Lazy, on-demand initialization of things (with potential side
effects) is a bad thing, if you don't know what you're doing.
If we define toplevel IO bindings to be just like the unsafePerformIO
hack, we get 1,3 and 4 (and 4 is actually a bad thing).
If we define toplevel IO bindings as mdo-style module initialisation,
we get 1 and 2 directly, and 3 with an obvious use of
unsafeInterleaveIO. We don't get 4, because obviously, when you use
unsafeInterleaveIO, you're already claiming to know what you're doing.
Also note that if useless initialization of IORefs ever becomes a
problem, we can still use lots of nasty hacks inside the compiler to
optimize for those common functions. But I don't think we'll ever have
to do this.
Cheers,
Wolfgang
More information about the Haskell
mailing list