world as value

Fergus Henderson fjh@cs.mu.OZ.AU
Mon, 21 Jun 1999 19:52:00 +1000


On 21-Jun-1999, Marco Kesseler <mke@oce.nl> wrote:
> >On 17-Jun-1999, Marco Kesseler <mke@oce.nl> wrote:
> >> And Fergus wrote:
> >> >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.
...
> >You can easily write higher-order looping functions, [...]
> >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
> 
> Why is this better than the following?
> 
> main ()
> {
>     int x;
>     for (x = 1; x <= 20; x++)
>         fprintf (stdout, "%d\t%d\n", x, x * x);
> }

It's not.  I never said it was.
I was only arguing that it is not much worse.

You had said that what modern purely declarative languages gave you
was not the same as the "good old" imperative programming world;
I argue that they do give you basically the same thing, or at least
something which is similar enough that it is not much worse.

> >> 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.
> 
> Indeed, it is.
> 
> >You can do that kind of thing quite easily in Mercury,
> >and probably in Haskell too, for at least some implementations of Haskell.
> 
> I do not know enough about Mercury to comment on this.
> How does Mercury deal with passing lazy streams/pipes, higher
> order functions, C structs (including ptrs to other structs),
> between Mercury and C?

Data structures defined in one language are treated as opaque data types
in the other language.  If you want to access C data structures from Mercury,
then you write some little access functions in C and export them to Mercury.
Likewise if you want to access Mercury data structures from C, then
you write some little access routines in Mercury and export them to C.

For example, the Mercury tcl/tk interface contains a higher-order predicate
for registering event handlers.  You pass it a closure (higher-order term)
representing the handler, and when the appropriate event occurs, tcl/tk will 
call a C function in the Mercury tcl/tk interface which will invoke this
closure.  The Mercury code in the Mercury tcl/tk interface contains a
function named "call_mercury_closure" which gets passed a higher-order
predicate and some arguments and simply applies the given predicate to
those arguments.  This function is exported to C, and is used by the C
code when it needs to invoke a closure.

-- 
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.