• No results found

Declarative vs Imperative

Declarative and imperative programming are competing paradigms, an opposition that raises interesting issues for the time-based computer arts. Declarative programming is the coding ofwhatshould happen, and imperative programming is the coding ofhowsomething should occur. is distinction is frequently used, and gives a sense of what is meant, but lacks practical detail. is situation is reminiscent of that of the definition of timbre in music§3.3; an important distinguishing feature within a domain, that is oen defined in vague and sometimes conflicting terms.

e use of computer language can be broadly divided into the description of algorithmic control, and of problem logic (Kowalski, 1979). Imperative programming languages support the former, where programmers describe a method for solving a problem, rather that the problem itself. Declarative programming languages support the laer, allowing programmers to focus on the description of problems, by leaving the interpreter to find the algorithmic solution. Well- known examples of declarative programming languages include the logic language Prolog, the database query language SQL, and the string matching language Regular Expressions (ch. 2). ese are as close as we get to the declarative promise, of programmers concerning themselves only with what they want to do, and not how it should be done. is promise holds for simple examples, but unfortunately hardly at all in practice. SQL database query optimisers are in constant development, and programmers must keep abreast of exact implementation details, structuring their queries and indexing their datasets in a way that allows their SQL queries to operate efficiently. Upgrading to a new version of an SQL engine is then a serious maer, as optimisations for general cases may have led to serious regressions in edge cases. Likewise, reg- ular expressions must be carefully craed for a particular interpreter, where implementation details such as backtracking or determinism can impact computational complexity by several orders of magnitude (Friedl, 2006). Prolog programmers have much the same problem, classi- cally requiring manual search space reduction by inhibiting backtracking, a technique known as thecut(Sterling and Shapiro, 1994).

C 4: L

While the imperative frequently intrudes, declarative programming styles nonetheless maintain a certain clarity of expression, giving high level descriptions largely separate from implementation details. is is related to the idea of purity inpure functional languages such as ML (Milner et al., 1990), where functions have no side-effects. is means a pure functional program cannot interact with the outside world while it is executing, beyond the singular, or- derly flow of input and output. Haskell is a pure functional programming language from the ML family, but gets around this limitation through modelling side-effects by chaining together pure functions. e result is a declarative description of an imperative program, which the interpreter then takes care of executing.

Another distinction made between declarative and imperative programming (e.g. Dijkstra, 1985) is concerned with the passing of time. In declarative programming, time is a concern of optimisation, to be separated as much as possible from the problem description. In imperative programming one statement follows another, describing a sequence of operations, each with its own time ‘cost’. In the general case this makes a great deal of sense; the imperative ‘how’ approach is concerned with algorithms as programmes of work over time, and the declarative ‘what’ approach with logical relationships abstract from time. However within our theme of the design of programming languages for artists, the focus on time is problematic. In particular, when we consider the time-based arts, the unfolding of an algorithm over time isboth the imperative howandthe declarative what. In this case, the distinction between declarative and imperative programming appears to not apply, as the particular operation of how an algorithm works has strong influence over what we experience. If the distinction is to make any sense in this context, it must be defined carefully.

We argue that a declarative approach to programming is indeed desirable for artists. We define it however not in general terms, or even relative to algorithms, but as the closeness of mapping(§5.1) of the programming notation to the target domain. If a programmer is only interested in logic, then a declarative approach is to choose a programming language that takes care of how a program is solved over time. However if our programmer is interested in the problem of how to complete a piece of music, then they are concerned with how the solution is arrived at as well as the problem; the howisthe what. A declarative approach in this case would then be concerned with how events are ordered to reach a musical resolution. is does not however mean precisely specifying an algorithm, certain aspects of operation may be musically inconsequential, and so may be specified in an ambiguous manner.

Our characterisation of declarative programming is closely related to the concept of Do- main Specific Language (DSL) (van Deursen et al., 2000). To a limited extent, a straightforward programming library is DSL, in that it provides functions particular to a domain. However in

C 4: L

a fuller sense, DSL goes further to provide higher order means of abstraction and combina- tion tailored to the target domain, allowing programmers to find the level of abstraction that best mirrors the structure of their problem. For example, a computer musician working with paerns may create language for combining functions which represent generation and trans- formation of paern. We will approach this subject in depth in the following section, before introducing Tidal, DSL for live coding of paern.