[Haskell-cafe] Haskell as data manipulation language?

Graham Klyne GK at ninebynine.org
Tue Dec 7 05:25:35 EST 2004

I'm struggling to keep up with this list, so I'll make two brief responses 
here.  Sorry to not be more forthcoming:

1. The lack of variables in Haskell isn't a problem so much as an 
opportunity to think in new and interesting ways.

2. I think that when you talk about "versioning", you come close to a 
useful way of thinking about mutable data in Haskell.  My understanding is 
that the "classical" way (i.e. pre-monads) to think of mutable values in 
functional languages was to model them as a time-sequence of intermediate 
values, where a function to "update a state" returns the next value in that 
sequence.  Expressed this way, a practical problem arises that the 
intermediate values don't (necessarily) go away, creating a potential for 
exploding storage requirements.  (If, as with document versioning, you want 
to keep the intermediate values, then you need to figure a way to live with 
this;  value sharing in pure functional languages is a big help here.)  But 
often one is only interested in the "latest" or "current" value in the 
time-sequence.  Monads provide a way of capturing this:  the state is 
implicitly threaded through a sequence of computations (e.g. the 
expressions in a do-list), with old versions thrown away as new ones are 
created (unless the state is explicitly saved, which is not always possible).


At 00:50 04/12/04 -0500, Dimitry Golubovsky wrote:
>I am probably not the first to think about this, yet I was unable to find 
>any signs of activities in this direction, so maybe I will be able to know 
>something from this list.
>First of all, reading multiple messages about global and mutable variables 
>desired in Haskell, I was thinking: isn't the root of the problem in the 
>fact that there are no variables in Haskell at all?
>Indeed (and my experience of digging in Hugs sources confirms) Haskell 
>program (function) is just a description of some memory structure which 
>being completed by the bindings of its arguments, is further transformed 
>by the evaluator into some other data structure, etc.
>Now imagine a data storage with structure similar to one of a Haskell 
>program. I. e. a storage having metadata-objects like data constructor 
>functions,  data types which are parents to data constructors (like in 
>data X = Foo Int | Bar Float), classes, instances, modules, etc. Also data 
>objects themselves, i. e. precompiled and serialized functions along with 
>their type information. Data objects do not differ from functions i. e. 
>they are stored the same way.
>Now quoting Graham Klyne
>Subject was: [HAskell-Cafe] Mutable and persistent values (was: Top Level 
>TWI's again) posted 2004-11-23 05:11:25 PST:
>(I tried to post reply via Google Groups, but it did not make it back to 
>the list):
> > It is my view that use a functional language effectively, it is necessary
> > to think differently about its structure than one would for a conventional
> > imperative program.  Global values become parameters and return
> > values;  mutable values become input values and new (separate) return
> > values.  If you're used to writing imperative programs that do not use
> > global state, but rather use parameters to pass values, the difference
> > isn't always quite as great as might be imagined.
> >
> > For complex values, this sounds horribly inefficient, but because values
> > are pure (not mutable), very high levels of sharing can (sometimes, with
> > good design!) be extensively shared.  Thus, a return value may well consist
> > mostly of a copy of the input value, with differences, rather than actually
> > being a complete new copy.  (Chris Okasaki's book shows well how to design
> > to obtain these benefits.)
> >
> > Also, because Haskell is lazy, complex structures passed between functions
> > don't necessarily ever exist in their entirety.  Sometimes, I think of a
> > data structure as describing a computational traversal through some data,
> > rathert than something that actually exists.  (This leads to very elegant
> > expression of things like Prolog search-and-backtrack algorithms.)
>So, if there is a data object (say, a list) stored with version number N, 
>and another value is cons'ed to the list, then version N+1 will be stored 
>as an application of cons to the value added, and the version N.
>Thus, via versioning, some kind of mutability may be achieved (and of 
>course these check-in and check-out must belong to IO monad).
>These stored functions must be visible to the compiler, and when compiling 
>some function f which calls g (compiled earlier and stored as version N), 
>the code of this version of f (say, M) is built to call version N of g 
>further on. So, all the type checks are done during compilation, and are 
>not necessary during runtime, and yet the functions are compiled and 
>stored separately (trying to address the issue with too large monolithic 
>Newer version of f (say M+1) may be compiled against newer (at that time) 
>version of g (N+1). So different versions of the same function may 
>demonstrate different behaviors, but the "history of development" is preserved.
>Put together, this gives some conceptual image of a "programmable data 
>storage" with queries being calls to stored functions (with externally 
>supplied agruments). All good things of Haskell like static type safety 
>are preserved.
>I am thinking of implementation of something like this using Hugs runtime 
>as the basis. I realize, this may be very time consuming, so I am 
>wondering, maybe someone already is developing something like this?
>Or someone already tried, and found this inefficient or in some other way 
>not feasible to implement?
>Dimitry Golubovsky
>Middletown, CT
>Haskell-Cafe mailing list
>Haskell-Cafe at haskell.org

Graham Klyne
For email:

More information about the Haskell-Cafe mailing list