world as value

Adrian Hey ahey@iee.org
Fri, 23 Jul 1999 22:32:52 +0100 (BST)


On Thu 22 Jul, Fergus Henderson wrote:
> Yes, we really have referential transparency with world as value.
> That is demonstated by my earlier lengthy posts explaining how you can model
> "world as value" programs as functions from sequences of input events
> to sequences of output events.

Oh well, it seems I'm in a minority of one again. This is not an unusual
situation for me :-)

The problem I have with these models is that to me a model and an
implementation (which is realisable as a computer program in my chosen
language) are entirely different. I take it this isn't the view of the
functional programming community at large :-(  

> Of course the physical world can be a little bit difficult to reason
> about, so it's handy to have a simpler abstract model, like the one
> I discussed in my earlier posts.

I actually think it's far harder to reason about the (hypothetical:-)
limitations of functional programming languages because their worlds seem
to contain an awful lot more than the physical world. So let's strip away
the flesh of IO libraries, OS's and built in environments and consider a
bare bones system which I have to program from the ground up starting with
nothing but hardware (a common situation for embedded systems designers)
using a purely functional programming language. This way we can be
reasonably confident that the *World really is the physical hardware world. 

What IO functions do I need as primitives (because they work by 'magic'),
and what IO functions can be built using these primitives? To perform IO in
the raw, all I really need is to be able to read and write hardware IO
ports or memory locations external to the program. So 2 primitives are
needed...
 in  :: Int *World -> (*World,Int)    // read  an address by magic
 out :: Int Int *World -> *World      // write an address by magic 

What can I do with these? Not a lot really. The best I could do would be
to produce a rigidly deterministic system which sat around polling ports
for input and occasionally evaluated some output (during which time no
more polling could be done). So some more magic is needed. In particular
if the Concurrent Haskell magic of forkIO and MVars is added (possibly
with hardware specific magic to associate MVars with interrupt vectors etc..)
then the situation is changed completely. I think I now have all I really
need to implement a very powerful system. No more magic from IO libraries is
needed (unless I want to produce a real OS which can compile and launch
new programs).

So we're left with the question: Is a Concurrent Haskell program (or
anything similar) purely functional? I got the impression from Simon
Peyton Jones' post that the designers of Concurrent Haskell didn't
consider it to be a purely functional programming language (because
it was no longer deterministic). I also get the impression that you think
otherwise? I don't really know who's right, although I'm inclined to concur
with the Concurrent Haskellians:-)

Regards
-- 
Adrian Hey