world as value
Thu, 22 Jul 1999 14:46:27 +0100 (BST)
On Thu 22 Jul, P.R. Serrarens wrote:
> Hmmm. I though we liked a functional approach?
Up to a point, I certainly like the purely functional approach to internal
computation and wouldn't want to give it up without good reason. But I am
begining to have doubts about it as far as issues like IO and program
behaviour are concerned. Determinism is a nice property, but it also comes
at a price in terms of constraints on program behaviour. A lot of these
problems probably don't seem serious because most 'purely functional'
programs are operating on top of a non-deterministic black box (the OS)
which provides handy things like 'non-blocking' IO. In other words, the
program may be deterministic, but the _system_ isn't.
To me the issue is not really functional vs. (sequential) imperative.
The issue is deterministic vs. non-deterministic. My comments about
world as value or IO monads are just as valid for C, Ada, Java...
> So the type of an action should be something like (Action -> a). Yes,
> it is a function, but it does not explicitly use environments.
Action a :== Action -> a ? I don't think so.
In the Haskell IO system is (IO a :== IO -> a)?, no, it's just an
abstract data type. In Clean terms it would be something like..
IO a :== *World -> (*World,a)
But if I'm not using world as value I can't say the same about an Action.
So it also is just an abstract data type, in the sense that _no_ function
can ever look inside it.
> But this will not give you a functional system, but merely a kind of
> coordination language which may use functional expressions.
Yes, that's it, but I don't think there's anything merely about it :-)
> But remember we are working on functional languages: if the result of an
> action is not represented in the result of the program, then this action
> should not have happened, otherwise we loose referential transparency.
Do we really have referential transparency with world as value? I don't
think so, I think it's been lost anyway.
This is is really where we disagree I think. The functional perspective is
that the purpose of a program (the hidden imperative) is to compute a new
world value, (and physical IO occurs as a side effect of this). My
perspective is that generating output is the real purpose of a program, and
computation is a means to that end. So the hidden imperative is to perform
_all_ actions present, even if they have no visible effect on the final
'world value' (because there is no such thing, in my opinion).