world as value

Fergus Henderson fjh@cs.mu.OZ.AU
Fri, 18 Jun 1999 13:53:36 +1000


On 17-Jun-1999, Marco Kesseler <mke@oce.nl> wrote:
> And Fergus wrote:
> >On 17-Jun-1999, Marco Kesseler <mke@oce.nl> wrote:
> >>
> >> Well, wat would be really great is to have a proper interface between
> >> these two paradigms, so than one can use both instead of choosing one.
> >
> >That's exactly what modern "purely functional" or "purely declarative" 
> >languages (e.g. Haskell, Clean, Mercury) give you.
> 
> Not exactly. They allow me to 'do' imperative-like things IN a functional
> paradigm, forcing me to pass around states or to use Monads. That is
> not bad, but it is not the same as giving me the 'good old'
> imperative programming world.

How is using Monads different from "good old" imperative programming?

Is it just the syntax that you don't like?  Haskell has this nice "do"
syntax which makes things look very much like imperative programming.
Perhaps you should nag the Clean team to support "do" syntax.
Mercury too lets you write imperative style programs without explicitly
passing around the state of the world arguments -- Mercury uses DCG
(definite clause grammar) syntax for this.

Is it the lack of mutable variables?  Hugs/ghc have those, as does Mercury.
The syntax for them is not quite as nice as in imperative languages,
but it's not that bad, really.

Is it the lack of imperative-style loop syntax? 
You can easily write higher-order looping functions, e.g.

	while cond action =
	    do  res <- cond
		if res
		    then do 
		        action
		    	while cond action
		    else
		        return ()

and then use them, e.g.

	-- print a table of squares, from 1 to 20
	main =
	    do  x <- newIORef 1		    -- initialize the value of x to 1
		while (testval x (<= 20))   -- loop while the value of x < 20
		    (do xval <- readIORef x
		        putStrLn ((show xval) ++ "\t" ++ (show (xval * xval)))
		      	incr x)		    -- increment the value of x

Here I've used a few utility routines:

	-- apply some action using the value of a variable
	useval var action = do { val <- readIORef var; action val; }

	-- test the value of a variable
	testval var test = useval var (\ val -> return (test val))

	-- increment or decrement the value of a variable
	addto var incr_val =
		useval var (\ val -> writeIORef var (val + incr_val))
	incr x = addto x 1
	decr x = addto x (-1)

newIORef, readIORef, and setIORef are the Hugs/ghc library routines for
manipulating mutable variables.

> >So what's the problem?
> 
> The 'problem' is that I sometimes want to call Clean functions
> easily from C and I can't.

Oh, that's just an implementation problem, I think.
You can do that kind of thing quite easily in Mercury,
and probably in Haskell too, for at least some implementations of Haskell.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.