Fudgets – Purely Functional Processes with applications to Graphical User Interfaces

Magnus Thomas Carlsson Hallgren

Department of Computing Science 1998

Do ctoral thesis for the degree of Do ctor of Philosophy

Fudgets

Purely Functional Pro cesses

with applications to

Graphical User Interfaces

Magnus Carlsson

Thomas Hallgren

EKNISKA T H S O R G E

S

M K

L

O

A

L

H A C G O G

TEBOR

Department of Computing Science

Chalmers University of Technology

Gteb org University

S Gteb org Sweden

Gteb org

ISBN

ISSN X

httpwwwcschalmerssehallgrenThesis

Department of Computing Science

Gteb org

Abstract

The main result of this thesis is a metho d for writing programs with graphical

user interfaces in purely functional languages The metho d is based on a new

abstraction called the fudget The metho d makes go o d use of key abstraction

p owers of functional languages such as higher order functions and parametric

p olymorphism

The Fudget concept is dened in terms of the simpler concept of stream

processors which can b e seen as a simple but practically useful incarnation

of the pro cess concept Programs based on fudgets and stream pro cessors are

networks of communicating pro cesses that are built hierarchically using combi

nators Communication is typ e safe The basic combinators provide serial com

p ositions parallel comp ositions and lo ops A key dierence b etween previous

work on stream pro cessing functions and our approach is that we delib erately

abstract away from the streams We obtain a system that can b e implemented

deterministically entirely within a purely functional language but which also

makes it p ossible to take advantage of parallel evaluation and indeterminism

where such is available within the functional language The purely functional

approach makes pro cesses rst class values and makes it easy to express pro cess

cloning and pro cess migration

The practical viability of the approach is demonstrated by the Fudget li

brary which is an implementation of a graphical user interface to olkit in the

purely functional language Haskell together with a numb er of small an large

applications that have b een implemented on top of the library

In addition to GUI programming fudgets are suitable for other forms of

concurrent IO programming We demonstrate how clientserver based appli

cations can b e we written with typ e safe communication b etween client and

server We show a web browser as an example where GUI programming and

network communication come together

We view fudgets as one example of a more general combinatorbased ap

proach to promote the idea that a functional language together with combina

tor libraries is a go o d alternative to using less expressive languages propp ed

by applicationsp ecic to ols We describ e a set of combinators reminiscent of

parsing combinators for building syntaxdirected editors

Preface

This monograph acts as theses for b oth authors Most of the work b ehind has

b een carried out in close co op eration b etween the authors but some chapters

present work of a more individual nature

Thomas Hallgren Chapters and He has also develop ed the ap

plications in Part V some contributions are due to Magnus Carlsson in

Chapters and though

Magnus Carlsson Chapters and

Acknowledgements

We wish to thank Thomas Johnsson Lennart and Jessica Augustsson Johan

Nordlander Bengt Nordstrm Niklas Rjemo David Sands Colin Runciman

and Simon Peyton Jones for pro ofreading and numerous suggestions for im

provements on drafts of the thesis A sp ecial thanks to Ola Freijd who has

made all illustrations and the cover page

Ideas and implementation work by a numb er of p eople have increased the

usefulness of the Fudget library Jan Sparuds spaceleak x in an early ver

sion suddenly made it p ossible to run fudget programs until someb o dy pulls the

plug Jan also implemented an initial version of the name layout mechanism

Lennart Augustssons integration of the Xlib interface with HBCs runtime sys

tem made fudget programs easier to use and more ecient John Hughes in

vented the default parameter simulation which made fudget programming much

more pleasant

The department of Computing Science has not only provided a wealth of

academic stimulus but also technical and administrative supp ort that has shown

a exibility of unusual quality Esp ecially we want to thank Christer Carlsson

Grgen Olofsson Marie Larsson Per Lundgren and Hasse Hellstrm

Part of our work has b een supp orted by NUTEK

Historical reections

Once up on a time on a gray autumn day in three functional programmers

were chatting during a coee break They were quite happy that the LML

compiler AJ allowed them to write real programs in a pure functional

language One of these three had implemented a version of the game Tetris in

LML Another had implemented Worms an interactive multiuser realtime

game Hal They had no eciency problems with these kinds of programs

even though the computers of that time were times slower than the ones

we use to day

But at that time the three functional programmers were b eginning to use

graphical workstations instead of simple text terminals They were unhappy

ab out the fact that they did not have a way to write programs with graphical

user interfaces in their functional language

The two younger of the three functional programmers decided to start work

ing on a solution to this problem The older of the three was a bit skeptical

and said that it would probably not b e p ossible to obtain a solution that was

ecient enough to write real programs with

The two younger implemented an interface that allowed LML programs to

talk to the X Windows system They also designed an abstraction to b e used

as the basic building blo ck when constructing graphical user interfaces This

abstraction was later named the Fudget

The rst X Windows interface was implemented as a separate program that

the LML program could talk to via ordinary text IO The oldest programmer

later integrated the interface with the runtime system of the LML compiler

making the interface much more ecient

Approximately one year later the two younger functional programmers felt

they had a reasonably ecient system and a fairly nice abstraction They wrote

a pap er ab out it and it was accepted at a functional programming conference

CHb One of the younger functional programmers wrote some more ab out

it and turned it into a licentiate thesis CHa

The work continued A numb er of improvements to make it easer to write

programs were made and the library was converted into Haskell Improvements

to the layout system allowed layout and plumbing to b e sp ecied separately A

lot of distracting extra function arguments could b e removed after a parameter

passing mechanism with default values was intro duced The resulting version of

the Fudget library was presented at the Spring Scho ol on Advanced Functional

Programming in Bstad in HC

Contents

Preface

Acknowledgements : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Historical reections : : : : : : : : : : : : : : : : : : : : : : : : : : : :

I Intro duction

Programming by combination : : : : : : : : : : : : : : : : : : : : : :

Combinator libraries replace to ols : : : : : : : : : : : : : : : : : : :

Declarative programming and inputoutput : : : : : : : : : : : : : :

IO in functional languages : : : : : : : : : : : : : : : : : : : : : :

What is a Fudget : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Contributions of the thesis : : : : : : : : : : : : : : : : : : : : : : :

Roadmap : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

II Programming with Fudgets

A brief intro duction to Haskell : : : : : : : : : : : : : : : : : : : : :

Your rst Fudget programs : : : : : : : : : : : : : : : : : : : : : :

Fudget library GUI elements : : : : : : : : : : : : : : : : : : : : : :

Sp ecifying layout : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Abstract fudgets : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Fudget plumbing : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Fudgets for nonGUI IO : : : : : : : : : : : : : : : : : : : : : : : :

Parameters for customisation : : : : : : : : : : : : : : : : : : : : :

III Stream pro cessors the essence of Fudgets

Stream pro cessors : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Plumbing comp osing stream pro cessors : : : : : : : : : : : : : : :

Pragmatic asp ects of plumbing : : : : : : : : : : : : : : : : : : : :

Application programming with plain stream pro cessors : : : : : : :

IV Design and implementation

Implementing stream pro cessors : : : : : : : : : : : : : : : : : : : :

Fudgets as stream pro cessors : : : : : : : : : : : : : : : : : : : : : :

Fudget IO the gory details : : : : : : : : : : : : : : : : : : : : : :

Automatic layout : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Filter fudgets : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Moving stream pro cessors : : : : : : : : : : : : : : : : : : : : : : :

Typ ed so ckets for clientserver applications : : : : : : : : : : : : :

Displaying and manipulating graphical ob jects : : : : : : : : : : : :

CONTENTS

Combinators for syntaxoriented manipulation : : : : : : : : : : : :

Typ e directed GUI generation : : : : : : : : : : : : : : : : : : : : :

Parameters for customisation : : : : : : : : : : : : : : : : : : : : :

Gadgets in Fudgets : : : : : : : : : : : : : : : : : : : : : : : : : : :

V Applications

WWWBrowser a WWW client : : : : : : : : : : : : : : : : : : :

Alfa a pro of editor for typ e theory : : : : : : : : : : : : : : : : :

Humake a distributed and parallel make to ol for Haskell : : : :

Space Invaders realtime and simulation : : : : : : : : : : : : : :

FunGraph : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

A mobile data communication proto col prototyping to ol : : : : : :

Two b oard games : : : : : : : : : : : : : : : : : : : : : : : : : : : :

VI Discussion

Eciency and program transformations : : : : : : : : : : : : : : : :

Comments on Haskell and other language design issues : : : : : : :

Related work : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Evaluation and conclusions : : : : : : : : : : : : : : : : : : : : : : :

Future work : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

A Online resources

A The Fudgets Home Page : : : : : : : : : : : : : : : : : : : : : : :

A Supp orted platforms downloading and installation : : : : : : : : :

A Compiling Fudget programs : : : : : : : : : : : : : : : : : : : : :

B Fudget library quick reference guide

B Top level main program : : : : : : : : : : : : : : : : : : : : : : :

B GUI building blo cks widgets : : : : : : : : : : : : : : : : : : : :

B Combinators plumbing : : : : : : : : : : : : : : : : : : : : : : : :

B Adding applicationsp ecic co de : : : : : : : : : : : : : : : : : : :

B Layout : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

B Graphics : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :

B Alphab etical list : : : : : : : : : : : : : : : : : : : : : : : : : : : :

Pro duction notes

Bibliography

I Intro duction

Programming by combination

This thesis is to a large extent oriented around programming by combination

By this we mean the imp ortant programming metho d where you make programs

by combining subprograms The inner details of the subprograms can then b e

abstracted from which makes it p ossible for the human brain to create and

understand very complex programs This metho dology has of course b een

practised for many decades in various programming languages However it is a

metho d that sometimes is forgotten and often only used in parts of a program

for example when doing tasks related to the op erating system

For programming by combination to b e p ervasive it is imp ortant not only

that we have access to a go o d library of subprograms but the programming

activity must also deal with forming new subprograms suitable for combination

Otherwise the variety of programs we can write b ecomes limited b ecause they

get to o complex Therefore programming by combination is also ab out forming

new levels of subprograms

One imp ortant asp ect of programming is of course which programming

language one uses Dierent programming languages vary strongly in the sup

p ort they give us when we want to program by combination This is esp ecially

true when it comes to forming new subprograms The authors have found that

programming languages which are based on the declarative style are suitable in

this resp ect Declarative programming languages allow us to write programs in

a mathematical style For example consider the expression

fa b a b

In a declarative programming language we might identify a subprogram which

we can name average

let average a b

in faverageaverage

It is imp ortant that the activity of forming subprograms should b e as easy as

p ossible for the programmer If the programmer is required to write many

more characters than are shown in the previous example another programming

metho d might b ecome more attractive namely programming by copy and paste

This will so on result in programs which are complex to understand and maintain

but unfortunately it is a to o widely practised metho d

The previous example did not actually intro duce a subprogram It could

simply b e seen as declaring a lo cal variable However in declarative program

ming languages we can use the same style when we want to form subprograms

The expression

faab faac faad

uses a recurring calling pattern to the function f This pattern is easily captured

by a subprogram that we can call f

let fx faax

in fb fc fd

Forming a corresp onding subprogram in the p opular programming language C

for example would b e more involved We would rst need to declare a new

toplevel function then make sure that its name did not collide with some other

toplevel function in the same source le and nally the function would need

an extra parameter for the variable a All parameters would need some typ e

declaration

As a more advanced example of programming by combination in declarative

style we might consider parsing combinators BurWad from now on

we will often talk ab out combinators when we mean subprograms which are

designed for versatile combination A large numb er of text parsers can b e

formed by four combinators

 tokenc which accepts the character c

 p q which forms an alternative it either accepts whatever the parser

p accepts or it accepts whatever the parser q accepts

 p q which forms a sequence it rst accepts whatever p accepts and

then accepts whatever q accepts when given the rest of the text

 epsilon which parses the empty string

From these combinators a programmer might build more useful combinators

Here is a combinator which can b e used for parsing things within parentheses

withinParenthesesp token p token

Or we might declare the combinator manyp which forms a parser which ac

cepts whatever p accepts zero or more times in a sequence this is often written

p

manyp p manyp epsilon

Note that in most of these combinators we have used the p ossibility to param

eterise over subprograms which is another imp ortant feature that declarative

programming languages naturally supp ort

Declarative programming and inputoutput

Combinator libraries replace to ols

Why would we want to use parsing combinators when we could instead use a

parser generator to ol A parser generator like Yacc Joh comes with a sp ecial

programming language suitable for the task of sp ecifying parsers Although this

is a quite p owerful to ol it comes with a price in that we have to learn this new

programming language Other to ols for example for sp ecifying graphical user

interfaces also come with their own domainsp ecic programming languages

Although they are often sup erb in many cases they all have in common that

the programmer must learn a quite new syntax and often the p ossibilities for

the programmer to form new abstractions are p o or In the case of Yacc it is

not p ossible to express the abstraction withinParentheses for example It is also

hard or imp ossible to share abstractions b etween the dierent to ol languages

and the programmers general programming language something which adds to

the overall complexity of a software system

To return to our example parsing combinators allow us to smo othly integrate

parsers in our software without any additional to ols languages or compilers We

only need a library for parsing combinators More generally combinator libraries

can b e seen as dening an emb edded language inside our general programming

language This way the numb er of concepts a programmer has to learn decreases

drastically since the general programming languages idioms apply directly

However it should b e noted that combinator libraries often miss features

that sp ecialised to ols have like eciency It is a challenge for creators of

combinator libraries to catch up with this

Declarative programming and inputoutput

In later sections we will describ e how one can use combinators for programming

inputoutput But b efore that we will discuss how output can b e done in a

declarative programming language Output from a program can also b e seen as

an eect that the program has on the outside world When combining eects

their order is often highly imp ortant the reader might want to try dierent

combinations of the eects Op en do or and Walk through do or for exam

ple This is an imp ortant asp ect which we must have in mind when considering

subprograms for dening eects

There are two widely used styles for dealing with eects in declarative pro

gramming languages We either allow all subprograms to directly have eects

on the outer world or we only allow subprograms to return values that represent

eects

Consider a subprogram in a programming language using direct eects If

the subprogram is a function that returns some value it is often said that the

function can have a side eect while computing its value The order in which

these side eects happ en is made precise by dening a computation order for ex

pressions This is most easily done by saying that all arguments to subprograms

should b e computed left to right and then the subprogram is called Also an

expression which uses a lo cal denition should compute the denition b efore the

expression Such programming languages are called strict

Side eects can interact with the programmers activity of forming new sub

programs or naming sub expressions For example it is no longer clear that we

could write

let average a b

in faverageaverage

instead of

fa b a b

b ecause a p otential side eect of the subprogram a would b e carried out once

in the rst case but twice in the second

Another problem with combinator programming in strict programming lan

guages is that we must b e much more careful when dening combinators in

terms of themselves If we use the denition

manyp p manyp epsilon

for many we end up in an innite lo op if arguments are computed strictly

It is a very desirable feature of a programming language that subprograms

do not have side eects This feature is used in the nonstrict purely functional

programming languages that we will use in the rest of this thesis The term

purely functional means that it is guaranteed that a function always return

the same value if its arguments have the same value and that it do es not have

any side eect More generally if the same expression o ccurs in many places as

a ab ove for example it is guaranteed that all those o ccurrences compute to

the same value It is only in a purely functional programming language that we

can intro duce the variable average in the previous example regardless of what

a and b are

In purely functional languages we use the second way of dealing with ef

fects where subprograms may return values that represent eects instead of

p erforming them directly A representation of an eect can then b e combined

with other representations of eects yielding a new representation of an ef

fect Finally the eect that our whole program represents is carried out This

means that issues of eects and computations are separated When dening and

combining eects we do not have to b other ab out which parts of our program

should b e computed how many times they might b e computed and in which

order

Having combinators that return representations of eects op ens up the p os

sibility to manipulate these eects b efore they are carried out This can b e used

to adapt the eects of existing combinators to new situations

In what follows we will often sp eak ab out combinators having various eects

or doing various kind of inputoutput At times it will b e convenient to think

that the combinators actually p erform these eects directly but it is imp ortant

to rememb er that they only dene a representation of an eect

IO in functional languages

A program in a pure functional language is an expression that denotes the

eect that the program should have on the outside world when the program is

IO in functional languages

Program

Characters Characters

Figure A program and a user interacting via a text terminal

executed The question we turn to now is how are the basic eects sp ecied

and how are eects combined

Supp ose the outside world is a simple text terminal see Figure Then

the interesting eects are outputting characters to the terminal screen and

inputting characters from the terminal keyb oard The b ehaviour of a program

could b e describ ed by a sequence of the basic eects so it is natural to use

sequential compositions of eects to build programs with nontrivial b ehaviour

This is what is provided in the typical imp erative languages As an example

consider a program that reads some numb ers separated by white space and

outputs the sum of the numb ers In an imp erative language it would lo ok

something like this

program sumNumb ers

sumNumb ers acc

if endofinput

then putNumb er acc

else do n getNumb er

sumNumb ers accn

getNumb er

putNumb er

We can identify the subprograms getNumb er and putNumb er as reusable com

p onents By taking a step back and reecting on what a program is we can

p erhaps nd ways of comp osing programs other than the sequential comp osition

of eects Having more versatile ways of comp osing programs is likely to give

us more opp ortunities to construct reusable subprograms

We cho ose to view programs as dening stream processors that is a program

describ es some kind of pro cess that consumes an input stream and pro duces an

Figure A stream pro cessor

output stream This view go es back to Landin Lan We use the symb ol

shown in Figure to denote a stream pro cessor

A stream pro cessor can b e seen as a function on streams A program that

interacts with a text terminal could b e seen as a function from a stream of

characters to a stream of characters When the program is run the function is

applied to the stream of characters received from the keyb oard and the resulting

stream of characters is output to the screen

In a lazy functional language streams can b e represented as ordinary lists A

program that interacts with a text terminal can thus b e built using ordinary list

functions The typical lazy functional solution to the numb ersumming problem

lo oks something like this

program show sum map read words

The input stream is chopp ed into words the words are converted to numb ers

the numb ers are summed and converted back into characters that can b e output

to the screen

Let us compare this solution with the imp erative one In b oth solutions

subprograms for parsing and printing numb ers are reusable In the functional

solution the numb ersumming function is reusable as well And although we

have used a standard function to sum a list of numb ers the ab ove program can

execute in constant space since in a lazy language computations are p erformed

on demand Likewise input from the terminal is read on demand allowing

the computation of the sum to b e interleaved with the reading and parsing of

keyb oard input If we tried to use the sum function in the imp erative solution

we would rst have to read all the numb ers and store them in a list and then

call the sum function The program would thus not run in constant space

In the functional solution the program is no longer expressed as a comp o

sition of basic eects Instead we have built the program from a numb er of

stream pro cessors in a pip e line

We have now seen two ways of describing stream pro cessors

 the basic way of using sequential comp osition of IO op erations

 the more highlevel way of using serial comp osition of stream pro cessors

What is a Fudget

Previously we lo oked at programs that communicate with a text terminal We

now rene the view of the outside world and consider graphical user interfaces

GUIs In contrast to the typical text terminal program which interacts with

the user through a dialogue and thus is sequential in nature programs with

What is a Fudget

Counter

Display Button

Figure The desired program structure of the counter example

graphical user interfaces interact with the user by showing a window which can

b e seen as a control panel providing various control and indicator devices The

various devices exist in paral lel in the window and their resp ective b ehaviours are

mostly indep endent of other devices This suggest that programs with graphical

user interfaces should b e built using some kind of paral lel composition rather

than sequential comp osition

To illustrate what kind of program structure we are lo oking for take a lo ok

at the counter example pun intended The user interface should contain two

GUI elements a button and a numeric display Each time the button is pressed

the numb er in the display is incremented We would like the program to contain

one stream pro cessor p er GUI element taken from a library often called GUI

to olkit or widget set and an applicationspecic stream pro cessor that counts

the button presses and outputs numb ers to the numeric display The stream

pro cessors should b e connected as in Figure The key idea is that stream

pro cessors from the library handle the lowlevel details of the GUI elements

and the co de that the application programmer writes communicates with the

GUI elements on a higher level of abstraction

GUI elements can b e seen as a particular kind of IO device that a program

can communicate with The idea naturally extends to communication with

other typ es of IO devices such as other computers on the Internet

Our solution to building programs with this structure in a purely functional

language is based on a sp ecial kind of stream pro cessor the Fudget see Fig

ure Fudget is an abbreviation of functional widget where widget is an

abbreviation of window gadget A fudget has b oth lowlevel streams and high

level streams The lowlevel streams are always connected to the IO system

allowing the fudget to control a GUI element by receiving events and sending

commands to the window system The highlevel streams can carry arbitrary

usually more abstract values and they connect the fudgets that make up a

program in an applicationsp ecic way

We will write the typ e of a fudget as

F hi ho

where hi and ho are the typ es of the messages in the highlevel input and output

streams resp ectively

ho hi High level messages

Low level requests & responses

I/O system

Figure The Fudget

Figure Serial comp osition parallel comp osition and lo op

The highlevel streams b etween fudgets are connected by the programmer

using combinators Three basic ways to combine fudgets and stream pro cessors

in general are serial composition paral lel composition and loops see Figure

The typ es of these combinators are

F a b F c a F c b serial composition

F a b F a b F a b paral lel composition

lo opF F a a F a a loop

These simple ideas allow programs with graphical user interfaces to b e built in

a hierarchical way using a declarative style For example the counter example

can b e expressed as

displayF counterF buttonF Increment

that is a serial comp osition of three fudgets where displayF and buttonF handle

the widgets that the user interacts with and counterF just counts the button

presses

Serial comp osition is closely related to ordinary function comp osition With

this in mind one can see that the program has much the same structure as the

Landin stream IO numb ersumming example shown in Chapter Examples

like this one will b e explained further in Chapter

Roadmap

Contributions of the thesis

The work presented in this thesis started with the desire to write programs

with graphical user interfaces in a purely functional language We also wanted

to implement the GUI to olkit itself in the functional language The questions

we asked ourselves were

 Would the features of functional languages b e appropriate for this task

Functional languages were known to b e weak when it came to IO Im

plementations of GUI to olkits had traditionally b een done in an ob ject

oriented style Lacking features such as subtyp es inheritance and paral

lelism would a functional language still suce

 Would implementations of functional languages b e ecient enough to cop e

with the p otentially large volume of IO and high requirements on re

sp onse times

We b elieve that the thesis shows that the answer is yes to b oth of these questions

The main result of the work b ehind this thesis is the Fudget library which is

an implementation of the ideas outlined in the previous section Among other

things it provides

 typ es and combinators for fudgets and stream pro cessors

 a GUI to olkit providing the usual widgets and

 supp ort for network communication

The Fudget library shows how a concurrent programming paradigm can b e

implemented and applied in a purely functional programming language

We demonstrate the practical usefulness of the Fudget library by presenting

a numb er of application programs some of which are quite large A numb er

of programming styles and metho ds are presented which can b e used when

programming with Fudgets

Roadmap

 Part II deals mainly with what a programmer can do with Fudgets It

b egins with a brief intro duction to Haskell Chapter The next chapter

is a tutorial Chapter where a numb er of fudget programs are presented

ranging from the tiniest Hello world fudget to a simple calculator and

continues with an overview of the most imp ortant stu that a programmer

can use in the Fudget library This includes an overview of some basic

GUI building blo cks Chapter how to sp ecify layout Chapter a

description of how to attach applicationsp ecic co de to the Fudget library

comp onents Chapter how to combine fudgets Chapter and how

to customise fudgets Chapter

 Part III distills the fudget concept to get stream processors which can

b e regarded as a simplication of fudgets that do not necessarily need

IO The last chapter in this part Chapter gives some programming

examples using plain stream pro cessors

 The reader interested in how the Fudget library works can continue with

Part IV which is devoted to the design and implementation It also de

scrib es extensions and programming metho ds as outlined further in its

intro duction The last chapter Chapter describ es how an existing

functional GUI to olkit was implemented on top of Fudgets

 Part VI starts with a discussion of the eciency of Fudget programs

in Chapter and suggests some p ossible program transformations for

sp eedup In Chapter we comment on the programming language

Haskell itself describ e some problems and discuss extensions Chap

ter discusses related work and presents a numb er of other functional

GUI to olkits that have emerged Chapter contains a brief evaluation

and conclusions Some suggestions for future research including a more

formal study of stream pro cessors is given in Chapter

II Programming with

Fudgets

The fudget concept and the Fudget library was rst conceived and designed as

an aid in constructing graphical user interfaces in a lazy functional language

Although the Fudget library now supp orts other kinds of IO the main part of

the library still relates to GUI programming

In the Fudget library each GUI element is represented as a fudget The

library provides fudgets for many common basic building blo cks like buttons

p opup menus text b oxes etc The library also provides combinators that allow

building blo cks to b e combined into complete user interfaces

This section intro duces the Fudget library by presenting a numb er of GUI

programming examples They illustrate the basic principles of how to create

complete programs from GUI elements and applicationsp ecic co de After the

examples follows an overview of the library We show

 some common GUI fudgets from the library

 how to sp ecify the layout of GUIs

 dierent ways of writing abstract fudgets and intro duce stream pro ces

sors

 combinators for building networks of fudgets and

 a scheme for parameter passing with default values

A brief intro duction to Haskell

The purely functional programming language that we will use in the rest of

the thesis is Haskell Pet An intro duction can b e found at HPF and

there are also two rep orts that dene the language and its standard libraries

PHbPHa

We b elieve that the program examples will b e readable without detailed

knowledge of Haskellfamiliarity with some functional language is hop efully

sucient However some recurring patterns are p erhaps worth explaining

 Haskell uses layout indentation rather than delimiting character to sep

arate declarations branches in case expressions etc

 Anonymous functions are written using and for example x x

is the identity function

 The op erator is function comp osition

 The op erator is just function application that is f x f x It is

right asso ciative and has low precedence so it can b e used to avoid nested

parentheses We often write expressions like

f g h x x

instead of

f g h x x

 An ordinary alfanumeric identier can b e used as an inx op erator by

enclosing it in back quotes We sometimes write for example

f x ap y

instead of

ap f x y

 Inx op erators are turned into functions that can b e passed as arguments

by enclosing parentheses For example is equal to x y x y

Op erators can b e partially applied using sections again using parentheses

For example is the function x x and is the function x

x

 The Haskell syntax for tuples lists and functions is chosen so that a typ e

and the values of the typ e lo ok similar For example the typ e of the tuple

Falsefudget is IntBo olString the typ e of the list is Int and

the typ e of the function x x is a a

 In typ e expressions names starting with lower case letters are typ e vari

ables and names starting with upp er case letters are typ e constructors

 We often use the Haskell standard typ e Either for disjoint unions dened as

A brief intro duction to Haskell

data Either a b Left a Right b

and the typ e Mayb e for optional values dened as

data Mayb e a Nothing Just a

 The result of a Haskell program is the value b ound to the identier main

This value should b e a representation of the eect as discussed in Chap

ter the execution of the program should have on the outside world A

program can b e as simple as

main print Hello world

A unique feature of Haskell is the type class system WB which is a system

atic treatment of overloading A type class declaration intro duces a numb er of

functions that will b e overloaded An instance declaration gives denition of the

overloaded functions for a particular typ e For example a standard typ e class

in Haskell is the class for typ es that supp ort equality

class Eq a where

a a Bo ol

To allows b o olean values to b e tested for equality with the op erator an

instance declaration like the following can b e used

instance Eq Bo ol where

True True True

False False True

False

For some standard typ e classes instance declarations can b e generated auto

matically by adding a deriving clause to the typ e denition

data Bo ol False True deriving Eq

When an overloaded function is used in a new function denition the overload

ing may b e inherited by the new function For example consider the function

elem that checks if a value o ccurs in a list dened as

x elem False

x elem yys xy x elem ys

The typ e of elem is written

elem Eq a a a Bo ol

where the part Eq a is called a context It means that the typ e variable a is

restricted to range over typ es that are instance of the Eq class

In Haskell the class system was generalised to allow classes of typ e

constructors Jon instead of just classes of base typ es Typ e variables were

extended to range over typ e constructors This means a that typ e scheme like

a Int is allowed The typ e variable a can b e instantiated to for example Mayb e

and the list typ e constructor giving the typ es Mayb e Int and Int resp ectively

The well known function map

map ab a b

which is dened for lists in many functional languages can now b e generalised

by intro ducing the class Functor

class Functor f where

map ab f a f b

Instances for the lists and the Mayb e typ e can b e dened as

instance Functor where

map f

map f xxs f x map f xs

instance Functor Mayb e where

map f Nothing Nothing

map f Just x Just f x

However the intro duction of constructor classes was motivated by the change

to monadic IO see Section and a convenient syntax for monadic pro

gramming The class Monad is dened as

class Monad m where

return a m a

m a a m b m b

and the sp ecial do syntax for monadic expressions

do x m

1 1

x m

2 2

m

n

is dened to mean the same as

m x

1 1

m x

2 2

m n

Your rst Fudget programs

Your rst Fudget programs

In the following we present simple GUI programming examples For each

example we show a window snapshot the program text and explain the ma jor

p oints of the example To keep the size of the presentation reasonable many

unimp ortant details are delib erately left unexplained The reader is referred to

the Fudget Library Reference Manual CH for full information In addition

the WWW version of this thesis contains hyp er links into the Reference Manual

for many combinators and typ es The WWW version is lo cated at

httpwwwcschalmerssehallgrenThesis

The window snapshots were made on a Unix workstation running the X Win

dows system and a window manager providing Windowslike window frames

For practical details such as where to get the Fudget library which platforms

are supp orted and how to compile programs see App endix A

Hello world

We b egin with a simple program that only displays a mes

sage in a window This example illustrates what the main

program should lo ok like as well as some other practical

details As the window dump shows the window manager

adds a title bar to the message

Here is the source co de

imp ort Fudgets

main fudlogue shellF Hello lab elF Hello world

Note

 To use the Fudget library the mo dule Fudgets should b e imp orted

 A fudget program consists of a numb er of fudgets combined in a hierar

chical structure that makes up one main fudget The function fudlogue

fudlogue F a b IO

connects the main fudget to Haskells IO system thus starting a dialogue

b etween them It sets up the communication with the window system

gathers commands sent from all fudgets in the program and sends them

to the window system and distributes events coming from the window

system to the appropriate fudgets

 A fudget program with a graphical user interface needs one or more shell

windows toplevel windows These can b e created with the function

shellF

shellF String F a b F a b

which given a window title and a fudget creates a shell window containing

the graphical user interface dened by the argument fudget The fudgets

for GUI elements like lab elF can not b e used directly on the top level in

a program but must app ear inside a shell window

The factorial function

 In this simple program the contents of the shell window are merely a

simple string lab el that is created with the function lab elF

lab elF Graphic a a F b c

The argument is the lab el to b e displayed The lab el can b e a value of any

typ e that is an instance of the Graphic class The Fudget library provides

instances for many predened typ es including strings The Graphic class

is discussed in Section

Both the input and output typ es of lab elF are typ e variables that do not

o ccur anywhere else This indicates that none of the highlevel streams

are used by lab elF

lab elF has only one parameter the lab el to b e displayed Most GUI fud

gets come in two versions a standard version like lab elF and a customis

able version for example lab elF which allows you to change parameters

like fonts and colors for which the standard version provides default val

ues See Chapter for more details

 The size and placement of the GUI elements need not b e sp ecied The

fudget system automatically picks a suitable size for the lab el and the size

of the shell is adapted to that

Useful programs of course contain more than one GUI element The next ex

ample will contain two GUI elements

The factorial function

This program illustrates how data is communicated b etween

dierent parts of a Fudget program It illustrates a simple

way to combine applicationsp ecic co de in this case the fac

torial function with GUI elements from the Fudget library

The program shows a numeric entry eld at the b ottom

and a numb er display at the top Whenever the user enters

a numb er in the entry eld and presses the Return key the

factorial of that numb er is computed and displayed in the

numb er display

Here is the source co de

imp ort Fudgets

main fudlogue shellF Factorial facF

facF intDispF mapF fac intInputF

fac

fac n n fac n

Note

 The program facF is structured as a serial comp osition of three parts using

the op erator Notice that as with ordinary function comp osition

data ows from right to left The parts are

Your rst Fudget programs

the numeric entry eld intInputF

mapF fac an abstract fudget a fudget without a corresp onding GUI

element that applies fac the factorial function to integers received

from the entry eld and

the numb er display intDispF which displays the computed factorials

 We have used fudlogue and shellF on the top level as in the previous ex

amples Section

The typ es of the new library comp onents used in this example are

F a b F c a F c b

intInputF F Int Int

mapF a b F a b

intDispF F Int a

Although this program do es something useful at least compared to the two

previous examples it could b e made more user friendly eg by adding some

explanatory text to the user interface The next example shows how to do this

The factorial function with improved layout

This program shows how to use layout combinators to

improve the visual app earance of a Fudget program

We have made the factorial function example from

Section more self do cumenting by adding lab els to

the entry eld and the output display We have also

changed the order of the two parts the entry eld is

now ab ove the display

Here is the source co de

imp ort Fudgets

main fudlogue shellF Factorial facF

facF placerF revP verticalP

x labLeftOfF intDispF

mapF fac

x labLeftOfF intInputF

fac

fac n n fac n

Note

 We have used the function labLeftOfF to put lab els to the left of the entry

eld and the display In Haskell back quotes can b e used to turn any

function into an inx op erator as we have done with labLeftOfF here

An up counter

 The function placerF can b e applied to a comp osition of fudgets to sp ecify

the relative placement of the parts The layout system automatically

picks some placement if layout is left unsp ecied The rst argument to

placerF is a placer in our case revP verticalP where verticalP causes the

parts to b e stacked vertically with the leftmost fudget in the comp osition

at the top and revP reverses the order of the parts

 Everything else is as in the previous examples

The typ es of the new library comp onents used in this example are

labLeftOfF Graphic a a F b c F b c

placerF Placer F a b F a b

revP Placer Placer

verticalP Placer

An up counter

This program illustrates a more general way to com

bine applicationsp ecic co de with GUI elements from

the Fudget library It illustrates that state information

can b e encapsulated State information is often consid

ered as dicult to handle in pure functional languages

hop efully this counter example shows how easy it is

This program has a button and a numeric display

Pressing the button increments the numb er in the display

The applicationsp ecic co de in this example sits b etween the button and

the display It maintains an internal counter which is incremented and output

to the display whenever a click is received from the button

Here is the source co de

imp ort Fudgets

main fudlogue shellF Up Counter counterF

counterF intDispF mapstateF count buttonF Up

count n Click nn

Note

 As with the factorial example Section the central part of the program

counterF is a serial comp osition of three parts At the output end we see

the familiar intDispF At the input end of the pip e line is a button created

with buttonF It outputs a Click when pressed The middle comp onent

maintains an internal counter The counter is incremented and output to

the display when a Click is received from the button

 mapstateF like mapF allows messages sent b etween fudgets to b e pro

cessed in an applicationsp ecic way With mapstateF an arbitrary num

b er of messages can b e output as resp onse to an input message In ad

dition the output can dep end not only on the current input but also on

Your rst Fudget programs

Figure The updown counter

an internal state mapstateF has two arguments a state transition func

tion and an initial state When applied to the current state and an input

message the state transition function should pro duce a new internal state

and a list of output messages

The function count is the state transition function in this program

 There is a small pitfall in this program intDispF automatically displays

when the program starts The initial value of the counter happ ens to b e

as well If the is changed in the denition of counterF the display will

still show when the program starts One way to x this is to use the

customisable version of intDispF to sp ecify the initial value to display

The typ es of the new library comp onents used in this example are

buttonF Graphic a a F Click Click

data Click Click

mapstateF a b a c a F b c

This and the previous examples show how serial comp osition creates a commu

nication channel from one fudget to another But what if a fudget needs input

from more than one source The next example shows one p ossible solution

An updown counter

This example illustrates how to handle input from more than one source Fig

ure The two buttons aect the same counter

Here is the source co de

imp ort Fudgets

main fudlogue shellF UpDown Counter counterF

counterF intDispF mapstateF count

buttonF lledTriangleUp

buttonF lledTriangleDown

count n Left Click nn

count n Right Click nn

An updownreset counter

Note

 The updown counter is a small extension of the Up Counter Section

We have added a button by replacing

buttonF

with

buttonF buttonF

using the op erator for parallel comp osition

 The output from a parallel comp osition is the merged output from the two

comp onents Output from the left comp onent is tagged Left and output

from the right comp onent is tagged Right The constructors Left and Right

are constructors in the datatyp e Either

 The count function will now receive Left Click or Right Click dep ending on

which button was pressed It has b een adjusted accordingly Note that

Left Click and Right Click have nothing to do with the left and right mouse

buttons

 Just to illustrate that buttons can display arbitrary graphics and not just

text we have used two suitable shap es that happ en to b e provided by the

library

 Everything else is as in the previous example Section

The typ es of the new library comp onents used in this example are

F a b F c d F Either a c Either b d

lledTriangleUp FlexibleDrawing

lledTriangleDown FlexibleDrawing

An updownreset counter

This example shows how to cre

ate parallel comp ositions of many

fudgets of the same typ e

This program extends the

counter example with yet another

button The counter can now

b e incremented decremented and

reset

Here is the source co de

Your rst Fudget programs

Figure The loadable updown counter

imp ort Fudgets

main fudlogue shellF UpDownReset Counter counterF

counterF intDispF mapstateF count buttonsF

data Buttons Up Down Reset deriving Eq

buttonsF listF Up buttonF Up

Down buttonF Down

Reset buttonF Reset

count n Up Click n n

count n Down Click n n

count n Reset Click

Note

 When putting more than two fudgets of the same typ e in parallel it is

more convenient to use listF than The argument to listF is a list of

pairs of addresses and fudgets The addresses are used when messages are

sent and received from the comp onents in the comp osition

 In this program there is a user dened enumeration typ e Buttons the

elements of which are used as the addresses of the buttons The messages

received by the count function are pairs of Buttons values and Clicks

 Everything else is as in the previous example Section

The typ e of the new library comp onent used in this example is

listF Eq a a F b c F a b a c

A loadable updown counter

This example illustrates the use of lo ops to handle userinterface elements that

are used for b oth input and output Figure The program extends the

A simple calculator

updown counter in Section by allowing the user to set the counter to any

value by entering it in the display eld

Here is the source co de

imp ort Fudgets

main fudlogue shellF Loadable UpDown Counter counterF

counterF lo opThroughRightF mapstateF count intInputF

buttonF lledTriangleUp buttonF lledTriangleDown

count n Left n n

count n Right Left Click n Left n

count n Right Right Click n Left n

Note

 Instead of intDispF we have used intInputF which not only displays num

b ers but also allows the user to enter numb ers

 We have used the combinator lo opThroughRightF to allow the count func

tion to b oth receive input from and send output to intDispF In the comp o

sition lo opThroughRightF fud fud fud handles the communication with

1 2 1

the outside world the buttons in this example while fud can commu

2

nicate only with fud and is in this sense encapsulated by fud In fud

1 1 1

messages tofrom fud are tagged Left and messages tofrom the outside

2

world are tagged Right

The typ e of the new library comp onent used in this example is

lo opThroughRightF F Either a b Either c d F c a F b d

A simple calculator

As a nal example we show how a slightly larger program a simple calculcator

can b e built using the ideas illustrated by the previous examples Figure For

simplicity p ostx notation is used ie to compute you enter Ent

The source co de can b e found in Figure

Note

 The program structure is much the same as in the updownreset counter

Section

 To sp ecify the placement of the buttons we have used placerF as in Sec

tion and the placer matrixP which has the numb er of columns as an

argument

 The state maintained by the applicationsp ecic co de the function calc

is a stack represented as a list of numb ers The function calc pushes

and p ops numb ers from the stacks as appropriate The last clause in the

denition means that nothing happ ens if there are to o few values on the

stack for an op eration

Your rst Fudget programs

Figure The calculator

 As it stands the calculator can b e controlled with the mouse only The

customisable version of buttonF allows you to sp ecify a keyb oard shortcut

for the button It would thus b e relatively easy to make the calculator

controllable from the keyb oard

The typ e of the new library comp onent used in this example is

matrixP Int Placer

A simple calculator

imp ort Fudgets

main fudlogue shellF Calculator calcF

calcF intDispF mapstateF calc buttonsF

data Buttons Plus Minus Times Div Enter Digit Int deriving Eq

buttonsF placerF matrixP

listF d d d op Div

d d d op Times

d d d op Minus

hole d ent op Plus

where

d n Digit nbuttonF show n

ent op Enter

hole EnterholeF

op o obuttonF opLab el o

where opLab el Plus

opLab el Minus

opLab el Times

opLab el Div

opLab el Enter Ent

calc ns Digit d new n d s

calc s Enter s

calc yxs Plus new xy s

calc yxs Minus new xy s

calc yxs Times new x y s

calc yxs Div new x div y s

calc s s

new n s nsn

Figure Source co de for the calculator

Fudget library GUI elements

Fudget library GUI elements

In this chapter we present some common GUI elements provided by the Fudget

library For more information consult the reference manual which is available

via WWW HC

Before we intro duce the GUI elements we discuss briey how fudget pro

grams are formed using the function fudlogue

Functions used on the top level of programs

As we have seen in the examples in Chapter a fudget program consists of

a numb er of fudgets combined in a hierarchical structure that makes up one

main fudget of typ e F a b for some typ es a and b The main program in Haskell

should have typ e IO so we need a glue function to b e able to plug in the

main fudget The function fudlogue is provided for this purp ose

fudlogue F a b IO

The main program of a fudget program usually consists just of a call to fudlogue

with an argument fudget like

main IO

main fudlogue themainfudget

However it is p ossible to combine fudlogue with other monadic IO op erations

For example to create a program that starts by reading some conguration le

you could write

main do cong readFile conglename

fudlogue mainfudget cong

Programs with graphical user interfaces need at least one shell toplevel win

dow These are created with the function shellF

shellF String F a b F a b

The typical GUI program has only one shell window and the main program

thus lo oks something like

main fudlogue shellF windowtitle mainguifudget

A program with more than one shell window could for example lo ok something

like

main fudlogue shellF title fud shellF title fud

1 1 2 2

The fudget shellF is not restricted to the top level You could write the ab ove

example as

main fudlogue shellF title fud shellF title fud

1 1 2 2

and achieve the same result

Displaying values

toggleButtonF Run

radioGroupF PPPO

Figure Toggle buttons and radio groups

Displaying values

We have already seen lab elF which displays static lab els and intDispF which

displays numb ers that can change dynamically There is also displayF

displayF Graphic a F a b

a more general display for dynamically changing values It can display values of

any typ e in the Graphic class It could in fact also display numb ers but intDispF

has the advantage that the numb ers are displayed right adjusted

Buttons

We have already seen buttonF

buttonF Graphic a a F Click Click

in the examples ab ove It provides command buttons ie buttons trigger some

action when pressed The Fudget library also provides toggle buttons and radio

groups Figure Pressing these buttons causes a change that has a lasting

visual eect and probably also some other lasting eect A toggle button

changes b etween two states on and o each time you press it A radio group

allows you to activate one of several mutually exclusive alternatives The typ es

of these fudgets are

toggleButtonF Graphic a a F Bo ol Bo ol

radioGroupF Graphic b Eq a a b a F a a

The input messages can b e used to change the setting under program control

Menus and scrollable lists

Menus serve much the same purp ose as buttons but they save screen space by

app earing only when activated The fudget menuF name alts where

menuF Graphic a Graphic c a b c F b b

Fudget library GUI elements

imp ort Fudgets

main fudlogue shellF Compact UpDownReset Counter counterF

counterF

serCompLeftToRightF

p opupMenuF menu intDispF mapstateF count

data Buttons Up Down Reset deriving Eq

menu Up Up Down Down Reset Reset

count n Up n n

count n Down n n

count n Reset

Figure A compact version of the updownreset counter presented in Sec

tion

provides pulldown menus name is the constantly visible name you press to

activate the menu and alts is the list of menu alternatives

The fudget

p opupMenuF Graphic b Eq b

a b F c d F Either a b c Either a d

provides p opup menus ie menus that are activated when a certain mouse

button the third by default is pressed over some screen area The fudget

p opupMenuF initialmenu fud creates a fudget which b ehaves like the fudget fud

with the addition that the menu initialmenu p ops up when the user presses the

third menu button You communicate with the fudget as with a tagged parallel

comp osition of the menu and the fudget fud Messages tofrom the menu are

tagged Left and messages tofrom fud are tagged Right You can replace the

initialmenu by sending Left newmenu to the fudget

As an example supp ose we wanted a compact version of the counter in

Section We could then replace the three buttons with a p opup menu

attached to the display The source co de for this and the resulting user interface

is shown Figure We have used the combinator serCompLeftToRightF which

turns a parallel comp osition into a serial comp osition see Section When

the numb er of alternatives is large or when they change dynamically you can

use a scrollable list instead of a menu The function

Menus and scrollable lists

Figure pickListF

Figure stringInputF

pickListF a String F PickListRequest a

InputMsg Int a

shown in Figure takes a show function and returns a fudget that displays

lists of alternatives received on the highlevel input When an alternative is

selected by clicking on it it will app ear in the output stream Actually the

output from pickListF is of typ e InputMsg which is explained in Section

b elow

The values in the input stream are of typ e PickListRequest to allow the list

of alternatives to b e mo died in various ways To replace the entire list you

can use

replaceAll a PickListRequest a

but there are other functions that let you insert new alternatives at some p osition

in the list

insertText Int a PickListRequest a

or more generally replace part of the list with new alternatives

replaceText Int Int a PickListRequest a

and so on The screen will b e up dated in an ecient way when you do mo di

cations of this kind

Fudget library GUI elements

Entering values

Cho osing an alternative from a list is usually easier than typing something eg

the name of a colour on the keyb oard But when there is no predened set of

alternatives you can use fudgets that allow the user to enter values from the

keyb oard The library provides

stringInputF F String String

intInputF F Int Int

for entering strings and integers see Figure For entering other typ es of

values you can use stringInputF and attach the appropriate printer and parser

functions

More detailed information on user input

The fudgets stringInputF and intInputF do not pro duce any output until the user

presses the Enter or Return key to indicate that the input is complete This

is often a reasonable b ehaviour but there are versions of these fudgets that

provide more detailed information

stringF F String InputMsg String

intF F Int InputMsg Int

These fudgets output messages of typ e InputMsg which contain the current

contents of the entry eld and an indication of whether the value is intermediate

or complete

There are some stream pro cessors that are useful when p ost pro cessing mes

sages from entry elds

stripInputSP SP InputMsg a a

inputLeaveDoneSP SP InputMsg a a

inputDoneSP SP InputMsg a a

The rst one passes through all messages so that you will know ab out all

changes to the contents of the entry eld The second one outputs a message

when the user indicates that the input is complete and when the input fo cus

leaves the entry eld The last one outputs a message only when the input is

indicated as complete

The fudget stringInputF is dened as

stringInputF absF inputDoneSP stringF

As we saw ab ove the fudget pickListF also pro duces output of typ e InputMsg

In this case input is considered to b e complete when the user double clicks on

an alternative Hence you use stripInputSP if a single click should b e enough to

make a choice and inputDoneSP if a double click should b e required

Displaying and editing text

The library provides the fudgets

Scroll bars

Figure The text editor fudget editorF

moreF F String InputMsg Int String

moreFileF F String InputMsg Int String

moreFileShellF F String InputMsg Int String

1

which can display longer text The input to moreF is a list of lines of text to

b e displayed The other two fudgets display the contents of le names received

on the input In addition moreFileShellF app ears in its own shell window with

a title reecting the name of the le b eing displayed

There also is a text editor fudget Figure which supp orts cutpaste

editing with the mouse as well as a small subset of the keystrokes used in GNU

emacs It also has an undoredo mechanism

Scroll bars

GUI elements that can p otentially b ecome very large like pickListF moreF and

editorF have scroll bars attached by default There are also combinators to

explicitly add scroll bars

scrollF vScrollF hScrollF F a b F a b

The v and h versions give only vertical and horizontal scroll bars resp ectively

The argument fudget can b e any combination of GUI elements

1

The names come from the fact that they serve the same purp ose as the UNIX program

more

Sp ecifying layout

Figure When no layout is sp ecied in the program the automatic layout

system cho oses one

Sp ecifying layout

When combining fudgets for GUI elements there are two considerations

 The data ow aspect how should they communicate ie should one use

a serial parallel or some other combinator

 The visual aspect how should the GUI elements b e placed on the screen

When developing fudget programs it is not necessary to b e concerned with the

actual layout of the GUI fudgets For example the fudget

shellF Buttons

buttonF A Button buttonF Another Button

will get some default layout which might lo ok like Figure But so oner or

later we will want to have control over the layout The GUI library lets us do

this two dierent ways

 Combinatorbased layout This metho d is based on the combinator placerF

that has app eared in some of the previous examples It allows you to at

tach layout information to an arbitrary fudget Usually you rst combine

some fudgets using combinators like and listF and then

apply placerF to the combination to sp ecify a layout This is a fairly easy

metho d for adding layout information to a program However the layout

p ossibilities are somewhat limited by the structure of the program

 Name layout Here the layout is sp ecied separately from the fudget

structure GUI fudgets are assigned names which are later referred to in

layout sp ecications placed inside each shellF

Before describing these we will present the layout combinators that b oth of

them use

Boxes placers and spacers

Layout is done hierarchically Each GUI fudget will reside in a box which will

have a certain size and p osition when the layout is complete A list of b oxes can

b e put inside a single b ox by a placer A placer denes how the b oxes should b e

placed in relation to each other inside the larger b ox This enclosing b ox can b e

sub ject to further placement but the enclosed b oxes are hidden by the placer in

Boxes placers and spacers

x

horizontalP y

revP horizontalP

matrixP 3

verticalP

Figure Dierent placers

the sense that they cannot b e manipulated individually any more The eects

of some placers are illustrated in Figure The parameter to matrixP sp ecies

the numb er of columns the matrix should have The typ es of the placers are

horizontalP Placer

verticalP Placer

matrixP Int Placer

revP Placer Placer

The placer revP reverses the list of b oxes it is applied to Another higher order

placer is ipP which transforms a placer into a mirror symmetric placer with

resp ect to the line x y that is it ips the x and y co ordinates

ipP Placer Placer

Hence we can dene verticalP as

verticalP ipP horizontalP

Placers can b e applied to fudgets by means of placerF

placerF Placer F a b F a b

It applies the placer to all b oxes in the argument fudget The order of the b oxes

is left to right with resp ect to the combinators listF and etc

As an example supp ose we want to sp ecify that the two buttons in Figure

should have vertical layout We could then write

shellF Buttons placerF verticalP buttonF A Button

buttonF Another Button

The result can b e seen in Figure In a similar way the rst button could

b e placed b elow to the right of or to the left of the second button by using

Sp ecifying layout

Figure The same GUI elements as in Figure but the program explicitly

sp ecies vertical layout

verticalCounterF placerF verticalP counterF

counterF intDispF mapstateF count

buttonF Up buttonF Down

Figure An updown counter with vertical layout Abstract fudgets do not

have a corresp onding b ox in the layout

the placers revP verticalP horizontalP or revP horizontalP resp ectively Abstract

fudgets do not have a corresp onding b ox in the layout This means that the

presence of mapstateF in the denition of counterF in Figure do es not leave

a hole in the layout of verticalCounterF What if we want the display to app ear

b etween the two buttons With the placers we have seen the two buttons

will app ear together in the layout since they app ear together in the program

structure One solution is to use a placer op erator that allows the order of the

b oxes to b e p ermuted

p ermuteP Int Placer Placer

We can then replace verticalP with

p ermuteP verticalP

to get the display in the middle This kind of solution works but it will so on

b ecome quite complicated to write and understand A more general solution is

to use name layout Section

Boxes placers and spacers

(none)

leftS

hCenterS

rightS

Figure Spacers for alignment

Placers are used to sp ecify the layout of a group of b oxes In contrast

spacers are used to wrap a b ox around a single b ox Spacers can b e used to

determine how a b ox should b e aligned if it is given to o much space or to add

extra space around a b ox Examples of spacers that deal with alignment can

b e seen in Figure The topmost b ox placed with horizontalP must ll up

all the available space The lower three b oxes have b een placed inside a b ox

which consumes the extra space The spacers used are derived from the spacer

hAlignS whose argument states the ratio b etween the space to the left of the

b ox and the total available extra space

hAlignS Alignment Spacer

leftS hAlignS

hCenterS hAlignS

rightS hAlignS

There is a corresp onding spacer to ipP namely ipS It to o ips the x and y

co ordinates and lets us dene some useful vertical spacers

ipS Spacer Spacer

vAlignS a ipS hAlignS a

topS ipS leftS

vCenterS ipS hCenterS

b ottomS ipS rightS

With compS we can comp ose spacers and dene a spacer that centers b oth

horizontally and vertically

compS Spacer Spacer Spacer

centerS vCenterS compS hCenterS

To add extra space to the left and right of a b ox we use hMarginS left right

where

hMarginS Distance Distance Spacer

typ e Distance Int

2

Distances are given in numb er of pixels From hMarginS we can derive marginS

which adds an equal amount of space on all sides of a b ox

2

This is easy to implement but makes programs somewhat device dep endent

Sp ecifying layout

vMarginS ab ove b elow ipS hMarginS ab ove b elow

marginS s vMarginS s s compS hMarginS s s

Spacers can b e applied to fudgets by means of spacerF

spacerF Spacer F a b F a b

The fudget spacerF s f will apply the spacer s to all b oxes in f which are not

enclosed in other b oxes We can also mo dify a placer by wrapping a spacer

around the b ox that the placer assembles

spacerP Spacer Placer Placer

For example spacerP leftS horizontalP gives a horizontal placer which will left

adjust its b oxes

Name layout

To separate layout from fudget structure we put unique names on each b ox

usually corresp onding to a simple GUI fudget whose layout we want to control

by using nameF

typ e LName String

nameF LName F a b F a b

The layout of the b oxes that have b een named in this way is sp ecied using

the typ e NameLayout Here are the basic functions for constructing NameLayout

values

leafNL LName NameLayout

placeNL Placer NameLayout NameLayout

spaceNL Spacer NameLayout NameLayout

To apply the layout to named b oxes we use nameLayoutF

nameLayoutF NameLayout F a b F a b

As an application of name layout we show how the vertical counter in Figure

can b e changed so that the display app ears b etween the up and down buttons

Figure

nlCounterF nameLayoutF layout counterF

counterF nameF dispN intDispF

mapstateF count

nameF upN buttonF lledTriangleUp

nameF downN buttonF lledTriangleDown

only layout below

layout placeNL verticalP map leafNL upN dispN downN

upN up

downN down

dispN disp

Pros and cons of the dierent layout metho ds

Figure With name layout the order of the GUI elements in the window

do es not have to corresp ond to their order in the program text

Now we can control the layout of the two buttons and the display without

changing the rest of the program

The actual strings used for names are unimp ortant as long as they are

unique within the part of the fudget structure where they are in scop e So

instead we can write

upNdownNdispN map show

Pros and cons of the dierent layout metho ds

When it comes to sp ecifying the layout of user interfaces the Fudget library

provides at least three solutions that dier in expressiveness and safety

The dont care solution ignore the problem The programmer can com

p ose a numb er of GUI fudgets using plumbing combinators without sp ec

ifying the layout The system will automatically pick some layout This is

p erfectly safe but it obviously do es not give the programmer any control

over layout

The combinatorbased approach the programmer inserts placerF applied

to some placer at some selected p oints in the fudget hierarchy This gives

the programmer more control over layout and is still p erfectly safe but

there is a coupling b etween how the fudgets have b een comp osed and how

they app ear on the screen This is not necessarily bad but it limits the

freedom in the choice of layout

Name layout the b oxes of the GUI elements are lab elled with unique

names On the top level of the program the programmer inserts nameF

applied to a layout sp ecication which by referring to the names can

achieve a layout of the GUI elements completely unrelated to how they

were comp osed

In this solution it is p ossible to make mistakes however For the layout

sp ecication to work prop erly the name of every named b ox should o ccur

exactly once in the layout sp ecication If you forget to mention a b ox

or if you mention it twice or if you name a b ox that do es not exist the

layout will not work prop erly These mistakes are not detected at compile

time but give rise runtime errors or a weird layout

Sp ecifying layout

The Fudget library thus oers safe solutions with limited freedom and unsafe

solutions with full freedom With resp ect to safety and expressiveness the

solutions used in some other functional GUI to olkits for example Haggis FP

and Gadgets Nob are equivalent to name layout

The problem with the name layout solution is that it requires a certain consis

tency b etween two dierent parts of the program Maintaining this consistency

during program development is of course an extra burden on the programmer

Can a typ e system b e used to make name layout safe It would p erhaps b e

p ossible to include layout information in some form in the typ es of GUI fudgets

and catch some mistakes with the ordinary Haskell typ e system However

the requirement that each name o ccurs exactly once in the layout sp ecication

suggests that you would need a typ e system with linear typ es Hol to catch

all mistakes

o i

sp

Figure Turning a stream pro cessor into an abstract fudget

Abstract fudgets

When using the Fudget library in a program fudgets from the library are usually

combined with some applicationsp ecic co de that is typically attached to the

program in serial comp ositions In the examples we have seen the use of mapF

and mapstateF for this

facF intDispF mapF fac intInputF

counterF intDispF mapstateF count buttonF Up

The functions mapF and mapstateF create abstract fudgets that is fudgets that

do not p erform any IO They communicate only via their highlevel streams

A more general way to construct abstract fudgets is provided by the function

absF

absF SP a b F a b

where SP is the typ e constructor for plain stream processors These have a single

input stream and a single output stream The function absF creates a fudget

by connecting the streams of a stream pro cessor to the highlevel streams of the

fudgets while leaving the lowlevel streams disconnected as shown in Figure

The functions mapF and mapstateF are in fact dened in terms of absF

mapF absF mapSP

mapstateF absF mapstateSP

where mapSP and mapstateSP

mapSP a b SP a b

mapstateSP a b a c a SP b c

are discussed in Section and Section resp ectively

Although highlevel combinators like mapF and mapstateF are adequate for

most fudget application programming some programmers may prefer the exi

bility of the more basic ways of creating stream pro cessors Two examples where

abstract fudgets are dened in terms of absF can b e found in Section An

extensive discussion of stream pro cessors can b e found in Part I I I

Fudget plumbing

f 1

f 1 f 2

f 2

Figure Serial and parallel comp osition of fudgets

Fudget plumbing

We have already seen examples of how to use the fudget plumbing combina

tors There are three basic forms of comp ositions serial comp osition parallel

comp osition and lo ops

Serial composition

F b c F a b F a c

Paral lel composition

F i o F i o F Either i i Either o o

F i o F i o F i o

listF Eq t t F i o F t i t o

Loops

lo opF F a a F a a

lo opLeftF F Either lo op input Either lo op output F input output

lo opThroughRightF F Either oldo newi Either oldi newo

F oldi oldo

F newi newo

The dierent fudget combinators treat the highlevel streams in dierent ways

while the lowlevel streams are treated in the same way in all combinators Fig

ure illustrates serial and parallel comp osition of fudgets Apart from the

plumbing combinators listed ab ove the Fudget library contains further combi

nators that capture common patterns Some of these combinators are describ ed

in the following sections

The fudget combinators have corresp onding combinators for plain stream

pro cessors which are discussed in more detail in Chapter Their names are

obtained by replacing the F sux with an SP or substituting for

in the op erators

Serial comp ositions

Serial comp ositions

Serial comp osition connects the output of one fudget to the input of another

fudget As with function comp osition data ow from right to left so that in

the comp osition fud fud the output of fud is connected to the input

2 1 1

of fud

2

Many of the examples in Chapter contain serial comp ositions of the form

mapF f fud

fud mapF f

The library provides the following combinators to capture these cases

F a b c a F c b

fud f fud mapF f

a b F c a F c b

f fud mapF f fud

The library versions of and have more involved denitions to b e

more ecient

Comp ositions of the form

absF sp fud

fud absF sp

are also common The library provides two op erators for these sp ecial cases

SP b c F a b F a c

sp fud absF sp fud

F b c SP a b F a c

fud sp fud absF sp

Some combinators like p opupMenuF see Section create parallel comp o

sitions of fudgets but sometimes a serial comp osition is instead required This

could b e accomplished by using a lo op and an abstract fudget to do the necessary

routing but the library contains two combinators that do this

serCompLeftToRightF F Either a b Either b c F a c

serCompRightToLeftF F Either a b Either c a F b c

The following equations hold

serCompRightToLeftF l r l r

serCompLeftToRightF l r r l

Fudget plumbing

Parallel comp ositions

When combining more than two or three fudgets the tagging obtained by using

can b ecome a bit clumsy It may then b e more convenient to use listF

listF Eq a a F b c F a b a c

which allows any typ e in the Eq class to b e used as addresses of the fudgets to

b e combined The restriction is that the fudgets combined must have the same

typ e See Section for a discussion of how a language with dep endent typ es

could eliminate this kind of restriction

There is also a combinator for untagged parallel comp osition

F i o F i o F i o

Input to an untagged parallel comp osition is sent to both argument fudgets

There is a list version of untagged parallel comp osition as well

untaggedListF F a b F a b

which can easily b e dened using

untaggedListF foldr nullF

where nullF

nullF F a b

is the fudget that ignores all input and never pro duces any output

The untagged parallel comp ositions are not as widely used as the tagged

ones The reason is probably that you usually do not want input to b e broadcast

to all fudgets in a comp osition

There are some further combinators that tend to b e useful every once in a

while These are various parallel comp ositions with the identity fudget

idRightF F a b F Either a c Either b c

idLeftF F a b F Either c a Either c b

bypassF F a a F a a

throughF F a b F a Either b a

idRightF fud fud idF

idLeftF fud idF fud

bypassF fud idF fud

throughF fud idRightF fud toBothF

toBothF F a Either a a

toBothF concatMapF x Left xRight x

idF F a a

idF mapF id

Lo ops

Lo ops

The simplest lo op combinator is lo opF

lo opF F a a F a a

In the comp osition lo opF fud the output from fud is not only output from the

comp osition but also sent back to the input of fud

The most useful lo op combinator is probably lo opThroughRightF An exam

ple use was shown in Section and it is discussed further in Section

Some lo op combinators that have b een useful are

lo opCompThroughRightF F Either Either a b c

Either Either c d a F b d

lo opCompThroughLeftF F Either a Either b c

Either b Either a d F c d

These turn parallel comp ositions into lo ops The following equations hold

lo opCompThroughRightF l r lo opThroughRightF l r

lo opCompThroughLeftF l r lo opThroughRightF r l

Dynamic fudget creation

The combinators describ ed in the previous sections can b e used to build static

networks of fudgets The Fudget library also provides combinators that can b e

used to add or remove fudgets dynamically for example to create new windows

dynamically

To create dynamically changing parallel comp ositions of fudgets the library

provides

dynListF F Int DynFMsg a b Int b

where

data DynFMsg i o DynCreate F i o DynDestroy DynMsg i

Ab ove we saw listF that creates tagged parallel comp ositions that are static

The combinator dynListF can b e seen as a variant of listF with a more elab orate

input message typ e When the program starts dynListF is an empty parallel

comp osition A new fudget fud with address i can b e added to the parallel

comp osition by passing the message

iDynCreate fud

to dynListF The fudget with address i can b e removed from the parallel com

p osition by passing the message

iDynDestroy

Finally one can send a message x to an existing fudget with address i by passing

the message

Fudget plumbing

iDynMsg x

to dynListF

The addresses used by dynListF have b een restricted to the typ e Int for e

ciency reasons but in principle more general address typ es could b e supp orted

as for listF

A simpler combinator that allows fudgets to change dynamically is dynF

dynF F a b F Either F a b a b

The fudget dynF fud starts out b ehaving like fud except that messages to fud

should b e tagged with Right The fudget fud can b e replaced by another fudget

fud by passing in the message Left fud

Fudgets for nonGUI IO

Standard IO fudgets

To read the standard input usually the keyb oard and write to the standard

output or standard error stream the screen you can use the fudgets

stdinF F a String

stdoutF F String a

stderrF F String a

The output from stdinF is the characters received from the programs standard

input channel For eciency reasons you do not get one character at a time

but larger chunks of characters If you want the input as a stream of lines you

can use

inputLinesSP SP String String

which puts together the chunks and splits them at the newlines

A simple example is a fudget that copies text from the keyb oard to the

screen with all letters converted to upp er case

stdoutF map toUpp er stdinF

It applies toUpp er to all characters in the strings output by stdinF and then

feeds the result to stdoutF

Here is a fudget that reverses lines

stdoutFnreverseinputLinesSPstdinF

The precedences and asso ciativities of the combinators are such that these fud

gets can b e written as

stdoutF map toUpp er stdinF

stdoutF nreverse inputLinesSP stdinF

Accessing the le system

The following fudgets allow you to read les write les and get directory con

tents

readFileF F FilePath FilePathEither IOError String

writeFileF F FilePathString FilePathEither IOError

readDirF F FilePath FilePathEither IOError FilePath

These can b e seen as servers with a onetoone corresp ondence b etween requests

and resp onses For convenience the resp onses are paired with the le path

from the request The resp onses contain either an error message or the result

of the request The result is the contents of a le readFile a directory listing

readDirF or writeFileF

Fudgets for nonGUI IO

The timer fudget

The timer fudget generates output after a certain delay andor at regular time

intervals Its typ e is

data Tick Tick

timerF F Mayb e Int Int Tick

The timer is initially idle When it receives Just id on its input it b egins

ticking The rst tick will b e output after d milliseconds Then ticks will

app ear regularly at i millisecond intervals unless i is in which case only one

tick will b e output Sending Nothing to the timer resets it to the idle state

As a simple example here is a fudget that outputsonce a second the numb er

of seconds that have elapsed since it was activated

countSP timerF putSP Just nullSP

where countSP mapAccumlSP inc

inc n Tick nn

Parameters for customisation

When constructing software libraries there may b e a tension b etween simplicity

and generality Generality can b e achieved by providing many parameters for

adapting library comp onents to dierent needs But it ruins simplicity if the

programmer has to sp ecify a large numb er of parameters each time a library

comp onent is used To solve this some programming languages allow some of

the arguments in a function call to b e omitted provided that default values are

sp ecied for them in the function denition Haskell do es not allow this but by

using one of the p owers of functional languages higher order functions and the

Haskell class system something very similar can b e achieved The solution used

in the Fudget library is presented b elow Design and implementation issues are

discussed in more detail in Chapter

Customisers

In order to make fudgets easy to use in the common case and still exible

they often come in two versions a standard version for example buttonF and

a customisable version for example buttonF The name of the customisable

version is obtained by app ending a to the name of the standard version

Customisable fudgets have a numb er of parameters that allow things like

fonts colors b order width etc to b e sp ecied All these parameters have

default values which are used in the standard version of the fudget

Rather than having one extra argument for each such parameter customis

able versions of fudgets or other functions have one extra argument which is

a customiser The customiser is always the rst argument A customiser is a

function that mo dies a data structure containing the values of all parameters

typ e Customiser a a a

The typ e of the data structure is abstract Its name is usually the name of the

fudget with the rst letter change to upp er casefor example ButtonF in the

case of buttonF

buttonF Graphic a

Customiser ButtonF a a F Click Click

So customisers are obtained by comp osing a numb er of mo difying functions

using ordinary function comp osition The function standard

standard Customiser a

acts as the identity customiser and do es not change any parameters The stan

dard versions of the fudgets are simply the customisable versions applied to

standard for example

buttonF buttonF standard

Sample customisers

There are customisable versions of most fudgets presented earlier in this chapter

The customisers that are common to many fudgets are overloaded Some

customiser classes are shown in Figure The table in Figure shows what

Parameters for customisation

class HasBgColorSp ec a where setBgColorSp ec ColorSp ec Customiser a

class HasFgColorSp ec a where setFgColorSp ec ColorSp ec Customiser a

class HasFont a where setFont FontName Customiser a

class HasMargin a where setMargin Int Customiser a

class HasAlign a where setAlign Alignment Customiser a

class HasKeys a where setKeys Mo dState KeySym

Customiser a

Figure Some customiser classes

BgColorSp ec FgColorSp ec Font Margin Align Keys

TextF y y y y y n

DisplayF y y y y y n

StringF y y y n n n

ButtonF y y y n n y

ToggleButtonF n n y n n y

RadioGroupF n n y n n n

ShellF n n n y n n

Figure Some customiser instances

customisers are supp orted by the dierent customisable fudgets in the current

version of the Fudget library

Some fudgets also have nonoverloaded customisers for example

setInitDisp a Customiser DisplayF a

changes what is displayed initial ly

setAllowedChar Char Bo ol Customiser StringF

changes what characters are al lowed

setPlacer Placer Customiser RadioGroupF

changes the placements of the buttons

As an example of the use of customisation Figure shows a variation of the

radio group shown in Figure

radioGroupF setFont xed

setPlacer matrixP

PPPO

Figure Custom version of the radio group in Figure

III Stream pro cessors

the essence of Fudgets

The starting p oint of the work describ ed in this thesis was the idea of the

fudget as a pro cess that communicates with other fudgets through the highlevel

streams and with the IO system through the lowlevel streams A fudget thus

has two input streams and it is not known in advance in which order the elements

in the two streams will b ecome available Fudgets should b e able to listen to

either the highlevel input or the lowlevel input but also cho ose to react to the

rst input to b ecome available irresp ective of what stream it b ecomes available

on We exp ected that the former case would b e the exception and the latter case

would b e the rule so rather than providing some op erator for indeterministic

choice that the programmer could use in the denition of fudgets we cho ose to

merge the high and lowlevel streams b efore feeding them to the fudget thus

moving the indeterministic choice outside the fudget

So we started out thinking of fudgets as the primitive concept but so on saw

them as b eing derived from a simpler concept the stream processor which is a

pro cess that communicates with its surroundings through a single input stream

and a single output stream

This part of the thesis is devoted to stream pro cessors

Stream pro cessors

Stream pro cessors

We have not used stream pro cessors extensively in the examples presented so

far but plain stream pro cessors are interesting for at least these reasons

 As suggested in Chapter the application programmer can write the

applicationsp ecic co de in the form of stream pro cessors

 As an application programmer you usually abstract away from the low

level streams and in fact handle fudgets as if they were plain stream pro

cessors with a single input and a single output stream Hence a lot of the

discussion of stream pro cessors applies to fudget application programming

as well

 They are simpler than fudgets but fudgets can b e represented as stream

pro cessors We show how in Section

 Stream pro cessors can b e used to structure an ordinary sequential Haskell

program as a set of concurrent pro cesses Examples of this are shown in

Chapter

Viewed in a more general context the stream pro cessor can b e seen as a sim

ple but practical incarnation of the pro cess concept and has connections with

process algebras such as CCS Mil An advantage with stream pro cessors is

that they admit a simple implementation within a purely functional language

We can dene a set of combinators for building networks of stream pro cessors

and the stream pro cessors are rst class values which can b e passed around as

messages

We use the following informal denitions

 A stream is a p otentially innite sequence of values o ccurring at dierent

p oints in time A stream can b e seen as a communication channel trans

ferring information from one place a pro ducer to another a consumer

 A stream processor is a pro cess which consumes some input streams and

pro duces some output streams A stream pro cessor may have an internal

state ie output pro duced at a certain p oint in time can dep end on all

input consumed b efore that p oint in time

These denitions allow stream pro cessors to have many input and output

streams but in the following we will only consider stream pro cessors with a

single input stream and a single output stream see Figure The restric

tion may seem severe but the chosen set of combinators allows streams to b e

merged and split so a stream pro cessor with many inputoutput streams can b e

represented as one with a single input stream and a single output stream The

advantage is that we can take a combinatorbased approach to building networks

of communicating stream pro cessors The combinators are discussed further in

Chapter Below we discuss how to write atomic stream pro cessors that is

stream pro cessors that do not consist of several concurrently running stream

pro cessors Their b ehaviour is dened by a linear sequence of IO actions

The streampro cessor typ e

Figure A general stream pro cessor and a stream pro cessor with a single

input stream and a single output stream

o i

Figure A stream pro cessor of typ e SP i o

The streampro cessor typ e

The Fudget library provides an abstract typ e for stream pro cessors

data SP input output

where input and output are the typ es of the elements in the input and output

streams resp ectively Figure The implementation of stream pro cessors

in a lazy functional language are discussed in Chapter The library also

provides the function

runSP SP i o i o

which can b e used on the top level of a program built with stream pro cessors

see Chapter The function absF discussed in Chapter can b e used to

combine stream pro cessors with fudgets

Atomic stream pro cessors in continuation style

The b ehaviour of an atomic stream pro cessor is describ ed by a sequential pro

gram There are three basic actions a stream pro cessor can take

 it can put a value in its output stream

 it can get a value from its input stream

 it can terminate

The Fudget library provides the following continuation style op erations for these

actions

putSP output SP input output SP input output

getSP input SP input output SP input output

nullSP SP input output

Stream pro cessors

As an example of how to use these in recursive denitions of stream pro cessors

consider the identity stream pro cessor

The identity stream processor

idSP SP a a

idSP getSP x putSP x idSP

the busy stream pro cessor

A stream processor that is forever busy computing

busySP SP a b

busySP busySP

and the following streampro cessor equivalents of the well known list functions

mapSP a b SP a b

mapSP f getSP x putSP f x mapSP f

lterSP a Bo ol SP a a

lterSP p getSP x if p x

then putSP x lterSP p

else lterSP p

The stream pro cessor nullSP need actually not b e considered as a primitive It

can b e dened as

nullSP getSP x nullSP

ie it is a stream pro cessor that ignores all input and never pro duces any

output A practical advantage with an explicitly represented nullSP is that it

allows stream pro cessors that terminate to b e garbage collected

Example Implement concatMapSP io SP i o

Solution First we dene putListSP that outputs the elements of a list one

at a time

putListSP o SP i o SP i o

putListSP id

putListSP xxs putSP x putListSP xs

And concatMapSP itself

concatMapSP f

getSP x

putListSP f x

concatMapSP f

Example Implement mapFilterSP iMayb e o SP i o

Solution mapFilterSP f

getSP x

case f x of

Nothing mapFilterSP f

Just y putSP y

mapFilterSP f

Stream pro cessors with encapsulated state

Stream pro cessors with encapsulated state

A stream pro cessor can maintain an internal state In practice this can b e

accomplished by using an accumulating argument in a recursively dened stream

pro cessor As a concrete example consider sumSP a stream pro cessor that

computes the accumulated sum of its input stream

sumSP Int SP Int Int

sumSP acc getSP n putSP accn sumSP accn

In this case the internal state is a value of the typ e Int which also happ ens to

b e the typ e of the input and output streams In general the typ e of the input

and output streams can b e dierent from the typ e of the internal state which

can then b e completely hidden

The Fudget library provides two general functions for construction of stream

pro cessors with internal state

mapAccumlSP s i s o s SP i o

concatMapAccumlSP s i s o s SP i o

concatMapAccumlSP is also known as mapstateSP The rst argument to these

functions is a state transition function which given the current state and an

input message should pro duce a new state and an output message zero or more

outputs in the case of concatMapAccumlSP Using mapAccumlSP we can dene

sumSP without using explicit recursion

sumSP Int SP Int Int

sumSP mapAccumlSP acc n accnaccn

Representing state information as one or more accumulating arguments is useful

when the b ehaviour of the stream pro cessor is uniform with resp ect to the state

If a stream pro cessor reacts dierently to input dep ending on its current state

it can b e more convenient to use a set of mutually recursive stream pro cessors

where each stream pro cessor corresp onds to a state in a nite state automaton

As a simple example consider a stream pro cessor that outputs every other

element in its input stream

passOnSP getSP x putSP x skipSP

skipSP getSP x passOnSP

It has two states the pass on state where the next input is passed on to the

output and the skip state where the next input is skipp ed

The two ways of representing state illustrated ab ove can of course b e com

bined

Example Implement mapAccumlSP and concatMapAccumlSP using putSP and

getSP

Stream pro cessors

Solution concatMapAccumlSP s i s o s SP i o

concatMapAccumlSP f s

getSP x

let s ys f s x

in putListSP ys

concatMapAccumlSP f s

mapAccumlSP s i s o s SP i o

mapAccumlSP f s

getSP x

let s y f s x

in putSP y

mapAccumlSP f s

Sequential comp osition of stream pro cessors

Unlike CCS style pro cess algebras Milwhere nontrivial sequential b e

haviours can b e constructed only by prexing an existing b ehaviour with an

IO op erationthe stream pro cessors can b e combined sequentially

seqSP SP a b SP a b SP a b

The stream pro cessor sp seqSP sp b ehaves like sp until sp b ecomes nullSP

1 2 1 1

and then b ehaves like sp However the same can also b e achieved by making

2

all pro cedures end with a call to a continuation stream pro cessor instead of

nullSP so seqSP do es not add any new p ower

We should also note that if this is to work prop erly the op eration nullSP

must b e explicitly represented and not just dened as a stream pro cessor that

ignores all input and never pro duces any output contrary to what was suggested

in Section

Streampro cessor monads

The presentation thus far suggests that atomic stream pro cessors should b e

programmed in continuation style This is often natural but for complex stream

pro cessors it can b e b enecial to use a monadic style instead Wad Wad

The two styles are compatible The op erations of the stream pro cessor monad

are shown in Figure Thanks to runSPm you can use the combinators for

plain stream pro cessors to construct networks of streampro cessor monads

For writing complex stream pro cessors it is of course p ossible to combine the

streampro cessor monad with other monads eg a state monad The Fudget

library denes the typ e SPms for stream pro cessormonads with state A closer

presentation and an example of its use can b e found as part of Chapter

Streampro cessor monads

The type

typ e SPm input output answer

Standard monad operations

unitSPm a SPm i o a

bindSPm SPm i o a a SPm i o b SPm i o b

Monadic versions of nul lSP putSP and getSP

nullSPm SPm i o

putSPm o SPm i o

getSPm SPm i o i

A glue function

runSPm SPm i o SP i o

Figure The streampro cessor monad

Plumbing comp osing stream pro cessors

sp 1 sp 2

Figure Serial comp osition of stream pro cessors

sp 1

sp 2

Figure Parallel comp osition of stream pro cessors

Plumbing comp osing stream pro cessors

This section describ es the combinators used to combine atomic stream pro

cessors into networks of communicating stream pro cessors We rst describ e

combinators for the three basic comp ositions serial comp osition parallel com

p osition and lo ops

Serial comp osition

The simplest combinator is the one for serial comp osition

SP b c SP a b SP a c

It connects the output stream of one stream pro cessor to the input stream of

another as illustrated in Figure Streams ow from right to left just like

values in function comp ositions f g Serial comp osition of stream pro cessors

is very close to function comp osition For example it ob eys the following law

mapSP f mapSP g mapSP f g

Parallel comp ositions

The combinator for parallel comp osition in Figure is indeed the key combi

nator for stream pro cessors It allows us to write reactive programs comp osed

by more or less indep endent parallel pro cesses The output streams should b e

merged in chronological order We will not b e able to achieve exactly this in

a functional language but for stream pro cessors whose b ehaviour is dominated

by IO op erations rather than internal computations we will get close enough

for practical purp oses There is however more than one p ossible denition of

parallel comp osition How should values in the input stream b e distributed to

the two stream pro cessors How should the output streams b e merged We

dene two versions

Parallel comp ositions

 Let sp sp denote parallel comp osition where input values are prop

1 2

agated to b oth sp and sp and output is merged in chronological order

1 2

We will call this version untagged or broadcasting parallel comp osition

 Let sp sp denote parallel comp osition where the values of the input

1 2

and output streams are elements of a disjoint union Values in the input

stream tagged Left or Right are untagged and sent to either sp or sp

1 2

resp ectively Likewise the tag of a value in the output stream indicates

which comp onent it came from We will call this version tagged parallel

comp osition

The typ es of the two combinators are

SP i o SP i o SP i o

SP i o SP i o SP Either i i Either o o

Note that only one of these needs to b e considered as primitive The other can

b e dened in terms of the primitive one with the help of serial comp osition and

some simple stream pro cessors like mapSP and lterSP

Example Dene in terms of and vice versa

Solution SP i o SP i o SP i o

sp sp

mapSP stripEither

sp sp

toBothSP

stripEither Either a a a

stripEither Left a a

stripEither Right a a

toBothSP SP a Either a a

toBothSP concatMapSP x Left x Right x

SP i o SP i o SP Either i i Either o o

sp sp sp sp

where

sp mapSP Left sp lterLeftSP

sp mapSP Right sp lterRightSP

lterLeftSP mapFilterSP stripLeft

lterRightSP mapFilterSP stripRight

stripLeft Either a b Mayb e a

stripLeft Left x Just x

stripLeft Right Nothing

stripRight Either a b Mayb e b

stripRight Left Nothing

stripRight Right y Just y

Plumbing comp osing stream pro cessors

sp

Figure A simple lo op constructor

sp 1 sp 2

Figure Using a lo op to obtain bidirectional communication

Circular connections

Serial comp osition creates a unidirectional communication channel b etween two

stream pro cessors Parallel comp osition splits and merges streams but do es not

allow the comp osed stream pro cessors to exchange information So with these

two op erators we cannot obtain bidirectional communication b etween stream

pro cessors Therefore we intro duce combinators that construct lo ops

The simplest p ossible lo op combinator connects the output of a stream pro

cessor to its input as illustrated in Figure As with parallel comp osition we

dene two versions of the lo op combinator

lo opSP sp output from sp is b oth lo op ed to the input of sp and propagated to

the output outside the lo op

lo opLeftSP sp output from sp is required to b e in a disjoint union Values

tagged Left are lo op ed and values tagged Right are output At the input

values from the lo op are tagged Left and values from the outside are tagged

Right

The typ es of these combinators are

lo opSP SP a a SP a a

lo opLeftSP SP Either l i Either l o SP i o

Each of the two lo op combinators can b e dened in terms of the other so only

one of them needs to b e considered primitive

Using one of the lo op combinators one can now obtain bidirectional com

munication b etween two stream pro cessors as shown in Figure

Another example shows that we can use lo ops and parallel comp osition to

create fully connected networks of stream pro cessors With an expression like

lo opSP sp sp sp

1 2 n

Circular connections

we get a broadcasting network By replacing with and some tag

ginguntagging we get a network with p ointtop oint communication

Example Dene lo opSP in terms of lo opLeftSP and vice versa

Solution Dening lo opSP in terms of lo opLeftSP is relatively easy

lo opSP SP a a SP a a

lo opSP sp

loopLeftSP

toBothSP sp mapSP stripEither

Vice versa is a bit trickier

lo opLeftSP SP Either l i Either l o SP i o

loopLeftSP sp

mapFilterSP p ost

lo opSP sp

mapSP Right

where

p ost Left Right x Just x

p ost Nothing

sp mapSP Left sp mapFilterSP pre

where

pre Right x Just Right x

pre Left Left x Just Left x

pre Nothing

Pragmatic asp ects of plumbing

sp 2

sp 1

sp 3

Figure Handling multiple input streams

Pragmatic asp ects of plumbing

Having seen a basic set of streampro cessor combinatorswhich we can consider

as a complete set of primitives on top of which further combinators can b e

builtwe now take a lo ok at how the combinators can b e used to achieve some

common connection patterns and intro duces some further combinators we have

found useful

Fudgets are comp osed in the same way as plain stream pro cessors There

fore the description of the streampro cessor combinators also holds true for the

corresp onding fudget combinators The fudget combinators are presented by

name together with some further combinators in Chapter

Handling multiple input and output streams

Although stream pro cessors have only one input stream it is easy to construct

programs where one stream pro cessor receives input from two or more other

stream pro cessors The case with several outputs is analogous For example

the expression

sp sp sp

1 2 3

allows sp to receive input from b oth sp and sp For most practical purp oses

1 2 3

sp can b e regarded as having two input streams as illustrated in Figure

1

When you use getSP in sp to read from the input streams messages from

1

sp and sp will app ear tagged with Left and Right resp ectively You can not

2 3

directly read selectively from one of the two input streams but the Fudget

library provides the combinator

waitForSP i Mayb e i i SP i o SP i o

which you can use to wait for a selected input Other input is queued and can

b e consumed after the selected input has b een received Using waitForSP you

can dene combinators to read from one of two input streams

getLeftSP i SP Either i i o SP Either i i o

getLeftSP waitForSP stripLeft

getRightSP i SP Either i i o SP Either i i o

getRightSP waitForSP stripRight

Example Implement startupSP i SP i o SP i o that prep ends some

elements to the input stream of a stream pro cessor

Stream pro cessors and software reuse

sp old

sp new

Figure Encapsulation

Solution startupSP xs sp sp putListSP xs idSP

Note this implementation leaves a serial comp osition with idSP b ehind

after the messages xs have b een fed to sp An ecient implementation

that do es not leave any overhead b ehind can b e obtained by making use

of the actual representation of stream pro cessors

Example Implement waitForSP describ ed ab ove

Solution waitForSP i Mayb e i i SP i o SP i o

waitForSP exp ected isp

let contSP p ending

getSP msg

case exp ected msg of

Just answer startupSP reverse p ending isp answer

Nothing contSP msg p ending

in contSP

Stream pro cessors and software reuse

For serious applications programming it is useful to have libraries of reusable

software comp onents But in many cases when a useful comp onent is found in

a library it still needs mo dication b efore it can b e used

A variation of the lo op combinators that has turned out to b e very use

ful when reusing stream pro cessors is lo opThroughRightSP illustrated in Fig

ure The key dierence from lo opSP and lo opLeftSP is that the lo op do es

not go directly back from the output to the input of a single stream pro cessor

Instead it go es through another stream pro cessor A typical situation where

lo opThroughRightSP is useful is when you have a stream pro cessor sp that

old

do es almost what you want it to do but you need it to handle some new kind

of messages A new stream pro cessor sp can then b e dened This new

new

stream pro cessor can pass on old messages directly to sp and handle the new

old

messages in the appropriate way on its own or by translating them to messages

that sp understands See also Section in NR

old

In the comp osition lo opThroughRightSP sp sp all communication with

new old

the outside world is handled by sp sp is connected only to sp and is

new old new

in this sense encapsulated inside sp

new

The typ e of lo opThroughRightSP is

Pragmatic asp ects of plumbing

lo opThroughRightSP SP Either oldo newi Either oldi newo

SP oldi oldo

SP newi newo

Programming with lo opThroughRightSP corresp onds to inheritance in ob ject

oriented programming The encapsulated stream pro cessor corresp onds to the

inherited class Overridden metho ds corresp ond to message constructors that

the encapsulating stream pro cessor handles itself

Example Implement lo opThroughRightSP using lo opLeftSP together with par

allel and serial comp ositions as appropriate

Solution loopThroughRightSP

SP Either oldo i Either oldi o SP oldi oldo SP i o

loopThroughRightSP spnew sp old

loopLeftSP

mapSP p ost sp old spnew

mapSP pre

where

pre Right input Right Right input

pre Left Left newToOld Left newToOld

pre Left Right oldToNew Right Left oldToNew

p ost Right Right output Right output

p ost Right Left newToOld Left Left newToOld

p ost Left oldToNew Left Right oldToNew

Example Implement serial comp osition using a tagged parallel comp osition

and a lo op

Solution SP b c SP a b SP a c

sp sp

lo opThroughRightSP mapSP route sp sp

where

route Right a Left Right a

route Left Left c Right c

route Left Right b Left Left b

The combinator lo opThroughBothSP

lo opThroughBothSP SP Either l i Either l o

SP Either l i Either l o

SP Either i i Either o o

is a symmetric version of lo opThroughRightSP A comp osition lo opThrough

BothSP sp sp allows b oth sp and sp to communicate with the outside world

1 2 1 2

and with each other see Figure

An interesting prop erty of lo opThroughBothSP is that the circuit diagrams

of the more basic combinators and lo opSP can b e obtained

from the circuit diagram of lo opThroughBothSP by just removing wires Other

combinators are thus easy to dene in terms of lo opThroughBothSP

Dynamic pro cess creation

sp 1

sp 2

Figure Circuit diagram for lo opThroughBothSP

Dynamic pro cess creation

We implicitly made a distinction b etween the op erators that dene the dynamic

b ehaviour of an atomic stream pro cessors nullSP putSP and getSP and the

op erators that are used to build static networks of stream pro cessors

lo opSP etc But there is in fact no reason why networks must b e static

By using combinators like and in a dynamic way the numb er

of stream pro cessors can b e made to increase dynamically The numb er of

stream pro cessors can also decrease for example if a comp onent of a parallel

comp osition dies since nullSP sp is equivalent to sp

A practical application of these ideas is discussed in Section

Application programming with plain stream pro cessors

Application programming with plain stream

pro cessors

Although plain stream pro cessors are mostly used in conjunction with fudgets

they can b e used indep endently In this chapter we take a lo ok at some examples

of interactive Haskell programs written using stream pro cessors

An adding machine

In Section we dened

sumSP Int SP Int Int

that computes the accumulating sum of a stream of integers Let us write

a complete Haskell program that uses sumSP to implement a simple adding

machine

Haskell provides the function interact which allows functions of typ e Char

Char to b e used as programs as in Landins stream IO mo del outlined

in Chapter By combining this with the function runSP

runSP SP i o i o

from Section we can run stream pro cessors of typ e SP Char Char

main interact runSP mainSP

mainSP SP Char Char

mainSP

To b e able to use sumSP we need only add some glue functions that convert the

input stream of characters to a stream of numb ers and conversely for the output

stream This is done in two stages First the streampro cessor equivalents of

the standard list functions lines and unlines are used to pro cess input and output

line by line instead of character by character

mainSP unlinesSP adderSP linesSP

adderSP SP String String

adderSP

Now the standard functions show and read are used to convert b etween strings

and numb ers

adderSP mapSP show sumSP mapSP read

and the program is complete

Example Implement unlinesSP SP String Char

Solution unlinesSP concatMapSP s sn

Example Implement linesSP SP Char String

A stream pro cessor for input line editing

One line at a time One character at a time

Screen Program System Keyboard

Figure Line buered input

One character at a time

Screen Program Keyboard

Figure Unbuered input

Solution linesSP lnSP

where

lnSP acc

getSP msg

case msg of

n putSP reverse acc lnSP

c lnSP c acc

A stream pro cessor for input line editing

In the example ab ove it was assumed that input is line buered co oked termi

nal mo de in Unix ie the system allows the user to enter a line of text and edit

it by using the backspace key and p ossibly other cursor motion keys and send

it to the program by pressing the Return key The system is thus resp onsible for

echoing characters typ ed on the keyb oard to the screen Figure Assuming

a simpler system where keyb oard input is fed directly to the program and the

only characters shown on the screen are those output by the program raw ter

minal mo de in Unix Figure the streampro cessor combinator lineBuerSP

is now dened to do the job

lineBuerSP SP String Char SP Char Char

It takes a stream pro cessor that exp ects the input to b e line buered and returns

a stream pro cessor that do es the necessary pro cessing of the input buering

echoing etc so that it can work in an unbuered environment

We implement lineBuerSP using lo opThroughRightSP

Application programming with plain stream pro cessors

bufSP

Screen progsp Keyboard

Figure Circuit diagram for lineBuerSP

lineBuerSP progsp lo opThroughRightSP bufSP progsp

where

bufSP SP Either Char Char Either String Char

bufSP

We get the connectivity shown in Figure ie bufSP will receive program

output and keyb oard input on its input stream and should pro duce input lines

and screen output on its output stream The implementation of bufSP is shown

in Figure

Using lineBuerSP the adding machine in the previous section can b e

adapted to run in raw terminal mo de by change mainSP to

mainSP lineBuerSP unlinesSP adderSP

Running two programs in parallel on a split screen

This last example is a combinator that splits the terminal screen into two win

dows and runs two programs in parallel one in each window

splitViewSP SP Char Char SP Char Char SP Char Char

A simple implementation of splitViewSP can b e structured as follows

splitViewSP sp sp

mergeSP sp sp distrSP

where

distrSP SP Char Either Char Char

distrSP

mergeSP SP Either Char Char Char

mergeSP

distrSP takes the keyb oard input and sends it to one of the two windows The

user can switch windows by pressing a designated key

mergeSP takes the two output streams from the windows and pro duces a

merged stream which contains the appropriate cursor control sequences to make

the text app ear in the right places on the screen This can b e done in dierent

ways dep ending on the terminal characteristics A simple solution if scrolling

is not required is to split the pro cessing into two steps the rst b eing to

Running two programs in parallel on a split screen

bufSP inputSP

inputSP line getSP either fromProgsp fromKeyb oard

where

fromProgsp c putSP toScreen c inputSP line

fromKeyb oard c

case c of

The Enter key

n putSP toScreen n

putSP toProgsp reverse line

bufSP

The backspace key

b if null line

then inputSP line

else putsSP map toScreen b b

inputSP tail line

Printable characters

putSP toScreen c

inputSP cline

toScreen Right

toProgsp Left

Figure bufSP the core of lineBuerSP

Application programming with plain stream pro cessors

((Int,Int),Char)

Char Char Char Char track

sp 1

sp 2 encode distr track

mergeSP

Figure Circuit diagram for splitViewSP sp sp

1 2

interpret the output streams from the two windows individually to keep track

of the current cursor p osition using a stream pro cessor like

trackCursorSP SP Char IntIntChar

It takes a character stream containing a mixture of printable characters and cur

sor control characters and pro duces a stream with pairs of cursor p ositions and

printable characters The next step is to merge the two streams and feed them

into a stream pro cessor that generates the appropriate cursor motion commands

for the terminal

enco deCursorMotionSP SP IntIntChar Char

Thus we have

mergeSP

enco deCursorMotionSP

mapSP stripEither

trackCursorSP trackCursorSP

Using the ab ove outlined implementation of mergeSP we get the circuit diagram

shown in Figure for splitViewSP sp sp

1 2

Filling in some details we ignored in the ab ove description we get the im

plementation shown in Figure

Running two programs in parallel on a split screen

splitViewSP IntInt SP Char Char SP Char Char SP Char Char

splitViewSP wh sp sp

mergeSP sp sp distrSP Left Right

where

mergeSP enco deCursorMotionSP

mapSP stripEither

trackCursorSP wh

mapSP movey trackCursorSP wh

h h div

h hh

movey xyc xyhc

distrSP dst dst

getSP c

case c of

t distrSP dst dst

putSP dst c distrSP dst dst

ackCursorSP IntInt SP Char IntIntChar

ackCursorSP size mapstateSP winp os

where winp os p c nextp os p cpc

co deCursorMotionSP SP IntIntChar Char

co deCursorMotionSP mapstateSP term

where

term curcurxcury pxyc

nextp os p cmovec

where

move if pcur

then

else moveTo p

xtp os IntInt Char IntInt

xtp os p c cursor position after c has been printed

veTo IntInt String

veTo xy generate the appropriate cursor control sequence

Figure An implementation of splitViewSP

IV Design and

implementation

In this part we will describ e the design and implementation of the Fudget

library itself as well as some extensions we have done The organisation of

the rst chapters can b e summarised in the words the library extensions and

programming methods

The library These chapters describ e the fundamental principles b ehind the

Fudget library Chapter discusses dierent implementations of stream

pro cessors The implementation of the fudget combinators is based on

stream pro cessors and allows them to communicate with dierent kind

of IO systems Chapter Chapter describ es the mechanism b e

hind the GUI fudgets asynchronous IO and the lowlevel interfaces to

X Windows

The automatic layout system in Chapter can b e seen as a sublibrary

of combinators which is used not only for placing the GUI fudgets but

also to comp ose graphics

Two examples of lter fudgets combinators that mo dify the eect of fud

gets are presented in Chapter The cache lter makes fudget programs

run faster using less memory and the fo cus lter mo dies the input mo del

of GUI fudgets that use the keyb oard

Extensions The next chapters describ e extensions that we do not consider

absolutely essential for the library although some of them reside in the

library itself and others have at least prompted mo dication of the library

in order to work

A distinguishing feature of stream pro cessors and fudgets is that they

can b e detached from their original p osition in the program passed as

messages and attached at another p osition Chapter describ es how this

can b e used to program draganddrop applications where GUI fudgets

actually move inside the program when dragged

Chapter shows how the fudget concept can b e used for programming

clientserver applications Server programs do usually not have any graph

ical interface but it is can b e advantageous to program servers in a con

current style so that they can serve many clients simultaneously

The library contains a class of typ es that has a graphical appearance which

can b e manipulated by the user Chapter presents the Graphic class

and its implementation

Programming metho ds These chapters describ e our exp eriments in pro

gramming metho ds using Fudgets Chapter describ es combinators for

creating syntaxoriented editors in a style similar to parsing combinators

and Chapter shows how Haskells class system can b e used to auto

matically generate simple GUIs As we have already seen in the previous

part the class system has also b een used to program functions that use

named parameters with default values The implementation is describ ed

in Chapter

Finally Chapter describ es an implementation of the functional to olkit

Gadgets on top of the Fudget library This includes a functional implemen

tation of the pro cess concept in Gadgets and allows Gadget programs to b e

incorp orated in Fudgets As a b onus a proling utility was added which pro

vides a graphical monitor of the message queues

Implementing stream pro cessors

Implementing stream pro cessors

In this chapter we present dierent implementations of stream pro cessors in

cluding a indeterministic solution that requires a language extension for parallel

evaluation and two purely functional ones the rst is based on streams as

lazy lists and the other uses a datatyp e with constructors corresp onding to the

op erations of atomic stream pro cessors We also discuss how suitable dierent

representations are for parallel and sequential implementations We start by

discussing some design goals that we had in mind

Design goals for stream pro cessors

The design of the stream pro cessors was already from the start inuenced by

the intended application as building blo cks in a GUI library In this context

we found the following prop erties imp ortant

Hierarchical structure The result of a comp osition of stream pro cessors

should also b e a stream pro cessor thus allowing complex pro cess networks

to b e built in an hierarchical structure There should b e no dierence in

principle b etween an atomic stream pro cessor and one comp osed from

several smaller stream pro cessors

Encapsulated state We should p ermit each stream pro cessor to have an in

ternal state which is invisible from the outside and which do es not inter

fere with the state of other stream pro cessors

IO connectedness It should b e p ossible to connect stream pro cessors to the

IO system in an abstract way so that the IO eects can b e hidden by

an abstract typ e with asso ciated combinators for their combination

Reactive b ehaviour The intended use of stream pro cessors is in the imple

mentation of interactive reactive programs This means that programs

are dominated by communication rather than computation a program

waits idly for some input to arrive computes and outputs a resp onse to

the input and then go es back to the idle state

Demanddriven evaluation The intention is to use stream pro cessors in a

lazy functional language where expressions are evaluated on demand

Stream pro cessors should also b ehave lazilythey should not do any work

until a value is demanded from their output stream and they should not

demand anything from their input stream unless the input can b e used to

pro duce a demanded output

Typ ed and higher order There should b e no restriction on the element

typ e of streams It should b e p ossible to transfer anything from num

b ers and b o oleans to functions and stream pro cessors Communication

should b e typ e safe

Parallel and sequential implementations Stream pro cessors should b e

implementable in a sequential language but we still want to keep the

denitions general enough to b e able to take advantage of constructions

for indeterministic choices and parallel evaluation

Intuitive ideaswhat is the problem

Esp ecially in the light of the last prop erty it seems desirable to have an

abstract formal semantics which can b e used to reason ab out dierent imple

mentations of stream pro cessors and programs using them So far we have not

elab orated such a semantics but instead we have concentrated on more practi

cal work by developing the Fudget library and application programs Moreover

the implementation of the basic streampro cessor combinators is quite simple

and can therefore b e viewed as b eing a semantics on its ownalthough not the

most concise and abstract one could imagine Nevertheless we have outlined a

simple streampro cessor calculus with an accompanying op erational semantics

in the future work chapter see Section

Intuitive ideaswhat is the problem

In a lazy functional language a natural choice is to represent streams as lists

Thanks to laziness the elements of the list can b e computed on demand one

element at a time The elements can thus form a sequence in time rather than

a sequence in space which would b e the case in a strict language

So a stream with elements of typ e a can b e represented as a list with elements

of typ e a A stream pro cessor can b e represented as function from the input

stream to the output stream

typ e Stream a a

typ e SP i o Stream i Stream o

We call this the listbased representation An obvious advantage with this ap

proach is that the list typ e is a standard typ e and all op erations provided for

lists can b e reused when dening stream pro cessors

Another advantage with this representation is that it clearly shows the close

relationship b etween functions and stream pro cessors For example serial com

p osition is simply function comp osition

SP m o SP i m SP i o

sp sp sp sp

The basic stream pro cessor actions also have very simple denitions

nullSP xs

x putSP sp xs x sp xs

getSP isp xs case xs of

xxs isp x xs

A problem with this representation however is that parallel comp osition is

imp ossible to implement A reasonable denition would have to lo ok something

like this

sp sp xs merge sp xs sp xs

where merge ys zs

But what should b e replaced with so that the rst output from the comp o

sition is the rst output to b ecome available from one of the comp onents For

example supp ose that

Implementing stream pro cessors

sp ? ?

1

sp ? ?

2

that is sp needs some input b efore it can pro duce some output but sp can

1 2

output immediately Then the comp osition should immediately output

sp sp ? ?

1 2

But sp sp ? should also b e ? so must b e an expression that

2 1

cho oses the one of ys and zs which happ ens to b e nonb ottom This can clearly

not b e done in an ordinary purely functional language

As a more concrete example consider what should happ en if we apply the

stream pro cessor

map lter even

to If the input elements app ear at a slower rate than they can b e

pro cessed by either map or lter the desired output stream would b e something

like ie in this particular case there should b e two

elements from the left stream pro cessor for every element from the right stream

pro cessor

The elements in the two output streams should b e merged in the order they

b ecome computable as more elements of the input stream b ecome available

However there is no way of telling in a sequential language which of the two

stream pro cessors will b e the rst one to b e able to pro duce an output Is seems

that the two streams need to b e evaluated in parallel and then elements must

b e chosen in the order they b ecome available

The most natural and general solution to this problem is to use parallel eval

uation and we will take a lo ok at this next But by changing the representation

of stream pro cessors it is p ossible to obtain solutions that work in an ordinary

sequential language We will lo ok at these solutions in Section

Parallel implementations

As illustrated in the previous section when representing stream pro cessors as

list functions parallel evaluation is needed not to gain sp eed but b ecause no

sequential evaluation order can give the desired result We need an op erator

that starts the evaluation of two sub expressions in parallel and then tells which

evaluation nished rst The result is thus not determined by the values of the

expressions but rather from their op erational b ehaviour Therefore such an

op erator cannot b e added to a purely functional language without problems

The op erator suggested ab ove is a variant of amb McCarthys ambivalent

op erator McC But a programming language with such an op erator is not

purely functional and thus makes ordinary equational reasoning unsound Al

though such a language may still b e useful Mor there are solutions that

allow you to make indeterministic choices in a purely functional way

In the following section we will intro duce a variant of amb which is purely functional

Sequential implementations

Oracles

To b e purely functional the result of an op erator must dep end entirely on the

values of the arguments and the same arguments should always give the same

result One way to make an op erator for indeterministic choice purely functional

is to intro duce an extra argument and pretend that the result is determined

solely by this argument although op erationally something else happ ens Such

an extra argument is called an oracle Bur

We call our op erator for indeterministic choice cho ose

cho ose Oracle a b Bo ol

Op erationally the expression cho ose o a b is evaluated by starting the evaluation

of a and b in parallel and then returning True if a reaches head normal form

rst and False if b do es Denotationally cho ose o a b returns True or False

dep ending only on the value of the oracle o which magically happ en to have

the right value An oracle should only b e used once since it must always

give the same answer We therefore distribute an innite tree of oracles to all

stream pro cessors as an additional argument

data OracleTree OracleNo de OracleTree Oracle OracleTree

typ e SP i o OracleTree Stream i Stream o

Using the oracle tree we can now easily implement parallel comp osition of

stream pro cessors see also Figure

sp sp

OracleNo de OracleNo de ot ot ot xs

merge ot sp ot xs sp ot xs

where merge OracleNo de ot o ys zs

if cho ose o ys zs

then merge ot ys zs

else merge ot zs ys

merge ot yys zs ymerge ot ys zs

merge ot zs zs

In this implementation the oracle tree is split into three two subtrees are fed

to the comp osed stream pro cessors and one is given to the function merge

together with the output streams from the comp osed stream pro cessors The

function merge extracts fresh oracles from the tree and uses cho ose to see which

stream is rst to reach head normal form It then calls merge with the second

argument b eing the stream which has b een evaluated

Sequential implementations

As we have seen ab ove the most natural representation of streams ie as

lists requires parallel evaluation and indeterministic choices But there are

solutions that allow you to stay within a purely functional language like Haskell

Although they do not provide the same degree of parallelism they have proved

to b e adequate for practical use The solutions b elow have b een used in the

implementation of the Fudget system

Implementing stream pro cessors

oracle stream

sp 1

sp 2

Figure Parallel comp osition of stream pro cessors using oracles

Synthetic oracles

As seen in Section the problem with the most natural representation of

stream pro cessorsrepresenting streams as lazy lists and stream pro cessors as

functions on lazy listsis the implementation of parallel comp osition It is

imp ossible to know in which order the output streams should b e merged

If we imp ose the restriction that sp and sp must pro duce output at the

1 2

same rate then sp sp can b e dened as

1 2

sp sp xs merge sp xs sp xs

where merge yys zzs yzmerge ys zs

However it is awkward to imp ose such a constraint b etween the output streams

of two dierent stream pro cessors Also this solution do es not work well for

tagged parallel comp osition A more useful constraint relates the input and

output stream of a single stream pro cessor

 We imp ose the constraint that there must b e a onetoone corresp ondence

b etween elements in the output and the input stream ie a stream pro ces

sor must put one element in the output stream for every element consumed

from the input stream

The function map is an example that satises this constraint whereas lter is a

function that do es not

With this restriction tagged parallel comp osition can easily b e implemented

the next element in the output stream should b e taken from the stream pro cessor

that last received an element from the input stream The following implementa

tion of tagged parallel comp osition uses this fact by merging the output streams

using a stream of synthetic oracles computed from the input stream see also

Figure

Sequential implementations

synthetic oracles

sp 1

sp 2

Figure Parallel comp osition of stream pro cessors using synthetic oracles

SP a b SP a b SP Either a a Either b b

sp sp xs merge os sp xs sp xs

where

xs x Left x xs

xs y Right y xs

os a synthetic oracle stream

os map isLeft xs

merge Trueos yys zs

Left ymerge os ys zs

merge Falseos ys zzs

Right zmerge os ys zs

isLeft Left True

isLeft Right False

This solution has some practical problems however As it stands ab ove there

is a p otentially serious spaceleak problem Consider the evaluation of an ex

pression like

sp sp Left n n

1 2

Here sp will never receive any input This means that merge will never need to

2

evaluate the argument sp xs which holds a reference to the b eginning of the

2

input stream via xs This would cause all input consumed by the comp osition

to b e retained in the heap However provided that pattern bindings are imple

mented prop erly Spa this problem can b e solved by computing xs and xs

with a single recursive denition that returns a pair of lists

split Either a b ab

split

split xxs

case x of

Left x xxsxs

Right x xsxxs

where

xsxs split xs

Another problem is that the restriction is rather severe What should a

stream pro cessor do if it do es not want to put a value in the output stream

after consuming an input like lter What if it wants to output more than

Implementing stream pro cessors

one value Obviously if an implementation with this restriction is given to a

programmer he will invent various ways to get around it It is b etter to provide

a solution from the b eginning

One way to relieve the restriction is to change the representation of stream

pro cessors to

typ e SP a b a b

thus allowing a stream pro cessor to output a list of values to put in the out

put stream for every element in the input stream Unfortunately with this

representation the standard list functions like map and lter can no longer b e

used in such a direct way For example instead of map f one must use map

xf x Serial comp osition is no longer just function comp osition rather

it is something more complicated and less ecient Also it is still p ossible to

write stream pro cessors that do not ob ey the restriction leading to errors

that can not b e detected by a compiler Consequently it is not a go o d idea to

reveal this representation to the application programmer but rather provide the

streampro cessor typ e as an abstract typ e And while we are using an abstract

typ e we might as well use a b etter representation

Continuationbased representation

Instead of using lists the Fudget library uses a data typ e with constructors

corresp onding to the actions a stream pro cessor can take as describ ed in Section

data SP i o

NullSP

PutSP o SP i o

GetSP i SP i o

We call this the continuationbased representation of stream pro cessors The

typ e has one constructor for each op eration a stream pro cessor can p erform

The constructors have arguments that are part of the op erations the value

to output in PutSP and arguments that determine how the stream pro cessor

continues after the op eration has b een p erformed

The continuationbased representation avoids the problem with parallel com

p osition that we ran into when using the listbased representation since it makes

the consumption of the input stream observable With list functions a stream

pro cessor is applied to the entire input stream once and for all The rate at

which elements are consumed in this list is not observable from the outside

With the continuationbased representation a stream pro cessor must evaluate

to GetSP sp each time it wants to read a value from the input stream This is

what we need to b e able to merge the output stream in the right order in the

denition of parallel comp osition

An implementation of broadcasting parallel comp osition is shown in Fig

ure The implementation of tagged parallel comp osition is analogous Note

that we arbitrarily cho ose to insp ect the left argument sp rst This means

1

that even if sp could compute and output a value much faster than sp it will

2 1

not get the chance to do so With the continuationbased representation serial

comp osition can b e implemented as shown in Figure

A denition of the lo op combinator lo opSP is shown in Figure

Sequential implementations

NullSP sp sp

sp NullSP sp

PutSP o sp sp PutSP o sp sp

sp PutSP o sp PutSP o sp sp

GetSP xsp GetSP xsp GetSP i xsp i xsp i

Figure Implementation of parallel comp osition with the continuationbased

representation

NullSP sp NullSP

PutSP o sp sp PutSP o sp sp

GetSP xsp NullSP NullSP

GetSP xsp PutSP m sp xsp m sp

GetSP xsp GetSP xsp GetSP i GetSP xsp xsp i

Figure Implementation of serial comp osition with the continuationbased

representation

loopSP sp lo opSP empty sp

where

lo opSP q NullSP NullSP

lo opSP q PutSP o sp PutSP o lo opSP enter q o sp

loopSP q GetSP xsp

case qremove q of

Just iq lo opSP q xsp i

Nothing GetSP lo opSP xsp

Fifo queues

data Queue

empty Queue a

enter Queue a a Queue a

qremove Queue a Mayb e aQueue a

Figure Implementation of lo opSP with the continuationbased representa tion

Implementing stream pro cessors

Example Implement runSP SP a b a b

Solution runSP sp xs

case sp of

PutSP y sp y runSP sp xs

GetSP xsp case xs of

x xs runSP xsp x xs

NullSP

Continuations vs list functions

We have seen two representations of stream pro cessors one based on list func

tions and one based on continuations Which one is b etter

Using list functions works well for parallel implementations Demand is prop

agated from the output to the input stream by the normal evaluation mechanism

of the functional language Since streams are represented as lists the standard

list functions can b e used directly as stream pro cessors

For sequential implementations we saw that representing stream pro cessors

as functions from streams to streams prevented us from implementing paral

lel comp osition Here the continuationbased representation seems more at

tractive and is the one that we currently employ in the Fudget library The

continuationbased representation also allows stream pro cessors to b e detached

moved and plugged in somewhere else in the programsomething that is used

in Chapter

Since our implementation is based on a sequential programming language

we do not get true concurrency As long as all stream pro cessors quickly react

to input to avoid blo cking other stream pro cessors in the program this is ac

ceptable in practice The reactiveness prop erty is not enforced by the compiler

however

It would b e nice to have a representation that works well for b oth parallel and

sequential implementations Is p erhaps the continuationbased representation

useful also for parallel implementations Consider the comp osition

sp idSP sp

1 2

The rst output from the comp osition should b e either the rst output from

sp or the rst output from sp whichever happ ens to b e ready rst But the

1 2

parallel comp osition must evaluate to either PutSP or GetSP In the rst

case we have prematurely committed ourselves to taking the output from sp

1

rst In the second case we will not b e able to deliver the rst output until after

sp has delivered its rst output It is not clear to us how the desired b ehaviour

2

should b e achieved

Fudgets as stream pro cessors

Having an implementation of stream pro cessors we are ready to build fudget

combinators and some simple fudgets based on the stream pro cessor combi

nators and op erations With Figure in mind we can view fudgets in two

ways

As plain stream pro cessors which can have IO eects This is the abstract

view that is presented to the application programmer With this view

the fudget combinators simply do the same things as the corresp onding

streampro cessor combinators

As stream pro cessors with explicit highlevel and lowlevel streams In

this chapter we will take this view in order to implement fudgets

It should b e noted that there are other ways of implementing fudgets We give

two examples suitable for a monadic IO system in Section references to

other work in implementing fudgets are given in Chapter

The fudget implementation used in the library is highly inuenced by the

synchronised stream IO system used in version of Haskell HPJWe

Synchronised stream IO

Synchronised stream IO can b e seen as a variant of the Landin stream IO

in Figure where characters in the output and input streams are replaced

by request and response constructors The program and the IO system are

synchronised in that for each request that the program pro duces one resp onse

is pro duced by the IO system Thus the program and the IO system can

b e seen as two parts in a sp ecial typ e of dialogue The typ e of a synchronised

stream program main is

typ e Dialogue Request Resp onse

main Dialogue

Each request constructor represents a sp ecic eect and is dened in the

datatyp e Request in Haskell

data Request ReadFile String

WriteFile String String

ReachChan Chan

App endChan Chan String

The constructor ReadFile f is a request for the IO system to read the contents

of the le with name f WriteFile f s is a request for writing s to a le with

name f Standard input and output are instances of so called channels reading

the character stream from standard input is requested by ReadChan stdin and

App endChan stdout s is a request to write s on standard output

The typ e of the resp onse that is generated when a request is carried out

dep ends on the request constructor All resp onse typ es are put in the union

typ e Resp onse

Fudgets as stream pro cessors

data Resp onse Success

Failure IOError

Str String

IntResp Int

If the IO requests are successful requests for output merely generate a Success

resp onse whereas input requests generate a value tagged with Str IntResp or

some other constructor dep ending on its typ e If a request fails an error value

tagged Failure is generated

A program that uses the synchronised stream IO mo del can b e viewed as

an atomic sequential stream pro cessor that explicitly uses lists for representing

the streams

The tagged lowlevel streams

When adapting the synchronised stream mo del to Fudgets we do two mo di

cations Firstly we discard the explicit representation of streams as lazy lists

and secondly we tag the requests and resp onses to allow more than one stream

pro cessor to do IO in our program

We dene a fudget of typ e F hi ho to b e a stream pro cessor that can input

messages of typ e hi or tagged resp onses and outputs ho messages or tagged

requests

typ e F hi ho SP Message TResp onse hi Message TRequest ho

data Message low high Low low High high

We could have used the standard typ e Either but we prefer using the equivalent

typ e Message for clarity

The lowlevel streams carry IO requests and resp onses Fudget combina

tors like and merge the requests streams from the two argument

fudgets But when a fudget outputs a request we must b e able to send the cor

resp onding resp onse back to the same fudget For this reason messages in the

lowlevel streams are tagged with p ointers indicating which fudget they come

from or should b e sent to Since a fudget program can b e seen as a tree of fud

gets where the no des are fudget combinators and the leaves are atomic fudgets

we have chosen to use paths that p oint to no des in the tree structure

typ e TResp onse PathResp onse

typ e TRequest PathRequest

typ e Path Turn

data Turn L R left or right

The messages output from atomic fudgets contain an empty path The binary

fudget combinators prep end an L or an R onto the path in output messages

to indicate whether the message came from the left or the right subfudget

Combinators that combine more than two fudgets such as listF uses a binary

enco ding of subfudget p ositions On the input side the path is insp ected to nd

out to which subfudget the message should b e propagated

As an example consider the fudget

The tagged lowlevel streams

F i o F i o F Either i i Either o o

f f mapSP p ost f f mapSP pre

where

p ost msg

case msg of

Left High ho High Left ho

Right High ho High Right ho

Left Low pathreq Low Lpathreq

Right Low pathreq Low Rpathreq

pre msg

case msg of

High Left hi Left High hi

High Right hi Right High hi

Low Lpathresp Left Low pathresp

Low Rpathresp Right Low pathresp

Figure Tagged parallel comp osition of fudgets

f f f f

1 2 3

When f wants to p erform an IO request r it puts r in its lowlevel output

2

stream The combinator will prep end an L to the path since f is the

2

left subfudget so Lr will app ear in the lowlevel output of f f

2 3

Analogously the combinator will prep end an R so the lowlevel output

from f will contain RLr When a resp onse later app ears in the input stream

of f it will b e tagged with the same path RL which will cause the combinators

to propagate it to f

2

As should b e apparent the length of the paths is determined directly by

the nesting depth of fudget combinators in the program For programs that are

structured roughly as balanced trees of fudgets the length of the paths thus

grow logarithmically with the numb er of atomic fudgets in the program Hence

the overhead of constructing and analysing the paths also grows logarithmically

with the numb er of fudgets In practice the maximal path length we have

observed varies from for trivial programs the Hello world program in

Section for small programs the calculator in Section and for

large programs the pro of assistant Alfa in Chapter

Constructing and analysing the paths of messages is not the only source

of overhead in the lowlevel message passing Some fudget combinators most

notably the lters see Chapter treat some commands or events sp ecially

They thus need to insp ect all messages that pass through them When a large

numb er of messages have to b e sent the overhead may b ecome to o high In

Section we present a situation in which we encountered this problem and

give a solution

An implementation of tagged parallel comp osition of fudgets is shown in

Figure We have reused tagged parallel comp osition of stream pro cessors by

adding the appropriate tag adjusting pre and p ost pro cessors The other fudget

combinators can b e implemented using similar techniques

When a request reaches the top level of a fudget program the path should

Fudgets as stream pro cessors

fudlogue F a b Dialogue

fudlogue mainF runSP lo opThroughRightSP routeSP lowSP mainF

routeSP

getLeftSP pathrequest

putSP Right request

getRightSP resp onse

putSP Left pathresp onse

routeSP

lowSP SP Message li hi Message lo ho SP li lo

lowSP fud lterLowSP fud mapSP Low

lterLowSP mapFilterSP stripLow

stripLow Low low Just low

stripLow High Nothing

Figure A simple version of fudlogue for synchronised stream IO It do es

not handle asynchronous input

b e detached b efore the request is output to the IO system and then attached

to the resp onse b efore it is sent back into the fudget hierarchy This is taken

care of in fudlogue A simple version of fudlogue is shown in Figure This

version will suce for programs where individual fudgets do not blo ck in their

IO requests If we want to react on input from many sources which comes in

an unknown order eg so ckets standard input the window system timeout

events this implementation will not b e enough so what should we do We will

discuss this more in Section The short answer is that we can detect when

the main fudget has b ecome id le that is it has evaluated to getSP and do es

not wait for a synchronous resp onse At this p oint we p erform a system call

namely select to wait for input to happ en on any of our sources of events

Writing synchronous atomic fudgets

With the fudget representation in Section an atomic fudget which rep eat

edly accepts a Haskell IO request p erforms it and outputs the resp onse can

b e implemented as follows The combinators getHighSP and getLowSP waits

for high and lowlevel messages resp ectively They are dened in terms of

waitForSP Section

requestF F Request Resp onse

requestF getHighSP req

putSP Low req

getLowSP resp onse

putSP High resp onse requestF

Fudget kernels

Some requests should b e avoided since when we evaluate their resp onses the

program might blo ck For example we should not use ReadChan stdin b ecause

its resp onse is a lazy list representing the character streams from the standard

input

Files are usually OK to read a fudget like readFileF Section can b e

implemented as follows

readFileF F String Either IOError String

readFileF p ost requestF ReadFile

where p ost Str s Right s

p ost Failure f Left f

On its input it waits for le names to op en The output is either an error value

or the content of the le

Fudget kernels

The fudget requestF in the previous section provides an interface to the Haskell

stream IO system To program a fudget with a particular sequential IO

b ehaviour a combinator like

Preliminary version

streamIoF SP Either Resp onse i Either Request o F i o

streamIoF sp lo opThroughRightF absF sp requestF

could b e used The argument stream pro cessor sp can talk to requestF using mes

sages tagged Left and to other fudgets through messages tagged Right However

it seems more appropriate to tag messages with the typ e Message intro duced

ab ove and let the typ e of streamIoF b e

Final version

streamIoF K i o F i o

where

typ e K i o SP Message Resp onse i Message Request o

We call stream pro cessors of typ e K i o fudget kernels Fudget kernels are thus

used when dening new atomic fudgets with particular IO b ehaviours We

dene some combinators for describing IO b ehaviours in continuation style

putHighK o K i o K i o

getHighK i K i o K i o

nullK K i o

doStreamIOK Request Resp onse K i o K i o

The rst three op erations corresp ond directly to the streampro cessor combi

nators putSP getSP and nullSP so fudget kernels can b e seen as plain stream

pro cessors with access to the IO system

The implementations of the combinators intro duced in this section are shown

in Figure

Fudgets as stream pro cessors

typ e K i o SP Message Resp onse i Message Request o

streamIoF K i o F i o

streamIoF kernel mapSP p ost kernel mapSP pre

where

pre High i High i

pre Low resp Low resp

p ost High o High o

p ost Low req Low req

putHighK o K i o K i o

putHighK putSP High

getHighK i K i o K i o

getHighK waitForSP high

where

high High i Just i

high Nothing

nullK K i o

nullK nullSP

doStreamIOK Request Resp onse K i o K i o

doStreamIOK request contK

putSP Low request

waitForSP low contK

where

low Low resp Just resp

low Nothing

Figure Fudget kernel combinators

Alternative implementations using monadic IO

Alternative implementations using monadic IO

To day Haskell uses the monadic IO mo del which is briey explained in Sec

tion A monadic version of fudlogue can b e dened as follows

fudIO F a b IO

fudIO f case f of

NullSP return

GetSP return

PutSP High f fudIO f

PutSP Low pathreq f

do resp doRequest req

fudIO startupSP Low pathresp f

This version still uses the stream IO constructors internally to represent eects

It relies on an auxiliary function

doRequest Request IO Resp onse

that converts requests to corresp onding monadic eects

We can also go one step further by throwing out the request and resp onse

datatyp es and use the IO monad directly to represent eects This can b e im

plemented by adding a constructor to the continuationbased streampro cessor

typ e

data F i o PutF o F i o

GetF i F i o

NullF

DoIoF IO F i o

The constructor DoIoF is used to express IO eects This constructor do es

not have any explicit argument for the continuation fudget which instead is

returned from the IO computation To connect fudgets to the IO system we

use fudIO

fudIO F i o IO

fudIO f case f of

NullF return

GetF return

PutF f fudIO f

DoIoF io io fudIO

We can provide an op eration doIoF for plugging in monadic IO op erations in

a fudget

doIoF IO a a F i o F i o

doIoF io c DoIoF map c io

The fudget combinators are dened just as the corresp onding for stream pro

cessors with extra cases for the DoIoF constructor For example in the case of

parallel comp osition these are

DoIoF io g DoIoF map g io

f DoIoF io DoIoF map f io

Fudget IO the gory details

Fudget IO the gory details

In this chapter we will dive into some of the gory details in the Fudget library

implementation We will see how the GUI fudgets are designed to t with

X Windows in Section using the hierarchical windows that X provides

Asynchronous IO is necessary to handle events from many sources such as

the X server standard input and so ckets The implementation of asynchronous

IO is describ ed in Section

The communication b etween a fudget program and the X server uses the

library Xlib Nye which is written in C Xlib denes a numb er of data typ es

and calls for creating and maintaining windows drawing in windows and receiv

ing input events

There is no standardised foreignlanguage interface for Haskell so Haskell

programs cannot directly call Xlib To solve this problem we have implemented

a numb er of interfaces to Xlib one of which is compiler indep endent and three

which are sp ecic for HBC NHC and GHC These interfaces are describ ed in

Section

GUI Fudgets

The implementation of GUI fudgets uses the p ossibility to create hierarchical

windows in X Windows a feature that works as follows

In X Windows an application program creates one or more shel l windows

We have already seen in Chapter how the fudget shellF is used to create a shell

window These windows app ear on the users desktop and are decorated with

a title bar by the window manager The window manager allows the user to

manipulate shell windows in various ways for example they might b e resized

and moved around on the desktop A shell window thus corresp onds to the

users concept of a window

From the p oint of view of the application programmer a shell window pro

vides an area which can b e lled with graphics and which can react to events

such as mouse clicks which the X server can rep ort to the application as events

The window has its own co ordinate system which has its origin in the upp er left

corner regardless of the windows p osition on the desktop The window system

also ensures that when the application draws in a shell window only areas that

are visible are up dated This implies a simplication for the application pro

grammer since he do es not have to consider other applications that the user

has started

So far this story holds for most window systems X Windows go es one

step further and allows the programmer to create more windows within the

shell window These can in turn contain even more windows Each window has

its own co ordinate system and can b e moved and resized but not directly by

the user of the application as was the case with shell windows If a window

is moved all windows inside it will follow keeping their p osition in the lo cal

co ordinate system In addition each window is asso ciated with an event mask

which allows the programmer to control how sensitive the application should

b e to user input when the p ointer is in the window

The simplication that the concept of shell windows brought us as appli

cation programmers can b e carried over to hierarchical windows If each GUI

element is put in its own subwindow the application program do es not need to

GUI Fudgets

know the elements p osition in the shell window when drawing in it for exam

ple It is also p ossible to have a large subwindow inside a smaller window By

moving the large window we get the eect of scrolling an area

Since each GUI fudget has its own window p ossibly containing subwindows

we have also used the p ossibility to asso ciate each GUI fudget with its own

event mask something that we use to limit the network trac of events from

the server to the application This was initially an imp ortant asp ect in Fudgets

see Section and is still an advantage when running programs over low

bandwidth links

Using one window p er GUI fudget also simplies the routing of events inside

the application which receives one single stream of events from the X server

The handling of events is not centralised instead the GUI fudgets handle events

by themselves When the X server rep orts a mouse click the event contains in

formation ab out what subwindow was clicked and the p osition uses the lo cal

co ordinate system of the subwindow The window information is used in fud

logue which maintains a mapping from window identiers to GUI fudget paths

Data typ es for the X Windows interface

The GUI fudgets uses four datatyp es for their communication with the X server

via Xlib First we have the datatyp es XRequest and XResp onse which can b e

seen as extensions to Request and Resp onse which allow us to communicate

with the X server

data XRequest

Op enDisplay DisplayName

CreateSimpleWindow Path Rect

CreateRo otWindow Rect

CreateGC Drawable GCId GCAttributeList

LoadFont FontName

CreateFontCursor Int

data XResp onse

DisplayOp ened Display

WindowCreated Window

GCCreated GCId

FontLoaded FontId

CursorCreated CursorId

The remaining two datatyp es are XCommand which can b e seen as a set of

requests without resp onses and XEvent which enco de events that the X server

asynchronously rep orts to the application

Fudget IO the gory details

data XCommand

CloseDisplay Display

DestroyWindow

MapRaised

LowerWindow

UnmapWindow

Draw Drawable GCId DrawCommand

ClearArea Rect Bo ol

ClearWindow

CreateMyWindow Rect

data XEvent

KeyEvent timeTime

p osro otPosPoint

stateMo dState

typ ePressed

keyco deKeyCo de

keySymKeySym

keyLo okupKeyLo okup

ButtonEvent timeTime

p osro otPosPoint

stateMo dState

typ ePressed

buttonButton

MotionNotify timeTime

p osro otPosPoint

stateMo dState

EnterNotify timeTime

p osro otPosPoint

detailDetail

mo deMo de

LeaveNotify timeTime

p osro otPosPoint

detailDetail

mo deMo de

Exp ose rectRect

countInt

The datatyp es corresp ond more or less closely to Xlib calls and X events with

one imp ortant dierence The Xlib calls and events deal with additional display

a display is a connection to an X server and window arguments which are

added by fudlogue see Section

A numb er of auxiliary data typ es that also corresp ond more or less directly

to denitions found in the Xlib library are shown in Figure

GUI Fudgets

Resource identiers

newtyp e Display Display Int

and similarly for Window PixmapId FontId GCId CursorId

ColormapId

Type synonyms for readability

typ e FontName String

typ e ColorName String

typ e Time Int

typ e Depth Int

GC and Window attributes

data WindowAttributes

CWEventMask EventMask

CWBackingStore BackingStore

CWSaveUnder Bo ol

typ e GCAttributeList GCAttributes Pixel FontId

data GCAttributes a b See Section

Various enumeration types

data EventMask

KeyPressMask KeyReleaseMask ButtonPressMask ButtonReleaseMask

EnterWindowMask LeaveWindowMask PointerMotionMask

Exp osureMask

data BackingStore NotUseful WhenMapp ed Always

Geometry

data Point Pointxco ordInt yco ordInt

data Rect Rectrectp osPoint rectsizeSize upper left corner and size

typ e Size Point

data Line Line Point Point coordinates of the two end points

Figure Some of the auxiliary typ es used by the interface to Xlib

Fudget IO the gory details

groupF the primitive window creation fudget

GUI fudgets are created with the group fudget

groupF K a b F c d F Either a c Either b d

The typ e of groupF resembles and indicates that it puts two stream

pro cessors in parallel It will also create a window which will b e controlled by

the rst stream pro cessor which is a kernel see Section All X commands

that the kernel outputs will go to the group fudgets window and the X events

from the window will go to the kernel

As the name indicates groupF also groups the GUI fudgets in its second

argument in the following sense Assume we have the group g

g groupF k f

All the windows that are created by groups inside f will b e created inside the

window created by g and thus group ed A consequence is that if the kernel k

decides to move its window all groups inside f will follow

The atomic GUI fudgets are constructed along the pattern groupF k nullF

that is they do not have any internal fudgets just a kernel controlling a window

As an example consider a group fudget of the form

groupF k groupF k groupF k nullF groupF k nullF

1 2 3 4

It will have a window with two subwindows one of which will have yet another

subwindow as is illustrated in Figure

A group fudget starts by outputting the command CreateMyWindow r where

r is a rectangle determining the size and p osition of the window in its parent

window This is a command that do es not corresp ond to any Xlib call Instead

it will b e intercepted by the closest containing group fudget which will see

it as a tagged command of the form pCreateMyWindow r The containing

group fudget will convert this to the request CreateSimpleWindow p r When

this request reaches fudlogue it will b e of the form qCreateSimpleWindow p r

From this information fudlogue will b e able to deduce in which window the new

window should b e created and new windows path is found by concatenating q

and p see also the end of section Section

The observant reader now asks What if there is no containing group fud

get The answer is that shellF also counts as a kind of group fudget and

we know that a shellF is always wrapp ed around GUI fudgets The main dif

ference b etween groupF and shellF is that the latter starts by outputting Cre

ateRo otWindow instead of CreateMyWindow The request CreateRo otWindow is

used to create shell windows

The group fudget concept can b e used for structuring complex fudgets One

example is buttonGroupF

buttonGroupF F Either BMevents a b F a b

data BMevents BMNormal BMInverted BMClick

It is used in the Fudget library to program push buttons The enclosed fudget

will get messages which indicate what visual feedback is appropriate to give

and when the user actually has clicked in the window This is an example of a

group fudget which is invisible to the userit only deals with input

Synchronous versus asynchronous IO

k 1

k 2 k 4

k 3

Figure Four group fudgets Each group has a kernel stream pro cessor

controlling an X window

As an example of a group fudget which only deals with output we can have

a lo ok at buttonBorderF

buttonBorderF F a b F Either Bo ol a b

which is used to draw the threedimensional b order around push buttons which

can lo ok either pressed or released The familiar button fudget buttonF is a

combination of these two group fudgets and a lab elF

One would think that the buttonBorderF always is used im

mediately inside a buttonGroupF but this is not necessary A

go o d counter example is toggleButtonF in which a buttonGroupF

is wrapp ed around two fudgets a buttonBorderF which has a little

onODispF in it indicating its state and a lab elF The user can

control the toggle button by clicking anywhere in the buttonGroupF including

the lab el Note that the group structure in the toggle button coincides with

Figure

Synchronous versus asynchronous IO

The implementation of stream pro cessors in the Fudget library gives us co op er

ative multitasking which implies that stream pro cessors should b e programmed

in a reactive style This means that the normal state for a stream pro cessor is to

b e idle waiting for input When such input comes the stream pro cessor reacts

by more or less immediately outputting zero or more messages and then go es

back to the waiting state

Fudget IO the gory details

Moreover fudgets must b e co op erative when p erforming IO tasks As we

have seen in Chapter the IO requests from all fudgets in a program are

p erformed in fudlogue We must make sure that these requests are of a transient

nature and can b e carried out more or less immediately

For these reasons the Fudget library makes a distinction b etween syn

chronous and asynchronous IO Synchronous IO where the whole fudget pro

gram must wait for the IO op eration to complete is only used for transient

op erations Its implementation is straightforward as we saw in Section

Since synchronous IO is simple to implement the Fudget library currently uses

it when reading and writing to les and when writing to so ckets standard out

put and the X server In most cases but not all these op erations are transient

and a future improvement of Fudgets would b e to use asynchronous IO even for

these When it comes to reading from standard input or so ckets or waiting for

events from the X server asynchronous IO is used since these are op erations

that are likely to blo ck for arbitrary long p erio ds of time

Fudgets for asynchronous IO

The fudgets timerF Section and so cketTransceiverF Section are ex

amples of fudgets that must use asynchronous IO to avoid blo cking the whole

program Both of them create descriptors as a rst step

data Descriptor So cketDe So cket

TimerDe Timer

DisplayDe Display

A so cket descriptor of typ e So cket is returned as a resp onse to the request

Op enSo cket h p which op ens a so cket connection to the p ort p on host h Sim

ilarly a request CreateTimer i d results in a timer descriptor asso ciated with

interval i and delay d

Simply creating a descriptor do es not result in any asynchronous IO A

fudget can use the sp ecial request

Select Descriptor Request

to signal to fudlogue that it is interested in asynchronous input from a sp ecied

set of descriptors

The asynchronous fudlogue

To handle asynchronous IO fudlogue maintains a mapping b etween descriptors

and paths to fudgets We have just seen that fudlogue can receive messages of

the form p Select ds which announce that there is a fudget with path p which

waits for the asynchronous input asso ciated with the descriptors in ds The

function fudlogue collects all descriptors received in this way from all fudgets in

the program When the main fudget evaluates to getSP without an outstanding

request fudlogue knows that it is time to wait for some asynchronous event to

happ en It emits a Select request with all collected descriptors as an argument

The eects of this request are

a call to the UNIX function select which will wait for input to arrive on

any of the descriptors or a timeout and

The interfaces to Xlib

a read op eration on the corresp onding descriptor unless it was a timeout

The resp onse generated is of typ e AsyncInput

typ e AsyncInput Descriptor AEvent

data AEvent So cketAccepted So cket Peer

So cketRead String

TimerAlarm

XEvent WindowId XEvent

As the typ e AEvent indicates the resp onse of Select is the descriptor which

b ecame ready paired with the data read

Using the descriptor table fudlogue is able to route the received asyn

chronous input to the waiting fudget

In addition fudlogue p erforms the following translations to handle events to

the GUI fudgets

 For each group fudget fudlogue has an asso ciation from its path to the

identier of its window and a display descriptor the so cket connection

to the X server The group fudgets are unaware of which window or

display they are asso ciated with so fudlogue adds this information to the

X related commands and requests from GUI fudgets

 There is also the reversed mapping from window identiers to paths which

fudlogue uses to route events from the X server to the group fudget asso

ciated with the window

The interfaces to Xlib

We have already seen in Section that we have extended the Request and

Resp onse datatyp es with constructors divided in XRequest XResp onse XCom

mand and XEvent that corresp ond to Xlib calls and X events These data

typ es do not provide a complete interface to Xlib We have implemented those

calls that we found useful and extended the interface by need Also some pa

rameters have b een omitted from some constructors Somewhere the actual

IO that these requests and commands represent must b e carried out and this

is done in what we call the interface to Xlib We have implemented a numb er

of dierent such interfaces and they are describ ed in what follows

A compiler indep endent interface

The rst implementation of Fudgets was done in LML in and used Landins

stream IO mo del see Chapter A program in LML is a function of typ e

StringString The rst interface to Xlib was done by outputting the calls

and receiving the return values and events in text form via the standard output

and input channels The program was connected by a bidirectional pip e to

an external C program that p erformed the actual Xlib calls The typ e of the

function fudlogue was F i o StringString

The advantage with this metho d is that it is p ortable No changes need to b e

made to the compiler or its asso ciated runtime system The same C program

can b e used with another compiler or even another programming language

Fudget IO the gory details

typ e Dialogue Resp onse Request

data Request ReadFile String

WriteFile String String

Extensions

XCommand XDisplayXWIdXCommand

XRequest XDisplayXWIdXRequest

So cketRequest So cketRequest

Select Descriptor

data Resp onse Success

Str String

Failure IOError

Extensions

GotSelect AsyncInput

So cketResp onse So cketResp onse

XResp onse XResp onse

Figure Extending the Haskell dialogue IO typ es with requests for the

interface to Xlib

The disadvantage with this metho d is that it is inecient b ecause of the

parsing and printing of commands return values and events By printing them

in a simple format the overhead can b e kept down though Also for most

userinterface tasks the throughput need not b e very high

The interface for HBC

To avoid the overhead of the text communication with a separate pro cess

Lennart Augustsson integrated the interface to Xlib with the runtime system

of LML LML uses the synchronised stream IO see Section so the inte

gration was done by adding new constructors to the request and resp onse typ es

The extensions are shown in Figure They handle commands and requests

corresp onding to Xlib calls requests for so cket IO and the asynchronous IO

describ ed in Section The typ e of the function fudlogue was changed to

F i o Dialogue

The part of HBCs runtime system that handles dialogue IO is imple

mented in C The pro cedure that implements the Requests was mo died to

handle the XRequest and XCommand requests by calling a new pro cedure dox

call outlined in Figure As can b e seen in Figure a few lines of C co de

p er supp orted Xlib call are needed

The interfaces to Xlib

PTR doxcallt p

int t tag of the Request

PTR p p ointer to the argument of the Request

PTR resp onse

p evaluatep

switcht

case XCommand Display Window XCommand

p evalArgsp

xdo commandDisplay INTOFGETOFp

INTOFGETOFp

GETOFp

resp onsemkconstrRSuccess

break

case XRequest Display Window XRequest

PTR xresp

p evalArgsp

xrespdoxrequestDisplay INTOFGETOFp

INTOFGETOFp

GETOFp

resp onsemkconstrXResp onsexresp

break

default

fprintfstderr Unknown X IO request

exit

break

return resp onse

void xdo commanddisplay wi p

Figure The C function doxcall was added to HBCs runtime system to

handle the extra requests XCommand and XRequest

Fudget IO the gory details

PTR

doxrequestdisplaywip

Display display

Window wi

PTR p

PTR rp

Window parent

switchgetcnop

case XRqOp enDisplay DisplayName

char displaynameBUFSIZE

Display display

evalstringEARGp displayname sizeof displayname

displayXOp enDisplaydisplayname NULL displayname

return MkPtrXRespXRDisplayOp eneddisplay

break

case XRqCreateRo otWindow Rect

Figure The C function doxrequest analyses the XRequest constructor and

carries out the corresp onding call to Xlib

The interfaces to Xlib

The interface for NHC

In the summer the Fudget library was p orted to NHC Rjb for Haskell

PH to allow fudget programs to take advantage of the new heap proling

features available in NHC RRaRRb

The Fudget library could b e p orted to NHC by a relatively small eort

 A mo dule containing the denitions of the Haskell typ es Request and

Resp onse typ es was added since none of these are dened in Haskell

 The fudlogue function was mo died to lo ok like fudIO in Section

 The runtime system of NHC was extended to implement the Xlib calls and

the other extensions Fortunately HBC and NHC have very similar run

time systems so all of the C co de written for HBC could b e reused with

only minor changes in spite of the dierences b etween the IO systems

The extensions were made available as a new monadic IO op eration

similar to doRequest in Section

doXCall Request IO Resp onse

The eect of this function is a call to the pro cedure doxcall in Figure

Supp ort for twopass heap proling Heap proling can help you

improve the memory b ehaviour of your programs For example you may nd

out using a biographical heap prole that a large p ortion of the data in the heap

is drag that is a lot of no des that are kept in the heap after their last use You

may then use a combination of a biographical prole and a retainer prole to

nd out which set of functions in the program that are resp onsible for retaining

the drag This may give you a clue as to how you should change the program

to get rid of the drag

The implementation of certain combined proles as describ ed in RRb

collects the needed information in two passes that is the program is run twice

In order to create two identical runs the return values of all IO op erations

must b e recorded during the rst run and then played back during the second

run

In order to allow fudget programs to take advantage of the latest heap prol

ing technology Niklas Rjemo added the necessary co de for recording and play

ing back the results of the Xlib calls and other extended IO op erations used by

the Fudget library As a typical example the glue co de for the Xlib pro cedure

XOp enDisplay which we have already seen in Figure was changed as shown

in Figure The macros RECORDONE and REPLAYONEANDSKIP ex

pand to co de that records the result during the rst run and recalls it and skips

the actual call during the second run Their denitions are shown in Figure

The variables replay record and inputFILE are set by NHCs runtime system as

appropriate

The interface for GHC

As a consequence of the NHC implementation the Fudget library did not dep end

on a Haskell IO system anymore This op ened the do or for an interface

+

to Xlib using the IO monad and the Cinterface in GHC J By using

Fudget IO the gory details

case XRqOp enDisplay DisplayName

char displayname

Display display

evalstringEARGp displayname sizeof displayname

REPLAYONEANDSKIPdisplay

displayXOp enDisplaydisplayname NULL displayname

RECORDONEdisplay

return MkPtrXRespXRDisplayOp eneddisplay

break

Figure Changes to the Xlib glue co de for two pass heap proling

dene REPLAYONEANDSKIPx ifreplay REPLAYx else

dene RECORDONEx ifrecord RECORDx

dene RECORDx fwritevoid xsizeofxinputFILE

dene REPLAYx freadvoid xsizeofxinputFILE

Figure Macros for two pass heap proling

this p ort it is p ossible to take advantage of GHCs time proling to ols and

p ossibility to generate ecient co de

The interface to Xlib in GHC is written in a rather ad ho c style using ccall

and casm statements To day a nicer interface could b e created using the

foreignlanguage interface supp ort of Green Card JNR

Automatic layout

The layout combinators in Chapter are used to sp ecify the p osition and size

of graphical ob jects To day these ob jects can b e of two typ es GUI fudgets or

drawings as describ ed in Chapter The original layout system was designed

for the GUI fudgets and its implementation will b e describ ed in this section

The purp ose of the automatic layout system is to relieve the application

programmer of the task to sp ecify the exact p osition and size of each GUI

fudget This task has several dynamic asp ects To start with it dep ends on

factors that are not known until the program has started For example the

size of a text drawn in a lab el fudget dep ends on the the font and size chosen

and can only b e determined after the lab el fudget has communicated with the

X server Individual GUI fudgets can also change their size at any time and

the user might resize a shell window Both these activities may imply that a

numb er of GUI fudgets must change their p osition and size

The layout system also simplies the implementation of the individual GUI

fudget in that it do es not have to worry ab out the place and p osition of other

GUI fudgets It must only sp ecify an initial request for a size and the layout

system will allo cate a place and actual size

The implementation of the layout system op erates by moving and resizing

rectangular units corresp onding to the group fudgets Section Rememb er

that a group fudget basically consists of a stream pro cessor controlling an X

window p ossibly with a numb er of group fudgets inside it Each group fudget

also contains a piece of the layout system which is resp onsible for the placement

and sizing of each immediate subgroup fudget The resp onsibility is only one

level deep a group fudget do es not control any group contained in any of its

groups As an example the group corresp onding to k in Figure is resp onsible

1

for the layout of k and k but not k

2 4 3

This division of resp onsibility is natural since a group is easily placed and

resized by the single Xlib command CongureWindow All subwindows inside

the group will follow and keep their relative p ositions

The mechanism of the layout system can b e studied by lo oking at the message

trac b etween a group fudget and its immediate subgroups

The group fudget has a lter other lters are describ ed in Chapter

called autoLayoutF which listens for layout messages that are output on the

lowlevel streams from the subgroups

data LayoutMessage

LayoutRequest LayoutRequest

LayoutName String

LayoutPlacer Placer

LayoutSpacer Spacer

The subgroups decide what sizes they need and output a layout request

data LayoutRequest

Layout minsize Size

xedh xedv Bo ol

The eld minsize is the requested size and xedh xedv b eing true sp ecies

that the size is not stretchable in the horizontal vertical direction Some

placers use this information to allo cate extra space to stretchable b oxes only

Automatic layout

The layout lter also receives placers and spacers that the programmer has

wrapp ed around subgroups Since all layout messages are tagged with a path

the layout lter can asso ciate the placers and spacers with the wrapp ed sub

groups by analysing the paths The constructor LayoutName is used in a similar

way to asso ciate a subgroup with a name

The placers and spacers are functions that decide the actual layout A placer

op erates on a list of layout requests yielding one single request for space needed

for the placement of all the asso ciated subgroups Lo oking back at the discussion

of b oxes in Section we will recognise that there will b e one layout request

corresp onding to each b ox

In contrast to the placers a spacer takes a single request as an argument

and the layout lter maps it on all requests corresp onding to the enclosed b oxes

asso ciated with the spacer yielding the same numb er of requests

typ e Placer LayoutRequest LayoutRequest Rect Rect

typ e Spacer LayoutRequest LayoutRequest Rect Rect

As can b e seen from these typ es placers and spacers also return a residual

function which we will describ e b elow

Having collected layout requests and having applied the layout functions to

them the group fudget must decide on one single layout request to output

Since programs should work even if no layout is sp ecied by the programmer a

default placer is wrapp ed around the subgroups

The default placer used is called autoP which picks a suitable layout based

on the layout requests at hand In the current implementation it simply cho oses

b etween verticalP and horizontalP based on two preferences

layouts which do not waste space by unwanted stretching are preferred

over those that do

square layouts are preferred over long and narrow layouts

Future implementations could conceivably take more parameters into account

when cho osing a layout and have a wider choice of layouts to cho ose b etween

Having pro duced a single layout request the group fudget outputs it and it

will b e handled by the enclosing group unless the group is a shell group In this

case the minsize eld in the request is used to set the size of the shell window

The XEvent typ e includes constructors that are used to rep ort changes in

layout to the GUI fudgets

data XEvent

LayoutPlace Rect

LayoutSize Size

The propagation of these layout events start in the shell group fudget When

the shell window has b een resized the X server sends a CongureNotify event

containing the new size to the shell group fudget Note that this event is gener

ated regardless of whether the resize op eration was done by the program as a

result of a layout request or the user via the window manager Anyhow the

shell group fudget generates an event of the form LayoutPlace Rect s to the

layout lter This informs the layout lter that the rectangle from the origin

The historic steps of fudget layout

to s is available for the subgroups Now the layout lter applies the residual

placers and spacers to this rectangle in a reversed pattern Each residual placer

will yield a list of rectangles where the elements corresp ond to the list of re

quests and thus to the b oxes that was fed to the original placer Similarly

residual spacers are mapp ed over rectangles to adjust p ositions of the asso ciated

subgroups

When this reversed pro cess is nished the layout lter outputs one Layout

Place message to each subgroup which will move itself accordingly pass the

message to its layout lter and so the pro cess go es on recursively

When a group receives a LayoutPlace message it also sends a LayoutSize

message to the kernel stream pro cessor so that it can adjust the graphical

content of its window to the new geometry Note that the kernel only needs to

know the size of its window and not its place This is due to the fact that all

window op erations use lo cal co ordinates

The historic steps of fudget layout

Initially there was no supp ort at all for layout The programmer had to

explicitly sp ecify the size and p osition of each GUI fudget

Then automatic layout was implemented with the restriction that each

GUI fudget had to corresp ond to exactly one b ox This implied that

when two GUI fudgets where comp osed a placer had to b e sp ecied

The combinators for parallel and serial comp osition had an extra placer

argument As a result the layout was to o tightly coupled to the dataow

b etween the GUI fudgets

The current system allows many b oxes p er fudget Together with named

layout this allows more exible layout

Filter fudgets

Filter fudgets

The fact that all IO eects of a fudget are represented through constructors in

the datatyp es Request Resp onse and others op ens up the p ossibility to write

what we will call lters which alter sp ecic asp ects of a fudgets inputoutput

b ehaviour Filters have typ e F a b F a b which indicates that they do not

tamp er with the highlevel messages they only analyse and mo dify the lowlevel

messages

A numb er of problems can b e solved by using ltersfor example swapping

the meaning of the left and the right mouse buttons or swapping the black and

white colors in GUI fudgets

In the following sections we will see two examples of lters from the Fudget

library which alter the b ehaviour of complex fudgets

 The cache lter which improves the space and time b ehaviour of fudget

programs by letting subfudgets share X server resources Section

 The focus lter which implements clicktotyp e input style in forms by

redirecting keyb oard events Section

The lters in the Fudget library are constructed by means of a combinator that

resembles lo opThroughRightF and is called lo opThroughLowF

lo opThroughLowF SP Either TRequest TResp onse

Either TRequest TResp onse

F i o F i o

Just as lo opThroughRightF is often used by application programmers to encap

sulate and mo dify the b ehaviour of existing fudgets lo opThroughLowF is used

in lters lo cated in fudlogue and shellF and can thus mo dify certain asp ects of

all fudgets in an application The controlling stream pro cessor which is the

rst argument to lo opThroughLowF receives as input the stream of all tagged

requests that are output from the encapsulated fudgets and also all tagged

resp onses directed to the same fudgets It can analyse and manipulate these

messages in any manner b efore outputting them after which they will continue

their way to the IO system in the case of the requests or the fudgets in the

case of the resp onses The simplest conceivable lter is

lo opThroughLowF idSP

which simply passes through all requests and resp onses undisturb ed and thus

acts as the identity lter

The cache lter

Each GUI fudget allo cates or queries a numb er of resources in the X server such

as fonts font descriptions graphical contexts and colors For example a fudget

program with a large GUI may query a large numb er of font descriptions This

can result in a slow startup time esp ecially if the round trip delay b etween the

program and server is large Usually most GUI fudgets will query the same

resources as the others in the program which seems wasteful It would b e

b enecial if the resource allo cation could b e shared b etween the GUI fudgets

The cache lter

Not only would this result in a faster startup and less network load but the

program would also consume less memory This is relevant in the case where

font descriptions are queried since these could o ccupy a signicant amount of

the heap

It is the role of the cache lter to supp ort this resource sharing b etween

fudgets It is part of fudlogue which means that all fudgets in the program

b enet from the resource sharing

The eect of the cache lter is most notable on slow connections with high

round trip delays such as dialup connections To demonstrate this we have run

Cla one of the demonstration programs from the Fudget distribution over a dial

up connection using PPP and secure shell ssh compression rate The mo dem

sp eed was bits p er second and the round trip delay milliseconds on

average To eliminate errors due to dierent compression rates the program

was started rep eatedly until the startup time converged Without the cache

lter the minimum startup time for Cla was clo cked to seconds When

enabling the cache the startup time decreased to seconds a sp eedup factor

of over As a comparison we also ran Cla on this slow connection without

compression the startup times were seconds with no cache and seconds

with cache Compression is a go o d thing

The heap usage is also b etter when the cache is enabled the p eak decreases

from to kilobytes

These gures should not come as a surprise since the GUI in Cla consists of

one display and push buttons which can share the same resources

Using the cache lter means that there is an overhead in the program Except

for drawing commands the lter will analyse each request that is output As a

result the calculator startup time is ab out longer when the X server runs

on the same computer as the calculator In this case the connection is fast and

has negligible round trip delay

Implementation

Before describing the implementation we will show a communication scenario

that takes place when a fudget allo cates a particular kind of resource namely

a graphics context GC First the fudget outputs the X request CreateGC d

tgc al where d is the drawable in which the GC will b e used tgc is a template

GC and al is a list of attributes that the new GC should have The request

is turned into a call to the Xlib function XCreateGC which returns a reference

to a new GC This is sent back as the resp onse GCCreated gc to the requesting

fudget which brings it to use When the GC is not needed anymore the fudget

can explicitly deallo cate it by outputting the X command FreeGC gc

The idea of using a cache is of course that if a second fudget wants to create

a GC with the same template and attributes we could reuse the rst GC if

it is not yet deallo cated So a GC cache maintains table from template and

attributes to graphics contexts and reference counts

It turns out that most resource deallo cation follows the same pattern as

our scenario if we abstract from the sp ecic request and resp onse constructors

This abstraction is captured in the typ e RequestTyp e which expresses whether

a request is an allo cation a deallo cation or something else

Filter fudgets

data RequestTyp e a r Allo cate a

Free r

Other

The argument to the Allo cate constructor carries allo cation data that the cache

lter uses as search key in the resource table Similarly the Free constructor

carries the resource that should b e freed In the case of graphics contexts the

allo cation data are pairs of template GCs and attribute lists and the resources

are graphics contexts

The function gcRequestTyp e determines the typ e of request for graphics con

texts

gcRequestTyp e Request RequestTyp e GCIdGCAttributeList GCId

gcRequestTyp e r

case r of

CreateGC d tgc al Allo cate tgcal

FreeGC gc Free gc

Other

The general cache lter cacheFilter is parameterised over the function that de

termines the request typ e

cacheFilter Eq aEq r Request RequestTyp e a r

F i o F i o

cacheFilter rtf lo opThroughLowF cache

where cache table

The internal state table is a list of typ e a r Int where the elements are

allo cation data with asso ciated resources and reference counts

The denition of a cache for graphics contexts is now simple

gcCacheFilter F i o F i o

gcCacheFilter cacheFilter gcRequestTyp e

The Fudget library denes request typ e functions like gcRequestTyp e for a

numb er of resources and the corresp onding cache lters using the general

cacheFilter All these lters are combined into allCacheFilter

allcacheFilter F a b F a b

allcacheFilter

fontCacheFilter

fontStructCacheFilter

gcCacheFilter

colorCacheFilter

bitmapFileCacheFilter

fontCursorCacheFilter

This cache lter is wrapp ed around all fudget programs in fudlogue One should

fear that allcacheFilter would imp ose a considerable overhead since all com

mands must b e insp ected in turn by each of the six lters In practice the

overhead is not a big problem

The fo cus lter

The fo cus lter

When I typ e on the keyb oard which GUI element should receive the typ ed

characters Equivalently which GUI element has the input focus Initially the

Fudget library implemented the simple mo del of pointtotype fo cus since it is

directly supp orted by X Windows With p ointtotyp e a GUI fudget cannot

have the input fo cus unless the p ointer is over it A GUI fudget such as

stringF signals its interest in fo cus by conguring its event mask to include

KeyPressMask EnterWindowMask and LeaveWindowMask This means that the

fudget can receive keyb oard input and also events when the p ointer enters or

leaves the fudget crossing events The crossing events are used to give visual

feedback ab out which fudget has the fo cus

A p otential problem with p ointtotyp e controlled fo cus is that the user

must move a hand back and forth a lot b etween the keyb oard and the p ointing

device assuming that the p ointer cannot b e controlled from the keyb oard if

she wants to ll in data in a form that consists of several input elds It is also

easy to touch the p ointing device accidentally so that the p ointer jumps a little

which could result in a fo cus change

These problems vanish when using a clicktotype fo cus mo del With click

totyp e the tight coupling b etween the p ointer p osition and fo cus is removed

Instead the user clicks in an input eld to indicate that it should have the fo cus

The fo cus stays there until the user clicks in another input eld In addition

if the keyb oard can b e used for circulating fo cus b etween the input elds in a

form it can b e lled in without using the p ointing device

A limited variant of this improved input mo del has b een added to the Fudget

library as a lter in the shell fudgets leaving the various GUI fudgets unmo di

ed The limitation is that the mo del is only clicktotyp e as long as the p ointer

is inside the shell fudget When the p ointer leaves the shell fudget fo cus go es

to whatever application window is under it unless the window manager uses

clicktotyp e

Implementation

The implementation of the fo cus is based on the key observation that GUI

fudgets that need keyb oard input let us call them focus fudgets can b e distin

guished by the kind of events that they congure their window to rep ort All

fo cus fudgets are of course interested in key press events but they also need

crossing events for giving prop er visual feedback when they have fo cus There

fore fo cus fudgets will initially set their window event mask so that Mask is a

subset

Mask KeyPressMask EnterWindowMask LeaveWindowMask

A simplied implementation of a fo cus lter is shown in Figure The fo cus

lters reside immediately inside the shell fudgets To get keyb oard events no

matter the p osition of the p ointer as long as it is inside the shell window a

group fudget is created around the inner fudgets with a suitable event mask

This is done with simpleGroupF which acts as a groupF without a kernel

The ltering is done in fo cusSP whose argument fpaths accumulates a list

of paths to the fo cus fudgets This is done by lo oking for window conguration

commands with matching event masks The event masks of the fo cus fudgets

Filter fudgets

fo cusFilter F a b F a b

fo cusFilter f lo opThroughLowF fo cusSP

simpleGroupF KeyPressMask f

fo cusSP Path SP Either TRequest TResp onse

Either TRequest TResp onse

focusSP fpaths getSP either request resp onse

where

request pr

case getEventMask r of

Just mask Mask issubset mask

putSP Left psetEventMask mask r

fo cusSP pfpaths

where mask ButtonPressMask union mask

putSP Left pr

fo cusSP fpaths

resp onse pr

if keyPressed r

then putSP Right head fpaths r

fo cusSP fpaths

else if leftButtonPressed r p elem fpaths

then putSP Right pr

fo cusSP aftb ef

else putSP Right pr

where b efaft break path fpaths

Auxiliary functions

simpleGroupF EventMask F a b F a b

getEventMask Request Mayb e EventMask

setEventMask EventMask Request Request

keyPressed Request Bo ol

leftButtonPressed Request Bo ol

Figure A fo cus lter

Pros and cons of lters

is mo died to mask so that the windows of fo cus fudgets will generate mouse

button events

The head of fpaths is considered to own the fo cus and incoming key events

are redirected to it If the user clicks in one of the fo cus fudgets fpaths is

reorganised so that the path of the clicked fudget comes rst

As noted Figure shows a simplied fo cus lter The lter in the Fudget

library is more develop ed it also handles crossing events and fo cus changes

using the keyb oard More complex issues like dynamic creation and destruction

of fudgets are also handled Still it ignores some complications intro duced by

the migrating fudgets in Chapter

It should also b e noted that the X window mo del supp orts sp ecial focus

change events which should rather b e used when controlling fo cus This ts

b etter with window managers that implement clicktotyp e

Pros and cons of lters

The exp erience we have had with lters in the Fudget library are b oth go o d

and bad On the go o d side the lters op en the p ossibility to mo dify the IO

b ehaviour of existing software without having to alter its source co de On the

other side although the lters were develop ed without changing the source

co de of the GUI fudgets detailed knowledge ab out their source co de was used

in order to decide on what assumptions we could make ab out their b ehaviour

For example we have seen that the fo cus lter assumes that all GUI fudgets

that should b e under fo cus control can b e distinguished by analysing their event

masks This complicates the semantics of event masks something that must b e

taken into account when programming new GUI fudgets Similarly the p ossible

sharing of a resource caused by the cache lter means that imp erative op erations

on resources such as XChangeGC must b e avoided in the GUI fudgets

The implementation of lters often involves that a piece of state must b e

asso ciated with each GUI fudget This means that the state of some GUI

fudgets are spread out in the library in some sense One piece resides in the

fudget itself as lo cal state then there is nonlo cal state in the fo cus lter and in

the fudlogue tables which are used to route asynchronous events If fudget state

is distributed like this there is always a danger that it b ecomes inconsistent

for example when fudgets move or die

Moving stream pro cessors

Moving stream pro cessors

One distinguished feature of stream pro cessors is that they are not directly

connected to their input streams Rather a stream pro cessor reacts to one

message at a time A b etter name would really b e message processor since

there are no explicit streams anywhere only messages This is in contrast to

functions op erating on streams as lazy lists which are instances of the typ e

i o if we only consider functions from one input stream to one output

stream To get the output stream of such a stream function one must apply

it to the input stream Once that is done there is no easy way to detach the

stream function from the stream again

Why would one want to do such a detachment One reason arises if we want

a stream pro cessor to run for a while in one environment and then move it to

some other environment and continue running it there Rememb er that stream

pro cessors are rst class values and may b e sent as messages This together

with the fact that there is no dierence in the typ e b etween a stream pro cessor

that has b een executing for a while and a new one allows us to program a

combinator that can catch the current continuation of an arbitrary stream

pro cessor whenever we want

extractSP SP i o SP Either i Either SP i o o

extractSP s case s of

PutSP o s PutSP Right o extractSP s

NullSP NullSP

GetSP is GetSP m

case m of

Right i extractSP is i

Left PutSP Left s

NullSP

The stream pro cessor extractSP s accepts messages of the form Right i which

are fed to s Output o from s is output as Right o At any time we can feed

the message Left to it and it will output the encapsulated stream pro cessor

in its current state as a message tagged with Left Note that in general the

stream pro cessor that is output in this way is not equal to the original stream

pro cessor s

So when we demand the continuation extractSP s outputs it and dies But

why should it die It might b e useful to have it carry on as if nothing had

happ ened This reminds us of cloning of ob jects and forking of pro cesses The

variant is easily programmed by mo difying the last line of extractSP

cloneSP SP i o SP Either i Either SP i o o

cloneSP s case s of

PutSP o s PutSP Right o cloneSP s

NullSP NullSP

GetSP is GetSP m

case m of

Right i cloneSP is i

Left PutSP Left s

cloneSP s

Since stream pro cessors are mere values we do not need any machinery for

duplication of statethis is indeed a case where we appreciate purely functional

programming

We can promote these ideas to fudgets as well although the implementation

gets more complicated In the case of a GUI fudget some action must b e taken

to ensure that it brings its asso ciated window along when it moves for exam

ple We can then program drag and drop for any GUI fudget as illustrated in

Figure In what follows we will describ e a set of combinators for supp ort

ing draganddrop in fudget programs We call the fudgets that the user can

drag and drop drag fudgets and the areas in which they live drop areas The

communication of drag fudgets b etween the drop areas is mediated by a single

invisible draganddrop fudget A schematic picture of these fudgets is shown

in Figure These three typ es of fudgets exchange sp ecial messages to control

the motion of the drag fudgets To allow the drag fudgets to communicate with

the rest of the program indep endently of these control messages we pretend for

a moment that fudgets have two midlevel input and output connections

typ e SF mi mo hi ho F Either mi hi Either mo ho

The typ e SF stands for stratied fudget With this typ e we can think of the

message typ es of stream pro cessors as stratied in three levels The drag fudgets

are formed by the container dragF

dragF F a b DragF a b

typ e DragF a b SF DragCmd DragEvt a b a b

The result typ e of dragF f is a stratied fudget in which the highlevel streams

are connected to f and the midlevel streams are used for control by means of

drag commands and drag events The drag commands are sent from the drop

area to the drag fudgets during drag The most imp ortant drag command is

DragExtract and informs the drag fudget that it has b een accepted by another

drop area To this command the drag fudget resp onds with an event containing

itself

data DragCmd

DragExtract

data DragEvt a b

DragExtracted DragF a b

Since the drag events can contain drag fudgets we see that it is necessary to

parameterise the typ e DragEvt The exact typ e of the drag fudget must b e

visible in the typ e of drag events as well as in other control message typ es we

will intro duce in the following Thus the typ e system ensures that a dragged

fudget cannot b e dropp ed in an area for fudgets of dierent typ e

The drop area is a stratied variant of dynListF see Section

dropAreaF SF DropCmd a b DropEvt a b Inta Intb

The midlevel messages are called the drop commands and drop events and are

used by the draganddrop fudget to control the drop areas Note that b oth these

Moving stream pro cessors

Ab out to drag

While dragging

After dropping

Figure Pictures showing a fudget we are ab out to drag while dragging and

after dropping it After the fudget was dropp ed the user changed its text Note

that the output from the moved fudget now go es to Drop area

dragAndDropF

dropAreaF dropAreaF

dragF f 1

dragF f 3

dragF f 4

dragF f 2

Figure Schematic view of an invisible draganddrop fudget indicated by

the dashed frame which in this case contains two rectangular drop areas each

of which contains a numb er of draggable fudgets The dotted arrow indicates

what will happ en if a user drags the fudget f from the rst to the second

1

area it will b e extracted as a message from the rst drop area and reach the

draganddropfudget which will b ounce it to the second drop area

Moving stream pro cessors

typ es are parameterised b ecause b oth can carry drag fudgets as messages As

indicated in Figure the drop area contains drag fudgets which furthermore

are tagged The highlevel messages from these are therefore tagged when they

enter or leave the drop area

There is one drop command that is interesting for the application program

mer

dropNew DragF a b DropCmd a b

It is used to inject new drag fudgets inside a drop area

Finally we have the draganddrop fudget which mediates dropp ed fudgets

b etween drop areas

dragAndDropF SF tDropCmd a b tDropEvt a b c d F c d

The argument to dragAndDropF is a stratied fudget whose midlevel messages

should b e uniquely tagged drop area messages The intension is that the strat

ied fudget contains a list of drop area fudgets Such a list can conveniently b e

created using a stratied variant of listF

listSF Eq t tSF a b c d SF ta tb tc td

listSF s pullEither listF s pushEither

pushEither Left ta tLeft a

pushEither Right ta tRight a

pullEither tLeft a Left ta

pullEither tRight a Right ta

By means of dragF dropAreaF and dragAndDropF we can program the example

illustrated in Figure As drag fudgets we use lab elled stringInputFs

drag Show i DragF String String

drag i dragF

labAb oveF Drag me show i

show i stringInputF

The string output from the drag fudget is prep ended with its identity i

We dene a drop area with an asso ciated display which shows the output

from the drag fudgets in it We initialise the drop area by creating a drag fudget

in it with the same identity as the drop area

area Show i

i SF DropCmd String String DropEvt String String

IntString a

area i vBoxF

idLeftF displayF snd

startupF Left dropNew drag i dropAreaF

Finally we dene a draganddrop fudget with two drop areas inside shell fud

gets

dnd F IntIntString Inta

dnd dragAndDropF listSF

tshellF Drop area show t area t t

main fudlogue dnd

Problems with dragging windows in X Windows

Problems with dragging windows in X Windows

Dragging ob jects as windows under the p ointer in the X Window system is not

problem free it is dicult to determine where the ob ject is dropp ed when the

user releases the mouse button This release generates a button event which

contains information ab out what window is under the p ointer But this will

not b e the window in which we drop the ob ject it will b e the ob jects window

itself If we are content with somewhat less sp ectacular visual feedback we

could cho ose not to move the ob ject itself but change the p ointer to a symb ol

that carries a little ob ject as is done in Op en Windows Sol

What we need is to have the dragged ob jects

window transparent with resp ect to certain events

We achieve this in a brutal way by simply zapping

a small temp orary hole in the ob ject window under

the p ointer as shown in the detail

However we now have timing problem which can

app ear if the user moves the p ointer quickly and im

mediately drops the ob ject There is a delay in the

movement of the p ointer and the ob ject since it is

the client which is doing the tracking With a con

stant delay the tracking error is prop ortional to the sp eed of the p ointer which

means that if the sp eed is large enough the p ointer will not b e ab ove the hole

anymore Currently we do not know if there exists a go o d solution to this drop

problem in X Windows

Typ ed so ckets for clientserver applications

Typ ed so ckets for clientserver applications

In this section we will see how fudgets can b e suitable for other kinds of IO

than graphical user interfaces We will write clientserver applications where

a fudget program acts as a server on one computer The clients are also fudget

programs and they can b e run on other computers if desired

The server is an example of a fudget program which may not have the need

for a graphical user interface However the server should b e capable of handling

many clients simultaneously One way of organising the server is to have a client

hand ler for each connected client Each client handler communicates with its

client via a connection a so cket but it may also need to interact with other

parts of the server This is a situation where fudgets come in handy The

server will dynamically create fudgets as client handlers for each new client that

connects

We will also see how the typ e system of Haskell can b e used to asso ciate

the address a host name and a p ort numb er of a server with the typ e of the

messages that the server can send and receive If the client is also written in

Haskell and imp orts the same sp ecication of the typ ed address as the server

we know that the client and the server will agree on the typ es of the messages

or the compiler will catch a typ e error

The typ e of so ckets that we consider here are Internet stream so ckets They

provide a reliable twoway connection similar to Unix pip es b etween any two

hosts on the Internet They are used in Unix to ols like telnet ftp nger mail

Usenet and also in the World Wide Web

Clients

To b e able to communicate with a server a client must know where the server is

lo cated The lo cation is determined by the name of the host a computer on the

network and a p ort numb er A typical host name is wwwcschalmersse The

p ort numb er distinguishes dierent servers running on the same host Standard

services have standard p ort numb ers For example WWW servers are usually

lo cated on p ort

The Fudget library uses the following typ es

typ e Host String

typ e Port Int

The fudget

so cketTransceiverF Host Port F String String

3

allows a client to connect to a server and communicate with it Chunks of

characters app ear in the output stream as so on as they are received from the

server compare this with stdinF in Section

The simplest p ossible client we can write is p erhaps a telnet client

telnetF host p ort stdoutF

so cketTransceiverF host p ort

stdinF

3

The library also provides combinators that give more control over error handling and the

op ening and closing of connections

Servers

This simple program do es not do the option negotiations required by the stan

dard telnet proto col RFC so it do es not work well when connected to

the standard telnet server on p ort However it can b e used to talk to many

other standard servers eg mail and news servers

Servers

Whereas clients actively connect to a sp ecic server servers passively wait for

clients to connect When a client connects a new communication channel is

established but the server typically continues to accept connections from other

clients as well

A simple fudget to create servers is

simpleSo cketServerF Port F IntString IntString

The server allows clients to connect to the argument p ort on the host where the

server is running A client is assigned a unique numb er when it connects to the

server The messages to and from simpleSo cketServerF are strings tagged with

such client numb ers Empty strings in the input and output streams mean that

a connection should b e closed or has b een closed resp ectively

This simple server fudget do es not directly supp ort a program structure with

one handler fudget p er client A b etter combinator is shown in the next section

Typ ed so ckets

Many Internet proto cols use messages that are human readable text When im

plementing these the natural typ e to use for messages is String However when

we write b oth clients and severs in Haskell we may want to use an appropriate

data typ e for messages sent b etween clients and server as we would do if the

client and server were fudgets in the same program In this section we show how

to abstract away from the actual representation of messages on the network

We intro duce two abstract typ es for typed port numbers and typed server

addresses These typ es will b e parameterised on the typ e of messages that we

can transmit and receive on the so ckets First we have the typ ed p ort numb ers

data TPort c s

The client program needs to know the typ ed address of the server

data TServerAddress c s

In these typ es c and s stand for the typ e of messages that the client and server

transmit resp ectively

To make a typ ed p ort we apply the function tPort on a p ort numb er

tPort Show c Read c Show s Read s Port TPort c s

The Show and Read contexts in the signature tells us that not all typ es can b e

used as message typ es Values will b e converted into text strings b efore they

are transmitted as a message on the so cket This is clearly not very ecient

but it is a simple way to implement a machine indep endent proto col

Given a typ ed p ort we can form a typ ed server address by sp ecifying a

computer as a host name

Typ ed so ckets for clientserver applications

tServerAddress TPort c s Host TServerAddress c s

For example supp ose we want to write a server that will run on the host animal

listening on p ort The clients transmit integer messages to the server which

in turn sends strings to the clients This can b e sp ecied by

thePort TPort Int String

thePort tPort

theServerAddr tServerAddress thePort animal

A typ ed server address can b e used in the client program to op en a so cket to

the server by means of tSo cketTransceiverF

tSo cketTransceiverF Show c Read s

TServerAddress c s F c Mayb e s

Again the Show and Read contexts app ear since this is where the actual con

version from and to text strings o ccurs The fudget tSo cketTransceiverF will

output an incoming message m from the server as Just m and if the connection

is closed by the other side it will output Nothing

In the server we will wait for connections and create client handlers when

new clients connect This is accomplished with tSo cketServerF

tSocketServerF Read c Show s

TPort c s

F s Mayb e c F a Mayb e b

F Inta IntMayb e b

So tSo cketServerF takes two arguments the rst one is the p ort numb er to listen

on for new clients The second argument is the client handler function When

ever a new client connects a so cket transceiver fudget is created and given to

the client handler function which yields a client handler fudget The client han

dler is then spawned inside tSo cketServerF From the outside of tSo cketServerF

the dierent client handlers are distinguished by unique integer tags When a

client handler emits Nothing tSo cketServerF will interpret this as the end of a

connection and kill the handler

The idea is that the client handler functions should use the transceiver argu

ment for the communication with the client Complex handlers can b e written

with a lo opThroughRightF around the transceiver if desired In many cases

though the supplied so cket transceiver is go o d enough as a client handler di

rectly A simple so cket server can therefore b e dened by

simpleTSo cketServerF Read c Show s

TPort c s F Ints IntMayb e c

simpleTSo cketServerF p ort tSo cketServerF p ort id

Avoiding typ e errors b etween client and server

By using the following style for developing a client and a server we can detect

when the client and the server disagree on the message typ es

First we dene a typ ed p ort to b e used by b oth the client and the server

We put this denition in a mo dule of its own Supp ose that the client sends

integers to the server which in turn can send strings

Example a group calendar

module MyPort where

myPort TPort Int String

myPort tPort

We have picked an arbitrary p ort numb er Now if the client is as follows

module Main where Client

imp ort MyPort

main fudlogue tSo cketTransceiverF myPort

and the server

module Main where Server

imp ort MyPort

main fudlogue tSo cketServerF myPort

then the compiler can check that we do not try to send messages of the wrong

typ e Of course this is not fo olpro of There is always the problem of having

inconsistent compiled versions of the client and the server for example Or one

could use dierent p ort declarations in the client and the server

Now what happ ens if we forget to put a typ e signature on myPort Is

it not p ossible then that we get inconsistent message typ es since the client

and the server could instantiate myPort to dierent typ es The immediate

answer is no and this is b ecause of a subtle prop erty of Haskell namely the

monomorphism restriction A consequence of this restriction is that the typ e of

myPort cannot contain any typ e variables If we forget the typ e signature this

would b e the case and the compiler would complain It is p ossible to circumvent

the restriction by explicitly expressing the context in the typ e signature though

If we do this when dening typ ed p orts we sho ot ourselves in the fo ot

module MyPort where

myPort Read a Show a TPort a String Wrong

myPort tPort

We said that this was the immediate answer The real answer is that if the

programmer uses HBC we might get inconsistent message typ es since it is

p ossible to give a compiler ag that turns o the monomorphism restriction

which circumvents our check This is a feature that we have used a lot see also

Section

Example a group calendar

Outside the lunch ro om in our department there is a whiteb oard where the

weeks activities are registered We will lo ok at an electronic version of this

calendar where p eople can get a view like this on their workstation Figure

The entries in the calendar can b e edited by everyone When that happ ens

all calendar clients should b e up dated immediately

The calendar consists of a server maintaining a database and the clients

running on the workstations

Typ ed so ckets for clientserver applications

Figure The calendar client

databaseSP tSocketServerF

Figure The structure of server The small fudgets are client handlers created

inside the so cket server

The calendar server

The servers job is to maintain a database with all the entries on the whiteb oard

to receive up date messages from clients and then up date the other connected

clients The server consists of the stream pro cessor databaseSP and a tSo ck

etServerF where the output from the stream pro cessor go es to tSo cketServerF

and vice versa Figure The program app ears in Figure The stream

pro cessor databaseSP maintains two values the client list cl which is a list of

the tags of the connected clients and the simple database db organised as a list

of keyvalue pairs This database is sent to newly connected clients When a

user changes an entry in her client it will send that entry to the server which

will up date the database and use the client list to broadcast the new entry to

all the other connected clients When a client disconnects it is removed from

the client list The client handlers clienthandler initially announce themselves

with NewHandler then they apply HandlerMsg to incoming messagesThe typ e

of the keyvalue pairs in the database is the same as the typ e of the messages

received and sent and is dened in the mo dule MyPort

Example a group calendar

module Main where Server

imp ort Fudgets

imp ort MyPortmyPort

main fudlogue server myPort

data HandlerMsg a NewHandler HandlerMsg a

server p ort lo opF databaseSP

tSo cketServerF p ort clienthandler

clienthandler transceiver

putSP Just NewHandler mapSP map HandlerMsg

transceiver

databaseSP cl db

getSP ie

let clbuti lter i cl

in case e of

Just handlermsg case handlermsg of

NewHandler

A new client send the database to it

and add to client list

putsSP id d db

databaseSP icl db

HandlerMsg s

Tel l the other clients

putsSP is i clbuti

and update database

databaseSP cl replace s db

Nothing

A client disconnected remove it from

the client list

databaseSP clbuti db

replace Eq a ab ab ab

replace

Figure The calendar server

Typ ed so ckets for clientserver applications

module MyPort where

imp ort Fudgets

typ e SymTPort a TPort a a

myPort SymTPort StringIntString

eg TorsdagDoktorandkurs

p ort tPort

Displaying and manipulating graphical ob jects

So far we have seen that fudgets can display text but we have not seen how to

create and display other kinds of graphical ob jects You might have wondered

how button b orders are drawn for example In the rst few sections of this

chapter we present data typ es typ e classes and fudgets for handling graphics

Structure editors of various kinds are programs that can make go o d use of

graphics Examples of such programs are drawing programs WYSIWYG word

pro cessors le managers etc The common characteristic is that they allow

you to manipulate a graphical representation of some ob ject on the screen for

example by selecting a part of the ob ject and p erforming some editing op eration

on it for example making a word italic in a word pro cessor or deleting a le

in a le manager The editing op erations p erformed by the user can lead

to marginal or radical changes to the structure of the ob ject and its graphical

representation The editor will need to have an ecient mechanism for up dating

the screen to reect these changes The fudget for graphics that we describ e in

this chapter supp orts this

The Fudget library comp onents we have seen so far allow you to build user

interfaces that consist of a numb er of parts that communicate but we have not

seen any mechanisms that allow an arbitrary part to b e selected by the user

and p erhaps replaced by something else so we have not seen a general mecha

nism for building structure editors Some basic fudgets like toggleButtonF and

stringF can b e seen as structure editors for particular structures b o oleans and

strings resp ectively The later sections in this chapter present data typ es and

fudgets that can b e used as a starting p oint when building more general struc

ture editors In Chapter we go on and describ e combinators more directly

aimed at building structure editors or syntax directed editors

The supp ort for graphics in the Fudget library was prompted by the de

velopment of the syntax directed editor Alfa Chapter and functionality

was added to the fudget system as needed for that particular purp ose Some

development was also prompted by the work on the web browser describ ed in

Chapter

The class Graphic

We have already encountered the class Graphic many times Many of the GUI

fudgets presented in Chapter display graphics Recall for example buttonF

buttonF Graphic a a F Click Click

It has an argument that determines what is displayed inside the button In

early versions of the Fudget library the typ e of buttonF was

buttonF String F Click Click

but later the class Graphic was intro duced and many fudgets were generalised

from displaying only strings to displaying arbitrary graphical ob jects Since

the new typ es are more general than the old ones the changes are backwards

4

compatible old programs continue to work unmo died

4

This kind of change can actually cause ambiguous overloading

Displaying and manipulating graphical ob jects

data DrawCommand

DrawLine Line

DrawImageString Point String

DrawString Point String

DrawRectangle Rect

FillRectangle Rect

FillPolygon Shap e Co ordMo de Point

DrawArc Rect Int Int

FillArc Rect Int Int

CopyArea Drawable Rect Point

CopyPlane Drawable Rect Point Int

DrawPoint Point

CreatePutImage Rect ImageFormat Pixel

DrawLines Co ordMo de Point

Figure The typ e DrawCommand provides an interface to the Xlib library

calls for drawing geometrical shap es and strings

The Graphic class serves a purp ose similar to that of the Show class typ es

whose values have graphical representations are made instances of the Graphic

class just like typ es whose values have textual representations are instances of

the Show class As with the Show class the metho ds of Graphic class are not

often used directly except when dening new instances and we discuss them

in a later section The library provides instances in the Graphic class for many

standard typ es

Primitive drawing op erations

Before we describ e the data typ es that are instances of the Graphic class we

take a lo ok at the lowlevel interface that allows a fudget to draw something in

its window

The Fudgets GUI to olkit is built on top of the Xlib Nye library level of the

X Windows system SG as describ ed in Section This shines through

in the Fudget library supp ort for graphics the primitive drawing op erations

available in the fudget library corresp ond directly to what is provided by Xlib

An interface to the Xlib library calls for drawing geometrical shap es and

strings is provided through the data typ e DrawCommand shown in Figure

Apart from the parameters describing the shap e to b e drawn the Xlib calls

have some additional parameters that are not present in the constructors of the

DrawCommand typ e As a typical example of the relationship b etween the Xlib

calls and the constructors consider XDrawLine

XDrawLinedisplay d gc x y x y

Display display

Drawable d

GC gc

int x y x y

Typ es for simple graphical ob jects

imp ort Fudgets

main fudlogue shellF Hello helloF

helloF lab elF BitmapFile helloxbm

Figure The graphical version of the Hello world program is just as simple

as the textual version in Section

A drawable d a window or a pixmap and a graphics context gc are supplied

by the fudget that outputs the drawing command The typ e XCommand see

Section contains the following constructor for outputting drawing com

mands

data XCommand Draw Drawable GCId DrawCommand

The display argument can b e determined from the drawable The current

Fudget library supp orts only one display connection so nothing extra is needed

for this

Typ es for simple graphical ob jects

Having seen how a fudget can output drawing commands to draw in its window

we can now take a lo ok at some simple typ es for graphical ob jects These typ es

provide the most lowlevel interface to the Xlib drawing commands

BitmapFile

Apart from the drawing commands supp orted through the typ e DrawCommand

the Fudget library also supp orts the Xlib library call XReadBitmapFile for read

ing images bitmaps from les

data XRequest ReadBitmapFile FilePath

data XResp onse BitmapRead BitmapReturn

data BitmapReturn BitmapBad BitmapReturn Size Mayb e Point PixmapId

This means that we can easily create a data typ e that allows us to use images

stored in les as graphical ob jects

data BitmapFile BitmapFile FilePath

instance Graphic BitmapFile where

As you can see in Figure by using the typ e BitmapFile a program that loads

an image from a le and displays it is as just as simple as the Hello world

program see Section

Displaying and manipulating graphical ob jects

FlexibleDrawing

The Fudget library provides the following typ e to create stretchable graphical

ob jects

data FlexibleDrawing FlexD Size Bo ol Bo ol Rect DrawCommand

instance Graphic FlexibleDrawing where

The rst argument of the FlexD constructor indicates a nominal size but the

actual size is determined by the fudget layout system and dep ends on the con

text The next two arguments indicate the stretchiness that is whether the

size should b e xed horizontally and vertically resp ectively

The last argument is a function that should pro duce drawing commands

that draw within the given rectangle The argument is a rectangle rather than

just a size to make exible drawings more ecient to use as parts of structured

graphical ob jects Although the drawing function could draw completely dif

ferent things for dierent rectangle p osition and sizes changing the p osition is

exp ected to have no other eect than a translation that is

f Rect p os size moveDrawCommands f Rect origin size p os

where moveDrawCommands

moveDrawCommands DrawCommand Point DrawCommand

moves translates drawing commands Changing the size is exp ected make the

function adjust the drawing to ll the available space typically by stretching it

As an example here are exible drawings for lled rectangles horizontal

lines and vertical lines

lledRect hFiller vFiller Int FlexibleDrawing

lledRect ller False False

hFiller ller False True

vFiller ller True False

ller fh fv d FlexD Point d d fh fv rFillRectangle r

A sample usage can b e seen in Figure

Fixed size drawings

Having dened the typ e FlexibleDrawing we can easily dene a function for

creating graphical ob jects of a xed size

xedD Size DrawCommand FlexibleDrawing

xedD size dcmds FlexD size True True drawit

where drawit Rect p os moveDrawCommands dcmds p os

The arguments are a list of drawing commands to draw the desired shap e and

a size The commands are exp ected to draw within a rectangle of the indicated

5

size with the origin as the upp er left corner

5

Instead of leaving it to the user to indicate the size of the drawing it would b e p ossible to

compute a b ounding rectangle by insp ecting the drawing commands but doing it accurately

in the general case is rather involved and would b e less ecient

Typ es for structured graphical ob jects

Notice that dep ending on how you dene your FlexibleDrawing value you

may get very dierent op erational b ehaviour Using xedD you will get a value

containing a reference to a list of drawing commands that will b e retained in

the heap and translated to the appropriate p osition by moveDrawCommands

each time the drawing is used For FlexibleDrawings created like ller ab ove the

drawing commands may b e recomputed and thrown away each time the drawing

is used So although the result on the screen will b e the same how much

recomputation that o ccurs and how much memory is used dep ends on details in

how the program is written and what kind of lamb da lifting the compiler do es

whether it supp orts full laziness Kar

Typ es for structured graphical ob jects

The typ es for graphical ob jects presented ab ove lack two imp ortant features

 The ability to sp ecify drawing attributes such as colors line widths and

fonts

 The ability to comp ose simple ob jects into larger ones with a layout sp ec

ied in a simple way

As discussed in the intro duction of this chapter we also need a way to iden

tify parts of a comp osite graphical ob ject when building structure editors We

intro duce the typ e Drawing to take care of these needs

data Drawing lab el leaf

AtomicD leaf

Lab elD lab el Drawing lab el leaf

AttribD GCSp ec Drawing lab el leaf

SpacedD Spacer Drawing lab el leaf

PlacedD Placer Drawing lab el leaf

Comp osedD Drawing lab el leaf

instance Graphic leaf Graphic Drawing lab el leaf where

placedD Placer Drawing l a Drawing l a

placedD p ds PlacedD p Comp osedD ds

So comp osite drawings are trees The leaves built with the constructor Atom

icD can contain values of any typ e but as seen from the instance declaration

ab ove the drawing can b e displayed only if the leaf typ e is an instance of the

Graphic class The internal no des can contain

 drawing attributes the constructor AttribD that are in eect in the sub

tree of the no de These are discussed further b elow

 layout information in the form of spacers and placers the constructors

SpacedD and PlacedD from the ordinary fudget layout system Chap

ter

 lab els that can b e used to identify or just hold some extra information

on part of a drawing the constructor Lab elD These have no graphical eect

Displaying and manipulating graphical ob jects

typ e DPath Int

up DPath DPath

drawingPart Drawing a b DPath Drawing a b

mayb eDrawingPart Drawing a b DPath Mayb e Drawing a b

up datePart Drawing a b DPath Drawing a b Drawing a b Drawing a b

mapLab elDrawing a b Drawing a c Drawing b c

mapLeafDrawing a b Drawing c a Drawing c b

drawingLab els Drawing a b DPath a

deletePart Drawing a b DPath Drawing a b

Figure Some functions for manipulating parts of drawings

 Comp osed drawings the constructor Comp osedD Most of the time when

drawings are comp osed it is useful to also sp ecify a layout so rather than

using the constructor Comp osedD directly you use the function placedD

Since the Drawing typ e is an instance of the Graphic class drawings can b e

displayed by GUI fudgets that create lab els buttons menus displays and so

on There is also a fudget that makes use of the prop erties of the Drawing typ e

hyp erGraphicsF Eq lbl Graphic gfx

Drawing lbl gfx F lbl Drawing lbl gfx lbl

It displays a drawing with lab els in it When you click on a p oint in a drawing

the fudget outputs the lab el of the smallest part containing the p oint where you

clicked You can replace a part by feeding a pair of a lab el and a new drawing to

the fudget hyp erGraphicsF can thus b e the starting p oint for simple graphical

browsers and editors

Manipulating drawings

Some functions to manipulate parts of drawings are shown in Figure These

can b e used in the implementation of structure editors Values of typ e DPath

identify parts of drawings

Mixing graphical ob jects of dierent typ es in one drawing

In a Drawing all the leaves must have the same typ e Although you could draw

anything using only leaves of typ e FlexibleDrawing it would b e more conve

nient to b e able to mix dierent typ es of leaves For this purp ose the Fudget

library provides the following typ e that makes use of existentially quantied

typ es LO

data Gfx Graphic a G a

instance Graphic Gfx where trivial

g Graphic a Drawing lbl Gfx

g AtomicD G

Typ es for structured graphical ob jects

placedD verticalP SpacedD centerS g

g hFiller

g xy

Figure A sample drawing with leaves of dierent typ es

In the denition of Gfx a is an existentially quantied typ e variable The

context Graphics a limits the domain of the variable to the typ es in the

Graphic class The result is that the constructor G can b e applied to a value of

any typ e in the Graphic class yielding a value of typ e Gfx When you later use

pattern matching to extract the argument of G you will not know what typ e it

has but you will know that the typ e is in the Graphic class so you can apply

the metho ds of that class on it So making Gfx an instance of the Graphic class

b ecomes trivial The instance declaration is shown in Figure

An example where strings and a FlexibleDrawing are mixed in a Drawing is

shown in Figure

The use of existential typ es gives us a way of packaging data with the meth

o ds that op erate on it and abstract away from the concrete representation of

the data This is reminiscent of how data abstraction is achieved in ob ject

oriented programming The reader is referred to CW for a fuller discussion

of the relation b etween existential typ es data abstraction and ob jectoriented

programming

Drawing attributes

Most of the Xlib drawing commands have an argument of typ e GC a graphics

context This is a data structure containing the values of a numb er of parameters

that aect the result of the drawing commands but which would b e tiresome to

have to pass explicitly as arguments every time you draw something Examples

of such parameters or attributes are

 foreground and background colors

 which font to use for text

 line width line style eg solid or dashed ll style

Most of these attributes are sp ecied by numb ers or elements of enumeration

typ es but colors and fonts are more troublesome Colors can b e sp ecied using

eg color names or RGB values but b efore a color can b e used in a GC it must

b e converted to a pixel value Dep ending on the visual type of the display a

pixel value can b e eg an bit index into a element colormap for bit

PseudoColor displays or RGB information packed into or bits for bit

and bit TrueColor displays resp ectively

Fonts can b e sp ecied by font names but b efore they can b e used they have

to b e converted to font identiers Also if you want to know how much space

the text you draw will take up you need obtain a data structure containing

metric information on the font

Displaying and manipulating graphical ob jects

The data typ es provided by the Fudget library for sp ecify drawing attributes

are shown b elow The typ es ColorSp ec and FontSp ec are describ ed further in

the next section

data GCSp ec

SoftGC GCAttributes ColorSp ec FontSp ec

HardGC GCtx

data ColorSp ec see below

data FontSp ec see below

data GCAttributes color font

GCFunction GCFunction

GCForeground color

GCBackground color

GCLineWidth Width

GCLineStyle GCLineStyle

GCFont font

GCCapStyle GCCapStyle

GCFillStyle GCFillStyle

GCTile PixmapId

GCStipple PixmapId

data GCtx GC GCId FontStruct

data FontStruct abstract type for font metric info

data GCId An Xlib GC

typ e Width Int

data GCFunction GXclear GXand GXandReverse GXcopy GXset

data GCLineStyle LineSolid LineDoubleDash LineOnODash

data GCCapStyle CapNotLast CapButt CapRound CapProjecting

data GCFillStyle FillSolid FillTiled FillStippled FillOpaqueStippled

To include drawing attributes in a Drawing dened ab ove you use the con

structor AttribD applied to a GCSp ec which usually is the constructor SoftGC

applied to a list of attributes containing highlevel sp ecications of fonts and col

ors However b efore the drawing can b e displayed this highlevel sp ecication

must b e converted into a GC In addition to b e able to automatically determine

the size of text the metric information for the sp ecied font is required The

highlevel drawing attributes are therefore converted into a value of typ e GCtx

by fudgets that display drawings This conversion may require calls to Xlib

library functions like XLoadQueryFont XAllo cNamedColor and XCreateGC For

drawings that are to b e displayed many times making these calls every time

can cause a noticeable p erformance degradation so the library provides a way

to create GCtx values in advance These can then b e included in drawings us

ing GCSp ecs with the constructor HardGC The drawing can then b e displayed

without making any calls except for the necessary drawing commands The

reason for cho osing the names SoftGC and HardGC is that the sub drawings of

a no de setting the drawing attributes using the SoftGC alternative inherit the

Typ es for structured graphical ob jects

attributes not present in the GCAttributes list from the parent drawing whereas

with the HardGC alternative al l attributes are taken from the given GCtx

Sp ecifying fonts and colors

To allow fonts and colors to b e sp ecied conveniently in dierent ways we have

intro duced the following typ es and classes

class ColorGen a where

data ColorSp ec an abstract type

colorSp ec ColorGen a a ColorSp ec

class FontGen a where

data FontSp ec an abstract type

fontSp ec FontGen a a FontSp ec

The following typ es are instances of the ColorGen class and can b e used to sp ecify

colors

typ e ColorName String color names as used by Xlib

data RGB RGB Int Int Int RGB values as used by Xlib

data Pixel previously obtained pixel values

Values of the RGB typ e sp ecies the intensities of the primary colors red green

and blue using bit integers RGB is black and RGB

is white

The following typ es are instances of the FontGen class and can b e used to

sp ecify fonts

typ e FontName String font names as used by Xlib

data FontStruct a previously obtained FontStruct

The canonical way of including font and color sp ecications in a drawing is to

do something like this

blueHelloMsg

AttribD SoftGC GCForeground colorSp ec blue

GCFont fontSp ec times r

g Hello world

As you can see this is rather clumsy so the Fudget library provides the following

more convenient functions

bgD fgD ColorGen color

color Drawing lbl leaf Drawing lbl leaf

fontD FontGen font

font Drawing lbl leaf Drawing lbl leaf

Using these you can write the ab ove example like this

blueHelloMsg fgD blue fontD times r

g Hello world

Displaying and manipulating graphical ob jects

Allo cating colors and fonts in advance

As mentioned ab ove you might for eciency reasons want to allo cate colors

and fonts in advance and include the resulting GCtx values in the drawings you

construct For this purp ose the Fudget library provides the following

wCreateGCtx FontGen b ColorGen a

GCtx GCAttributes a b GCtx F c d F c d

ro otGCtx GCtx

The function wCreateGCtx allows you to create GCtx values by mo difying a

template GCtx You can start from ro otGCtx which contains the default settings

for all attributes

Implementation

How should a fudget that displays Drawings b e implemented Drawings are

trees comp osed from leaves containing simple graphical ob jects using placers

and spacers from the ordinary fudget layout system A natural solution thus

seems to b e to implement new fudgets for displaying simple graphical ob jects

and then display comp osed drawings by comp osing fudgets that display the

leaves While this at rst seems like a simple and elegant solution that gives

us maximal reuse of existing Fudget library comp onents rememb er that we

not only want to display drawings to build structure editors we also need a

mechanism that lets the user select and manipulate parts of a structure We

would need to set up a structure where every no de in a Drawing is represented

by a fudget and a communication structure which allows us to communicate

which each no de fudget Further in order to b e able to replace arbitrary no des

with new drawings we would have to use the combinator dynF Section

at each no de

dynF F a b F Either F a b a b

We tried this approach but when taking all requirements into account this

seemingly natural solution b ecame rather tricky It also turned out to b e rather

inecient and there are several p ossible reasons for this

 the solution requires a lot of the work to b e done by message passing in a

complex structure of fudgets Compared to making function calls passing

messages b etween fudgets can b e exp ensive see Section

 each graphical fudget is represented by a window in the X Windows sys

tem This means that there will b e at least one window p er drawing leaf

Creating and maintaining windows requires some work b oth by the fudget

program and the X server

As a result we have develop ed another solution that is now part of the Fudget

library It uses one fudget graphicsF to display complete drawings in one win

dow This has proved to b e reasonably ecient It has allowed us to implement

usable nontrivial applications the syntax directed editor Alfa Chapter

and the web browser WWWBrowser Chapter b eing the largest A draw

back is that some functionality most notably hit detection and clipping that in

Implementation

principle could b e handled by the window system and it was in the natural

solution had to b e duplicated in the implementation of graphicsF The fud

get graphicsF could actually b e seen as an implementation of a simple window

system

The capabilities of graphicsF

Since graphicsF is intended to satisfy all the needs for displaying graphics within

the Fudget library and also b e the ground on which applications like syntax

directed editors and web browsers can b e built it has b een made fairly general

In addition to just displaying graphics graphicsF

 can receive requests to change parts of a complex drawing This allows you

to create editors with ecient screen up dates If graphicsF only accepted

complete drawings as input either the entire window would have to b e

redrawn after each change or exp ensive computations would b e needed to

calculate the dierence b etween the new and the old drawing

 can highlight part of a drawing in a fairly ecient way This can b e used

to implement cursors in editors

 supp orts receiving mouse and keyb oard input graphicsF indicates which

part of a drawing a mouse click o ccurred in

 can display a background image b ehind a drawing

 can sound the terminal b ell

 can b e told to make a certain part of a drawing visible when displaying a

large drawing in a scrolling area

The typ e of graphicsF is

graphicsF Graphic a F GfxCommand a GfxEvent

The denitions of the message typ es GfxCommand and GfxEvent are show in

Figure The constructor ChangeGfx creates messages that allow you to re

place or mo dify the graphical ob ject b eing displayed The argument is a list of

changes Each change has the form

pathhiliteoptrepl

where path selects which part of the ob ject should b e changed hilite switches

on or o highlighting and optrepl is an optional replacement for the selected

part

graphicsF is actually a simplication of graphicsGroupF

graphicsGroupF Graphic gfx

F a b F Either GfxCommand gfx a

Either GfxEvent b

which like groupF discussed in Section can contain subfudgets The fud

get activeGraphicsF discussed in Section for displaying drawing with active

parts for example forms in a web browser is built on top of graphicsGroupF

There are also customisable versions of these fudgets allowing you to change

parameters like the event mask b order width and resizing p olicy

Displaying and manipulating graphical ob jects

data GfxCommand gfx

ChangeGfx DPathBo olMayb e gfx

ChangeGfxBg ColorSp ec

ChangeGfxBgPixmap PixmapId Bo ol True free pixmap

ShowGfx DPath Mayb e AlignmentMayb e Alignment

makes the selected part visible

BellGfx Int sound the bel l

GetGfxPlaces DPath ask for rectangles of listed paths

data GfxEvent

GfxButtonEvent gfxState Mo dState

gfxTyp e Pressed

gfxButton Button

gfxPaths DPathPointRect

GfxMotionEvent gfxState Mo dState

gfxPaths DPathPointRect

GfxKeyEvent gfxStateMo dState

gfxKeySymKeySym

gfxKeyLo okupKeyLo okup

GfxPlaces Rect response to GetGfxPlaces

GfxResized Size

Figure The message typ es used by graphicsF

Implementation of graphicsF

The fudget graphicsGroupF is implemented using groupF

graphicsGroupF subfudgets groupF graphicsK subfudgets

graphicsK

The b ehaviour of the fudget is thus implemented in the fudget kernel graphicsK

Here is roughly what graphicsK do es in the course of displaying a graphical

ob ject

 A graphical ob ject is received on the highlevel input

 The sizes of the parts of the graphical ob ject are determined and the

required resources fonts colors GCs are allo cated This part requires

calls to Xlib which are made by graphicsK through the appropriate low

level messages The result is a value of typ e MeasuredGraphics Figure

containing leaves of known sizes ie with known LayoutRequests GCtxs

and placersspacers

The conversion from an arbitrary graphical ob ject to a value of typ e Mea

suredGraphics is done using the metho ds of the Graphic class These are

shown in Figure Sample instance declarations are shown last in this section

Implementation

data MeasuredGraphics

LeafM LayoutRequest GCtx RectDrawCommand

SpacedM Spacer MeasuredGraphics

PlacedM Placer MeasuredGraphics

Comp osedM MeasuredGraphics

Figure The typ e MeasuredGraphics

class Graphic a where

measureGraphicK a GCtx Cont K i o MeasuredGraphics

measureGraphicListK a GCtx Cont K i o MeasuredGraphics

Default method for lists

measureGraphicListK xs gctx cont

converts xs one element at a time and applies Comp osedM

to the resulting list

Figure The metho ds of the Graphic class

 The layout is computed generating a value of typ e CompiledGraphics Fig

ure containing b ounding rectangles and drawing commands for all the

parts This step is taken by a pure function

compileMG MeasuredGraphics

CompiledGraphics LayoutRequest

 When Exp ose events are received the drawing commands of the parts

whose b ounding rectangles intersect with the damaged rectangles can ef

ciently b e extracted and output Notice that the drawing commands are

kept in the form of XCommands in the CompiledGraphicss This means that

they can b e output as they are No temp orary data structures need to b e

created when resp onding to an Exp ose event This fact in combination

with the use of b ounding rectangles allows Exp ose events to b e handled

very eciently This is noticeable in applications like WWWBrowser and

Alfa

 When a part of the drawing is replaced by a new drawing the new draw

ing is converted into a MeasuredGraphics and inserted in the old Measured

Graphics at the appropriate place Paths are preserved when a Drawing

data CompiledGraphics CGraphics Rect Cursor XCommand CompiledGraphics

The only XCommand used is

Draw MyWindow someGC someDrawCommand

typ e Cursor Bo ol

Figure The typ e CompiledGraphics

Displaying and manipulating graphical ob jects

instance Graphic Gfx where

measureGraphicK G x measureGraphicK x

instance Graphic FlexibleDrawing where

measureGraphicK FlexD s fh fv drawf gctx k

k LeafM plainLayout s fh fv gctx drawf

plainLayout is dened in Section

instance Graphic Char where

measureGraphicK c measureString c

measureGraphicListK measureString

instance Graphic a Graphic a where

measureGraphicK measureGraphicListK

instance Graphic Int where and similarly for other basic types

measureGraphicK i measureString show i

measureString s gctxGC gc fs k

let rRect size stringrect fs s

d fontdescent fs

a fontascent fs

p Point a left end of base line reference point

p Point xco ord size a right end of base line ref point

drawit Rect p Point h DrawString pPoint hd s

in k LeafM refpLayout size True True pp gctx drawit

refpLayout is dened in Section

Figure Some sample instances for the Graphic class

is converted into a MeasuredGraphics A new CompiledGraphics is then

computed from the new MeasuredGraphics Guided by the paths of the

changes and the dierences b etween the b ounding rectangles of the cor

resp onding parts in the old and new CompiledGraphics only those parts

that have actually changed or have moved b ecause of the changes are

redrawn

A shortcoming of current implementation of graphicsF is that it do es not handle

overlapping parts prop erly not b ecause overlapping parts would b e to o dicult

to handle in the current solution but simply b ecause it has not b een imp ortant

in the applications where graphicsF has b een used so far This means that

a drawing with overlapping parts can lo ok dierent after part of it has b een

redrawn in resp onse to an Exp ose event

Finally some sample instance declarations for the Graphic class are shown

in Figure

Extended layout mechanisms

Eciency issues in the implementation of graphicsF

As mentioned ab ove when part of a drawing is replaced graphicsF recomputes

the layout of the complete drawing None of the old layout computations are

utilised in this step This may put an upp er limit on how big ob jects can b e

handled with reasonable resp onse times in a structure editor A b etter solution

would b e to reuse layout information for parts that are not aected by a change

This is done in the ordinary fudget layout system see Chapter

Large drawings consist of many DrawCommands Outputting these one at a

time in lowlevel messages turned out to entail a considerable overhead For ex

ample redrawing the window after a page scroll in the editor Alfa Chapter

in a typical situation could take second In an attempt to improve this we

added a new constructor to the XCommand typ e

data XCommand XDoCommands XCommands

It allows many commands to b e passed in one lowlevel message thus allowing

all the DrawCommands needed to redraw a window to b e passed in one message

from graphicsF to the top level of the fudget hierarchy The message passing

overhead thus b ecomes negligible Also caches and other lters see Chapter

that previously had to examine every DrawCommand now only examine one

XDoCommands message they do not lo ok inside This reduced the ab ove

mentioned redrawing time from second to ab out second which makes a

big dierence from the users p oint of view

Extended layout mechanisms

In Chapter we saw placers and spacers suitable for sp ecifying the layout of

GUI elements However to describ e the layout of text in structured graphical

ob jects fully and conveniently two new features are needed

 Base line alignment Text has a base line and when text is comp osed

horizontally the base lines of the pieces should b e aligned

 Line wrapping When displaying longer pieces of text it is usually not

convenient to sp ecify in advance where line breaks should b e inserted

since this can dep end on the size of the window which is under user

control

These two new features are provided through two new placers alignP

alignP Placer

which allows you to comp ose text with base line alignment and paragraphP

paragraphP Placer

which do es line breaking

To implement these two extensions of the layout system were needed Al

though they should still b e considered to b e in an exp erimental stage we de

scrib e them b elow

We also present the idea of conditional placers and spacers which could b e

implemented without any extensions These can b e used for example to select

b etween dierent layouts dep ending on the size of an ob ject

Displaying and manipulating graphical ob jects

Reference p oints

To implement alignP the layout requests see Chapter were extended to

contain in addition to the nominal size and the stretchiness a list of reference

p oints

data LayoutRequest

Layout minsize Size

xedh xedv Bo ol

refp oints Point

The use of these app ear in the Graphic instance for strings see the function

measureString in Figure

alignP places the argument b oxes so that the last reference p oint in one b ox

coincides with the rst reference p oint in the next b ox This gives us base line

alignment when comp osing text

Unlike most other placers alignP do es not stretch the argument b oxes In

fact we have not included a mechanism for sp ecifying how reference p oints are

aected by stretching so you may get o dd layout if a b ox containing refer

ence p oints is rst stretched by one placer and then aligned with another b ox

containing reference p oints by alignP

We have also found use for some spacers that manipulate reference p oints

refMiddleS refEdgesS noRefsS Spacer

moveRefsS Point Spacer

The spacer refMiddleS replaces the reference p oints of a b ox with two reference

p oints placed on the middle of the left and right edges refEdgesS takes the

rst and last reference p oints and moves them horizontally to the left and right

edges resp ectively noRefsS removes the reference p oints from a b ox moveRefsS

displaces the reference p oints of a b ox by a given vector

The placers and spacers we have presented do not make use of more than two

reference p oints so it p erhaps seems more appropriate to have a pair instead

of a list of reference p oints in the layout requests One can also consider

more elab orate use of reference p oints for example dierent placers might use

dierent sets of reference p oints To take a concrete example when putting

equations together horizontally in a comma separated list you probably want

to do base line alignment but when placing equations in a vertical list you may

want them to app ear with the symb ols on the same vertical line Also you

may want the layout system to cho ose b etween horizontal and vertical placement

dep ending on the available space so the equations must contain reference p oints

for b oth p ossibilities and the placers must b e able to cho ose b etween them

Line breaking

The fudget layout system computes the layout in two steps rst a b ottomup

pass collects the layout requests from the leaf b oxes giving the required size

of the toplevel window as a result Based on this size the exact placement of

each b ox is computed in a topdown pass The actual size of each b ox dep ends

on the requested sizes of all b oxes The actual sizes can also b e changed if the

user resizes the shell window

Extended layout mechanisms

To display text with automatic line breaking we would like the requested

height to dep end on the actual width The line breaking should b e redone when

the width of the window is changed

In the original fudget layout system there was no way for a fudget to ask

for a size where the requested height dep ends on the available width A fudget

could still achieve this b ehaviour whenever notied of a size change it could

output a new request with the same width as in the notication but with a new

height Care of course had b e taken to avoid generating innite sequences of

notications and requests and other unpleasant eects This solution was used

in an early version of the web browser describ ed in Chapter

As part of the work on supp ort for structured graphics we develop ed a b etter

solution to the line breaking problem We extended the layout requests with

a function that answers the question if you can b e this wide how tall do you

want to b e For symmetry there is also a function that allows the requested

width to dep end on the actual height otherwise ipP would not work The

two functions are called wAdj and hAdj resp ectively

data LayoutRequest

Layout minsize Size

xedh xedv Bo ol

refp oints Point

wAdj hAdj Int Size

The placers now combine such functions in addition to combining nominal sizes

and stretchiness Although the old b ehaviour can b e achieved by using con

stant wAdjhAdj functions the layout requests still contain the usual nominal

size This saves us from having to rewrite all placers and spacers Also the

usual nominal size is still used rather than the wAdjhAdj functions on the top

level in normal shell windows while the wAdj function is used in vScrollF see

Section where the width is constrained but the height can vary freely

Not surprisingly hAdj is used in hScrollF

Changing the data typ e LayoutRequest meant that all o ccurrences of the

constructor Layout in the Fudget library had to b e adjusted The functions

plainLayout and refpLayout were intro duced to simplify these adjustments

plainLayout s fh fv refpLayout s fh fv

refpLayout s fh fv rps Layout s fh fv const s const s rps

Conditional spacers and placers

Occasionally we have found use for combinators that try alternative layouts

and pick the b est one according to some condition We have implemented an

ad ho c choice of such combinators

ifSizeP SizeSizeBo ol Placer Placer Placer

ifSizeS SizeSizeBo ol Spacer Spacer Spacer

stretchCaseS Bo olBo olSpacer Spacer

alignFixedS Alignment Alignment Spacer

Displaying and manipulating graphical ob jects

The rst two allow you to cho ose b etween two placersspacers dep ending on

the size of the resulting b ox ie if placer and placer yield b oxes of size and

1 2 1

size resp ectively then ifSizeP p placer placer uses placer if p size size is

2 1 2 1 1 2

True and placer otherwise ifSizeS works analogously for spacers

2

stretchCaseS allows you to write spacers that dep end on the horizontal and

vertical stretchiness of the argument b ox alignFixedS is an application of stretch

CaseS It can b e used to allow stretchable graphical ob jects to b e stretched while

ob jects of xed size are aligned As an example when buttonF was generalised

from displaying strings to arbitrary graphics we switched from unconditionally

centering the lab el with centerS to conditionally centering it with alignFixedS

aCenter aCenter This means that text lab els will b e centered as b efore while

graphical lab els may b e stretched

Concluding remarks

As mentioned the supp ort for graphics in the Fudget library was prompted

by the development of the syntax directed editor Alfa Chapter and stu

was added as needed for that particular purp ose Some development was also

prompted by the work on the web browser describ ed in Chapter

The fudget graphicsF was designed to supp ort ecient screen up dates after

small changes to structured graphical ob jects Changes are made by sending

messages to graphicsF telling explicitly with part of an ob ject to replace Struc

tured graphical ob jects are trees and parts are identied by their path from the

ro ot of the tree A dierent approach to mo difying graphical ob jects is used in

Pidgets Sch see Section where the no des of a tree actually a dag

can b e mo died through mutable variables

We have of course b een inspired by other work on graphics in functional lan

guages An early example of such work is Hen where vertical and horizontal

comp osition of simple graphical ob jects are used together with recursion to cre

ate complex images in the style of Escher A more recent example is the Picture

data typ e FJ provided in the GUI to olkit Haggis FP see Section

Although our purp ose was not to implement a window system graphicsF

actually provides some of the core functionality of a window system Rob No

ble has studied the problem of implementing a window system in a functional

language more directly His implementation of Gadgets see Section

includes an implementation of a window system Nob

Some compromises in the design have b een made b ecause of p eculiarities of

Haskell

 We have limited the use of existential typ es since they are not part of the

Haskell standard

 Since you cant directly make the String typ e an instance of a typ e class

we had to add extra metho ds to the class denitions and make more typ es

than we wanted instances of the classes

These p eculiarities are discussed further in Section and Section re

sp ectively

We have not yet added any go o d supp ort for animation to the Fudget library

The ideas from Ary or Ell could probably b e used as they are without

to o much diculty

Combinators for syntaxoriented manipulation

In Chapter we have seen how graphical ob jects can b e drawn and manipu

lated using the typ e Drawing and the fudgets graphicsF and hyp erGraphicsF In

this chapter we will present a set of combinators that can b e used for building

syntaxoriented editors Such editors present a graphical view of a structured

value in an abstract syntax for example a program in a programming language

The editors let the user manipulate the graphical view of the program in

various controlled ways

One problem the programmer must deal with when developing syntax

oriented editors is how the values of the abstract syntax should b e represented

and how they should b e connected to the graphical ob jects We will present

a solution where the op erations on the abstract syntax is dened closely with

the corresp onding op erations on the graphical ob jects to avoid inconsistencies

b etween the abstract syntax and its graphical view

As a concrete example consider a grammar for a tiny expression language

with arithmetic op erations on numb ers

Expr Integer

Expr Op Expr

Op



Such an abstract syntax is straightforward to represent in Haskell using one

datatyp e for each nonterminal in the grammar and where each alternative

corresp onds to a data constructor

data Expr Numb er Integer

Op eration Expr Op Expr

data Op Add

Subtract

Multiply

Divide

How should we connect these datatyp es to the graphical ob jects One solution is

to dene Graphic instances for each typ e which means that they can b e used as

leaves in the typ e Drawing confer Section The drawing can b e decorated

with lab els containing functions for building the abstract syntax when needed

and manipulation functions describing how the user can mo dify dierent parts

of the abstract syntax However all lab els in a Drawing must have the same

typ e which presents a complication when we want to use dierent datatyp es

for dierent nonterminals In contrast the combinators in this chapter allow

editors of dierent typ e representing dierent nonterminals to b e combined

The inspiration of the combinators comes from a certain style of parsing

combinators that is part of the functional folklore the earliest publication we

know of is Rja If P a is the typ e of parsers which returns a value of typ e

a the combinators that are interesting in this context are

 ap P a b P a P b which combines two parsers sequentially

It also acts as lifted function application in that the function returned by

Combinators for syntaxoriented manipulation

somF h SOM i o h a F Either i SOM i o h a

Either o a

leaf Graphic g g a SOM i o h a

ap SOM i o h a b SOM i o h a SOM i o h b

map a b SOM i o h a SOM i o h b

select h a o

h a i Mayb e SOM i o h a

SOM i o h a

SOM i o h a

attr h a ha SOM i o h a

SOM i o h a

Figure The SOM combinators

the rst parser is applied to the value returned by the second yielding a

value that the combination returns

 map a b P a P b which applies a function to the value

that a parser returns

The ap combinator is left asso ciative just like function application and map

has higher precedence than ap This allow a concise style when writing parsers

For example if pExpr is an expression parser and pOp is an op eration parser

Op eration map pExpr ap pOp ap pExpr P Expr

parses an expression followed by an op eration and another expression and re

turns the appropriate Expr value using the Op eration constructor

The next section presents the basic combinators for building editors Sec

tion shows how the combinators can b e used to build an editor for arith

metic expressions Section discusses how nonlo cal editing op erations like

variable renaming can b e handled The implementation of the combinators is

outlined in Section

The SOM combinators

The combinators op erate on the abstract typ e SOM i o h a Syntax Oriented

Manipulation which represents a value or piece of abstract syntax of typ e a

that can b e manipulated through inputoutput of values of typ e i and o The

parameter h is used to pass inherited attributes The parameter a can also b e

used for passing synthesised attributes if needed

A SOM expression not only represents a structured value but also contains

information ab out how dierent parts of this value might b e manipulated and

how the value should b e graphically displayed

The combinators that op erate on SOM expressions are shown in Figure

The display and manipulation of SOM expressions are controlled by somF The

fudget somF h s will initially display the SOM expression s given an attribute

Example manipulating arithmetic expressions

h to inherit This expression can at any time b e replaced by sending a new

SOM expression to the fudget The fudget can also output the value that the

manipulated expression represents This happ ens when a new expression is sent

to the fudget or when a selected part of it is replaced The message typ es i and

o in somF are used for the manipulation of selected sub expressions

Primitive SOM expressions are built with the function leaf The arguments

to leaf are a graphical ob ject to display and the value it represents This

combinator is used together with ap and map to comp ose SOM expressions in

the same style as parsers

To manipulate a SOM expression the user must rst select a sub expression

A SOM expression might contain some no des that are not p ossible to manipulate

for example syntactic decorations like keywords and some that are The

programmer declares that it should b e p ossible to select and manipulate a no de

by using the select combinator The comp osition select f f s makes the SOM

o i

expression s selectable When the user clicks inside the graphical representation

of s but not inside any inner selectable no de the comp osition is selected and

highlighted As a result the output function f is applied to the inherited

o

attribute and the current value The result is output from the fudget somF that

contains the comp osition and is typically a set of editing op erations that are

applicable to the selected no de Initially the current value is merely the value

that s represents but this might change if some part of s is replaced If some

input typically an editing op eration picked by the user is sent to the fudget

while s is selected the input function f is applied to the inherited attribute the

i

current value and the input yielding a new expression which replaces select f

o

f s The input function also has a choice of returning Nothing in case the input

i

could not b e handled This is used to delegate input to selectable ancestors

and is covered in Section

The combinator attr allows the inherited attribute and the current value to

b e mo died simultaneously In the comp osition f attr s f is applied to the

inherited attribute and the current value that s represents The result of f is

the attribute that s will inherit and the current value of the comp osition

Example manipulating arithmetic expressions

By using leaf ap and map we can turn structured values into SOM expressions

As an example let us consider the expression language from the intro duction

We will dene the functions edExpr and edOp that turn arithmetic expressions

and op erators into SOM expressions Since we do not need any inherited at

tributes for the moment and the typ e of input and output will always b e the

same we dene a typ e synonym for the kind of SOM expressions that we will

form

typ e ArithSOM a SOM Choice Choice a

edExpr Expr ArithSOM Expr

edOp Op ArithSOM Op

The expression editor edExpr is used in exprF to form the fudget that presents

the editor

Combinators for syntaxoriented manipulation

Figure An arithmetic expression manipulator The user has selected the

sub expression  which can b e replaced by or

exprF Expr F Either Choice ArithSOM Expr

Either Choice Expr

exprF e somF edExpr e

When the user selects a sub expression exprF outputs a list of choices that is

presented in a menu These choices represent the op erations that are available

on the sub expression If a choice is picked it will b e sent back to the editor

exprF also outputs the arithmetic expression for evaluation in the main fudget

A screen dump of the program is shown in Figure

main fudlogue

lo opF shellF Cho ose smallPickListF show

displayF show evalExpr

shellF Expression scrollF exprF Numb er

evalExpr Expr Integer

evalExpr Numb er i i

evalExpr Op eration e b e evalOp b evalExpr e

evalExpr e

evalOp Op Integer Integer Integer

evalOp Add

evalOp Subtract

evalOp Multiply

evalOp Divide x y if y then else x div y

When we dene edExpr and edOp we use a programming style which resembles

the one we presented for parsing combinators in the intro duction

Example manipulating arithmetic expressions

edExpr e selExpr case e of

Numb er i Numb er map

leaf i i

Op eration e b e Op eration map

edExpr e ap

edOp b ap

edExpr e

Numb ers are shown as they are whereas binary expressions are handled recur

sively and by means of edOp Each sub expression can b e selected and manipu

lated by selExpr which is dened later

The denition of edOp is similar

edOp b selOp leaf showOp b b

showOp Add

showOp Subtract

showOp Multiply 

showOp Divide

We dene the typ e Choice to contain expressions that can replace the selected

sub expression Since sub expressions can b e of b oth typ e Expr and Op we use a

union typ e for the output

data Choice ReplaceExpr Expr

ReplaceOp Op

When the user selects an expression we arbitrarily cho ose to present three

alternatives which let the user replace the expression with its value plus or minus

one or replace it with The interface is not at all the most convenient

one could imagine but it allows a patient user to enter an arbitrary expression

the can b e replaced with any of the other op erators as we will see b elow

This part of the editor could of course b e elab orated as desired

selExpr ArithSOM Expr ArithSOM Expr

selExpr select outf inf

where

outf e map ReplaceExpr

Numb er evalExpr e

Numb er evalExpr e

Op eration Numb er Add Numb er

inf map edExpr stripExpr

stripExpr ReplaceExpr e Just e

stripExpr Nothing

If the user picks one of the choices it will b e propagated to the selected no de the

expression is extracted from the typ e union and a replacement SOM expression

is formed However the typ e system cannot prevent programming errors that

result in an op erator b eing sent to selExpr To get a more robust program the

function stripExpr ignores the input in this case and returns Nothing

When an op erator is selected we present a choice of the four arithmetic op erators

Combinators for syntaxoriented manipulation

selOp ArithSOM Op ArithSOM Op

selOp select outf inf

where

outf map ReplaceOp AddSubtractMultiplyDivide

inf map edOp stripOp

stripOp ReplaceOp b Just b

stripOp Nothing

Nonlo cal manipulation

With the combinators presented so far we can dene lo cal manipulation op er

ations The user can select a SOM sub expression and arbitrary replacements

can b e sp ecied for that expression If a manipulation would imply a change in

other parts of the expression we are forced to replace the complete expression

globally by sending a new SOM expression to somF There are situations where

we want the p ossibility to sp ecify replacements that are somewhere in b etween

the lo cal and global alternatives Supp ose that we want to add variables to our

arithmetic expressions We would then like to provide an op eration for chang

ing the name of a variable by selecting one o ccurrence p ossibly the binding

o ccurrence and give a new name to it This is an op eration that aects the

whole subtree that starts with the binding of the variable

This eect can b e achieved by using the p ossibility to delegate input as

follows Recall that the input function the second parameter of select can

return Nothing for input that cannot b e handled Instead of discarding the

input somF will delegate it to the closest selectable ancestor and apply its input

function This delegation propagates towards the ro ot of the SOM expression

until a select no de is found that accepts the input

In the case of variable manipulation delegation can b e used to propagate

input to the no de where the variable is b ound We will do this in the following

section where we present a variant of the expression manipulator in Section

extended with variables

Extended example manipulating variables

We extend the datatyp e Expr with constructors for variables and let expressions

data Expr

Var Name

Let Name Expr Expr

typ e Name String

In the construction of a SOM expression we assume the presence of an environ

ment where we can lo okup the value of variables

typ e Env NameInteger

We will use the inherited attribute for propagating the environment The typ e

of SOM expressions we will use are instances of ArithEnvSOM

typ e ArithEnvSOM a SOM Choice Choice Env a

Nonlo cal manipulation

We intro duce the additional combinators drLeft or drRight to prep end or app end

a graphical decoration to an expression

drLeft Graphic g g SOM i o h a SOM i o h a

drRight Graphic g SOM i o h a g SOM i o h a

These are used for drawing keywords as we will see in the case of let expressions

The asso ciativity of ap drLeft and drRight are set so that we avoid paren

theses at least in this application

inxl ap

inxr drLeft

inxl drRight

Haskell do es not declare any xity for map which means that it gets a default

declaration

inxl map

But the typ e of map suggests that it should b e right asso ciative If it were

and had the same precedence level as drLeft we could skip the parentheses in

expressions like f map d drLeft s If lo cal xity declarations were allowed in

Haskell we could x the xity

edExpr e

let inxr map

in

Lo cal xity declarations are not allowed in Haskell so we give map a new name

with the desired xity

inxr mapp

mapp a b SOM i o h a SOM i o h b

mapp map

With mapp we can construct SOM expressions in the style shown in in Figure

The function extendEnv will b e applied to the current let expression from which

it will extract sucient information to extend the environment that the b o dy

should inherit To avoid that the righthand side in the let expression also

inherits the extended environment we use the function dropEnv to p op the

added binding If we want to allow recursive declarations we omit dropEnv

Note that we have also used dierent selection functions for dierent kinds

of expressions Variables are handled by selVar let expressions by selLet and

the others by selExpr

The binding o ccurrence of a variable is handled by edName Figure and

selecting such a name results in a choice of renaming it For simplicity we pick

an arbitrary new name that is not present in the environment by using freshVar

The input function in selName ignores all input which instead is delegated to

selLet

We have extended the manipulation typ e with a command for renaming a

variable

data Choice

Rename Name Name

Combinators for syntaxoriented manipulation

edExpr Expr ArithEnvSOM Expr

edExpr e case e of

Numb er i selExpr Numb er mapp

leaf i i

Op eration e b e selExpr Op eration mapp

edExpr e ap

edOp b ap

edExpr e

Var n selVar n Var mapp

leaf n n

Let n e e selLet extendEnv attr

Let mapp

let drLeft

edName n ap

drLeft

dropEnv attr edExpr e ap

in drLeft

edExpr e

extendEnv Env Expr EnvExpr

extendEnv env eLet n e nevalExpr env eenve

dropEnv Env Expr EnvExpr

dropEnv env e tail enve

Figure The function edExpr extended for variables

edName Name ArithEnvSOM Name

edName n selName leaf n n

selName ArithEnvSOM Name ArithEnvSOM Name

selName select outf inf

where outf env n renameCommand n env

inf Nothing

renameCommand Name Env Choice

renameCommand old env Rename old freshVar env

freshVar Env Name

freshVar env head map a map fst env

Figure The editor for variable names

Nonlo cal manipulation

selExpr ArithEnvSOM Expr ArithEnvSOM Expr

selExpr selExpr const exprInf

selLet ArithEnvSOM Expr ArithEnvSOM Expr

selLet selExpr const letinf

where letinf env Let n e e Rename n new n n

Just edExpr Let new rename n new e

rename n new e

letinf env e i exprInf env e i

selVar Name ArithEnvSOM Expr ArithEnvSOM Expr

selVar n selExpr env renameCommand n env exprInf

selExpr Env Choice

Env Expr Choice

Mayb e ArithEnvSOM Expr

ArithEnvSOM Expr

ArithEnvSOM Expr

selExpr xchoices inf select outf inf

where outf env e xchoices env

map ReplaceExpr

Numb er v

Numb er v

Op eration n Add n

Let freshVar env n n

map Var fst env

where v evalExpr env e

n Numb er

exprInf Env Expr Choice Mayb e ArithEnvSOM Expr

exprInf env map edExpr stripExpr

Figure The selection functions for expressions

Combinators for syntaxoriented manipulation

Figure Manipulating variables There are additional choices for the variables

in the environment Since a variable is selected there is also a choice of renaming

it

The selection functions are dened in Figure The functions for let ex

pressions and variables are variants of the original selExpr from Section We

dene a parameterised version selExpr which lets us add choices and sp ecify

the input function Note that we have added choices for all variables in scop e

The standard selection function selExpr do es not have any additional

choices whereas the selection function for let expressions selLet denes an ex

tended input function which handles the renaming command For a renaming

command to match the old variable must equal the b ound variable Otherwise

input is meant for some outer let expression We assume a function rename

where rename old new e substitutes new for old in e

When selecting a variable we extend the expression selection menu with a

renaming choice Variable renaming can then take place at any o ccurrence of a

variable Note that we do not handle renaming in the input function it is the

same as in selExpr

The rest of the program is almost the same as in the rst example except

that we pass the empty environment as an initial inherited attribute in exprF

The program is seen in action in Figure

exprF Expr F Either Choice ArithEnvSOM Expr

Either Choice Expr

exprF e somF emptyEnv edExpr e

emptyEnv Env

emptyEnv

The implementation of the SOM combinators

The implementation of the SOM combinators

We have taken the approach to implement SOM as a datatyp e with constructors

corresp onding to the combinators leaf select map and ap Since the typ es of the

arguments to map and ap have variables that do not show up in the result typ e

we use the p ossibility to sp ecify lo cal existential quantication using variables

b eginning with in the datatyp e declaration Again existential quantication

in datatyp es proves to b e a useful extension to Haskell see also Section

data SOM i o h a

Select h a o

h a i Mayb e SOM i o h a

SOM i o h a

Map b a SOM i o h b

Ap SOM i o h b a SOM i o h b

Attr h a ha SOM i o h a

Leaf Dr a

Decor Dr Dr SOM i o h a

The rst four constructors corresp ond directly to the resp ective combinators

select Select

ap Ap

attr Attr

instance Functor SOM i o h where map Map

The rst argument to the Leaf constructor is a drawing

typ e Dr Drawing SOMPointer Gfx

The lab el typ e SOMPointer which is dened later is used to identify what

part of a SOM expression the user has selected The typ e Gfx is used to store

arbitrary graphical ob jects in the leaves Section In the denition of

leaf we turn these graphics into drawings by means of g which was dened in

Section

leaf Graphic g g a SOM i o h a

leaf d a Leaf g d a

The nal constructor in SOM is Decor and can b e used to dene layout or

add additional graphics on a part of a SOM expression Its rst argument is a

function which will b e applied to a drawing that is constructed from its second

argument The combinators drLeft and drRight uses this constructor

drLeft d n Decor d hb oxD g dd n

drRight n d Decor d hb oxD dg d n

The fudget somF is built around a hyp erGraphicsF which outputs a SelectionPtr

whenever the user selects a sub expression

data Dir Le Ri

typ e SelectionPtr Dir

A SelectionPtr is a list of turns to take whenever an Ap no de is encountered

in the SOM tree and p oints out a select no de Using the function somOutput

Combinators for syntaxoriented manipulation

somOutput h SOM i o h a SelectionPtr o

somOutput h n p case n of

Select outf n case p of

outf h somValue h n

somOutput h n p

Ap f n case p of

Lep somOutput h f p

Rip somOutput h n p

Map n somOutput h n p

Attr f n somOutput fst apAttr f h n n p

Decor n somOutput h n p

Figure The function somOutput

in Figure somF can get the output choices of a selected no de If somF

receives an input choice for the selected no de the function somInput Figure

is applied to the input and the selection p ointer to get the mo died SOM tree

somInput also returns the p ointer to the no de whose input function accepted the

input which is used by somF to up date the correct part of the drawing If all

input functions ignore the input somInput returns Nothing

The functions somOutput and somInput use the function somValue to get the

current value of a SOM expression and the function apAttr to apply attribute

functions Figure The recursive denition in apAttr mirrors the fact that

attributes and values can have cyclic dep endencies

The implementation of somF is shown in Figure and as mentioned pre

viously it is built around hyp erGraphicsF The auxiliary functions tohg out

up dateDr and replaceDr are routing functions that are typical when program

ming with lo opThroughRightF The function out is used when outputting mes

sages from somF and up dateDr and replaceDr are used when up dating part of

or the whole of the drawing in the hyp erGraphicsF Compare with the typ e of

hyp erGraphicsF in Section

The controlling stream pro cessor ctrl has an internal state which consists of

the SOM expression b eing edited n and a p ointer to the selected no de p If

there is no selected no de p is Nothing An incoming message to ctrl is either a

click from the hyp erGraphicsF indicating a new selection by the user handled

by click an input choice handled by input or a new SOM expression handled

by replace

In click the old selection cursor is removed and a new no de is selected

In input it is checked that there is a selection and that a replacement no de

can b e obtained from somInput In this case the appropriate sub drawing is

replaced and selected

The implementation of the SOM combinators

somInput h SOM i o h a i SelectionPtr

Mayb e SelectionPtrSOM i o h a

somInput h n i p case n of

Select o inf n case p of

myInput

mapSOM Select o inf

somInput h n i p

myInput

where myInput map nn

inf h somValue h n i

Ap f n case p of

Nothing

Lep map mapPair Leap n

somInput h f i p

Rip map mapPair Rif ap

somInput h n i p

Map f n mapSOM Map f

somInput h n i p

Attr f n mapSOM Attr f

somInput fst apAttr f h n n i p

Leaf dr a Nothing

Decor f n mapSOM Decor f

somInput h n i p

where mapSOM map apSnd

mapPair f g xy f xg y

Figure The function somInput

somValue h SOM i o h a a

somValue h n case n of

Select n somValue h n

Ap n n somValue h n somValue h n

Map f n f somValue h n

Leaf a a

Attr f n snd apAttr f h n

Decor n somValue h n

apAttr h a ha

h

SOM i o h a

ha

apAttr f h n ha where ha f h somValue fst ha n

Figure The functions somValue and apAttr

Combinators for syntaxoriented manipulation

somF h SOM i o h a F Either i SOM i o h a

Either o a

somF h n lo opThroughRightF

absF ctrl n Nothing

hyp erGraphicsF unselectedSomDr n

where

tohg putSP Left

out putSP Right

up dateDr tohg Left unselectedSomDr

replaceDr tohg Right

unselectedSomDr somDrawing

ctrl n p getSP click either input either replace

where

same ctrl n p

click p mayb e id deselect n p

selectO n p

ctrl n Just p

input i ip mayb e same p jp

ip mayb e same somInput h n i jp rpn

replaceDr rpsomDrawing rp n

selectO n jp

out Right somValue h n

ctrl n p

replace n up dateDr n

ctrl n Nothing

Select subnode and send its output

selectO n p select n p out Left somOutput h n p

Draw cursor

select setselect cursor

Remove cursor

deselect setselect id

setselect cu n p replaceDr pcu somDrawing p n

The cursor is a frame around the node

cursor d placedD overlayP b oxD dg frame

Extract selected subdrawing

somDrawing SelectionPtr SOM i o h a Dr

Figure The function somF

Typ e directed GUI generation

Intro duction

In the HCI Human Computer Interaction scho ol Shn it is go o d design

to rst concentrate on a go o d user interface when developing a GUI applica

tion then implement the functionality b ehind For example the Logical User

Centered Interactive Design Methodology LUCID Kre consists of six stages

in which the third stage includes the development of a socalled keyscreen pro

totyp e using a rapid prototyping to ol After a stage of iterative renement this

prototyp e is turned into a full system in the fth stage

To promote quick development of prototyp e programs a programmer might

prefer to concentrate on the functionality and ignore the GUI design at least to

start with Since this metho d can make life easier for the programmer and to

put it in contrast with HCI we call it PCI Programmer Computer Interaction

oriented

With the PCI metho d the GUI must b e generated automatically somehow

The basic idea is simple and can b e seen as the GUI variant of the Read and

Show classes in Haskell which allow values of any typ e to b e converted to and

from strings using the functions read and show

read Read a String a

show Show a a String

Part of the convenience with these classes is that instances can b e derived auto

matically by the compiler for newly dened datatyp es By using read and show

it is easy to store data on les or exchange it over a network as is done in

Chapter

In this section we will dene the class FormElement which plays a similar

role to Read and Show but for GUIs Form elements are combined into forms

which can b e regarded as simple graphical editors that allow a xed numb er of

values to b e edited They are often used in dialog windows to mo dify various

parameters in a GUI application

Assuming that all the necessary instances of FormElement are available we

show how forms can b e generated automatically entirely based on the typ e of

the value that the form should present

The FormElement class

An individual form element displays a value of some typ e a Whenever this

value is changed it will b e output by the element Such a change o ccurs when a

user enters a new value but it should also b e p ossible to change the value from

the program itself

A candidate typ e for form elements for a typ e a is a fudget with the typ e a

b oth on input and output

typ e FormF t F t t

The form element class has a metho d which sp ecies such a fudget

Typ e directed GUI generation

class FormElement t where

form FormF t

formList FormF t

instance FormElement t FormElement t

where form formList

We have used the standard trick of adding a sp ecial metho d formList which

handles lists so that we can get an instance for strings this is discussed in

Section

We can now dene instances for the basic typ es integers b o oleans and

strings

instance FormElement Int

where form intInputF

instance FormElement Bo ol

where form toggleButtonF

instance FormElement Char

where formList stringInputF

We also need instances for structured typ es The fundamental structured typ es

are pro duct and sum

instance FormElement t

FormElement u

FormElement Either t u

where form vBoxF form form

instance FormElement t

FormElement u

FormElement tu

where form hBoxF form  form

Note the vertical layout of alternatives whereas elements within an alternative

have a horizontal layout

The combinator  puts two fudgets in parallel just like and

but input and output are pairs

 F a b F a b F a a b b

f  g pairSP f g splitSP

pairSP SP Either a b ab

pairSP merge Nothing Nothing where

merge ma mb

case mamb of

Just aJust b put ab

id

get y case y of

Left a merge Just a mb

Right b merge ma Just b

Some suggestions for improvements

Input to f  g is split the rst comp onent is fed into f and the second

comp onent is fed into g The combined fudget will not output anything until

b oth f and g has output something After this has o ccurred a message from one

of the subfudgets f or g is paired with the last message from the other subfudget

and emitted

We are ready for a small example The gure shows a form which can handle

input which either is an integer or a pair of a string and a b o olean

myForm FormF Either Int StringBo ol

myForm b order labLeftOfF Form form

An extended example connects the input and output of the form with fudgets

to demonstrate the message trac

main fudlogue

shellF Form

labLeftOfF Output displayF show

myForm

labLeftOfF Input read stringInputF

This program is illustrated in Figure

Some suggestions for improvements

The little form program is a tangible example of how typ es can inuence the

semantics of a Haskell program through overloading To some extent this style

allows a programmer to freely mo dify the typ e of data structures during devel

opment without the need to change the co de that deals with the GUI Together

with the automatic layout system this provides limited automatic GUI gener

ation However as can b e seen in Figure there is much ro om for improvement

of the form For example there is no visual feedback that reveals the state of a

form element of typ e Either It would b e desirable to highlight the part that is

valid or to dim the other part

This generation can also b e p erformed for user dened datatyp es by using

polytypic programming JJ based on the instances for pro ducts and sums

Polytypic programming allows us to dene how instances should b e derived

based on the structure of the userdened datatyp e For more complicated for

example recursive typ es it might b e a b etter idea to base the form elements

on the fudgets for structured graphics in Chapter

After the functionality is there the programmers attention might turn to

the lo ok of the forms and we need a way to tune them An approach that

immediately comes to mind is to add an extra attribute parameter to the form

metho d

class FormElement a t where

form a FormF t

Typ e directed GUI generation

Figure First the user has entered the string Hello and activated the toggle

button Then the user entered a numb er in the integer form element The last

picture is a simulation of how the form can b e controlled by the program in

this case by entering a value in the Input eld The value sets the form and is

propagated to the output

Some suggestions for improvements

If we have an instance FormElement a t we can construct a form for a typ e

t given an attribute value of typ e a A problem with this approach is that

currently only one parameter may b e sp ecied in a class declaration in Haskell

Multiparameter classes are allowed in Mark Jones Gofer Jon which also

allows instance declarations for comp ound typ es like String With these features

we could dene instances as follows

instance FormElement a t

FormElement b u FormElement ab Either t u

where form ab vBoxF form a form b

instance FormElement a t

FormElement b u FormElement ab tu

where form ab hBoxF form a  form b

instance Graphic a FormElement a String

where form a labLeftOfF a stripInputSP stringF

instance Graphic a FormElement a Int

where form a labLeftOfF a stripInputSP intF

instance Graphic a FormElement a Bo ol

where form a toggleButtonF a

Parameters for customisation

Parameters for customisation

There are many asp ects of GUI fudgets that one might want to mo dify eg

the font or the foreground or background colours for displayF The simple GUI

fudgets have some hop efully reasonable default values for these asp ects but

so oner or later we will want to change them

In early versions of the Fudget library the GUI fudgets had several extra

parameters to make them general and adaptable to dierent needs For example

the typ e of displayF was something like

displayF FontName ColorName ColorName F String a

Having to sp ecify all these extra parameters all the time made it hard to write

even the simplest program when creating a program from scratch it was next

to imp ossible to write even a single line of co de without consulting the manual

When we wrote programs on overhead slides or on the blackb oard we always

left out the extra parameters to make the co de more readable

A simple way to improve on this situation would b e to intro duce two versions

of each GUI fudget one standard version without the extra parameters and

one customisable version with a lot of extra parameters

displayF F String a

displayF FontName ColorName ColorName F String a

displayF displayF defaultFont defaultBgColor defaultFgColor

This would make it easy to use the standard version and the blackb oard exam

ples would b e valid programs But the customisable version displayF would

still b e hard to use even if you just wanted to change one parameter you would

have to sp ecify all of them and you would have to rememb er the order of the

parameters So we went a step further

First we wanted b e able to change one parameter without having to explic

itly give values for all the other ones A simple way of doing this would b e to

have a data typ e with constructors for each parameter that has a default value

In the case of displayF it might b e

data DisplayFParams Font FontName

ForegroundColor ColorName

BackgroundColor ColorName

Then one could have the display fudget take a list of display parameters as a

rst argument

displayF DisplayFParams F String a

We no longer have to rememb er the order of the parameter and whenever we

are happy with the default values we just leave out that parameter from the

list and all is ne

displayF displayF

However supp ose we want to do the same trick with the button fudget We

want to b e able to customise font and colours for foreground and background

like the display fudget and in addition we want to sp ecify a hotkey that

could b e used instead of clicking the button

A mechanism for default values

data ButtonFParams Font FontName

ForegroundColor ColorName

BackgroundColor ColorName

HotKey Mo dStateKey

Now we are in trouble if we want to customise a button and a display in the

same mo dule b ecause in a given scop e in Haskell no two constructor names

should b e equal Of course we could qualify the names with mo dule names

but this is tedious We could also have dierent constructor names to start with

ButtonFFont ButtonFForegroundColor etc which is just as tedious

A mechanism for default values

6

Our current solution is not to use constructors directly but to use overloaded

functions instead We will dene a class for each kind of default parameter

Then each customisable fudget will have instances for all parameters that it

accepts This entails some more work when dening customisable fudgets but

the fudgets b ecome easier to use which we feel more than justies the extra

work

Let us return to the display fudget example and show how to make it cus

tomisable First we dene classes for the customisable parameters

typ e Customiser a a a

class HasFont a where

setFont FontName Customiser a

class HasForegroundColor a where

setForegroundColor ColorName Customiser a

class HasBackgroundColor a where

setBackgroundColor ColorName Customiser a

Then we dene a new typ e for the parameter list of displayF

newtyp e DisplayF Pars DisplayFParams

and add the instance declarations

instance HasFont DisplayF where

setFont p Pars ps Pars Font pps

instance HasForegroundColor DisplayF where

setForegroundColor p Pars ps Pars ForegroundColor pps

instance HasBackgroundColor DisplayF where

setBackgroundColor p Pars ps Pars BackgroundColor pps

The typ e of displayF will b e

displayF Customiser DisplayF F String a

6

The basics of this design are due to John Hughes

Parameters for customisation

We put these declarations inside the mo dule dening displayF making DisplayF

abstract When we later use displayF the only thing we need to know ab out

DisplayF is its instances which tell us that we can set font and colours For

example

myDisplayF displayF setFont xed

setBackgroundColor green

If we want to have buttonF customisable in the same way we dene the addi

tional class

class HasKeyEquiv a where

setKeyEquiv Mo dStateKey Customiser a

The button mo dule denes

newtyp e ButtonF Pars ButtonFParams

and makes it abstract as well as dening instances for font colours and hot

keys Note that the instance declarations for font and colours will lo ok exactly

the same as for the display parameters We can reuse the constructor name

Pars as long as we dene only one customisable fudget in each mo dule In

the Fudget library implementation we have used cpp macros to simplify the

implementation of customisable fudgets and avoid co de duplication

We can now customise b oth the display fudget and the button fudget if we

want

myFudget displayF setMyFont buttonF setMyFontsetMyKey Quit

where setMyFont setFont xed

setMyKey setKeyEquiv Metaq

If we do not want to change any default values we use standard which do es not

mo dify anything

standard Customiser a

standard p p

standardDisplayF displayF standard

Naming conventions for the customisable GUI fudgets

The GUI fudget library is designed so that when you start writing a fudget

program there should b e as few distracting parameters as p ossible Default

values will b e chosen for colour fonts layout etc But a customisable fudget

must inevitably have an additional argument even if it is standard We use

short and natural names for the standard versions of GUI fudgets without

customisation argument So we have

Dynamic customisation

buttonF String F Click Click

buttonF buttonF standard

buttonF Customiser ButtonF String F Click Click

buttonF

displayF F String a

displayF displayF standard

displayF Customiser DisplayF F String a

displayF

and so on This way a programmer can start using the to olkit without having to

worry ab out the customisation concept Later when the need for customisation

arises just add an ap ostrophe and the parameter One could also have the

reverse convention and use ap ostrophes on the standard versions something

that sounds attractive since ap ostrophes usually stand for omitted things in

this case the customiser But then a programmer must learn which fudgets

are customisable and thus need an ap ostrophe even if she is not interested in

customisation

Dynamic customisation

Apart from sp ecifying parameters in the program text most parameters can

in fact b e changed dynamical ly if needed Therefore each customisable fudget

comes in a third variant which is the most expressive Their names end with

two ap ostrophes These dynamical ly customisable fudgets allow customisers as

input messages in addition to the usual message typ e

typ e CF p a b F Either Customiser p a b

As an example the button and the display fudgets can b e dynamically cus

tomised

buttonF Customiser ButtonFStringCF ButtonF Click Click

displayF Customiser DisplayF CF DisplayF String a

Discussion

Collecting all parameters in a customiser rather than using a high arity function

has a numb er of advantages

 When you use a customisable fudget you only need to mention the pa

rameters you want to change from the default value

 Future versions of the library can add new parameters without invalidating

old co de

 You do not have to rememb er the order of the parameters

 By using Haskells class system for overloading the name of the customiser

for a certain parameter can b e the same for all fudgets that have that

parameter For example all fudgets that display text can b e customised

with the setFont function

Parameters for customisation

 Customisers are rst class values They can b e named and used in many

function calls even in calls to dierent functions Section contains

an example of this

The last p oint is an advantage even when compared to what you can do in

languages with supp ort for default values for parameters

In the X Windows system customisation is done via a resource database

where the application can lo okup values of various parameters The database

is untyp ed that is all values are strings so no static typ e checking can b e

p erformed With our customiser solution parameters are typ e checked In

addition the compiler can check that the parameters you sp ecify are supp orted

by the fudget in question whereas parameters stored in the resource database

are silently ignored if the are not supp orted

Disadvantages with this metho d as compared to such languages are that

 dening customisable functions is more cumb ersome

 you do not get an error message if you sp ecify the same parameter twice

and that

 you need two versions of each customisable function for example buttonF

and buttonF

We used lists of parameters in the implementation of customisers

newtyp e DisplayF Pars DisplayFParams

data DisplayFParams

An alternative would b e to use record typ es instead

data DisplayF Pars fontFontName

foregroundColor backgroundColor ColorName

instance HasFont DisplayF where setFont f p p fontf

This would make it easier to extract the values of the various parameters in

the implementation of the customisable fudgets A p ossible disadvantage with

this representation is that in the implementation of dynamically customisable

fudgets it would b e more dicult to tell what parameters have actually b een

changed With the list representation only the parameters that have b een

changed o ccur in the list

Gadgets in Fudgets

Gadgets Nob is a GUI to olkit on top of a mo died version of the Gofer

interpreter Jon As will b e describ ed the related work Section

the term Gadgets stands for Generalised Fudgets and Nob indeed presents

fudget combinators in Gadgets In this section we describ e a purely functional

implementation of the underlying pro cess scheduler in Gadgets which enabled

us to p ort the source co de for Gadgets to Haskell and use it on top of Fudgets

The Gofer implementation of the pro cess scheduler is implemented in C as

part of Gofers runtime system A feature of the scheduler is that it attempts to

keep the message queues short by giving higher priority to pro cesses that read

from channels with many waiting messages

A limitation in the Gofer implementation of Gadgets resulted in that for each

channel at most one pro cess can b e waiting for arriving messages and channels

must b e explicitly claimed by a pro cess b efore trying to read from them

The functional scheduler that we will describ e is not as advanced as the

original one but it is simpler and do es not have the ab ove mentioned limitation

Before describing the functional scheduler we give an overview of the pro cess

primitives as they app ear in the original Gofer version

Wires and pro cesses in Gadget Gofer

Gadget Gofer relies on an extension of Gofer with processes and wires The typ e

Pro cess s represents pro cesses which have an internal state of typ e s Commu

nication b etween pro cesses is asynchronous and mediated by typ ed wires

typ e Wire a In aOut a

data In a In Int

data Out a Out Int

The communication along wires is directed one end is input only In a the

other is output only Out a If a pro cess only knows the input output end of

a wire it can only read from write to it Note that the wire ends are merely

represented by integer identiers although the typ es carry extra information

ab out the message typ e

Wires are created by the primitive primWire

primWire Wire a Pro cess s Pro cess s

Just as with stream pro cessors the sequential b ehaviour of a pro cess is pro

grammed in a continuation passing style To transmit something along a wire

one uses primTx

primTx Out o o Pro cess s Pro cess s

A pro cess can wait for input from many wires simultaneously by using guarded

pro cesses A guarded pro cess which we denote AGuarded s is a pro cess con

tinuation that is waiting for input from one wire and is formed by primFrom

primFrom In m m Pro cess s AGuarded s

Given a list of guarded pro cesses we can wait for input to any of them by

primRx

Gadgets in Fudgets

typ e Guarded s AGuarded s

primRx Guarded s Pro cess s

Now why are there two primitives for receiving input when there is only one for

transmitting output The reason is that although we could combine primFrom

and primRx

not general enough

primRxFrom In m m Pro cess s Pro cess s Pro cess s

primRxFrom primRx map uncurry primFrom

the combination forces us to wait for messages of the same typ e The intro duc

tion of guarded pro cesses hides the message typ es and allows a pro cess to select

input from wires of dierent typ e

Pro cesses need not live forever they can die by calling primTerminate

primTerminate Pro cess s

Last but not least a pro cess can spawn a new pro cess

primSpawn Pro cess s s Pro cess s Pro cess s

Thus primSpawn p s c will spawn the new pro cess p giving it initial state s

0 0

and continue with c

Gadget Gofer also uses primitives for claiming and disowning wires and

requires that a wire should b e claimed by a pro cess b efore attempting to receive

from it Since the functional scheduler do es not have this restriction we ignore

them in the following The presentation will also ignore

that primRx actually takes an additional debugging argument and

the existence of the global p olymorphic wire ends nci and nco which are

not connected to anything

Connecting pro cesses to the world

Wires are not only used for interpro cess communication they also interface the

pro cesses to the outside world There are three primitive device processes that

when spawned attach wires to the keyb oard the mouse and the screen

keyb oard In Keyb oardCmnd Out Keyb oardEvnt Pro cess s

mouse In MouseCmnd Out MouseEvnt Pro cess s

screen In ScreenCmnd Out ScreenEvnt Pro cess s

The mouse and keyb oard can b e congured by transmitting mouse or keyb oard

commands resp ectively whereas the screen commands are used for drawing

The events rep ort key presses mouse clicks mouse movements and exp osure

events

These three primitives are started once inside the Gadget window system

For example the keyb oard pro cess is started with

wire smk

wire ksm

spawn keyb oard ip smk op ksm

A functional pro cess implementation

After this the keyb oard events are read from op smk and the keyb oard is

congured by writing to ip ksm

To execute a pro cess with a given initial state Gadget Gofer provides the

primitive primLaunch

primLaunch Pro cess s s IO

Manipulating the pro cess state

A pro cess uses the op erations readState and setState

readState s Pro cess s Pro cess s

setState s Pro cess s Pro cess s

In Gadget Gofer the typ e Pro cess s is a synonym for a function from s to s

that is a state transformer

typ e Pro cess s s s

The implementation of readState and showState is then straightforward

readState c s c s s

setState s c c s

A functional pro cess implementation

The Fudgets implementation of Gadgets is purely functional written in Haskell

which means that all primitives describ ed ab ove are dened within Haskell The

runtime system the pro cess scheduler is also written in Haskell except that

it uses a type cast not dened in ordinary Haskell at one place as we will see

In the functional version pro cesses cannot have the simple function typ e

s s any more since we must b e explicit ab out the eects that pro cesses can

have Instead we will dene the pro cess typ e in steps where we start with a

streampro cessor typ e that handles messages related to the keyb oard mouse and

screen On top of the streampro cessor typ e we dene a state monad SPms

with op erations for manipulating a state in addition to the IO op erations of

the stream pro cessor The state is used by the scheduler and is used to dene

a simple pro cess typ e Pro cess which amounts to the Gadget pro cesses except

that they do not have any lo cal state Having done this we dene the full

Gadget pro cesses on top The steps are summarised in the following table

Pro cess Gadget pro cesses with state

Pro cess Pro cesses without state

SPms Streampro cessor state monads

SP Plain stream pro cessors

The streampro cessor monad with state

We can build a streampro cessor monad with state by using the typ e SPms

typ e SPms i o s a a s SP i o s SP i o

A computation of typ e SPms i o s a can input messages of typ e i output

messages of typ e o manipulate a state of typ e s and return a value of typ e a

through the following op erations

Gadgets in Fudgets

getSPms SPms i o s i

putSPms o SPms i o s

loadSPms SPms i o s s

storeSPms s SPms i o s

getSPms k s getSP i k i s

putSPms o k s putSP o k s

loadSPms k s k s s

storeSPms s k k s

Pro cesses without state

We use the state streampro cessor monad to implement the stateless pro cesses

called Pro cess The state of the stream pro cessor is used by the scheduler for

b o okkeeping

typ e Pro cess i o SPms i o SchedulerState i o

data SchedulerState i o SS freeWire Wno

messageQs MessageQueues

ready Pro cess i o

guarded Guarded i o

input i Pro cess i o

Just as in the Gofer implementation we use integers to identify wire ends except

that we call the integers wire numbers Wno

newtyp e Wno Wno Int

newtyp e In a In Wno

newtyp e Out a Out Wno

What follows are denitions of the primitives for creating wires and pro cesses

and communication over wires We sux the primitives with a to indicate

that they op erate on pro cesses without lo cal state

A new wire is allo cated with primWire which increments the eld freeWire

in the state and hands a fresh wire to the continuation

primWire Wire a Pro cess i o Pro cess i o

primWire c

do psSS freeWire wWno i loadSPms

storeSPms ps freeWire Wno i

c In w Out w

The second comp onent in the scheduler state messageQs is a mapping from

wire numb ers to queues of not yet delivered messages

typ e MessageQueues IntMap Queue Msg

The typ es IntMap and Queue implement integer maps and Okasakis queues

Oka come from HBCs library and have the following signatures

A functional pro cess implementation

module Queue where

empty Queue a

sno c a Queue a Queue a

tail Queue a Queue a

head Queue a a

null Queue a Bo ol

module IntMap where

empty IntMap a

mo dify a a a Int IntMap a IntMap a

delete Int IntMap a IntMap a

lo okup Int IntMap a Mayb e a

The op erations are standard except mo dify which deserves an explanation The

expression mo dify f a i m applies the function f to the entry i in m if it exists

Otherwise it inserts the value a at i

Each message is paired with the wire numb er Since dierent wires can have

dierent typ e messages can also b e of dierent typ e We use an existential

typ e an extension to Haskell provided by HBC to hide the message typ e when

putting messages in the queue

data Msg Msg a

Constructing values of typ e Msg is easy but when deconstructing them we

cannot assume anything ab out the typ e of the argument We return to this

problem later

Sending a value on a wire amounts to queueing the wire numb er together

with the value

primTx Out a a Pro cess i o Pro cess i o

primTx Out wno msg p

if wno ncWno then p

else

do psSS messageQs ready loadSPms

storeSPms ps messageQs addMsg wno Msg msg messageQs

ready pready

scheduler

addMsg Wno Msg MessageQueues MessageQueues

addMsg wno m mo dify sno c m sno c m Queueempty wno

The eld ready holds a list of pro cesses that are ready to run When spawning

o a new pro cess we put it on the ready list

primSpawn Pro cess i o Pro cess i o Pro cess i o

primSpawn p p

do psSS ready loadSPms

storeSPms ps ready pready

p

There is also a list of pro cesses waiting for messages stored in the eld guarded

The elements are lists of stateless guarded pro cesses AGuarded i o

Gadgets in Fudgets

data AGuarded i o AGuarded Wno a Pro cess i o

A guarded pro cess is a wire numb er and a function which takes a message as a

parameter The actual typ e of the message is hidden in AGuarded so that we

can form a list of guarded pro cesses regardless of what message typ e they are

waiting for

typ e Guarded i o AGuarded i o

A guarded stateless pro cess is formed with primFrom

primFrom In m m Pro cess i o AGuarded i o

primFrom In wno f AGuarded wno f

The function primRx will wait for a message to arrive to any of the guarded

pro cesses in the rst parameter It adds the guarded pro cesses to the state and

then jump to the scheduler to nd another pro cess to execute

primRx Guarded i o Pro cess i o Pro cess i o

primRx g def

do psSS guarded loadSPms

storeSPms ps guarded gguarded

scheduler

The schedulers Figure job is to apply guarded pro cesses to matching mes

sages move them to the ready list and pick one from the ready list to run

In case the ready list is empty the input list is investigated This list con

tains pro cesses waiting for input from the outside of the stream pro cessor If

this list is also empty then the gadget program is nished Otherwise we do

streampro cessor input and give the message to all pro cesses in the input list

The function match applies all guarded pro cesses for which there are match

ing messages It returns the remaining unmatched messages and guarded pro

cesses together with a list of new ready pro cesses

Recall that each element in the eld guarded is itself a list which comes from

a call to primRx The function match lo oks for a matching message for one of

the elements in such a list p ossibly returning a new message queue and a ready

pro cess A matching message must have the same wire numb er as the guarded

pro cess It seems like this cannot b e expressed in the typ e system so we are

forced to use a typ e cast see the function match in Figure

The stateless pro cesses can do streampro cessor inputoutput by means of

get and put The output part is easy

put o Pro cess i o Pro cess i o

put o p

do putSPms Right o

p

When it comes to input the pro cess do es not directly call getSPms since that

would blo ck other threads as well Instead the continuation is put on the input

list in the scheduler state and jump to the scheduler Note that more than one

pro cess may call get As we have already seen the scheduler will ensure that

all of them will receive the next message that the stream pro cessor inputs

A functional pro cess implementation

scheduler Pro cess i o

scheduler

do psSS freeWire messageQs ready guarded input loadSPms

let messageQsguardedmoreReady match messageQs guarded

let run p ready input

do storeSPms ps messageQs messageQs

ready ready

guarded guarded

input input

p

case moreReadyready of

if null input

then nullSPms

else do i getSPms

case ih i ih input of

pready run p ready

pready run p ready input

match MessageQueues Guarded i o

MessageQueuesGuarded i oPro cess i o

match m m

match m gf case match m g of

Nothing mgf r where mf r match m f

Just mp mf pr where mf r match m f

match MessageQueues Guarded i o

Mayb e MessageQueuesPro cess i o

match m Nothing

match m AGuarded Wno w f gs

case IntMaplo okup w m of

Nothing match m gs

Just mq case Queuehead mq of

Msg msg Just mcast f msg type cast

where mq Queuetail mq

m if Queuenull mq

then delete w m

else mo dify Queuetail undened w m

cast a b Not dened in Haskel l

Figure The scheduler

Gadgets in Fudgets

get i Pro cess i o Pro cess i o

get i

do psSS input loadSPms

storeSPms ps input iinput

scheduler

If a pro cess terminates we need to schedule some other pro cess for execution if

p ossible Therefore primTerminate simply jumps to the scheduler

primTerminate Pro cess i o

primTerminate scheduler

To launch a pro cess the pro cess state must b e initialised This is done in

primLaunch

primLaunch Pro cess i o Pro cess i o

primLaunch p

do storeSPms SS freeWire startWno

messageQs IntMapempty

ready

guarded

input

p

So far we have b een quite general ab out the typ e of messages that our stateless

pro cesses will sp eak To implement gadget pro cesses we will use the stream

pro cessor IO to simulate the keyb oard mouse and screen as discussed in

Section We will call stateless gadget pro cesses GPro cess

typ e GPro cess Pro cess GEvent GCommand

The typ es GEvent and GCommand will b e dened in Section

Gadgets pro cesses with state

Now we have dened most of the necessary primitive op erations required for

Gadget pro cesses except for the ones that manipulate a lo cal state It turns

out to b e straightforward to add state to GPro cess

newtyp e Pro cess s P s GPro cess s GPro cess

A stateful pro cess is a pro cessvalued function which takes a stateless pro cess

continuation parameterised over its input state and an input state as param

eters It can mo dify the state b efore applying it to the continuation and also

use the stateless pro cess primitives

The state parameter is accessed by setState and readState

unp P p p

setState s Pro cess s Pro cess s

setState a p P c s unp p c a

readState s Pro cess s Pro cess s

readState p P c s unp p s c s

A functional pro cess implementation

We now need to lift the primitive op erations of typ e GPro cess to Pro cess We

use two auxiliary functions dep ending on whether the continuation takes an

argument or not This duplication of co de is a price we pay for not working

with monads in monadic style all op erations return a value which might b e

if it is uninteresting In CPS op erations without a result take continuations

without an argument which can b e seen as a slight optimisation but adds to

the complexity of CPS programming

liftParg a GPro cess GPro cess

a Pro cess s Pro cess s

liftParg p p P c s p aunp p a c s

liftPc GPro cess GPro cess

Pro cess s Pro cess s

liftPc p p P c s p unp p c s

We also need to lift stateless pro cesses into stateful ones

liftP GPro cess Pro cess s

liftP p P c s p

The op erations for creating a wire and transmitting a message are straightfor

ward to lift

primWire Wire a Pro cess s Pro cess s

primWire liftParg primWire

primTx Out o o Pro cess s Pro cess s

primTx o m liftPc primTx o m

We will also need an auxiliary function to downgrade a stateful pro cess to a

function from state to a stateless pro cess

down Pro cess s s GPro cess

down P p s p s primTerminate s

When lifting primFrom we must ensure that the guarded pro cesses get access to

the state Guarded stateful pro cesses are therefore guarded stateless pro cesses

parameterised over the state

typ e AGuarded s s AGuarded GEvent GCommand

typ e Guarded s AGuarded s

primFrom In m m Pro cess s AGuarded s

primFrom i p s primFrom i m down p m s

In primRx we apply the state to each guarded pro cess revealing the stateless

guarded pro cesses that primRx accepts

primRx Guarded s Pro cess s

primRx gs P c s primRx g s g gs

The remaining primitive op erations are straightforward to lift

Gadgets in Fudgets

primTerminate Pro cess s

primTerminate P c s primTerminate

primSpawn Pro cess a a Pro cess s Pro cess s

primSpawn p s p liftPc primSpawn down p s p

primLaunch Pro cess s s GPro cess

primLaunch p s primLaunch down p s

Simulating Gadget inputoutput

To complete the functional implementation of the Gadget primitives we still

must dene mouse screen and keyb oard We use the streampro cessor in

putoutput to mediate the events and commands fromto the mouse keyb oard

and screen

data GEvent ME MouseEvnt KE Keyb oardEvnt SE ScreenEvnt

data GCommand MC MouseCmnd KC Keyb oardCmnd SC ScreenCmnd

Each device is controlled by two pro cesses the output hand ler which injects

commands received on a wire into the typ e GCommand and outputs them and

the input hand ler which inputs events extracts those sp ecic for the device and

transmit them on a wire These two handlers run in parallel This is captured

with the deviceHandler

deviceHandler c GCommand GEvent Mayb e e

In c Out e Pro cess s

deviceHandler inj extract cw ew

liftP primSpawn ohandler ihandler

where ohandler primRx primFrom cw cmd

put inj cmd ohandler

ihandler get i

case extract i of

Just evt primTx ew evt

ihandler

Nothing ihandler

We can now form our devices

keyb oard In Keyb oardCmnd Out Keyb oardEvnt Pro cess s

keyb oard deviceHandler KC i case i of KE e Just e

Nothing

mouse In MouseCmnd Out MouseEvnt Pro cess s

mouse deviceHandler MC i case i of ME e Just e

Nothing

screen In ScreenCmnd Out ScreenEvnt Pro cess s

screen deviceHandler SC i case i of SE e Just e

Nothing

Discussion

Figure Example of wire queue length proles provided by the Gadgets

inFudgets implementation Each prole represents one wire its height is pro

p ortional to the length of the queue of messages waiting to b e delivered The

picture is a snapshot of the computation by pressing the button a new snapshot

is taken The time axis is the one growing into the graph

Outside the Gadget stream pro cessor the screen commands are transformed into

corresp onding Fudget drawing commands whereas the keyb oard and mouse

control commands are ignored Conversely Fudget keyb oard presses mouse

clicks and screen exp osure events are transformed into GEvent messages This

is done in the fudget gadgetF of typ e

gadgetF Gadget F a b

Note that the highlevel streams of gadgetF are unused It would b e nice to use

them for communication b etween gadget pro cesses and the rest of the fudget

program but this is not p ossible in a typ esafe way The reason is that such a

communication could b e used to exchange wires b etween dierent instances of

gadgetF Each gadgetF has its own scheduler and mixing wires b etween sched

ulers is not typ e safe

Discussion

For the functional programmer the Haskell implementation of a Gadget sched

uler seems attractive Dierent scheduling principles can b e implemented and

compared Proling to ols can b e added also in Haskell For example it might

b e interesting to see how the wire queue length evolves over time Figure

A disapp ointment is that we are not able to safely typ e check all parts of the

scheduler Nevertheless we b elieve that the Haskell implementation is more

typ e safe than the original scheduler which was written in C

The functional scheduler also has a serious p erformance problem for certain

pro cesses If a pro cess dynamically creates wires sends messages to them and

then forgets them the wire queues cannot b e garbage collected The functional

scheduler can never know if a pro cess drops its reference to a wire

A remedy for these problems is to use lazy state threads LPJ and their

imp erative variables for representing the queues

V Applications

One strong motivation b ehind the development of Fudgets was practical useful

ness that is we wanted to b e able to write serious applications with graphical

user interfaces in a declarative style in a pure functional language Hand in

hand with the development of the library we have therefore develop ed a num

b er of small and large applications

To give you some idea of what the p otential of the fudget library is and

to discuss various practical programming considerations this part presents in

varying detail some applications we have implemented using Fudgets

Figure WWWbrowser a simple web browser implemented using fudgets in

It supp orts inlines images and forms

WWWBrowser a WWW client

A go o d example of an application that makes full use of all asp ects of the Fudget

library is a WorldWideWeb client It displays hyp ertext do cuments with em

b edded images and GUI elements to implement llin forms The do cuments

are obtained from various information sources on the Internet through proto cols

like ftp nntp gopher and http

In this section we will take a lo ok at how such an application can b e im

plemented on top of the Fudget library in Haskell An actual implementation

called WWWBrowser was done mainly during the summer Some up dates

and improvements were made in the summer A window snapshot is shown

in Figure The version of WWWBrowser had the following features

 It accepted most of HTML the HTML standard in use in

including

llin forms

inlined images le formats gif jp eg xbm pnm

 It supp orted the usual proto cols http gopher ftp news lo cal

WWWBrowser a WWW client

lesdirectories

 It fetched multiple inlined images in parallel This made WWWBrowser

faster than Mosaic the most widely used browser in when fetching

pages with many small images

 It simplied copy and paste of URLs You could mark a URL in eg a

text editor and then click with the middle mouse button in the browser

window to view that page

Some quick facts ab out the implementation

 The HTML input was parsed into an abstract syntax tree which was then

converted in several stages into drawing commands pro ducing text with

the appropriate layout font and other attributes This was done using

fudget kernels see Section written sp ecically for this purp ose

 The HTML parser was implemented using the fairly ecient backtracking

parsing combinators develop ed by Niklas Rjemo Rja for use in his

Haskell compiler To improve the tolerance of bad HTML an extra tag

balancing pass was added b etween the lexical analyser and the parser but

the parser still failed on some web pages

 Form elements and images were implemented as ordinary fudgets placed

appropriately in the text Their sizes aect the layout

 Image conversion eg decompressing gif and jp eg was done by calling

external programs giftoppm etc

 Image pro cessing color remapping and optionally dithering was done

in Haskell

 Program size approximately lines of Haskell

 Implementation time approximately man month

The following was changed and added in

 The source co de was translated from Haskell to Haskell

 The parser was rewritten using a version of Swierstra Dup oncheels

deterministic errorcorrecting parsing combinators SD This parser

turned out to b e more elegant the extra tag balancing pass could b e

removed and more tolerant to bad HTML At the same time the parser

was up dated to accept most of HTML Eng The new parser ran

at roughly the same sp eed as the old one

 The rendering was done by translating the HTML into a Drawing see

Section using a function of the typ e Html Drawing roughly

The old tailor made fudget kernels were thrown out The fudget library

placer tableP was b e used to add supp ort for tables the table cell at

tributes rowspan and colspan were not supp orted yet

 The fudget layout system was improved with the capabilities to do para

graph lling and adjust the layout according to the width of the window

see Section

Overall structure of the current WWW browser

implementation

 Supp ort for background colors and background images was added

 Supp ort for fetching do cuments via a proxy was added A proxy is a server

that relays do cument requests Most WWW browsers can b e congured

to fetch all do cuments via a proxy instead of fetching them directly from

the server that has the do cument

 Image fetching conversion and pro cessing was moved to a separate pro

cess allowing the text of a page to b e displayed and b e sensitive to clicks

b efore the images have b een loaded Part of the page may b e redrawn

when the size of an image b ecomes known With a parallel implementa

tion of fudgets you would get this for free

 Exp erimental supp ort for fupplets functional applets was added Fup

plets are applets written in Haskell using the Fudget library

 WWWBrowser can now read the b o okmark le created by Netscap e Netb

and display it in a hierarchical menu

 The program size now is approximately lines

Overall structure of the current WWW browser im

plementation

WWWBrowser is implemented in a straightforward way The key data typ es

are not surprisingly URL and Html The key op erations on these typ es are

data URL

data Html

parseURL String Mayb e URL

showURL URL String

joinURL URL URL URL

parseHtml String Either ErrorInfo Html

drawHtmlDo c URL Html HtmlDrawing

typ e HtmlDrawing Drawing details in Section

Do cuments are fetched from their lo cation on the web by the fudget urlFetchF

urlFetchF F HttpRequest HttpResp onse details in Section

data HttpRequest HttpReq reqURLURL

data HttpResp onse HttpResp respBo dyString

The fudget urlFetchF handles several proto col b esides the HTTP proto col but

since HTTP is the primary proto col on the WWW it was the one that was

implemented rst The fudgets for other proto cols were then implemented with

the same interface

Do cuments are displayed by the fudget htmlDisplayF

htmlDisplayF F URLHtml HttpRequest

WWWBrowser a WWW client

wwwBrowserF

httpMsgDispF

lo opThroughRightF urlFetchF mainGuiF

menusF

where

mainGuiF urlInputF srcDispF

urlHistoryF htmlDisplayF toHtml

httpMsgDispF

nameF MsgDisp Progress labLeftOfF displayF

urlFetchF p ost urlFetchF stripEither

where

p ost msg

urlInputF parseURL stringInputF showURL

srcDispF

urlHistoryF

Figure wwwBrowserF the main fudget in WWWBrowser

which displays HTML do cuments received on the input and outputs requests for

new do cuments when the user clicks on links in the do cument b eing displayed

Not all do cuments on the WWW are HTML do cuments Other typ es of

do cuments for example plain text gopher pages ftp directory listings and

Usenet news articles are handled by converting them to HTML

toHtml URL HttpResp onse URLHtml

The function toHtml uses parseHtml and other parsers

Using the comp onents presented ab ove we can create a simple web browser

by something like

simpleWebBrowser

lo opF htmlDisplayF mapF toHtml urlFetchF

But in addition to the HTML display WWWBrowser provides backforward

buttons an URLentry eld a history window a b o okmarks menu a do cument

source window and a progress rep ort eld The structure of the main fudget is

shown in Figure The layout is sp ecied using name layout see Section

Implementing Internet proto cols

The fudget urlFetchF is implemented as a parallel comp osition of fudgets han

dling the dierent proto cols This is shown in Figure The function distr

Implementing Internet proto cols

urlFetchF F HttpRequest HttpResp onse

urlFetchF snd listF fetchers distr

where

fetchers

leleFetchFreqURL local les and ftp

httphttpFetchF http and gopher requests

newsnewsFetchFreqURL

telnettelnetStarterFreqURL

distr reqHttpReq reqURLurl fetcherreq

where

fetcher

Figure The fudget urlFetchF

extracts the proto col eld from the request URL and sends the request to the

appropriate subfudget The implementation of the individual proto col fudget

kernels are written in continuation style For the http proto col the following

op erations are p erformed

A request is received in a highlevel input

The host eld of the URL is extracted and a so cket connection to that

host is op ened If a proxy is used a connection to the proxy is op ened

instead

The request is sent to the host or the proxy

The reply is received in chunks see Section and assembled and the

connection is closed

If a redirection resp onse was received the pro cess is restarted from step

with the redirection URL

If a normal or an error resp onse was received it is put in the highlevel

output stream

The implementation of the NNTP news proto col is similar A dierence is

that the NNTP proto col can handle several requests p er connection so the

connection is kept op en after a request is completed so that it can b e reused if

the next request is directed to the same host This is usually the case since you

normally fetch all news articles from the same lo cal news server It is p ossible

but uncommon to sp ecify a particular news server explicitly in the URL

The FTP proto col can also handle several requests p er connection and since

you are required to log in b efore you can transfer les it is even more b enecial

to reuse connections

The FTP proto col diers in that it uses a control connection for sending

commands that initiate le transfers and a separate data connection for each

le transfer The data connection is normally initiated by the server to a so cket

sp ecied by the client In the fudget implementation these two connections are

handled by two separate but co op erating fudgets

WWWBrowser a WWW client

Displaying HTML

HTML do cuments contain a sequence of elements which are delimited by tags

Elements can contain plain text and other nested elements For example

HThe fudget TThtmlDisplayFTTH

is an element tagged as a toplevel heading and it has a nested element marked

to b e displayed with a typ ewriter font

There is a distinction b etween blo cklevel elements and textlevel elements

The former mark up text blo cks that are to b e treated as complete paragraphs

They are thus comp osed vertically Heading elements are examples of blo ck

level elements The latter mark up arbitrary sequences of characters within

a paragraph Blo cklevel elements can contain textlevel elements as in the

example ab ove but not vice versa

WWWBrowser makes use of the distinction b etween blo cklevel and text

level elements This makes it easier to do the layout The function parseHtml

builds a syntax tree which on the top level is a sequence of blo cklevel ele

ments Plain text o ccuring on the top level outside any blo cklevel element

is understo o d as o ccuring inside an implicit paragraph P element So for

example

HThe fudget TThtmlDisplayFTTH

The implementation of

is parsed into the same syntax tree as as

HThe fudget TThtmlDisplayFTTH

PThe implementation ofP

With this approach the function drawHtmlDo c can simply recurse down the

syntax tree comp osing the drawings of blo cklevel elements using verticalP and

textlevel elements using paragraphP

Web pages contain not only text but also images and form elements In

WWWBrowser these are implemented by emb edding fudgets in the drawing

We intro duce the typ e ActiveDrawing for drawings containing active comp onents

and dene the typ e HtmlDrawing intro duced ab ove as

typ e HtmlDrawing ActiveDrawing HtmlLab el Gfx HtmlInput HtmlOutput

typ e ActiveDrawing lbl leaf i o Drawing lbl Either F i o leaf

where HtmlInput and HtmlOutput are the message typ es used by the fudgets

implementing images and forms Elements with sp ecial functionality are marked

with a lab el of typ e HtmlLab el Currently hyp erlinks link targets forms and

image maps are lab elled

To display ActiveDrawings a generalisation of graphicsF see Section

has b een dened

activeGraphicsF

F Either GfxCommand ActiveDrawing lbl leaf i o Inti

Either GfxEvent Into

Fetching images in parallel

The fudget htmlDisplayF uses activeGraphicsF to display HTML do cuments It

also contains

 a stream pro cessor that collects the contents of form elements and gen

erates the appropriate HttpRequest when the submit button of a form is

pressed

 an instance of the fudget imageFetchF describ ed b elow that the image

fudgets communicate with to obtain the images they should display

Fetching images in parallel

Images in HTML do cuments are included by reference using URLs and are

fetched from their sources separately The fudget htmlDisplayF uses the fudget

imageFetchF for this

imageFetchF F ImageReq ImageReqImageResp

typ e ImageReq URLMayb e Size

typ e ImageResp SizePixmapId

The requests handled by imageFetchF contain the URL of an image to fetch and

an optional desired size to which the image should b e scaled The resp onses

contain the actual size after scaling and a pixmap identier

Since do cuments may contain many images and the time it takes to fetch an

image often is dominated by network latency rather than bandwidth limitations

it makes sense to fetch several images in parallel The fudget parServerF

parServerF Int F req resp F req resp

is a generic fudget for creating servers that can handle several requests in par

allel If serverF is a fudget that handles requests sequentially with a corre

sp ondence b etween requests and resp onses then the fudget parServerF n serverF

handles up to n requests in parallel

Clients of parServerF must have some way of telling which resp onse b elongs

to which request since the order in which the resp onses are delivered is not

guaranteed to corresp ond to the order in which the requests are received The

fudget imageFetchF accomplishes this by including the requests in the resp onses

We also want to avoid fetching the same image twice This is solved by using

a caching fudget

cacheF Eq req F req reqresp

F clientreq clientreqresp

In addition to caching resp onses it keeps track of multiple clients and avoids

sending the same request twice to the server even if two clients send the same

request at the same time This situation arises easily in htmlDisplayF since it

is common for the same image to o ccur in several places in the same HTML

do cument

In WWWBrowser a comp osition like this is used to fetch images

cacheF parServerF imageFetchF

The implementation of parServerF is shown in Figure The implementation

of cacheF is shown in Figure

WWWBrowser a WWW client

parServerF Int F req resp F req resp

parServerF n serverF

lo opThroughRightF absF ctrlSP serversF

where

serversF listF iserverF ins n paral lel servers

ns n server numbers

ctrlSP ctrlSP ns

The argument to ctrlSP is a list of currently free servers

ctrlSP servers

case servers of

If al l servers are busy wait for a response

getLeftSP fromServer

If there is a free server

sservers getSP either fromServer fromClient

where

fromClient req

When a requests is received send it to the

rst server in the free list and continue

with the remaning servers stil l in the free list

putSP Left sreq ctrlSP servers

where

fromServer nresp

When a response is received from a server

output it and add the server to the free list

putSP Right resp ctrlSP nservers

Figure The fudget parServerF

Fetching images in parallel

cacheF Eq req F req reqresp F clientreq clientreqresp

cacheF serverF lo opThroughRightF absF cacheSP serverF

cacheSP cache p ending

getSP either answerFromServerSP requestFromClientSP

where

requestFromClientSP nreq A request from client n

asso c oldSP newSP cache req

where

oldSP ans The answer was found in the cache

putSP Right nreqans

cacheSP cache p ending

newSP A new request send it to the server and

add the client to the pending list

if req elem map snd p ending

then cont

else putSP Left req cont

where

cont cacheSP cache nreqp ending

answerFromServerSP ansreq

The server delivered an answer to request req

save it in the cache

forward it to waiting clients and remove them from

the pending list

putsSP Right nans nready

cacheSP anscache p ending

where

readyp ending part reqsnd p ending

Figure The fudget cacheF

WWWBrowser a WWW client

Discussion

A drawback with WWWBrowser as compared to other mo dern browsers is

that it do es not display do cuments incrementally as they are received from the

network This is due to several facts

 The current design of urlFetchF do es not output anything until it has

received the complete do cument

 Even if urlFetchF was changed to output chunks as they are received you

would have to concatenate all the pieces b efore you apply the function

parseHtml to it

 The fudget htmlDisplayF is implemented with graphicsF When graphicsF

receives a new drawing to display it computes its size and adjusts the

window size accordingly b efore it draws anything in the window This

means that it needs the complete drawing b efore it can display anything

One way of achieving incremental display of received do cuments would b e to let

urlFetchF output a resp onse containing the do cument as a lazy list of characters

as so on as it b egins receiving it from the server This would allow you to apply

the parser and the drawing function immediately and send the resulting drawing

to graphicsF The parser parseHtml and drawing function drawHtmlDo c must b e

carefully constructed to b e lazy enough to pro duce some output even when only

an initial fragment of the input is available You would also have to change

graphicsF so that it do es not start by computing the size of the drawing It

should instead lazily compute drawing commands see Section to send

to the window system The size of the window should b e adjusted regularly

according to where the drawing commands generated so far have drawn

The ab ove solution seems to require the intro duction of some mechanism for

indeterministic choice since while the drawing commands for the do cument are

b eing computed and output the program should to continue to react to other

input

However the trend in IO systems for functional languages go es towards

making IO op erations more explicit Even the Fudget library has abandoned

the representation of streams as lazy lists in favour of a simpler deterministic

implementation Using a lazy list for input as ab ove is thus a step in the

opp osite direction However to program indeterministic systems on a high level

of abstraction streams as lazy lists seem to b e useful

One can of course think of ways of achieving incremental display without

doing input in the form of lazy lists

 We could let urlFetchF output chunks of characters as they b ecome avail

able

 We could create a parsing library that creates parsers in the form of stream

pro cessors The typ e of the function parseHtml would then b e SP String

Html instead of String Html However we will not achieve incremental

display if we continue to output the syntax tree of whole do cument in

one message We would instead have to output a sequence of do cument

fragments

Discussion

 The input of the fudget htmlDisplayF would b e do cument fragments in

stead of complete do cument We are thus moving one step in the direction

of an HTML editor instead of a simple display

But it do es not seem like go o d software engineering to have to create a dier

ent parsing library just b ecause we want to use the constructed parsers in an

interactive program but sticking to the philosophy b ehind the Haskell IO it

seems that this is what we would have to do

The conclusion we draw from this is that the current IO system in Haskell

do es not integrate well with laziness

Alfa a pro of editor for typ e theory

Figure Window dump of Alfa illustrating the construction of a simple pro of

in natural deduction style

Alfa a pro of editor for typ e theory

Alfa is a WYSIWYG pro of editor It allows you to interactively and incre

mentally dene theories axioms and inference rules formulate theorems and

construct pro ofs of the theorems All steps in the pro of construction are imme

diately checked by the system and no erroneous pro ofs can b e constructed The

logical framework used is one of Thierry Co quands versions of Per MartinLf s

Typ e Theory

Alternatively you can view Alfa as a syntaxdirected editor for a small purely

functional programming language with a typ e system that provides dep endent

typ es The editor immediately checks that programs you enter are syntactically

correct and typ e correct

Alfa is largely inspired by WindowAlf AGNvS implemented by Lena

Magnusson and Johan Nordlander and has a similar user interface

The plan is that Alfa should improve on WindowAlf by

 allowing the user to dene how pro of terms should b e presented on the

screen and on pap er This includes simple things like argument hiding

and inx op erators but also more advanced mathematical notation and

natural deduction style pro of trees and other representations of pro ofs

Alfa should also allow you to pro duce do cuments where explanatory text

and pro of fragments are interleaved

 using ideas from hyp ertext and Web browser to allow the user to eciently

navigate through large pro ofs and libraries

Some of this has b een implemented As shown in Figure pro ofs can b e

presented in natural deduction style

Whereas WindowAlf was implemented in Standard ML pro of engine and

C Interviews user interface Alfa is implemented entirely in Haskell

using Fudgets for the user interface At the time of writing the source co de

consists of ab out lines distributed as follows

Figure The smiley indicates whether there is a syntactic error in the input

 The pro of engine by Thierry Co quand lines This includes a parser

and parser combinators lines

 Extensions and improvements of the Fudget library lines The

largest part of this is the new fudgets for displaying structured graphics

describ ed in Chapter and syntaxdirected editing It also includes

a new leselection window and a stringentry window with immediate

syntax checking and feedback via a smiley see Figure Although the

development of these were prompted the Alfa pro ject they are general

enough to b e used in other contexts

 The Alfa User Interface lines The largest parts are the implementa

tion of the WYSIWYG style editing op erations lines and the co de

for drawingbuilding abstract syntax trees used by the syntaxdirected

editor fudget lines

In addition Aarne Ranta has supplied lines with supp ort for natural lan

guage Some of this co de had b een integrated in Alfa but this work was in a

rather exp erimental stage

More detailed and uptodate information on Alfa is available on the WWW

Hal

Humake a distributed and parallel make to ol for Haskell

Figure The user interface of Humake

Humake a distributed and parallel make

to ol for Haskell

Humake is a to ol for compiling Haskell programs It allows indep endent mo d

ules to b e compiled in parallel p ossibly on dierent computers It has a graph

ical user interface see Figure where the progress of the compilation can

b e monitored and information on individual mo dules can b e obtained The

mo duledep endency graph is automatically extracted from the source co de The

dep endency graph lemo dication dates and other mo dule information is re

tained b etween compilations and can b e dynamically up dated when a mo dule is

changed to minimise the work required to start a recompilation and thus make

the editcompiletest development cycle faster In the current version the user

interface shows

 a mo dule list where the status of each mo dule is indicated by a colored

lamp The color is green if the mo dule is uptodate yellow if it is b e

ing compiled or waiting to b e compiled b ecause it is out of date with

resp ect to its source co de or the interface of an imp orted mo dule red if

compilation of the mo dule failed and blue if the mo dule was taken from

a precompiled library A menu allows you to cho ose from a numb er of

dierent sorting orders

 a mo dule information window which shows imp orted mo dules mo dules

that imp ort this mo dule le lo cation and mo dication dates

 an up date button which makes Humake reread the mo dule information

after it has b een changed Humake can also receive change notications

directly from a text editor This has b een implemented for Emacs

 a list showing which mo dules are currently b eing compiled and how many

mo dules are currently waiting to b e compiled

Implementation

main fudlogue shellF Humake humakeF

humakeF

loopLeftF mo duleInfoFparallelCompileF dep endencyF

editorInterfaceF

GUI fudgets

statusDisplayF the bottom part of the window

mo duleInfoF the module list module info and the update buttons

NonGUI fudgets

parallelCompileF

lterRightSP statusDisplayFidF

lo opThroughRightF absF ctrlSP parServerF hosts compileF

where

ctrlSP

parServerF id idF req resp F req resp

parServerF ids serverF essential ly as in Figure

compileF String F CompilerReq CompilerResp

compileF host a compilation server

editorInterfaceF F a String

editorInterfaceF outputs the name of a le when it is saved

Figure Implementation of Humake

Implementation

The structure of the implementation is sketched in Figure Most of the work

is handled by the fudget dep endencyF It traverses the mo dules to extract the

mo duledep endency graph and builds a representation of it It also maintains a

data structure representing the status of the compilation pro cess This structure

is chosen so that when a compilation completes or a mo dule is up dated a new

compilation can b e started as quickly as p ossible

The source is ab out lines long

Space Invaders realtime and simulation

Figure Space Invaders a typical interactive realtime game

Space Invaders realtime and simulation

This section illustrates how the Fudget system can b e used to write realtime

interactive games This shows that the Fudgets GUI to olkit is not limited

to traditional fairly static graphical user interfaces but also allows you to

construct interfaces with lots of animated ob jects By structuring the program

with one concurrent pro cess one fudget p er animated ob ject the program can

b e seen as a mo del that simulates some realworld ob jects and the way they

communicate

Space Invaders

We start with a brief description of the classical game Space Invaders Only

the most fundamental parts of the game have actually b een implemented In

this game an army of invaders from outer space is approaching the earth The

player must sho ot them all down b efore they reach the surface Some p oints

are added to the players score for each invader that is shot down The player

controls a gun which can b e moved horizontally at the b ottom of the screen

the surface of the earth and which can re vertically The invaders initially

move from left to right When the rightmost invader reaches the right edge

of the screen all invaders rst move downwards a small distance then move

horizontally again until the leftmost invader reaches the left edge and so on

Structure of the SpaceInvaders implementation

In this section we describ e an implementation of Space Invaders where the each

ob ject is implemented as a fudget The ob jects are

Structure of the SpaceInvaders implementation

Int Point Point XEvent

spaceInvadersF =

scoreF invadersF torpedoF gunF spaceF

InvaderMsg Int Point+Tick Point

invadersF =

listF [invaderF n | n<- ...] shoutSP tempoF

Figure The pro cesses and their interconnection in the SpaceInvaders im

plementation

spaceF the space fudget This is the black background in which all the

other ob jects move around

gunF the gun

torp edoF the torp edo es red by the gun

invaderF a numb er of invaders

There is also scoreF which displays the current score and a highscore gunF

and torp edoF use timers internally to control the sp eed of their motion To

co ordinate the motion of the invaders they are controlled by a common timer

which is lo cated in a windowless fudget called temp oF There is also an abstract

fudget called shoutSP which broadcasts timer alarms and other input to all

invaders

Section illustrates how the fudgets are interconnected The information

ow is as follows the space fudget outputs mouse and keyb oard events to gunF

This allows the user to place the mouse p ointer anywhere in the window to

control the gun The gun resp onds to these events by starting or stopping its

movement or by ring a torp edo When the gun is red it outputs its current

p osition to the torp edo fudget The torp edo then starts moving upwards from

that p osition When it hits something it outputs its current p osition to the

invaders Each invader then checks if the hit is within the area it o ccupies on

the screen and if so it removes its window and dies

Below we take a closer lo ok at invaderF The other fudgets are just variations

on a theme so we will not discuss them further

The fudget invaderF maintains an internal state consisting of the following

parts the current p osition a Point the current direction left or right if it

is time to turn ie move downward at the next timer alarm and then change directions

Space Invaders realtime and simulation

The invaders sp eak the following language

data InvaderMsg Tick Turn Hit Point Death IntInt

When an invader hears a Tick it moves one step in the current direction It

also checks if it has reached an edge in which case it outputs Turn which is

received by all invaders When an invader hears a Turn it rememb ers that it is

time to turn at the next Tick When a torp edo has hit something at p osition

p all invaders receive Hit p and check if p is within their screen area If so it

outputs Death n where n is the identity of the invader This identity is recorded

by shoutSP so that it do es not have to shout to dead invaders It is also used

to determine how many p oints to add to the score

The fact that all ob jects are implemented as group fudgets means that each

ob ject has its own X window To move an ob ject you move its window No

drawing commands need to b e output

How do es the torp edo know if it has hit something The torp edo is a window

which moves b ehind all other windows This means that it b ecomes obscured

when it hits something The X server sends a VisibilityNotify event when this

happ ens This causes the torp edo to stop and send its current p osition to the

invaders Nice hack isnt it But isnt there a timing problem And what if

the torp edo is obscured by some other application window We leave it to the

reader to p onder over this

Ab out the eciency of the SpaceInvaders implemen

tation

One ma jor p oint of the Fudget system and of functional programming in gen

eral is to simplify and sp eed up program development But it is of course also

imp ortant that the eciency of the resulting program is acceptable

We have measured the CPU time consumption of the SpaceInvaders imple

mentation describ ed ab ove running on a Sparcstation IPX in a situation where

invaders move twice p er second the gun and the torp edo move every ms

The average CPU load was approximately of this was consumed by

the X server As a comparison the program xinvaders a C program imple

mented directly on top of Xlib consumes less than CPU time in a similar

situation

As usual programming on a higher abstraction level results in a less e

cient solution Part of the ineciency comes from the use of Haskell and the

Fudget system The load on the X server comes from the fact that the mov

ing ob jects are represented as windows Not surprisingly moving a window is

a more exp ensive op eration than just drawing an image of the same size But

using techniques outlined in the next section it is p ossible to rewrite the Fudget

program to draw in a single window like the C program and still keep the same

nice program structure ie one pro cess p er moving ob ject

Ab ove we compared the eciency of a highlevel implementation using the

Fudget system of the game with a lowlevel implementation It would also b e

interesting to compare other user interface to olkits eg Motif and Interviews

to the Fudget system

The CPU time consumption gures ab ove do not say much ab out the real

time b ehaviour of the two implementations The fact is that the C program

Replacing fudgets with stream pro cessors for eciency

meets the realtime deadlines but the Fudget program do es not As a resp onse

to a Tick from temp oF all invaders should move one step Computing and

outputting MoveWindow commands unfortunately takes longer than ms

which means that the MoveWindow commands for the gun and the torp edo will

b e output to o late resulting in a jerky motion This problem can b e solved

in at least two dierent ways manually by not moving all invaders at the

same time and thus not blo cking output from other fudgets for longer than

ms automatically from the p oint of view of the application programmer

by intro ducing parallel evaluation and some kind of fair indeterministic merge

of the output from dierent fudgets The latter solution is of course the more

general one and we hop e to improve the Fudget system in this direction

Replacing fudgets with stream pro cessors for eciency

Ab ove we outlined a program structure where each moving ob ject on the screen

is represented as fudget with an asso ciated window on the screen It is of course

p ossible to use fudgets for other kind of simulations where the ob jects do not

corresp ond to user interface elements

The b ehaviour of a single fudget is usually implemented as a sequential

program by using the streampro cessor op erators putSP getSP and nullSP To

increase the eciency of our space invaders implementation we can instead

structure the program as one fudget whose b ehaviour is describ ed by some

comp osition of stream pro cessors This increases the eciency in two ways

 The communication b etween stream pro cessors is cheap er less tag

ginguntagging

 The numb er of windows is reduced This means that conversions b etween

paths and window identiers in fudlogue Section will b e somewhat

cheap er and that the load on the X server is reduced since windows will

not b e moved

In Section the input to the invaders is broadcast to all invaders We im

plemented this using listF tagged parallel comp osition and a separate stream

pro cessor shoutSP Some overhead can b e avoided by using untagged parallel

comp osition of stream pro cessors instead

SP a b SP a b SP a b

This also makes it easy to write stream pro cessors that dynamically split into

two or more parallel pro cesses One of the pro cesses in a parallel comp osition

can terminate without leaving any overhead b ehind since

nullSP sp sp nullSP sp

Doing the same with pro cesses represented as fudgets would not give you the

same eciency advantage since the lowlevel streams remain tagged even in

untagged parallel comp ositions Thus when one pro cess in a parallel comp osition

terminates some tagging overhead will remain

The fact that parallel comp ositions can reduce to nullSP gives us an opp or

tunity to make use of the sequential comp osition op erator seqSP Section

in an interesting way Supp ose that all that is needed to start a new level in

Space Invaders realtime and simulation

the game is the creation of a new army of invaders Then the b ehaviour of the

game could b e programmed in the following way

playGameSP playLevelSP

playLevelSP level startNewLevelSP level seqSP playLevelSP level

startNewLevelSP level invaderArmySP level

invaderArmySP level creates a paral lel composition of invaders

When the last invader in the invader army dies the parallel comp osition will b e

reduced to nullSP which causes seqSP to invoke the next level

FunGraph

FunGraph is a prototyp e implementation of a typ ed visual programming envi

ronment inspired by the commercial pro duct ProGraph

A screen dump of FunGraph is shown in Figure Basically FunGraph is a

freeform spread sheet with typ es where the user can place and connect ob jects

such as cells sliders and graphs at will The ob jects have input connectors on

top and output connectors b elow

FunGraph was develop ed b efore the fudget graphicsF of Section was

implemented Instead graphics where implemented with ne grained fudgets

so to sp eak Each ob ject is implemented with a numb er of fudgets So each pin

is a separate fudget for example The ob jects reside in a dynListF placed in a

group window which controlled the wires All messages from the output pins of

the ob jects are routed by the group windows kernel and lo op ed back into the

dynListF so that the values seem to follow the wires

FunGraph

Figure A screen dump of the program FunGraph Two sliders controls

amplitude and frequency of a sine function dened in a cell This function is then

visualised in a graph The bubble window implemented by bubbleRo otPopupF

shows the typ e of the pin that the user p oints at for the moment which happ ens

to b e the left input pin of the graph ob ject It has the typ e Num Num which

is the typ e of the functions that the graph ob ject can display

The cell also shows the visual eect of one of the lter fudgets in the library

which is called the shap eGroupMgr The cell is currently b eing selected which

is indicated by a yellow glowing b order around it This eect is achieved by

wrapping a shap ed window whose b order tightly follows the fudgets inside it in

this case three pin fudgets and one stringF The b order of the shap ed window

is yellow and its width is set to zero when the ob ject is deselected or a couple

of pixels as is the case with our cell The shap eGroupMgr ensures that the shap e

of the yellowb order window tightly follows the contour of the wrapp ed fudgets

by analysing the CongureWindow commands that they output

Figure The user interface of the proto col prototyping to ol

A mobile data communication proto col proto

typing to ol

In collab oration with Carlstedt Research Technology AB and Eritel AB we

develop ed a prototyping to ol for testing and mo delling communication proto cols

in the mobile data network Mobitex A screen dump of the to ol is found in

Figure and shows a conguration with three radio base stations each which

covers a triangular area The small circular ob jects are mobile users Roaming

of the users b etween base station areas is simulated using the draganddrop

feature from Chapter

Two b oard games

Figure The Explo de game

Two b oard games

We have implemented two b oard games Explo de Figure and Othello Fig

ure using Fudgets

The two games use the same underlying combinators for implementing the

b oard The rst is a button that can display changing graphics

b oardButtonF ColorGen bgcolor Graphic gfx

bgcolor Size F gfx Click

b oardButtonF bg size

buttonF setBgColor bg g blankD size Left setLab el g

where buttonF is the dynamically customisable see Section version of

buttonF and setLab el is a customiser that changes the button lab el

The second combinator is b oardF

typ e Co ord IntInt

b oardF Co ord Co ord F a b F Co orda Co ordb

b oardF wh squareF

placerF matrixP w

listF xysqF xy yhxw

which given the size of the b oard and a function from the co ordinates of a

square to a fudget implementing that square creates a parallel comp osition of

square fudgets with the appropriate layout The square fudgets are addressed

with their co ordinates

The Explo de Game

Figure The Othello game

The Explo de Game

Before the GUI Festival in Glasgow a workshop on graphical userinterface

to olkits and functional programming Car a numb er of progamming chal

lenges were distributed to the participants One of the challenges was to imple

ment the Explo de game

In the Explo de game two players take turns placing stones or atoms in

the squares of a b oard A player can not place atoms in a square that already

contains atoms from the opp onent When a square is full that is contains

as many atoms as it has neighb ours it explo des sending one atom to each

neighb our All atoms of the invaded square change color to the invading atoms

color Invaded squares may b ecome full and explo de in turn When the b oard

has settled a new move can b e entered When the b oard starts to get full of

atoms placing a new atom may cause an innite chain reaction When this

happ ens the game is over and the player who caused it is the winner

The Fudgets implementation of the Explo de game

The Fudgets implementation of the Explo de game was done as shown in Fig

ure Comments

 The lo op on the top level together with routeSP allow all square fudgets to

communicate with each other However each square knows its co ordinates

and send messages only to its neighb ours The actual communication

structure is thus not directly reected in the program structure

 routeSP also acts as a referee It keeps track of whose turn it is to b e

able to discard illegal moves This is also where you would put a test for

Two b oard games

main fudlogue shellF Explo de explo deBoardF

explo deBoardF

lo opF absF routeSP b oardF b oardSize b oardSize atomsSquareF

where

routeSP concatMapAccumlSP route White

route side srcmsg

case msg of

ClickedWhileEmpty otherSide side srcside

ClickedWithColor side

if sideside

then otherSide side srcside

else side il legal move

Explo de dsts side side dstsidedstdsts

atomsSquareF Co ord F AtomColor SquareEvent Co ord

atomsSquareF xy

lo opThroughRightF absF ctrlSP atomsButtonF

where

ctrlSP concatMapAccumlSP ctrl Nothing

ctrl soldcntoldside msg

case msg of

Left Click sRight case oldside of

Just side ClickedWithColor side

Nothing ClickedWhileEmpty

Right side

let cntoldcnt

in if cntsize

then b ecome cntsize side explo demsgs side

else b ecome cnt side

b ecome cnt side msgs cntoptsideLeft cntsidemsgs

where optside if cnt then Nothing else Just side

size length neighb ours

explo demsgs Right Explo de neighb ours

neighb ours lter insided xyxyxyxy

insided xy inside x inside y

inside x x xb oardSize

atomsButtonF F Numb erOfAtomsAtomColor Click

atomsButtonF b oardButtonF bgColor sqsize drawAtoms

drawAtoms countcolor lines

Figure Fudgets implementation of the Explo de game

The Explo de Game

explosions involving all squares which should end the game Otherwise

all the work is done by the squares themselves

 Square fudgets receive input when they are invaded by an atom Square

fudgets pro duce output in the typ e SquareEvent

data SquareEvent dest

ClickNoColor

ClickColor AtomColor

Explo de dest AtomColor

where the messages mean

ClickNoColor I was clicked and I was empty routeSP then replies

with an atom of the appropriate color dep ending on whose turn it

is

ClickColor color I was clicked and my color was color If the color

matches with color of the current player routeSP replies with an atom

of that color otherwise the message is ignored some indication of an

illegal move could b e pro duced

Explo de square color I explo de and invade square with color

routeSP forwards the message to the square at square messages

of this kind are sent when a square explo des

The square fudgets also communicates with the internal atomsButtonF

 The auxiliary function drawAtoms in atomsButtonF pro duces the appro

priate graphical image for a square using the typ es FlexibleDrawing and

Drawing describ ed in Chapter

A comparison of the Fudgets and Gadgets versions of the

Exlo de Game

The submitters of the Explo de challenge also provided a solution using Gadgets

see Section Their solution see section in NR is similar to ours

in that the eects of the users moves are computed by message passing b etween

pro cesses representing the squares of the b oard In b oth solutions there is a

separate referee pro cess that for example keeps track of whose turn it is to

move

In the Fudgets solution the squares are in eect connected to all other

squares whereas in the Gadgets solution each square pro cess is connected

through wires only to its neighb ours As noted in NR combining fudgets to

achieve exactly this connectivity would b e dicult and it would probably also

b e dicult to add new pro cesses to such a solution

As describ ed ab ove in the current Fudgets solution each square fudget

knows its co ordinates and computes the co ordinates of its neighb ours It would

of course b e p ossible to parameterise the square fudgets by an abstract repre

sentation of the neighb ours instead

atomsSquareF address F AtomColor SquareEvent address

Two b oard games

and let routeSP compute the concrete addresses of the neighb ours This p erhaps

makes the communication pattern more visible in the program text and prevents

errors in the implementation of atomsSquareF from breaking the pattern

Since the Gadgets system uses indeterministic pro cess scheduling it is nec

essary to explicitly keep track of when an explosion is in progress and when the

b oard is stable since moves are allowed to b e entered only when the b oard is

stable The implementation of Fudgets is deterministic and internal communi

cation has priority over external communication so user input is automatically

queued until an explosion has subsided

The Othello Game

The fudgets version of the game Othello allows a human player to play against

the computer or another human player It was implemented by reusing an

existing implementation from with a TTYbased user interface of

lines were reused without changes Ab out new lines were added for the

new graphical user interface This demonstrates that the separation of user

interfacesp ecic co de and applicationsp ecic co de is go o d

In the implementation of the Explo de game we used a distributed solution

the work of computing the eects of the users moves is handled almost en

tirely by the square fudgets In the implementation of Othello we have taken

the opp osite approach the b oard fudget only displays the b oard and receives

user input The checking of the validity of a move and computation of its

eect is handled by a stream pro cessor attached in the typical way with the

lo opThroughRightF combinator see Section The structure of the pro

gram is

main fudlogue shellF Othello ottoF

ottoF

displayF

lo opThroughRightF absF newGameSP ottoBoardF

buttonF New Game

ottoBoardF F BoardReq Co ord

ottoBoardF

newGameSP playSP reptree moves startp os

playSP GameTree SP Either Co ord Click Either BoardReq String

playSP currentp osition

The function reptree lazily computes a game tree which has startp os as the ro ot

no de and where the children of a no de are obtained by applying the function

moves to it

The stream pro cessor playSP checks the current p osition for whose turn it is

to play and then either waits for the user to enter a move or computes a go o d

move for the computer using standard alfab eta gametree search

VI Discussion

Eciency and program transformations

Eciency and program transformations

Eciency considerations are of course imp ortant when building software li

braries Below we discuss some eciency asp ects of stream pro cessors that

have attracted our attention while working on the Fudget library

We can distinguish two kinds of eciency

 execution eciency programs should run reasonably fast

 programmer eciency programs should b e easy to write

While execution eciency was and to a large extent still is a weak p oint of

functional language implementations as compared to C for example program

mer eciency is a strong p oint and one of the reason why functional languages

are interesting in the rst place There is often a tradeo b etween the two

In the following section we will discuss in the context of the Fudgets system

how we obtain reasonable execution eciency We have not tried to quantify

programmer eciency in a way that p ermits further comparison or judgement

Execution eciency

Two factors that inuence how fast fudgets program run are

 the eciency of the interface to the window system X Windows in par

ticular eciency of event pro cessing

 the eciency of the fudget combinators

Eciency of the interface to the window system

The eciency of the interface to the window system was a concern right from

the start of the work on fudgets The initial implementation used conventional

text IO to talk to a C program which called routines in Xlib and returned the

results see Section The C program also forwarded events from X to

the functional program This was not a very ecient implementation and hence

we tried to minimise the amount of data passed b etween the window system

and the functional program Although this was done to avoid problems caused

by slow execution of functional programs an additional p ositive eect is that

fudget programs p erform well when using a low bandwidth connection eg

mo dem connection b etween the X server and the application Some gures to

back up this statement are given in Figure One can not draw any general

conclusions on p erformance from these of course

When it comes to event pro cessing we naturally wanted to to minimise the

numb er of events that has to b e handled by the functional program Fortunately

the X Windows system can do a lot of event pro cessing for the application By

setting event masks and button grabs appropriately you can often eliminate all

insignicant events ie all events that are sent to the application program carry

some meaningful information In simpler window systems the application has

to deal with every little mouse move and buttonkey pressesreleases by itself

Execution eciency

Two tiny programs

The Fudgets counter example from Section s

The Motif counter example from Figure s

Some small programs

The Fudget calculator from Section with buttons s

The Fudgets calculator Cla with buttons s

The calculator xcalc with buttons from X Windows distribution s

Some larger programs

The Fudgets WWW browser from Chapter s

Mosaic s

Netscap e s

Netscap e j s

Figure Comparing the startup times of some programs when running via

a kbps mo dem connection

As an example consider the implementation of a command

button It should b ehave as follows

 When the p ointer is over the area of the screen o ccupied by

the button and the user presses the mouse button the button image should

b e changed to lo ok depressed that is pressed down not discouraged If

the mouse button is released when the button app ears depressed the

button command is triggered

 If the mouse p ointer leaves the button image it should revert to its normal

raised app earance indicating that nothing will happ en if the user now

releases the mouse button If the user returns the p ointer to the button

image without releasing the mouse button the button should return to

its depressed app earance

The following typ e of events are thus of interest to the program

 Mouse button presses but only if the p ointer is within the command

button

 Mouse button releases but only if the mouse button has b een pressed

while the p ointer was inside the command button

 Mouse motion but only if the mouse button has b een pressed while the

p ointer was inside the command button and only if the p ointer crosses the

b order of the screen area o ccupied by the command button

In the X windows system a button grab see XGrabButton in the Xlib manual

with an event mask that selects button pressesreleases and enterleave window

events each GUI element is a window can b e used to select exactly these

events with only one small exception if the mouse p ointer enters the button

Eciency and program transformations

area the mouse button is pressed the p ointer leaves the button area and the

mouse button is released the program will receive an insignicant button re

lease event The imp ortant thing is that no unnecessary motion events will b e

received

Eciency of the Fudget combinators

Eciency of dierent representations of stream pro cessors

Two of the streampro cessor representations presented ab ove have b een used in

practice Early versions of the Fudget library used list functions and synthetic

oracles Section We later changed to the continuationbased represen

tation Section since it proved to b e slightly more ecient with the

compiler we used HBC Aug

We also tried a third representation

data SP i o StepSP o iSP i o

which was slightly less ecient than the continuationbased representation

In the discussion b elow we assume the continuationbased representation

although some of the ideas can b e carried over to other representations

Program transformations for eciency Using lo opThroughRight

Section is a general way to adapt an existing stream pro cessor for use in

a new context Another simple and common way to adapt a stream pro cessor

is by mapping a function on the elements of the input or output stream

sp mapSP g

mapSP f sp

For example tagged parallel comp osition of fudgets can b e dened like

fud fud

mapSP p ost fud fud mapSP pre

where pre and p ost are the appropriate retagging functions However if imple

mented directly such a denition has a rather high overhead

By transforming to a form not involving and mapSP but

instead recursion and pattern matching on the streampro cessor constructors a

more ecient solution can b e obtained

Programs transformations of this kind are tedious to do by hand but it could

still b e worthwhile if the resulting co de is to b e included in a library The ab ove

describ ed transformation has b een done by hand in the Fudget library We

measured the eect on a communication intensive fudget program containing

a parallel comp osition of fudgets the Space Invaders program describ ed in

Chapter The transformation reduced the CPU time consumption by over

Encouraged by this result we also transformed some more combinators

for example and discussed in Section in the same way

It would of course b e nicer to have these transformations done automati

cally esp ecially when they are needed in application programs The kind of

automatic transformation that would b e useful here is deforestation Wad

which eliminates intermediate data structures applications of PutSP and GetSP

in this case by using certain unfoldfold transformations

Execution eciency

A practical semiautomatic transformation Between the man

ual and fully automatic implementations of the ab ove program transformation

is a semiautomatic alternative It is interesting b ecause it requires less work

than the manual solution and it is more likely to b e supp orted by a compiler

than the fully automatic solution

The manual work required in this solution is lo cated in the library The

application programmer need not b e aware of it The automatic work required

is inlining unfold by the compiler It actually works even without inlining but

the eciency gain is not as big

The expressions we wish to optimise are of the kind illustrated ab ove a

streampro cessor combinator applied to mapSP f for some f The trick is to

make mapSP a constructor in the streampro cessor data typ e

data SP a b PutSP b SP a b

GetSP a SP a b

MapSP a b

NullSP

Since the typ e is abstract adding constructors to it like this will not b e visible

to application programmers

Now that MapSP is a constructor the implementation of serial comp osition

as shown in Figure can b e extended to handle the case when one or b oth

arguments are applications of MapSP in a more ecient way This means that

an expression like

MapSP f MapSP g

can evaluate to

MapSP f g

With inlining this step can b e taken by the compiler and the comp osition f

g can then b e optimised further Without inlining we have at least eliminated

a use of and thereby reduced the numb er of generated applications of

the PutSP and GetSP constructors

We have not tested the ab ove ideas in the Fudget library

Performance measurements To get some idea of how high the

communication overhead is in the fudgets system we p erformed some simple

measurements

The rst test measures the eciency of serial comp osition and compares

the op erators and We measured the time it to ok to

send around messages through a serial comp osition of a varying numb er of

identity fudgets or identity stream pro cessors The program used is shown in

Figure It was compiled with HBC and run on a Pentium Pro Mhz under

NetBSD Neta The results are shown in Figure We can see that the

time grows roughly linearly with the length of the comp osition and that serial

comp osition of fudgets is much more exp ensive than serial comp osition of stream

pro cessors

The last table in Figure shows the p erformance of the function comp osi

tion map id map id It is more ecient than the other serial comp ositions

Eciency and program transformations

imp ort Fudgets

main fudlogue mainF

mainF nullF tstF concatSP stdinF

tstF case argReadKey comb of

nest idF idF depth

nest idSP idF depth

absF nest idSP idSP depth

nest f z z

nest f z n f nest f z n

depth argReadKey depth

Figure A program to measure the eciency of serial comp osition

The second test measures the eciency of parallel comp osition We mea

sured the time it to ok to send ab out messages through one of the fudgets

in a parallel comp osition of identity fudgets The program used is shown in

Figure The parallel comp ositions were created by listF

listF Eq a a F b c F a b a c

which internally constructs a balanced binary tree of parallel comp ositions and

a table for translating the addresses of the fudgets to p ositions in the tree The

results are shown in Figure The depth of the tree and hence the time

it takes to send a message to a particular fudget in tree grows logarithmically

with the size of the parallel comp osition However since all that is known ab out

the address typ e is that it is an instance of the Eq class the table lo okup has

to b e implemented as a linear search and hence the lo okup time varies linearly

with the p osition in the list From the results we see that the time of the table

lo okup so on b ecomes the dominating factor This suggests that it would b e a

go o d idea to provide alternative combinators to listF which require the address

typ e to b e an instance of the Ord class or even the Ix class to reduce the time

complexity of the table lo okup time to logarithmic or constant resp ectively

Space eciency

A problem that almost inevitably o ccurs at some p oint when developing pro

grams in lazy functional languages is space leaks In early versions of the Fudget

library streams were represented as p otentially innite lists As discussed in

Section this gave us problems with streams b eing retained indenitely

eventually causing programs to run out of memory This problem was rst

solved by changing the way the compiler HBC treats pattern bindings as de

scrib ed in Spa Later the switch to the continuationbased representation

of stream pro cessors also eliminated the problem

Execution eciency

time Internal testinput S hM depth n

comb idF idF idF

n User time GCs GC time Max heap Max stack

u

u

u

u

u

comb idSP idSP idF

n User time GCs GC time Max heap Max stack

u

u

u

u

u

comb idSP idSP idSP

n User time GCs GC time Max heap Max stack

u

u

u

u

u

map id map id map id

n User time GCs GC time Max heap Max stack

u

u

u

u

u

Figure The eciency of serial comp osition

Eciency and program transformations

imp ort Fudgets

main fudlogue mainF

mainF nullF tstF concatSP stdinF

tstF listF iidF isize sel

size argReadKey size

sel argReadKey sel

Figure A program to measure the eciency of parallel comp osition

time Internal testinput size n sel k

k

n log n time GCs GC time max heap

u s

u s

u s

u s

n

k log n time GCs GC time max heap

u s

u s

u s

u s

Figure The eciency of parallel comp osition of fudgets

Comments on Haskell and other language de

sign issues

For the most part we have found Haskell to b e a pleasant language to work

with but there are a small numb er of features that we are not so pleased with

We discuss them b elow

Through exp eriences with other languages we have also realised that some

languages features not currently supp orted by Haskell would b e useful to have

The annoying monomorphism restriction

One of the most annoying features of Haskell when trying to program in a

combinatorial style is the monomorphism restriction It means that a denition

that is not syntactically a function is not allowed to b e overloaded unless an

explicit typ e signature is provided

As a simple example say that you are going to use the function show a lot

and want to intro duce a shorter name s say Because of the monomorphism

restriction you can not write

s show

There are two solutions you can provide a typ e signature

s Show a a String

s show

or you can etaexpand the denition

s x show x

In the Fudget library we have used the eta expansion trick whenever p ossible

since the inclusion of explicit typ e signatures just entail extra maintenance work

when the library is changed For example when a typ e is renamed or a function

is made more general an arbitrary numb er of typ e signatures may need to b e

up dated

Unfortunately the eta expansion trick can not always b e used b ecause not

all overloaded values are functions For example fudgets are not functions so

in case you want to intro duce a short name for displayF you have to use a typ e

signature

dF Graphic a F a b

dF displayF

Even more unfortunately there are cases when it is not p ossible to express the

typ e signature This o ccurs when the denition is lo cal to another denition

which is p olymorphic It can happ en that the lo cal typ e dep ends on typ e vari

ables in the outer denition but Haskell has no mechanism for expressing such

typ es explicitly Although these cases turn out to b e rare in practice it is a

principal aw of the language

Comments on Haskell and other language design issues

The Haskell string class system anomaly

An inelegance of Haskell is that you can not directly make the typ e String an

instance of a class This is due to the combination of two facts

 String is not a data typ e but a synonym for Char

 Instance denition can only b e made for uninstantiated typ e constructors

ie you can make instances for Char and for lists in general but you can

not make a particular instance for Char See JJM for a discussion of

class system design choices

This has aected the classes Graphic ColorGen and FontGen presented in Chap

ter and FormElement in Section At one p oint during the development

we avoided the problem by dening a data typ e that was used instead of strings

newtyp e Name Name String

but since this required the use of the constructor Name in a lot of places we

later resorted to the same hack that is used for the Haskell classes Show and

Read ie we added extra metho ds for dealing with lists to the classes This

allow the metho ds for strings to b e dened in the instance declarations for Char

This means that instead of getting an instance for String you get instances for

Char String String String and so on For our classes it was not to o dicult

to invent a meaning for the extra instances Char was treated as onecharacter

strings For the Graphic class nested lists of strings are drawn by drawing all

the strings using some layout chosen by the layout system For the ColorGen

and FontGen classes lists were taken to mean spare alternatives you can write

eg midnightblueblack to provide one nice color and a safe fallback color

Empty lists can give runtime errors but are also likely to cause typing problems

making the overloading unresolvable which are discovered at compile time

Existentially quantied typ es

Existentially quantied typ es LO provide a very nice language feature in

particular in conjunction with Haskells typ e classes Lu We feel that this

feature should have b een made part the Haskell standard a long time ago As

it is now existentially quantied typ es are provided as a language extension by

some Haskell compilers at the time of writing only HBC Aug as far as we

know

We have found existential typ es useful in several contexts the implementa

tion of Gadgets in Fudgets Chapter the combinators for syntaxoriented

manipulation Chapter and the datatyp es for graphics Chapter

Since existential typ es are not part of the Haskell standard we have tried

to keep their use away from core machinery of the Fudget library Instead we

use them on the side to provide a nice feature as an additional b onus This has

aected how we used them in the graphics data typ es For example since leaves

of drawing usually are of typ e Gfx we could have used existential quantication

directly in the Drawing typ e

data Drawing lbl

Graphic leaf AtomicD leaf

Dep endent typ es

eliminating the need for the typ e Gfx We could also have dened the GCSp ec

typ e as

data GCSp ec

ColorGen c FontGen f SoftGC GCAttributes c f

HardGC GCtx

allowing you to write for example

SoftGC GCForeground red

instead of

SoftGC GCForeground colorSp ec red

Dep endent typ es

The Fudget library provides two combinators for tagged parallel comp osition of

fudgets the binary op erator and the list combinator listF

F a b F c d F Either a c Either b d

listF Eq a a F b c F a b a c

The former allows the comp osed fudgets to have dierent typ es but comp osing

a large numb er of fudgets make addressing the individual fudgets clumsy you

use comp ositions of the constructors Left and Right

The latter makes it easy to comp ose many fudgets but they must all have

the same typ e

The use of dep endent typ es would allows us to dene a combinator that

combines the advantages of and listF In type theory NPS there are two

forms of dep endent typ es dep endent pro ducts function typ es and dep endent

sums pairs The second form is the one we need here It allows us to construct

pairs where the type of the second comp onent dep ends on the value of the rst

comp onent

Using a Haskelllike notation we write

ta b t

for the pair typ e where the rst comp onent is of typ e a and the second comp o

nent is of typ e b t where t is the value of the rst comp onent Note that b is a

function returning a typ e

By viewing t as a tag we can form lists of tagged values of dierent typ e

and dene a variant of listF with the following typ e

dListF Eq a ta F i t o t F ta i t ta o t

Related work

Related work

We start by giving a brief overview of combinators for sequential IO in Sec

tion Section discusses stream pro cessing and combinations of concur

rency with functional programming Section presents other GUI to olkits

written in functional languages and Section presents some functional GUI

libraries written on top of imp erative to olkits Section discusses to olkits

which are not GUI to olkits in the traditional sense but can b e used to write

interactive programs with animated graphics Finally Section presents

two imp erative GUI to olkits

Combinators for sequential IO

As noted in Chapter the stream IO mo del allows us to write interactive

programs in a pure lazy functional language The mo del do es not imp ose any

sp ecic way of comp osing subprograms into larger programs

Sequential comp osition is useful for structuring textual user interfaces where

the interaction can b e seen as a dialogue b etween the computer and the user

that is a linear sequence of input and output actions In the following we

give a brief overview of combinators for sequential comp osition of eects More

develop ed reviews can b e found in Nobles and Gordons theses NobGor

Dialogues

The dialogue combinators by ODonnell OD allow stream IO programs

b eing built from comp onents using sequential comp osition and were used to

build a programming environment Programs are assumed to input a stream of

Events and output a stream of Commands The typ e of the comp onents is

typ e Dlg state state Event Command state Event

The idea is that a comp onent consumes an initial segment of the input stream

and returns some commands to b e output and the remainder of the input stream

It may also use and mo dify some global state information

Sequential comp osition is dened as

join Dlg state Dlg state Dlg state

join dlg dlg state events cmdscmdsstateevents

where

cmdsstateevents dlg state events

cmdsstateevents dlg state events

Input and output op erations can b e dened as

put Command Dlg state

put cmd state events cmdstateevents

get Event Dlg state Dlg state

get edlg state eventevents edlg state event events

Streams and pro cess programming

Interactions

A renement of the dialogue combinators is Thompsons interactions Tho

The idea is much the same but instead of manipulating a global state interac

tions input a value of some typ e and output a value of another typ e

typ e Interaction a b a Event Command b Event

The typ e of the sequential comp osition op erator is

sq Interaction a b Interaction b c Interaction a c

and the denition is the same as for join ab ove Neither the typ e of join nor

the typ e of sq is the most general typ e of this function

Monads

Monads provide an even more general approach to IO and have also b een

used for pro cess programming something we will see in later sections Monads

were rst a vehicle for giving denotational semantics for imp erative program

ming languages Mog but the concept was then carried over to practical use

WadPJW The same kind of structure had then already b een used in

the KAOS pro ject as a renement of Thompsons interactions Tur Cup

and by Gordon Gor

Monads for IO build on a typ e IO awhich represents IO eects that

return a value of typ e a when carried outand the bind op eration which

is used for sequential comp osition The bind op eration also binds the return

value of the rst IO op eration to a variable so that it can b e used in further

op erations in the sequence

IO a a IO b IO b

The bind op eration comes with an identity called return which simply returns

a value without any IO

return a IO a

The IO typ e can b e seen as a function that transforms the world regarded as a

state and also returns a value

typ e IO a WorldState aWorldState

Streams and pro cess programming

As noted in the intro duction the idea of stream pro cessors as such is not new

However in most previous work where stream pro cessors are used streams are

assumed to b e represented as lists and stream pro cessors as functions from lists

to lists Moreover the cons op eration is usually strict or even hyp erstrict in

its rst argument ie values can not b e transferred b etween pro cesses without

b eing evaluated rst This is in contrast to the stream pro cessors dened here

which allow unevaluated values to b e communicated b etween stream pro cessors

This makes communication op erationally on a par with argument passing and

let binding

Related work

The idea of using demanddriven scheduling app ears in KM which uses

streams as a lazy data structure in an imp erative pro cess language The lan

guage also p ermits a functional notation where the output p ort from one pro cess

is connected to the input p ort of another pro cess without the need to declare

the intermediate stream

In purely functional languages there is a problem with indeterministic choice

since this is not a pure function In some work Tura this is solved by

moving the indeterministic choices to a b ox the sorting oce Sto outside

the functional program In other work JS a indeterministic merge op erator

is added to the languages which then is not purely functional anymore By

using oracles Bur indeterministic choice can b e added without breaking

the purely functional nature of a language This is the solution we suggest for

indeterministic stream pro cessors

Concurrent Haskell FGJ is an extension of a lazy functional language

with primitive monadic op erations for creating pro cesses and communicating via

value carrying semaphores The implementation is based on a parallel reduction

machinery

There is a numb er of functional languages with supp ort for concurrent pro

cesses and communication b oth in lazy and strict functional languages An

early example is PFL Hol Later examples are Amb er Car Concurrent

+

ML CML Repb and Facile TLP CML and Facile are b oth based on

Standard ML Sto Concurrency abstractions on top of lazy functional lan

guages have b een implemented by Scholz Sch Achten Ach and Claessen

Most of these systems use side eects in the implementations The exceptions

are PFL and Achtens system which have purely functional schedulers which

at some p oint go outside the typ e system just as our Gadgets scheduler do es

Chapter

There are also functional languages aimed at utilising parallel hardware to

sp eed up computations Examples of such languages are Id Nik SISAL

Sis This kind of parallelism do es not supp ort a concurrent programming

style though

Other work worth mentioning include the language Omelett Nora two

level language with reactive ob jects on the top level and pure lazy functional

expression language H Trua concurrent pure lazy functional language

with supp ort for indeterministic merge of input streams on the top level CBS

Prathe Calculus of Broadcasting Systems which has an implementation in

Haskell

Functional GUI to olkits

There are a numb er of GUI to olkits written in functional languages which im

plement widget sets on top of X Windows In the following we review Gadgets

Haggis BriX and eXene but rst we want to mention an early example of func

tional GUI programming by Dwelly although it was not a presented as a GUI

to olkit Dwe Dwellys work was based on the dialogue combinators with the

addition of a recursive typ e Object to capture dynamic evolution of dialogues

data Object t s O t Cond s Object t s Dlg s

typ e Cond s s Event Bo ol

Functional GUI to olkits

The typ e Object t s represents a p otential dialogue An ob ject value O t c k has

a tag t and a condition predicate c which signals if the continuation dialogue

k is applicable in the current state of the program Among other things the

conditions predicates were used to test if the user had clicked within the area

that a button o ccupied If the predicate c is true k is applied to a list of active

ob jects to get a dialogue This is done by the function treeCase which takes a

list of active ob jects as an argument and schedules the rst ob ject with a true

condition predicate

treeCase Object t s Dlg t s

The continuation k can do some IO and then again calls treeCase with a

manipulated list of active ob jects thus allowing a new set of p ossible dialogues

In the manipulation the tags are used as p ointers into the list

Gadgets

Noble has implemented a GUI library called Gadget Gofer Nob where Gad

get stands for generalised fudget The motivation for this name is that gadgets

are pro cesses that communicate via typ ed asynchronous channels called wires

thus allowing a gadget to have an arbitrary numb er of input and output pins

As a pro of that gadgets are more general than fudgets Noble implemented the

basic fudget combinators using gadgets For an implementation of Gadgets in

Fudgets see Chapter

Noble implemented pro cess scheduling and channel communication in the

runtime system of Gofer Jon and added primitives for communication with

X Windows A feature of Gadgets is that it only uses the most basic drawing

op erations in the Xlib interface in one single X window On top of this Noble

has implemented a functional window system complete with a window manager

The gadget in Figure implements the updown counter except that it

uses a bar graph to display the value The counter gadget uses the following

library gadgets

button Change ButtonAttributes Out a a Gadget

bargraph In Int Int Gadget

wrap Change WrapAttributes Gadget Gadget

Gadgets uses the same mechanism for default parameters as describ ed in Chap

ter so button and wrap are customisable versions of button and wrap The

button gadget button o a will send the value a on the wire output end o when

ever it is clicked The gadget bargraph is waits for input functions on any of the

wire input ends in is and when such a function arrives it is used to up date the

level of the bar graph Note how the wire w is used to connect the two buttons

to the bar graph The layout of the three gadgets is sp ecied to b e vertical us

ing the op erator The example shows how the sp ecications of layout by

gadget combinators and dataow by wires are separated in Gadgets Finally

the wrap gadget puts some space around the three gadgets

The button parameter picture is used to sp ecify up and down arrows

uparrow downarrow DrawFun

The typ e DrawFun roughly corresp onds to the FlexibleDrawings in Section

Related work

main go counterUpDown

counter Gadget

counter

wire w

let b button picture uparrow op w

b button picture downarrow op w

g bargraph ip w in

wrap b order b g b

Figure The Gadget updown counter

Haggis

Just like Gadgets Haggis FP is based on a pro cess extension of a functional

language namely Concurrent Haskell

The separation b etween user interface and application co de can b e explained

by studying the typ e of a couple of common GUI element namely push buttons

and lab els

button Picture a DC IO Button a DisplayHandle

lab el String DC IO Lab el DisplayHandle

The monadic expression button p v d creates a button which will show the

picture p The buttons value is v and d is an environment or display context

which carries default values Haggis uses this for customisation instead of the

default parameter mechanism in Fudgets and Gadgets The monadic expression

returns an application hand le of typ e Button and a display hand le The GUI

element lab el do es also return a display handle but its application handle has a

dierent typ e The display handles are p ointers to the GUI elements and can

b e combined with other display handles with layout combinators for example

hb ox

hb ox DisplayHandle DisplayHandle

The application handles can b e used to mo dify various asp ects of the GUI

elements dep ending on their typ e

setButtonLab el Button a Picture IO

disableButton Button a IO

enableButton Button a IO

setLab el Lab el String IO

The most imp ortant feature of the button handle is the p ossibility to wait for

it to b e clicked

Functional GUI to olkits

counter DC IO Lab el Button IntInt DisplayHandle

counter env

lab el show start env labldh

button text Up env incidh

button text Down env decddh

combineButtons incdec btn

return labbtn hb ox ldh idh ddh

start

main

wop en name Counter counter labbtn

let count n getButtonClick btn f

let n f n in

setLab el lab show n

count n

in

count start

Figure The Haggis updown counter

getButtonClick Button a IO a

When getButtonClick b is called in a pro cess it will b e susp ended until the

user clicks b and then the buttons value is returned Internally this uses a

trigger which can b e seen as value carrying condition variable one of several

synchronisation abstractions that Haggis provides on top of Concurrent Haskells

value carrying semaphore typ e MVar

The typ e Picture corresp onds somewhat to the Drawing typ e in Section

and p ermits advanced structured graphics to b e dened Haggis pictures are

describ ed further in FJ

In Figure we see a version of the the updown counter in Haggis The

function counter denes the user interface It returns a display handle and

handles to the lab el and a combination of the two buttons created by

combineButtons Button a IO Button a

This combination has the desirable prop erty that a call to getButtonClick waits

for any of the push buttons to b e clicked

In main the counter function is passed to wop en

wop en String DC IO aDisplayHandle

IO aWindow

which creates the user interface in a shell window The rst argument to wop en

can contain default values for the display context The example indicates that

the format for these values are similar to the resource data base in X SG

In the example it is used to set the window title The application handles

Related work

in counter are returned as they are from wop en which also returns a window

handle which can b e used to manipulate the shell window

The rest of main denes the application b ehaviour of the program by dening

a lo op which waits for button clicks and then up dates the lab el In this example

the lo op comes right after the initialisation of the interface in the main pro cess

but in general control lo ops are spawned as separate pro cesses

BriX

The to olkit BriX Ser is built on top of X as part of the Bristol Haskell

System HDD which aims at building concurrent and distributed systems

in a strictly deterministic manner BriX inherits this deterministic view of the

world and indeterministic merge is avoided by propagating information ab out

events through parallel comp ositions This has similarities with the synthetic

oracles used in an early version of the stream pro cessors Section

eXene

The to olkit eXene by Reppy and Gansner RG GR is an X Windows

to olkit written in a strict functional language namely Standard ML of New

Jersey SML It is written on top of Concurrent ML CML Repa and is

thus multithreaded eXene pushes the functional b order further even Xlib is

thrown out and the communication with X is written in ML

Events from the X server and control messages b etween widgets are dis

tributed in streams co ded as CML event values through the window hierar

chy where each window has at least one CML thread taking care of the events

Drawing is done by calling imp erative drawing pro cedures Highlevel events are

rep orted either imp eratively or by message passing when a button is pressed

a callback routine is called or a message is output on a CML channel

Interfaces to existing to olkits

A numb er of interfaces for functional languages have b een built on top of exist

ing imp erative to olkits Early examples include Lazy Wafe by Sinclair Sin

XViewMiranda by Singh Sin and MIRAX by Tebbs Teb More recent

examples are Taylors Embracing Windows using Hugs and Windows and

TkGofer VTS The latter oers a monadic interface in Gofer to the p opular

to olkit Tk Ous Application programs are written using a combination of

functional abstractions and a traditional imp erative style with callbacks that

mutate variables or mo dify widgets

TkGofer was further develop ed and improved in CVM by using Gofers

expressive class system to provide a typ ed means of sp ecifying parameters for

the widgets similar to the dynamically customisable fudgets in Section

The result is that most dynamic asp ects of the Tk widgets can b e controlled in

a typ esafe way For example the button widget has typ e

button Conf Button Window GUI Button

and since the typ e Button is instance of b oth HasText and HasCommand its

lab el and callback function can b e congured with the following memb ers

Interfaces to existing to olkits

counter IO

counter start

do w window title UpDown Counter

e entry initValue readOnly True w

let mybutton t f button text t

command mo difyEntry e f w

u mybutton Up

d mybutton Down

pack u e d

mo difyEntry Entry Int Int Int GUI

modifyEntry e f

do x getValue e

setValue e f x

Figure The TkGofer counter

text HasText a String Conf a

command HasCommand a GUI Conf a

An updown counter written with Gofers donotation syntactic sugar for mon

ads is found in Figure

Concurrent Clean

Concurrent Clean is an ecient implementation of a lazy functional language

which was originally develop ed for Macintosh Pv It comes with an IO

library which p ermits p ortable development of GUI programs that interface to

the GUI to olkits on Macintosh WindowsNT and XView or Op enLo ok

IO in Clean is carried out using the worldasvalue paradigm Ach which

means that an abstract value representing the state of the world or parts of

it is passed around as an extra parameter in the program The typ e system is

extended with a mechanism to guarantee that the world parameters are passed

in a singlethreaded way throughout the program It is this parameter thread

ing that sp ecies the order in which IO op erations are p erformed no explicit

sequencing combinator is used in the worldasvalue style However Clean pro

grams have a syntactic abbreviation for nested let expressions which is used

when sp ecifying sequences statements Using this style the monadic denition

f

do x c

1 1

x c

2 2

return e

is written roughly

Related work

f

x s c s

1 1

x s c s

2 2

es

The worldasvalue paradigm can b e seen as programming in an unfolded vari

ant of the IO monad in Section A disadvantage is that state and er

ror handling b ecomes explicit something which clutters the programs On

the other hand dierent kinds of state parameters can b e handledp ossibly

simultaneouslywithout the need of dening new combinators

A Clean version of the updown counter is shown in Figure The rst

lines in initcounter show the use of the nestedlet sugar and allo cate unique

identiers to b e used in the data structure dialog which sp ecies the GUI This

data structure also relates the callback function up d to the push buttons and

the initial lo cal state

Functional interactive graphics

Pidgets

The idea b ehind Pidgets by Enno Scholz Sch is to combine pictures with

widgets to allow arbitrarily shap ed ob jects to b e sensitive to input and to

change dynamically Denitions of pictures and some auxiliary typ es of values

for example numb ers vectors and colors can refer to mutable variables When

a variable is changed and a picture that dep ends on it is visible in a window

the window is automatically up dated

Pictures are describ ed in the PostScript mo del Ado for graphics A

picture can made sensitive to input by asso ciating it with a handler The handler

is called if an input event such as a mouse button press o ccurs while the mouse

p ointer is over the screen area covered by the picture The handler returns a

value of typ e IO and can thus have arbitrary IO eects including changing

a mutable variable that the picture dep ends on

Pidgets is based on an imp erative approach to dynamically changing graph

ical ob jects Monads are used to provide a purely functional interface to the

imp erative machinery Mutable variables are made part of the IO monad A

new monad Expr is dened for expressions that is values whose interdep enden

cies are describ ed by a directed acyclic graph that can dep end on the values of

mutable variables

In part the purp ose of Pidgets is similar to that of the fudget graphicsF

discussed in Chapter An interesting exp eriment would b e to see how Pidgets

could b e used to implement combinators for syntax directed editors

Fran

Fran Functional Reactive Animation by Elliott and Hudak Ell is a Haskell

library which supp orts a declarative sp ecication of D and D animation as

well as sound The basic datatyp es in Fran are behaviours and events Be

haviours can b e viewed as values that vary with time which is continuous

A b ehaviour value that sp ecies a picture is the basic animation mechanism

Functional interactive graphics

NoState NoState

Start World World

Start world startIO NoState NoState initcounter world

where

initcounter ps

windowid ps accPIO op enId ps

displayid ps accPIO op enId ps

ps op enDialog NoState dialog windowid displayid ps

ps

where

dialog windowId displayId

Dialog Counter

newLS init

newDef EditControl toString init dwidth dheight

ControlPos Centerzero

ControlId displayId

ControlSelectState Unable

ButtonControl

ControlPos Centerzero

ControlFunction up d

ButtonControl

ControlFunction up d

WindowClose noLS closePro cess

WindowId windowId

where

dwidth

dheight

init

up d Int IntPSt l p IntPSt l p

upd dx nps

nappPIO setWindow

windowId

setControlTexts displayIdtoString n ps

where n ndx

Figure Updown counter in Clean

Related work

Events can b e external for example a button press or calculated for example

two ob jects that collide and are asso ciated with the time at which they o ccur

The reactivity is achieved by combinators that allow a b ehaviour to b e re

placed by another at the o ccurrence of an event There are also combinators

for building complex b ehaviours and events from simpler ones The b ehaviour

combinators can b e seen as parallel comp osition of pro cesses allowing a numb er

of b ehaviours to act concurrently

The primary goal for Fran is to sp ecify multimedia and animation which

it do es in an elegant and declarative way It might b e p ossible to use Fran for

building complete GUI to olkits as well

Imp erative to olkits

Java

In the ob jectoriented programming language Java GJS graphical user in

terfaces can b e programmed using the class library AWT Abstract Window

To olkit AWT Figure shows how the updown counter is dened as a

sub class of the Frame which is used to construct toplevel windows The con

structor metho d UpDown creates two button ob jects and a lab el ob ject and

adds so called action listeners highlevel event handlers to the buttons as

anonymous classes These play the role of callbacks and mo dify the counter

variable and the display

The last lines in the constructor metho d denes the layout and adds the

buttons to the frame

Pizza

The Java extension Pizza OW allows the programmer to write p olymorphic

co de and use rstclass functions Of course the AWT library can b e used

directly in Pizza but the Pizza programmer may also use a style which more

resembles functionalimp erative to olkits like TkGofer using callback functions

instead of classes We exemplify this by dening a PizzaButton and a PizzaLab el

The PizzaButton is a Button where we dene the action as a callback function

directly in the constructor

class PizzaButton extends Button

public PizzaButtonString s nal void action

sup ers

addActionListener

new ActionListener

public void actionPerformedActionEvent e

action

The PizzaLab el is a p olymorphic Lab el with metho ds for getting or setting the

value and applying a function to it

Imp erative to olkits

public class UpDown extends Frame

public UpDown

int count

Lab el display new Lab el

displaysetTextcount

Button up new ButtonUp

upaddActionListener

new ActionListener

public void actionPerformedActionEvent e

displaysetText count

Button down new ButtonDown

downaddActionListener

new ActionListener

public void actionPerformedActionEvent e

displaysetText count

setLayoutnew FlowLayout

addup

adddisplay

adddown

public static void mainString args

UpDown a new UpDown

asetTitleUpDown Counter

apack

ashow

Figure Updown counter in Java

Related work

class PizzaLab elT extends Lab el

private T value

public PizzaLab elT i sup er i

value i

public T get return value

public void setT i value i

setText i

public void mo difyT T f setfvalue

The Pizza updown counter in Figure is almost the same as the Java counter

except that it do es not use a lo cal variable and uses callbacks instead of action

listeners for the buttons

C and Motif

For Cprogrammers the to olkit Motif You has b een a p opular choice An

implementation of the counter example in C using Motif is shown in Figure

The program starts with creating a shell widget called top which will b e the

ro ot of the widget tree The rest of the tree is created with rep eated calls of

XtCreateManagedWidget where the arguments sp ecify what kind of widget to

create and where to put it in the tree The widgets are

 row a layout widget which put all its children in a row or in a column

 display which shows a string which will b e the count

 button a button that the user can press Whenever this happ ens an

asso ciated callback routine is called

When the widget tree is created the display is reset to show zero and the

Cfunction increment is registered as a callback routine for the button widget

increment increments the counter and up dates the display widget

Imp erative to olkits

public class UpDown extends Frame

public UpDown

PizzaLab elint display new PizzaLab el

Button up

new PizzaButtonUp

fun void

displaymo difyfunint xint

return x

Button down

new PizzaButtonDown

fun void

displaymo difyfunint xint

return x

setLayoutnew FlowLayout

addup

adddisplay

adddown

public static void mainString args

UpDown a new UpDown

asetTitleUpDown Counter

apack

ashow

Figure The Pizza updown counter

Related work

include stdioh

include XIntrinsich

include XStringDefsh

include XmXmh

include XmLab elh

include XmPushBh

include XmRowColumnh

static int count

static void SetDisplayWidget display int i

char s

Arg wargs

int n

sprintfs d i

XtSetArgwargsn XmNlab elString

XmStringCreates XmSTRINGDEFAULTCHARSET n

XtSetValuesdisplay wargs n

static void incrementWidget b Widget display XtPointer calldata

count

SetDisplaydisplay count

int mainint argc char argv

Widget top row display button

top XtInitializecounter Counter NULL argc argv

row XtCreateManagedWidgetrow xmRowColumnWidgetClass

top NULL

display XtCreateManagedWidgetdisplay xmLab elWidgetClass

row NULL

button XtCreateManagedWidgetbutton xmPushButtonWidgetClass

row NULL

SetDisplaydisplay count

XtAddCallbackbutton XmNactivateCallback

XtCallbackPro cincrement XtPointerdisplay

XtRealizeWidgettop

XtMainLo op do es not return

Figure The updown counter in C and Motif

Evaluation and conclusions

In this thesis we have presented stream processors to supp ort a concurrent pro

gramming style in pure functional languages Stream pro cessors allow programs

to b e built in a hierarchical structure of concurrent pro cesses with internal state

They thus supp ort mo dular design of large programs

With the stream pro cessors dened here we abstract away from the streams

We dene a numb er of combinators for stream pro cessors but no op erations on

the streams themselves We have considered a numb er of dierent implementa

tions of stream pro cessors some of which are deterministic and work in a pure

sequential functional language without any extensions and some of which take

advantage of parallel evaluation and indeterministic choice Chapter

We have also presented a library of combinators for constructing applica

tions with graphical user interfaces Part I I and typ ed network communication

Chapter Together with a range of applications the library has demon

strated that the streampro cessorfudget concept is scalable it can b e used to

program not only toy examples but more complex applications like WWW

browsers Chapter and syntaxoriented pro of editors Chapter A key

combinator here is lo opThroughRightSP Section which allows existing

stream pro cessorsfudgets to b e reused in a style that resembles inheritance in

ob jectoriented programming

The library also demonstrates that pure functional programming languages

are suitable for these tasks something which was not clear when this work

started Although GUI fudget programs do a fair amount of IO resp onse

times can b e kept suciently low Section

Since we represent IO eects by data constructors sent as messages we

have b een able to write higher order functions that manipulate IO eects of

fudgets Chapter which provide a p ossibility for mo difying the b ehaviour of

existing fudgets A caching mechanism Section and a clicktotyp e input

mo del Section has b een implemented with this metho d

The default parameter mechanism Chapter and demonstrates how

Haskells class system and higher order functions can b e combined to simu

late a missing language feature Later two other GUI libraries Gadgets Sec

tion and TkGofer Section have adopted this mechanism

The fudget graphicsF in Chapter shows that the task of displaying and

manipulating graphics can b e handled eciently in a purely functional way

It has b een used b oth in the web browser in Chapter and in the pro of

editor Alfa in Chapter On top of graphicsF we have also implemented a

set of combinators that allow syntaxoriented editors to b e built in a highlevel

style resembling combinator parsers Chapter Our exp erience with these

combinators is limited sofar but we b elieve that they can b e employed in a

future version of Alfa

Although most stream pro cessors we have shown are programmed in a CPS

style other styles can b e used Simple stream pro cessors can b e programmed

by using concatMapAccumlSP and a state transition function A monadic style

can also b e used as is demonstrated in Chapter

As the related work shows in Chapter a numb er of elegant libraries

and interfaces have emerged for GUI programming in pure functional languages

during the last years Is it p ossible to evaluate and compare all these libraries

and the Fudget library This has b een done to some extent in the review in

Evaluation and conclusions

Nob We will not give any further comparison here but simply p oint out

some distinguishing features of fudgets and stream pro cessors in general

 Stream pro cessors oer a simple concurrency concept which can b e imple

mented in any pure functional language Of the other to olkits Concurrent

Clean also provides a purely functional pro cess concept but it has a rather

complex implementation Ach

The fudget concept has b een implemented on top of a numb er of GUI

to olkits NobTayRSCVM something which also gives evi

dence that fudgets are easy to implement

 Stream pro cessors come with a sp ecial programming style Since no ex

plicit streams channels or wires are used the routing of information b e

tween pro cesses must b e sp ecied by using combinators This can b e seen

as a limitation of the paradigm and some p eople indeed nd it dicult to

adopt On USENET this has b een formulated as you could use some

thing like Fudgets to build a GUI but thats less fun than having teeth

pulled OS An example of the typical amount of routing necessary is

shown in the implementation of somF in Section Figure which

has a stream pro cessor handling three output and three input streams

An extreme example is the toplevel fudget of Alfa Chapter whose

controlling stream pro cessor denes routing functions to handle ve

levels deep messages of Either typ e By using routing functions dened

in one place adding new subfudgets to the toplevel fudget has b ecome a

manageable task It still requires a bit to o much of mechanical work and

there is a need for some new set of combinators or some other solution to

simplify this programming task further

One could argue that the combinator plumbing of messages imp oses a

degree of structure on programs which could b e healthy Having explicit

identiers for streams spread over a program results easily in a gotolike

spaghetti The functional language FP by John Backus Bac is entirely

based on the use of combinators instead of named variables

 The stream pro cessor concept also oers supp ort the manipulation of mi

grating pro cesses with the sp ecial feature that when a pro cess is moved

it is completely detached from all streams in its old context Chapter

We are not aware of anything similar in any other to olkit or pro cess cal

culus In addition since stream pro cessors are pure values in particular

they do not use imp erative variables they can readily b e cloned at any

time

As shown in the Chapter the migration mechanism can b e applied to

fudgets and used to implement draganddrop of GUI fudgets

Frequently Asked Questions

How imp ortant was lazy evaluation in Fudgets library and program

ming Could Fudgets b e implemented in ML

When the work on Fudgets started Haskell used the streambased IO mo del

and stream pro cesses were represented as list functions Nowadays the

Frequently Asked Questions

continuationbased representation of stream pro cessors is used and Haskell has

switched to a monadic IO system b oth of which would work in a strict lan

guage So lazy evaluation is no longer essential

A problem with streambased IO is the danger of getting out of

synch and reading one result to o many or to o few Did this happ en

to you in practice

For a while when we used the list based representation and that representa

tion was visible to the programmer the programmer had to b e aware of the

fudget law that is the onetoone corresp ondence b etween input and output

messages see Section We sometimes made mistakes When the stream

pro cessor typ e was made abstract the fudget law b ecame builtin and the pro

grammer was relieved from thinking of it Also we started doing low level IO

through functions like doStreamIOK Section which eectively removed

all problems of this kind

Haskell has moved from streamstyle IO to monadstyle IO Your

op erations are CPSstyle but they could equally b e monad style

Did you make that choice consciously Why

The monadic programming style had not b ecome p opular when we intro duced

the CPS style combinators so we did not make a conscious choice b etween CPS

style and monadic style

Did you come across any situations where Haskells typ e system

prevented you doing the Right Thing

Yes For example the typ e XCommand is supp osed b e an interface to X Win

dows but we have added various pseudo commands that are handled within

the Haskell program and never output to the window system It would have

b een nice to dene the prop er commands as a subtyp e of all commands Making

this distinction in Haskell would require an extra level of tagging which we felt

was not justied Analogously the typ e XEvent contains some pseudo events

Future work

Future work

Towards a calculus for stream pro cessors

Certainly the implementation of stream pro cessors used in the Fudget library

could serve as a semantic base for formal reasoning ab out stream pro cessor

and fudget programs But we might want to use a more abstract semantics

of stream pro cessors which would also capture truly parallelevaluating and

indeterministic stream pro cessors Supp ose that we have an implementation

for indeterministic stream pro cessors Would the Fudget library still work

Or are we relying on some subtle ordering of messages that to days sequential

implementation gives us thus avoiding tricky race problems The answer is

probably that most of the library would still work but at some p oints we

implicitly rely on implementation details As one example consider two identity

stream pro cessors in parallel

p SP Either a b Either a b

p idSP idSP

When using the implementation from the Fudget library p is nothing but the

identity stream pro cessor for typ e Either a b But if we were to use indeter

ministic stream pro cessors we cannot b e sure that message order would b e

maintained through p If we rst send Left a immediately followed by Right b

to p why should there b e a guarantee that it will output these messages in the

same order

Naturally the Fudget library do es not have a lot of identity stream pro cessors

in parallel Fudgets on the other side are abundant in the library and they

very often sit in parallel One example where implicit assumptions exist ab out

message order output from parallel fudgets is in the radio group fudget radioF

Another more explicit assumption was made in the implementation of the

Explo de game in Section In Explo de it is crucial that the internal

communication after a explosion has priority over external communication This

is what the continuationbased implementation of stream pro cessors gives

In order to reason formally ab out indeterministic stream pro cessors we

present the streamprocessor calculus SPcalculus

Basic stream pro cessors

There are seven basic ways of forming a stream pro cessor We let the letter x

denote a variable and s t stream pro cessors

x Variable

s t Put

x s Get

s  t Feed

s t Serial comp osition

s t Parallel comp osition

` s Lo op

For the reader who has used stream pro cessors in the Fudget library these

op erators should b e familiar The op erator corresp ond to putSP and can

b e seen as a combination of abstraction and getSP x s is the same as getSP x

Towards a calculus for stream pro cessors

s The feed op erator in s  t feeds the message t to the stream pro cessor

s similar to startupSP which feeds a list of messages to a stream pro cessor

Serial comp osition corresp onds to and parallel comp osition and lo op

are untagged corresp onding to and lo opSP

Congruence rules

Following the style of BB we dene a bunch of congruence rules which can

b e used freely to nd reaction rules to apply

s t  t s Commutativity of

s t u  s t u Asso ciativity of

s t u  s t u Asso ciativity of

s t u  s  t u Internal communication in

s t  u  s  u t  u Distributivity of  over

s t  u  s t  u Output from 

s t u  s t u Output from

x s  t  stx Substitution

Reaction rules

Whereas the congruence rules in the last section can b e freely used in any direc

tion without changing the b ehaviour of a stream pro cessor the reaction rules

are irreversible and intro duce indeterminism The reason is that by applying a

rule we make a choice of how message streams should be merged There are two

places where merging o ccur in the output from a parallel comp osition and in

the input to a lo op

s t u ! s t u Output from

We can derive a symmetric rule by using the commutativity of but when it

comes to the lo op we need two rules

` s t ! s ` t  s Internal input to `

` s  t ! ` s  t External input to `

As an example of these rules consider the stream pro cessor s t u v which

can react to s t u v but also to u s t v using commutativity

Similarly the lo op ` s t  u can react to b oth s ` t  s  u and

` s t  u

The calculus emb edded

The SPcalculus is more expressive than the calculus and we can dene a

translation from the calculus into the SPcalculus

JxK x Variable

JxMK x JMK Abstraction

JM NK JMK  JNK Application

The substitution rule for the SPcalculus corresp ond to the b etarule of 

calculus However the etarule which would corresp ond to x s  x  s

do es not hold in general something that we will see after having dened equiv

alence of stream pro cessors

Future work

Having the p ower of calculus we can dene some familiar stream pro ces

sors such as the identity stream pro cessor and the null stream pro cessor

x f x f  x  x  x f  x  x

id x  f x x f

x  f x f

Equivalent stream pro cessors

We can dene an equivalence ' as the greatest equivalence relation satisfying

s ' s if and only if

1 2

 For all o and s that s can output and b ecome there must exist an

1 1 1

o and s that s can output and b ecome Furthermore o ' o and

2 2 2 1 2

s ' s must hold

1 2

 For all input t s  t ' s  t must hold

1 2

From this denition we can see that x s  x ' s do es not hold if s can

output something The lefthand side is blo cked waiting for input and could

not match the output from s

Future work

More investigation is needed to turn the SPcalculus into an op erational seman

tics for stream pro cessors

 Check that we have exactly the congruencereaction rules we need

 Check that the congruence rules form a decidable relation It must b e

p ossible to nd all p ossible reactions in a stream pro cessor

 The equivalence relation is go o d but we really want to nd a congruence

relation

 Relate the SPcalculus to other calculi so that we can reuse their theory

Stream pro cessors as Internet agents

The interest in the Internet has resulted in a fo cus on new features in program

ming languages The information exchange over Internet has explo ded and

there is a need to exchange not only text graphics and sound in a smo oth way

but programs For program exchange to b e smo oth the receiver of a program

must b e certain that it do es not do nasty things with his computer This can

b e achieved by accepting programs in a typ ed language where the typ e should

give information ab out everything that the program can do including all kinds

of side eects and communication This is a prop erty that stream pro cessors

have they can do nothing but outputting messages in a known typ e

There is also an interest in having programs running for a while at one site

then moving on to other sites while gathering information etc Such programs

are often called mobile agents As we have seen in Chapter the necessary ma

chinery for mobile agent programming is already there in the streampro cessor

concept However we need supp ort in the underlying language implementation

so that values that are closures can b e exchanged b etween computers

A Online resources

A The Fudgets Home Page

The address of the Fudgets Home Page is

httpwwwcschalmersseFudgets

On the home page you can nd out how to download fudgets and install them

what Haskell compiler to use and where to get it what platforms are supp orted

You can also browse and search the Fudget Library Reference Manual

A Supp orted platforms downloading and in

stallation

At the time of this writing fudgets run under the X Windows system on a

numb er of Unix platforms such as NetBSD FreeBSD SunOS SunOS

x Solaris x Digital Unix IRIX

The Fudget library is available in precompiled form for some of the ab ove

mentioned platforms The library is also available in source form

To compile the Fudget library in case you can not use a precompiled dis

tribution and fudget applications you need a Haskell compiler The current

version of the library works only with HBC Aug since the library makes use

of existential typ es which is an extension of Haskell currently supp orted only

by HBC as far as we know Earlier versions of the library work with NHC and

GHC as well

The Fudget library and HBC are available for download from

ftpftpcschalmerssepubhaskellchalmers

Read the README les and if you get the precompiled version of the Fudget

library make sure that you get matching versions of the compiler and the library

A Compiling Fudget programs

Fudget programs are easy to compile Assuming the program is stored in a le

called Hellohs the command line to compile the program is

hb cxmake Hello

A Compiling Fudget programs

Even if the program consists of several mo dules invoking hb cxmake with the

name of the main mo dule is enough to compile it hb cxmake calls hb cmake an

automatic make utility supplied with HBC

B Fudget library quick

reference guide

This is an brief index of the Fudget library listing the things that have app eared

in the examples throughout the text

A more complete description of the contents of the Fudget library is provided

in the reference manual which is available online via

httpwwwcschalmersseFudgetsManual

B Top level main program

fudlogue F a b IO used on the top level to connect the main fudget

to the Haskell IO system

shellF String F a b F a b creates shell toplevel windows All GUI

programs need at least one of these

These functions are discussed further in Section

B GUI building blo cks widgets

lab elF Graphic a a F b c creates static lab els

quitButtonF F Click a creates quit buttons

intInputF F Int Int creates integerentry elds

intDispF F Int a creates integer displays

buttonF Graphic a a F Click Click creates command buttons

More GUI elements are presented in Chapter which also explains the

ab ove fudgets in more detail

B Combinators plumbing

F a b F c a F c b serial comp osition

F a b F c d F Either a c Either b d parallel comp osition of

two fudgets which can b e of dierent typ e

B Graphics

listF Eq a a F b c F a b a c parallel comp osition of a list

of fudgets All parts must have the same typ e

lo opThroughRightF F Either a b Either c d F c a F b d a lo op

combinator for encapsulation

More combinators for plumbing are presented in Chapter and

B Adding applicationsp ecic co de

mapF a b F a b constructs stateless abstract fudgets

mapstateF a b a c a F b c constructs stateful ab

stract fudgets

Abstract fudgets are discussed further in Chapter

B Layout

labLeftOfF Graphic a a F b c F b c puts a lab el to the left of

a fudget

placerF Placer F a b F a b is used to sp ecify explicitly the relative

placement of the parts of a comp osite fudget The rst argument is a

placer

verticalP Placer sp ecies vertical placement top to b ottom

revP Placer Placer used to place parts in the reverse order

matrixP Int Placer creates a matrix with the given numb er of columns

holeF F a b creates holes which can b e used to ll unused slots in a matrix

of fudgets for example

Layout is discussed further in Chapter

B Graphics

lledTriangleUp FlexibleDrawing a triangle p ointing up

lledTriangleDown FlexibleDrawing a triangle p ointing down

Graphics is discussed further in Chapter

B Alphab etical list

Roughly of identiers dened in the Fudget library reference manual

have b een used in the examples throughout the text Here is an alphab etical

list of them

SP a b SP a b SP a b

SP a b SP c d SP Either a c Either b d

SP a b SP c a SP c b

F a b F c d F Either a c Either b d

F a b F c a F c b

F a b c a F c b

F a b SP c a F c b

a b F c a F c b

SP a b F c a F c b

aLeft Alignment

aTop Alignment

absF SP a b F a b

argKey Char Char Char

argReadKey Read a Show a Char a a

args Char

atomicD a Drawing b a

bgColor Char

bindSPm SPm a b c c SPm a b d SPm a b d

b orderdF Bo ol Int F a b F Either Bo ol a b

b ottomS Spacer

b oxD Drawing a b Drawing a b

buttonBorderF Int F a b F Either Bo ol a b

buttonF Graphic a a F Click Click

buttonF Graphic a Customiser ButtonF a a F Click Click

buttonF Graphic a Customiser ButtonF a a PF ButtonF a

Click Click

buttonGroupF Mo dState KeySym F Either BMevents a b F a b

bypassF F a a F a a

centerS Spacer

colorSp ec Show a ColorGen a a ColorSp ec

compS Spacer Spacer Spacer

concatMapAccumlSP a b a c a SP b c

concatMapF a b F a b

concatMapSP a b SP a b

concatSP SP a a

defaultFont FontName

deletePart Drawing a b Int Drawing a b

displayF Graphic a F a b

displayF Graphic a Customiser DisplayF a F a b

drawingPart Drawing a b DPath Drawing a b

dynF F a b F Either F a b a b

B Alphab etical list

dynListF F Int DynFMsg a b Int b

editorF F EditCmd EditEvt

fgD Show a ColorGen a a Drawing b c Drawing b c

ller Bo ol Bo ol Int FlexibleDrawing

lterLeftSP SP Either a b a

lterRightSP SP Either a b b

lterSP a Bo ol SP a a

ipP Placer Placer

ipS Spacer Spacer

fontD Show a FontGen a a Drawing b c Drawing b c

fontSp ec Show a FontGen a a FontSp ec

fontascent FontStruct Int

fontdescent FontStruct Int

frame Size FlexibleDrawing

fudlogue F a b IO

g Graphic a a Drawing b Gfx

getSP Cont SP a b a

getSPm SPm a b a

getSPms SPms a b c a

groupF XCommand K a b F c d F Either a c Either b d

hAlignS Alignment Spacer

hCenterS Spacer

hFiller Int FlexibleDrawing

hMarginS Distance Distance Spacer

hScrollF F a b F a b

hb oxD Drawing a b Drawing a b

hb oxD Distance Drawing a b Drawing a b

holeF F a b

horizontalP Placer

hyp erGraphicsF Eq a Graphic b Drawing a b F Either Drawing a b

a Drawing a b a

idF F a a

idLeftF F a b F Either c a Either c b

idRightF F a b F Either a c Either b c

idSP SP a a

inputDoneSP SP InputMsg a a

inputLeaveDoneSP SP InputMsg a a

inputLinesSP SP Char Char

intDispF F Int a

intF F Int InputMsg Int

intInputF F Int Int

isLeft Either a b Bo ol

issubset Eq a a a Bo ol

labAb oveF Graphic a a F b c F b c

labLeftOfF Graphic a a F b c F b c

lab elD a Drawing a b Drawing a b

lab elF Graphic a a F b c

leftS Spacer

linesSP SP Char Char

listF Eq a a F b c F a b a c

loadSPms SPms a b c c

lo op a a a

lo opCompF F Either Either a b Either c d Either Either c e Either a f

F Either b d Either e f

lo opCompThroughLeftF F Either a Either b c Either b Either a d F

c d

lo opCompThroughRightF F Either Either a b c Either Either c d a F

b d

lo opF F a a F a a

lo opLeftF F Either a b Either a c F b c

lo opLeftSP SP Either a b Either a c SP b c

lo opSP SP a a SP a a

lo opThroughRightF F Either a b Either c d F c a F b d

lo opThroughRightSP SP Either a b Either c d SP c a SP b d

mapAccumlSP a b a c a SP b c

mapF a b F a b

mapFilterSP a Mayb e b SP a b

mapLab elDrawing a b Drawing a c Drawing b c

mapPair a b c d a c b d

mapSP a b SP a b

mapstateF a b a c a F b c

mapstateSP a b a c a SP b c

marginS Distance Spacer

matrixP Int Placer

mayb eDrawingPart Drawing a b DPath Mayb e Drawing a b

menuF Graphic a Graphic c a b c F b b

moreF F String InputMsg Int String

moreFileF F String InputMsg Int String

moreFileShellF F String InputMsg Int String

moveDrawCommands Functor a aDrawCommand Point aDraw

Command

nullF F a b

nullK K a b

nullSP SP a b

nullSPm SPm a b

nullSPms SPms a b c

origin Point

overlayP Placer

part a Bo ol a a a

path Path Direction Path

B Alphab etical list

pickListF a String F PickListRequest a InputMsg Int a

placedD Placer Drawing a b Drawing a b

placerF Placer F a b F a b

p opupMenuF Graphic b Eq b a b F c d F Either a b c

Either a d

putSP a SP b a SP b a

putSPm a SPm b a

putSPms a SPms b a c

quitButtonF F Click a

radioGroupF Graphic b Eq a a b a F a a

radioGroupF Graphic b Eq a Customiser RadioGroupF a b a

F a a

readDirF F String String Either DIOError String

readFileF F String String Either DIOError String

rectp os Rect Point

rectsize Rect Size

remove Eq a a a a

replace Eq a a b a b a b

replaceAll a TextRequest a

revP Placer Placer

rightS Spacer

ro otGCtx GCtx

runSP SP a b a b

scrollF F a b F a b

serCompLeftToRightF F Either a b Either b c F a c

serCompRightToLeftF F Either a b Either c a F b c

serCompSP SP a b SP c a SP c b

setBgColor HasBgColorSp ec b Show a ColorGen a a Customiser b

setLab el a Customiser ButtonF a

setPlacer Placer Customiser RadioGroupF

shellF String F a b F a b

simpleGroupF WindowAttributes F a b F a b

splitSP SP a b Either a b

standard Customiser a

startupF a F a b F a b

startupSP a SP a b SP a b

stderrF F String a

stdinF F a String

stdoutF F String a

storeSPms a SPms b c a

stringF F String InputMsg String

stringInputF F String String

stringrect FontStruct Char Rect

stripEither Either a a a

stripInputSP SP InputMsg a a

stripLeft Either a b Mayb e a

stripLow Message a b Mayb e a

stripRight Either a b Mayb e b

throughF F a b F a Either b a

timerF F Mayb e Int Int Tick

toBothF F a Either a a

toggleButtonF Graphic a a F Bo ol Bo ol

topS Spacer

unitSPm a SPm b c a

up DPath DPath

up datePart Drawing a b DPath Drawing a b Drawing a b

Drawing a b

vAlignS Alignment Spacer

vCenterS Spacer

vFiller Int FlexibleDrawing

vMarginS Distance Distance Spacer

vScrollF F a b F a b

verticalP Placer

wCreateGCtx Show b FontGen b FudgetIO e Show a ColorGen a

GCtx GCAttributes a b GCtx ecd ecd

waitForSP a Mayb e b b SP a c SP a c

writeFileF F String String String Either DIOError

xco ord Point Int

yco ord Point Int

Pro duction notes

This thesis was written in an extended version of Haskell called HacWrite

develop ed by the authors The extension consists of a new string typ e that

can wrap over many lines and that can contain emb edded Haskell co de for

sp ecication of markup HacWrite consists of a prepro cessor that converts

HacWrite source into Haskell and a library of markup combinators written in

HacWrite The library also has backends for generating LaTeX and HTML

Bibliography

Ach Peter Achten Interactive Functional Programs PhD thesis

Katholieke Universiteit Nijmegen Feb

Ado Adob e Inc PostScript Language Reference Manual second edition

AddisonWesley

AGNvS Thorsten Altenkirch Veronica Gasp es Bengt Nordstrm and

Bjrn von Sydow A Users Guide to ALF Chalmers Univer

sity of Technology Sweden May Available on the WWW

ftpftpcschalmerssepubusersaltialfpsZ

AJ L Augustsson and T Johnsson Lazy ML Users Manual Pro

gramming Metho dology Group Department of Computer Sciences

Chalmers S Gteb org Sweden Distributed with the

LML compiler

Ary Kavy Arya A functional animation starterkit Journal of Func

tional Programming January

Aug Lennart Augustsson The hb c compiler

httpwwwcschalmersseaugustsshbchbchtml

AWT The Abstract Window To olkit httpjavasuncompro ductsjdkawt

Bac J Backus Can Programming b e Lib erated from the von Neumann

Style A functional style and its algebra of programs Communi

cations of the ACM August

BB G Berry and G Boudol The Chemical Abstract Machine In ACM

Principles of Programming Languages pages San Francisco

CA January

Bur W H Burge Recursive Programming Techniques AddisonWesley

Publishing Company Reading Mass

Bur W Burton Nondeterminism with Referential Transparency in

Functional Programming Languages The Computer Journal

Car Luca Cardelli Amb er In Combinator and Functional Programming

Languages numb er in LNCS pages Springer Verlag

Bibliography

Car Magnus Carlsson The Glasgow GUI Fest

httpwwwcschalmerssemagnusGuiFest July

CHa M Carlsson and T Hallgren Fudgets Graphical

User Interfaces and IO in Lazy Functional Languages

Chalmers University Anon FTP ftpcschalmersse

pubcsreportspapersfudgetreport May

CHb M Carlsson and T Hallgren Fudgets A Graphical User In

terface in a Lazy Functional Language In FPCA Conference

on Functional Programming Languages and Computer Architecture

pages ACM Press June

CH Magnus Carlsson and Thomas Hallgren Fudget library reference

manual httpwwwcschalmersseFudgetsManual

Cup J Cupitt A Brief Walk Through KAOS Technical Rep ort

Computing Lab oratory University of Kent Canterbury UK

CVM Ko en Claessen Ton Vullinghs and Erik Meijer Structuring graph

ical paradigms in TkGofer In International Conference on Func

tional Programming ACM June

CW Luca Cardelli and Peter Wegner On Understanding Typ es Data

Abstraction and Polymorphism Computing Surveys

Decemb er

Dwe A Dwelly Functions and Dynamic User Interfaces In Proceedings

of ACM pages

Ell Conal Elliott Functional reactive animation In Proc International

Conference on Functional Programming ICFP Amster

dam The Netherlands June

Eng Arnoud Engelfriet Wilbur HTML

httpwwwhtmlhelpcomreferencewilbur

FGJ Sigb jrn Finne Andrew Gordon and Simon Peyton Jones Concur

rent Haskell In rd Conference on The Principles of Program

ming Languages pages St Petersburg Florida January

FJ Sigb jorn Finne and Simon Peyton Jones Pictures A simple struc

tured graphics mo del In Glasgow Workshop on Functional Pro

gramming Ullap o ol

FP S Finne and S Peyton Jones Comp osing the user interface with

Haggis Lecture Notes in Computer Science

GJS James Gosling Bill Joy and Guy Steele The Java Language Spec

ication AddisonWesley

Gor Andrew Gordon PFL A kernel scheme for functional IO

Technical Rep ort Technical Rep ort University of Cambridge

Computer Lab oratory February

Gor Andrew D Gordon Functional Programming and InputOutput

PhD thesis Kings College University of Cambridge August

GR ER Gansner and J Reppy The eXene widgets man

ual Cornell University Anon FTP ramsescscornelledu

pubeXenedoctarZ June

Hal T Hallgren Intro duction to Realtime Multiuser Games Program

ming in LML Technical Rep ort Memo Department of Computer

Sciences Chalmers S Gteb org Sweden January

Hal Thomas Hallgren Alfa home page

httpwwwcschalmerssehallgrenAlfa

HC Thomas Hallgren and Magnus Carlsson Programming with Fud

gets In J Jeuring and E Meijer editors Advanced Functional

Programming pages Springer Verlag LNCS

HC Thomas Hallgren and Magnus Carlsson The Fudgets Home Page

httpwwwcschalmersseFudgets

HDD Ian Holyer Neil Davies and Chris Dornan The Brisk Pro ject

Concurrent and Distributed Functional Systems Technical Rep ort

CSTR Department of Computer Science University of Bris

tol June

Hen P Henderson Functional geometry In Conference Record of the

Symposium on LISP and Functional Programming Pittsburgh

PA New York NY ACM

Hol Sren Holmstrm pfl A Parallel Functional Language and Its Im

plementation PMG Memo Programming Metho dology Group

Chalmers University of Technology Gteb org

Hol Sren Holmstrm A Linear Functional Language In Proceedings

of the Workshop on Implementation of Lazy Functional Lan

guages

HPF Paul Hudak John Peterson and Joseph Fasel A gentle intro

duction to Haskell version httphaskellorgtutorial

March

HPJWe Paul Hudak Simon L Peyton Jones and Philip Wadler editors

Rep ort on the programming language haskell a nonstrict purely

functional language version SIGPLAN Notices Mar

+

J Simon Peyton Jones et al The Glasgow Haskell Compiler

httpwwwdcsglaacukfpsoftwareghc

JJ P Jansson and J Jeuring PolyP a p olytypic programming lan

guage extension In POPL The th ACM SIGPLANSIGACT

Symposium on Principles of Programming Languages pages

ACM Press

Bibliography

JJM Simon Peyton Jones Mark Jones and Erik Meijer Typ e Classes

an exploration of the design space In Proceedings of Haskel l Work

shop Amsterdam Hol land

JNR Simon Peyton Jones Thomas Nordin and Alastair Reid Green

Card a foreign language interface for Haskell In Proceedings of

Haskel l Workshop Amsterdam Hol land

Joh S C Johnson YaccYet Another Compiler Compiler Technical

Rep ort Bell labs Also in unix Programmers Manual

Volume B

Jon Mark P Jones Release notes for Gofer Technical rep ort

Department of Computer Science Yale University Novemb er

Included as part of the standard Gofer distribution

Jon Mark P Jones A system of constructor classes overloading and

implicit higherorder p olymorphism In Functional Programming

and Computer Architecture Cop enhagen Denmark June

JS SB Jones and F Sinclair Functional programming and op erating

systems The Computer journal

Kar Kent Karlsson Another Lo ok at Full Laziness In Demand Analysis

and Compilation of Lazy Functional Programs Gteb org Sweden

Septemb er

KM Gilles Kahn and David B MacQueen Coroutines and networks

of parallel pro cesses Information Pro cessing pages

NorthHolland

Kre Charles Kreitzb erg Managing for usability In Antone F Alb er ed

itor Multimedia a management perspective Wadsworth Belmont

CA

Lan P J Landin A Corresp ondence b etween Algol and Churchs

Lamb da Notation part Communications of the ACM

LO Konstantin Lufer and Martin Odersky An Extension of ML with

FirstClass Abstract Typ es In Proc Workshop on ML and its

Applications San Francisco June ACM SIGPLAN

LPJ J Launchbury and S Peyton Jones Lazy functional state threads

In Programming Languages Design and Implementation Orlando

ACM Press

Lu Konstantin Lufer Combining Typ e Classes and Existential Typ es

In Proc Latin American Informatics Conference PANEL Mex

ico Septemb er ITESMSEM

McC J McCarthy A basis for a mathematical theory of computations

In P Braort and D Hirschb erg editors Computer Programming

and Formal Systems pages NorthHolland

Mil Robin Milner A Calculcus of Communicating Systems volume

of Lecture Notes in Computer Science SpringerVerlag

Mog Eugenio Moggi Notions of computation and monads Information

and Computation

Mor A Moran Natural Semantics for NonDeterminism Licentiate

Thesis Chalmers University of Technology and University of Gte

b org Sweden May

Neta The NetBSD Pro ject httpwwwnetbsdorg

Netb Netscap e httphomenetscapecom

Nik RS Nikhil The pHluid System

wwwresearchdigitalcomCRLpersonalnikhilpHluidhomehtm

June

Nob Rob Noble Lazy Functional Components for Graphical User Inter

faces PhD thesis Dept of Computer Science University of York

Heslington York Y D England Novemb er

Nor Johan Nordlander OMELETT A Language

for Reactive Programming Licentiate Thesis

Chalmers University of Technology May

URL httpwwwcschalmerssenordlandlicpsZ

NPS Bengt Nordstrm Kent Petersson and Jan M Smith Programming

in MartinLf s Type Theory An Introduction Oxford University

Press

NR R Noble and C Runciman Functional languages and graphical

user interfaces a review and a case study Technical Rep ort YCS

Dept of Comp Sci Univ of York Heslington York Y

D England

NR Rob Noble and Colin Runciman Gadgets Lazy functional comp o

nents for graphical user interfaces In Manuel Hermenegildo and

S Doaitse Swierstra editors PLILP Seventh International

Symposium on Programming Languages Implementations Logics

and Programs volume of Lecture Notes in Computer Science

pages SpringerVerlag Sept

Nye A Nye Xlib reference manual volume OReilly Asso ciates

Inc

OD John T ODonnell Dialogues A Basis for Constructing Program

ming Environments SIGPLAN Notices Pro

ceedings of the Symp osium on Language Issues in Program

ming Environments

Oka C Okasaki Simple and Ecient Purely Functional Queues and

Dequeues Journal of Functional Programming

Bibliography

OS Bryan OSullivan Re Functional languages in software

engineering Posted to complangfunctional MessageID

nvgdfsfserp entinecom Dec

Ous JK Ousterhout Tcl and the Tk toolkit Addison Wesley

OW Martin Odersky and Philip Wadler Pizza into Java Translating

theory into practice In Proc th ACM Symposium on Principles

of Programming Languages January

Pet John Peterson The Haskell Home Page httphaskellorg

PH J Peterson and K Hammond The Haskell Rep ort Technical

Rep ort YALEUDCSRR Yale University

PHa J Peterson and K Hammond The Haskell Library Rep ort Version

Technical rep ort Yale University

PHb J Peterson and K Hammond The Haskell Rep ort Version

Technical rep ort Yale University

PJW SL Peyton Jones and P Wadler Imp erative Functional program

ming In Proceedings Symposium Principles of Programming

Languages Charleston NCarolina

Pra K V S Prasad A calculus of broadcasting systems In Volume

CAAP volume of LNCS Springer Verlag April

Pv Rinus Plasmeijer and Marko van Eekelen Concurrent Clean Lan

guage Report Avalible from the Concurrent Clean Home

Page wwwcskunnlclean

Repa J Reppy CML A Higherorder Concurrent Language In Pro

ceedings of the SIGPLAN Conference on Programming Language

Design and Implementation pages June

Repb J Reppy Cml A higherorder concurrent languages In Proceedings

of the SIGPLAN Conference on Programming Language Design

and Implementation pages

RG J Reppy and ER Gansner The eXene library man

ual Cornell University Anon FTP ramsescscornelledu

pubeXenedoctarZ June

Rja Niklas Rjemo Garbage col lection and memory eciency in lazy

functional languages PhD thesis Chalmers Tekniska Hgskola

Rjb Niklas Rjemo Highlights from nhc a spaceecient Haskell com

piler In Proc th Intl Conf on Functional Programming Lan

guages and Computer Architecture FPCA ACM Press June

RRa Niklas Rjemo and Colin Runciman Lag drag void and use heap

proling and spaceecient compilation revisited In Proc Inter

national Conference on Functional Programming ICFP

RRb Colin Runciman and Niklas Rjemo Twopass heap proling a

matter of life and death In Proceedings of the workshop on the

Implementation of Functional Languages

RS A Reid and S Singh Implementing fudgets with standard widget

sets In Glasgow functional programming workshop pages

SpringerVerlag

Sch E Scholz Four Concurrency Primitives for Haskell In Proc Haskel l

Workshop pages La Jolla CA Available as Yale Uni

versity Research Rep ort YALEUDCSRR

Sch Enno Scholz PIDGETS Unifying Pictures and Widgets in a

ConstraintBased Framework for Concurrent Functional GUI Pro

gramming In Herb ert Kuchen and S Doaitse Swierstra editors

PLILP Eighth International Symposium on Programming Lan

guages Implementations Logics and Programs numb er in

LNCS pages Septemb er

SD SD Swierstra and Luc Dup oncheel Deterministic errorcorrecting

combinator parsers In John Launchbury Erik Meijer and Tim

Sheard editors Advanced Functional Programming volume

of LNCSTutorial pages SpringerVerlag

Ser Pascal Serrarens BriX A Deterministic Concurrent Functional

X Windows System Technical rep ort Department of Computer

Science University of Bristol June

SG RW Scheier and J Gettys The X Window System ACM Trans

actions on Graphics April

Shn Ben Shneiderman Designing the user interface strategies for eec

tive humancomputer interaction Addison Wesley edition

Sin S Singh Using XViewX from Miranda In Heldal et al editors

Glasgow Workshop on Functional Programming

Sin DC Sinclair Lazy Wafe Graphical Interfaces for Functional Lan

guages Departement of Computing Science University of Glasgow

Draft

Sis Sisal language pro ject httpwwwllnlgovsisal

SML Standard ML of New Jersey httpcmb ell

labscomcmcswhatsmlnj

Sol Solaris users guide In Solaris User Collection Also at

httpdo cssuncomabcollSSUGAbPageView

Bibliography

Spa Jan Sparud Fixing Some Space Leaks without a Garbage Collector

In Proc th Intl Conf on Functional Programming Languages and

Computer Architecture FPCA pages ACM Press

June

Sto WR Stoy A new scheme for writing functional op erating systems

Technical Rep ort Computer Lab oratory Cambridge University

Sto Chris Stone Online information ab out Standard ML

httpfoxnetcscmuedusmlhtml

Tay Colin J Taylor Embracing windows Technical Rep ort NOTTCS

TR Department of Computer Science University of Notting

ham Nottingham UK Octob er

Teb M Tebbs MIRAX An Xwindow Interface for the Functional

Programming Language Miranda Technical rep ort Scho ol of En

gineering and Applied Science University of Durham April

Tho S Thompson Interactive Functional Programming In Turner

Turb

+

TLP B Thomsen L Leth S Prasad TS Kuo F Kab e and A Gi

acalone Facile Antigua Release Programming Guide Technical

Rep ort ECRC Europ ean ComputerIndustry Reserach Cen

ter GmbH

Tru Staan Truv An intro duction to the functional programming lan

guage H wwwcschalmerssetruvehintrops

Tur David Turner Functional Programming and Communicating Pro

cesses In J W de Bakker A J Nijman and P C Treleaven

editors PARLE Paral lel Architectures and Languages Europe

Volume Paral lel Languages volume of Lecture Notes in Com

puter Science pages Eindhoven The Netherlands June

Springer Berlin

Tura DA Turner An approach to functional op erating systems In

Research topics in Functional Programming Turb

Turb DA Turner editor Research topics in Functional Programming

AddisonWesley Publishing Company

VTS T Vullinghs D Tuijnman and W Schulte Lightweight GUIs for

functional programming In Proceedings th International Sympo

sium PLILP volume of LNCS Springer Verlag Septemb er

Wad P Wadler How to Replace Failure by a List of Successes In Pro

ceedings Conference on Functional Programming Languages

and Computer Architecture pages Nancy France

Wad Philip Wadler Deforestation transforming programs to eliminate

trees Theoretical Computer Science

Wad P Wadler The essence of functional programming In Proceedings

Symposium on Principles of Programming Languages pages

Albuquerque New Mexico

Wad Philip Wadler Monads for functional programming In J Jeuring

and E Meijer editors Advanced Functional Programming numb er

in LNCS pages Springer Verlag May

WB P Wadler and S Blott How to make ad hoc p olymorphism less

ad hoc In Proceedings Symposium Principles of Programming

Languages pages Austin Texas

You DA Young The X Window System Programming and Applica

tions with Xt OSFMotif Edition Prentice Hall