John Hughes, Datalogi

(Texten finns enbart på engelska)

As computer hardware becomes cheaper and more powerful, users expect software to be more sophisticated and it is therefore becoming more costly. This imbalance between the falling costs of hardware and rising costs of software is called the software crisis, and has inspired many attempts to speed up programming dramatically. One approach is to build programs by reusing standard parts, rather than crafting each line by hand as is often the case today. Software reuse aims to cut costs and improve quality, since the standard parts should be error-free. But it is hampered by the inflexibility and fragility of today’s software: a piece of software for one task often cannot be used to solve a closely related problem, and software fragments often do not work in isolation. A well-known approach to these problems is object-oriented programming, which has the advantage that it is close to conventional programming practice. A more radical approach is functional programming.

Functional programs are based on functions: a program is just a function, receiving its inputs as arguments, and producing its output as its result. Program fragments only interact with their environment via arguments and results, and therefore work independently. Moreover, functional languages abstract away from time and space: a program specifies only what calculations to perform, not when they should be performed or where the results should be stored. As a result, one structure can represent many conventional structures — for example, a sequence of values can represent an array (of values stored in different locations at the same time), a variable (storing values at the same location at different times), or a buffer (storing a limited number of values at any one time). A program fragment that operates on sequences can be used in all of these cases, and is therefore more flexible than its conventional counterpart. Finally, programs may operate not only on data such as integers, but on functions — i.e. programs. The functional programmer writes a program to build the desired program, which is much more effective than writing it all by hand.

Ideally, applications are built just by combining existing functions from a library. A good example is the library for programming X-windows user interfaces developed here by Magnus Carlsson and Thomas Hallgren. Program fragments (’fudgets’) manage a part of the screen — for example, a display panel or a button. The library defines functions for combining fudgets, for example by placing one above another. The calculator interface in the photograph consists of a display, above an invisible fudget that processes button clicks, above an array of buttons. The entire user interface is built by combining library functions — only the processing of buttons, the software interfaced to, must be written by hand.


The calculator and the clock are examples of functional user-interfaces, built with only a few lines of code which combine fudgets from the library.

This programming freedom comes at a price, however. The implementation is responsible for deciding how time and space are used. Such decisions are easiest to make while the program is running, since most information is then available. But each decision takes time to make, and the record-keeping necessary to support such flexibility is costly. Alternatively, given enough information the compiler can decide while translating the program to machine instructions. This is cheaper, and allows execution to be planned to minimise record-keeping and other costs. But it places great demands on compile-time analysis of programs, the process of deriving the information the compiler needs.

At present I am working on the trade-off between time spent on this compile-time analysis and the accuracy of the results, with a new method that promises to deliver accurate information thousands of times faster than previous techniques.

(Texten publicerades 1992 i skriften Ny kunskap.)