[Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions

Brian Hulley brianh at metamilk.com
Sun Aug 12 14:05:12 EDT 2007

apfelmus wrote:
> Brian Hulley schrieb:
>>    main = do
>>            buffer <- createBuffer
>>            edit1 <- createEdit buffer
>>            edit2 <- createEdit buffer
>>            splitter <- createSplitter (wrapWidget edit1) (wrapWidget 
>> edit2)
>>            runMessageLoopWith splitter
>> ... Thus the ability to abstract mutable state gives to my mind by 
>> far the best solution.
> I'm not sure whether mutable state is the real goodie here. I think 
> it's the ability to indpendently access parts of a compound state. In 
> other words, the IORef created by  buffer  is a part of the total 
> program state but you can access it independently. There is a 
> functional idiom for that, see also
>   Sander Evers, Peter Achten, and Jan Kuper. "A Functional Programming
>   Technique for Forms in Graphical User Interfaces".
>   http://www.st.cs.ru.nl/papers/2005/eves2005-FFormsIFL04.pdf

Thanks for this reference. This is indeed a real key to the problem. 
(Though a possible downside with compositional references might be 
efficiency as the modified sub-state needs to be injected back into a 
new composite state but perhaps the solution here would be to have 
uniqueness typing as in Clean so that these injections could hopefully 
be erased at compile time.)

I think one of the issues with Haskell is that there are so many 
features to choose from it is difficult to know how to approach a 
problem eg for streams you can have

1) A lazy list
2) A typeclass with get and pushBack methods
3) An object using an existential to wrap (2)
4) A record containing get and pushBack methods
5) A monad with get and pushBack actions
6) A simple function wrapped in a newtype:

          newtype Stream a = Stream (() -> Maybe (a, Stream a))

and I tend to only discover a simple solution like (6) (which works 
equally well for both strict and lazy languages) after spending an 
enormous amount of time on 1,2,3,4,5... ;-)

> - For Graphics, I want to build a graphic from smaller ones and then 
> draw it. I don't want to know how drawing is implemented and what 
> mutable state might be involved.
> - For a GUI, I want to write down the data dependencies and a library 
> converts this to a mesh of mutable state.
> That's what I mean with "higher level functional model".
I agree this would be ideal. A challenge I don't yet know how to solve, 
when dealing with 3d graphics, is that it seems that for efficiency it 
is necessary to consider a mesh of triangles to be an object with 
identity in order to be able to display an updated mesh (eg as the user 
drags a vertex with the mouse) in real time. This is because the 
representation of a mesh is constrained by the low level details of the 
graphics system eg vertices might need to be represented by a contiguous 
array of unboxed positions and normals, and triangles by a contiguous 
array of vertex indices, and it is too expensive to copy these arrays on 
each frame. Perhaps though this is another case where some form of 
uniqueness typing as in Clean could come to the rescue so one could write:

    createMesh :: [Vertex] -> [[VertIndex]] -> Mesh
    moveVertex :: Vertex -> *Mesh -> *Mesh

instead of

    createMesh :: [Vertex] -> [[VertIndex]] -> IO Mesh
    moveVertex :: Vertex -> Mesh -> IO ()

Best regards, Brian.

More information about the Haskell-Cafe mailing list