We have already seen problems that the march of time presents to computer language in the previous chapter (§4.3). It can be useful to separate the declarativewhatfrom the imperative how, but when the behaviour of an algorithm over time is important to the aesthetics of a digital artwork, the howisthe what. We introduced Tidal, which illustrates this point well, being a paern DSL solely concerned with the notation of events in time (§4.5).
Designers of conventional programming languages consider time in terms of efficiency, and as something to be saved or spent. For those designing languages for the time based arts, time is rather part of the structure of the experience that is being represented, a stratum of both digital paern and analogue movement.
ere is however an awkwardness about the relationship between thewhatof notation and howof the passage of time. On one level they seem separate: a declarative description of a time structure is one thing, and an imperative algorithm for accurately and efficiently producing that structure may be quite another. But in practice they rarely are completely separate, the algorithm leaves its imprint, paerning its output. On recognising the ‘glitches’ arising from the operation of a particular algorithm, artists bring them into the music itself (Cascone, 2000). Time may always be relied upon to pass, and it passes not only during a program’s interpre- tation but during the activity of notation itself. is is of concern to programming languages designed for the arts, where the separate timelines of development and execution effectively separates an artist from their target medium. Figure 5.1 shows the Processing programming environment, which is an adaptation of the general purpose Java programming language, and is designed for artists who are learning programming. To this end the interface has few distrac- tions, and makes running a program very straightforward: the programmer simply presses the ‘play’ buon marked with an icon familiar from music equipment. Nonetheless, the program- mer must stop writing code, press the buon and wait a lile while before seeing the results of their work. is is not wholly bad, and may be thought in terms of an artist taking a step back from their work to pause in consideration. However, such periods of reflection should be taken on an artist’s own terms, and not forced upon them by an external process.
C 5: N
Figure 5.1:e Processing programming environment. Every time the ‘play’ buon is pressed, the program is compiled and executed, with no state preserved between successive runs (unless explicitly defined).
Figure 5.2: e Fluxus programming environment. e editor containing the source code of a program is embedded in the same 3D scene as its output. e source is dynamically interpreted, so that the program may be anged during a live coding performance (§6.8).
C 5: N
step in an arts context. We will investigate the creative processes of live coding more broadly in§6.8, and so for now focus on notational aspects, in particular, how the removal of the com- pilation step results in the intertwining of active notation with interpretation. Figure 5.2 shows the Fluxus interface, where the code editor is placed in the same scene as the process output. ere is no ‘play’ buon in Fluxus as such, instead the code is continuously playing. Incremen- tal changes to the source code are reflected in the output whenever the programmer presses the F5 buon. e visual form of the code is more literally part of its own output; the visual output is a 3D scene, of which the text editor is part. It is therefore possible to write a program that modifies the display of its own code.
How is live coding technically possible? Using the programming environments that have become conventional, artists cannot generally experience what they make at the same time as they are making it. is problem may seem insurmountable; while it runs, a program maintains state, its ‘working memory’, the data generated and collected during its execution. Such data may come with no description apart from its declaration in program code. If one then changes the program code, there may be no mechanism in which the new version of the program may continue where the old version le off, as the old state may be of no use to the new version of the program. e cognitive dimension of progressive evaluationtherefore seems difficult to achieve. ere are however a number of ways in which it can be done, although each case has significant impacts on other cognitive dimensions.
External grounding. For certain task domains, the internal state of a program has lile or no significance. is is the case in Tidal (§4.5), where just about the only ‘state’ is the measurement of time kept by a separate process, the system clock. It is also the case in languages known as UNIX systemshells. ese developed from research intoconversational programming(Kupka and Wilsing, 1980), where programmers interact with a language interpreter one statement at a time, able to consider systems feedback at each step. Conversational programming lives on in shell languages such as Bash, where the state is global to the whole computer system, with access control for security. In particular, state is almost exclusively held within the filesystem, a tree structure able to hold not only permanent files on disks, but processes, their environment variables and working ‘core’ memory (Filesystem Hierarchy Standard Group, 2003). As such a shell programmer tends to work with live data, making irreversible and at times drastic actions, an impact along the cognitive dimension ofpremature commitment. However some systems, including some file systems and relational databases, implementtransactions, allowing a series of successive actions to be iteratively applied, but not commied. When live coders work before an audience, turning back performance time is impossible, but being able to roll back
C 5: N
development to a previous version, for example for musical reprise, is certainly useful.
Internal grounding. is approach toprogressive evaluation defines state in such a way that it may be passed from one version of a program to the next. is is conceptually similar to external grounding above, except the state is not shared with other processes. e programmer is le with thehard mental operationof being aware of certain conflicts that may arise, for example if a variable with the same name is used for different purposes in a successive ver- sion of the code, state will be carried across to unintended effect. In a strictly typed language such as Haskell, state is handled in a highly formalised manner, and so it is possible to arrange for a program to return its entire state for coercion into a form suitable for its successive ver- sion (Stewart and Chakravarty, 2005). Alternatively, dynamic scripting languages such as Perl make it straightforward to evaluate code that replaces existing functions, where state may be preserved using global variables.
Self-modification. A rather unusual approach, developed in theFeedba.pllive coding en- vironment by the present author, is to store state in the source code itself (McLean, 2004). e programmer is put in the position of writing code that stores, reads and modifies values in its own description. is is done either by programmatically updating assignment statements, or storing values as program comments, so thatsecondary notationis parsed and modified by its own program. is creates an interaction where the source code is used to modify both the instructions and state of a process, and also to show output from its execution.
Temporal recursion. is term was coined by Sorensen (2005) in describing the operation of the music live coding system Impromptu, based around the Lisp derivative Scheme. A recursive function is one that calls itself, and a temporal recursive one is one that calls itself but with a scheduled delay. Progressive evaluationis then simply a case of swapping one function for another between self-calls.
Hybrid. A hybrid approach is certainly possible, exemplified by SuperCollider, a music pro- gramming language with two concurrent processes. One process maintains a pure functional graph for sound synthesis, while the other acts as a dynamic language interpreter. e lan- guage process manages such tasks as scheduling events and signalling graph changes of the synthesis process. e synthesis process is largely stateless, and care must be taken to avoid discontinuities when the graph is changed, audible as clicks. JITLib has been developed to aid this, providing a means to transition audio between successive versions of code (Rohrhuber et al., 2005).
C 5: N
e above methods all act to embed program development in a timeline shared with its execution, with practical applications being explored in the arts. We now move from the role of time in notation, to examine the role ofspace.