[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haskell
Subject:    Re: advice wanted on GUI design patterns
From:       Sven Panne <Sven.Panne () informatik ! uni-muenchen ! de>
Date:       1999-09-28 8:45:42
Message-ID: 37F07F75.80FE6923 () informatik ! uni-muenchen ! de
[Download RAW message or body]

Antony Courtney wrote:
> Havoc Pennington wrote:
> > [...] It seems to me that the event-driven model requires "keeping
> > your data" ina way that Haskell does not provide for, because you
> > need to access "the same" data structure in all your event handlers
> > over time, yet there is no way to communicate between event handlers
> > without updating some fixed memory location...
> 
> Right.  The GUIRef monad provided by TclHaskell allows the programmer to
> perform get and set operations to access/update mutable state.  This at
> least enables the programmer to cleanly seperate the mutable state part
> of the program from the purely functional part.
> [...]

Just a few words for clarification:
In programming languages allowing mutation you have to distinguish
between a value and a location containing a value ("box"). If you
don't mess around with pointers you can easily forget this distinction
in imperative programs, e.g. in C's "x = x + x;" the x on the left
side means something quite different from the x on the right side
(lvalue vs. rvalue). In Haskell you always have to be explicit about
this: There are different kinds of boxes (IORefs, MVars, ...), each
having operations for

   * the creation of a new (typed) box with an initial value in it,
   * getting the value out of a box, and
   * putting a new value into a box

The type of these operations ensure that although actual mutation is
done, nothing "goes wrong" in a functional sense. The different kinds
serve different purposes: "simple" boxes in the IO monad, boxes for
synchronization between threads, etc., see

   http://www.haskell.org/ghc/docs/latest/libraries/libs-9.html
   http://www.haskell.org/ghc/docs/latest/libraries/libs-4.html

In the event-driven model for GUIs this means that you have to share
boxes between your event handlers, not values. Here a some pseudo-code
for this technique:

--------------------------------------------------------
main = do
   ...
   flag <- newIORef False
   registerRedisplayCallback (redisplay flag)
   registerKeyboardCallback (keyboard flag)
   guiMainLoop


redisplay :: IORef Bool -> ...
redisplay flag = do
   flagValue <- readIORef flag
   doSomethingWith flagValue

keyboard :: IORef Bool -> ...
keyboard flag = do
   when somethingHappened $ do
      writeIORef flag newFlagValue
      postRedisplay
--------------------------------------------------------

This shows the following:

   * You can use Haskell like C.   :-}

   * It is explicit which state is shared between the event handlers.

   * For larger programs this box fiddling should better be hidden in
     some GUI abstraction (URLs have already been given in this thread).

Cheers,
   Sven
-- 
Sven Panne                                        Tel.: +49/89/2178-2235
LMU, Institut fuer Informatik                     FAX : +49/89/2178-2211
LFE Programmier- und Modellierungssprachen              Oettingenstr. 67
mailto:Sven.Panne@informatik.uni-muenchen.de            D-80538 Muenchen
http://www.informatik.uni-muenchen.de/~Sven.Panne



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic