An interest in functional programming languages arose as a response to the software crisis of the late 1960s/early 1970s. They facilitate a number of important, although not universally appreciated, software engineering techniques: the proof of correctness of programs; the development of programs by transformation from specifications; the exploitation of parallel computer architectures. However, despite these valuable attributes of functional languages, for many years the poor performance of their implementations, and the awkwardness of programming the user and system interfaces, made them a poor choice for software developers.
This book is a new addition to the impressive range of Addison-Wesley texts on functional programming. At first I expected another text surveying the variety of functional languages currently available, the various implementation techniques commonly used and giving tuition on functional programming techniques in some selected language. Instead I found a book which fills an unoccupied niche in the Addison-Wesley stable: it is essentially a fairly complete presentation of a particular, well-regarded, implementation of the functional language (Concurrent) C1ean. The book does start with an introduction to functional languages, reduction-oriented evaluation mechanisms and the analysis of programs, but this is directed to supporting the implementation discussions which follow and is far from being a complete tutorial on functional programming techniques.
Concurrent Clean is an experimental functional language and implementation based on the notion of graph rewriting, both sequentially on single processor and on multiple processors. It is a test-bed for control annotations and optimization techniques, in particular based on the notion of unique types. The compiler generates fast code for the Motorola 68020. In a very significant experiment, Concurrent Clean incorporates a novel approach to input/output: the unique types and strict annotations allow management of input/output by single threading (components of) the input/output system state through a program. Functions acting on the system state are allowed to perform input/output by side-effect -- something usually considered taboo in the world of purely functional programming, but which is here tightly controlled by the single threading.
There is an elegant proposal for program architecture closely related to the conventional program architecture based on the events/callbacks of, for example, MIT~s X Window System. Concurrent Clean is equipped with extensive libraries for file management, and for interacting with the user through a modern graphical user interface (windows, menus, push buttons, etc.). One criticism that might be levelled against the scheme of input/output by side effect is that, if one wishes to reason about (make proofs about) the observed behaviour of a program, one cannot immediately use farmiliar functional proof techniques, as these are concerned with the results of functions and cannot be used to analyse their side-effects.
Nevertheless, speed and the programmability of the user/system interface make Concurrent Clean a highly useable system. With systems like this and no doubt with improvements still in the pipeline, I hope that there is a real chance that functional languages will start to make a greater practical impact on the world of soft-ware production.
The authors are members of a research team at the University of Nijmegen, working at the leading edge of research into the implementation of functional languages. The book is a very authoritative exploration of one 'hot and very interesting research topic' at Nijmegen, based on the team's actual experiences over a number of years. Despite this the research has 'many things in common with other approaches, so one will still get a very good overall insight on the actual problems and how they can be handled'.
The research basis of the book indicates its likely audience: advanced undergraduates students, postgraduates and researchers interested in functional programming and implementation techniques. The emphasis should be placed very strongly on the latter point: although there is some introductory material, the largest part of the text is concerned with implementation, and with the (admittedly fascinating) details of one implementation. To obtain full value for their investment, the reader must be seriously interested in how a functional language can be implemented througn graph rewriting. The book is not suitable as a general introduction to functional programming.
There are five parts to the book: an introduction to functional programming, a brief survey of the models of computation important for understanding graph rewriting, type assignment and strictness analysis for functional programs, implementation on sequential architectures and concurrency issues. Material of interest is easy to find and well presented: each chapter starts with an abstract and ends with a summary of the main points -- very readable and helpful. There are exercises at the end of each chapter -- ranging up to mini programming objects: however, no solutions are given -- a distinct negative point where there are exercises testing the precise understanding of a chapter.
A strong positive point is that te Concurrent Clean software can be ordered from the authors. This includes a programming environment, interpreter, code generator and input/output Iibraries. The system is especiailly designed for the Apple Macintosh, but is available on other platforms too. I have not yet had the opportunity to test the software, but one of my colleagues has been using it in his own research (not in the field of functional programming) and is very enthusiastic.
In summary, a very interesting book, an enjoyable read. although many of the details will be digestable only to those deeply involved in implementation issues. The book is important to the presentation of its novel approach to input/output and program architecture.