Andrea Agostini
email: andreaagostini@conservatoriotorino.eu

Daniele Ghisi
email: danieleghisi@berkeley.edu

Jean-Louis Giavitto
email: jean-louis.giavitto@ircam.fr

Andrea Agostin

Programming in style with bach

Keywords: Programming paradigms, computer-aided composition, Max, bach, bell

à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des établissements d'enseignement et de recherche français ou étrangers, des laboratoires publics ou privés.

Introduction

In spite of the way it is advertised, its own Turing-completeness and the sheer amount and complexity of things that have been done with it, programming in Max is difficult. Whereas setting up simple interactive processes with rich graphical interfaces may be immediate, it has been long observed that implementing nontrivial algorithms is far from straightforward, and the resulting programs are often very difficult to analyse, maintain and debug.

Several other popular programming languages and environments for computer music, such as OpenMusic [START_REF] Agon | OpenMusic : Un langage visuel pour la composition musicale assistée par ordinateur[END_REF], PWGL [START_REF] Laurson | PWGL: A Novel Visual Language based on Common Lisp, CLOS and OpenGL[END_REF] and Faust [START_REF] Orlarey | Faust: an efficient functional approach to dsp programming[END_REF], share with Max a superficially similar, but profoundly different, dataflow programming paradigm, which makes them better suited for 'real' programming and less for setting up highly interactive and responsive systems. This is reflected in the types of artistic practices these systems are typically used for, and mirrors the oft-discussed rift between composition-and performance-oriented tools in computer music [START_REF] Puckette | A divide between 'compositional' and 'performative' aspects of Pd[END_REF].

We are convinced that this rift is by no means necessary or natural, and, on the contrary, has proven problematic with respect to a wide array of practices lying somehow between the two categories, such as extemporaneous, 'intuitionistic' approaches to composition (including, but not limited to, improvisation), sound-based and multimedia installations, live coding and more.

In this paper, we shall investigate this divide and its reasons from the point of view of computational models, and consider how it can be bridged, or at least narrowed, through the use of the bach package for Max [START_REF] Agostini | A Max Library for Musical Notation and Computer-Aided Composition[END_REF].

Dataflow computational models

The concept of dataflow is an old one, dating back at least to [START_REF] Conway | Design of a separable transition-diagram compiler[END_REF], which first introduced the idea of independent computational modules communicating by sending data (discrete items) among directed links. Over the years, many kinds of dataflow computation models have been developed. In this section, we shall review some of them and how they apply to different languages and software systems for computer music.

The dataflow model

The term dataflow refers to a whole family of execution models that can be described by autonomous entities, called actors or processes interacting only through links connecting their input and output ports 4 . An actors triggers a computation according to the availability of data on its input ports and delivers its results on its output ports. The sequence of data passing through a link make up a stream and each value in the sequence is called a token. A token is sent through an output port and received by one or more destination actors, each of which retrieves the token through an input port. Often a dataflow graph (DFG) defines a whole computation that must be iterated periodically on a sequence of data (periodic dataflow). This is simply modeled by considering the stream of inputs.

The different dataflow execution models differ in the static or dynamic nature of the connection graph, the activation strategy of the actors, the capacity of the links to temporarily store the data produced (FIFO buffer), and the type of computation performed by each actor. By varying these parameters, the dataflow model is able to describe, in a unified manner, execution models ranging from electronic circuits to functional programming through audio graphs.

Homogeneous synchronous dataflow

One specific dataflow model is particularly useful, since it corresponds to the kind of computations done in real-time signal processing: the synchronous dataflow (SDF), also called the static dataflow. In this specific model, the graph is fixed and the order in which actors trigger their computations does not depend on the data that is processed (i.e., the value of the token).

In homogeneous SDF, an actor fires its computation when there is a token on each of its input port and produces a token on each output port. In other word, the connections are FIFO of size one and the activation of actors never leads to a buffer overflow. Homogeneous SDF corresponds well to audio graphs where tokens correspond to audio buffers and actors to unit generators, delays, filters and other effects. It also matches well the behavior of synchronous (clocked) electronic digital circuit: an actor is an electronic gate and a token is the value of the voltage on a pin. A clock is used to acquire and deliver the tokens simultaneously for all the gates.

Dynamic dataflow

The SDF model is not particularly expressive. A number of dataflow variants have been developed that relax the constraints of SDF. We loosely refer to them as dynamic dataflow (DDF). In DDF, the activation of an actor can be more complicated and the firing strategy may change in time, for instance with some internal state of the actor. The number of tokens produced can also vary on each output ports. This makes possible to express conditional firing, i.e., an actor triggers its computation only if the input token has a particular value.

For instance, the audio graph in Max5 is a SDF, while the control graph is a DDF in which the firing of an actor is driven by the so-called 'hot' inlets, and not by the availability of the incoming messages on all inlets. Which inlet is 'hot' may also depend on the specific data arriving in non-'hot' (or 'cold') inlets (as for example in the switch box). Moreover, the activation of a box does not lead necessarily to each of their outlets firing (as for example in the gate box). As for patchcords, the ones connecting an outlet to a cold inlet do not store the whole sequence of messages in transit before being consumed by the target, as only the last one (i.e., the most recent) is kept until its consumption.

DDF is also needed to handle several rates in an audio graph, for instance for the handling multimedia streams (audio and video).

Data-driven and demand-driven implementation strategies

Historically, there are two main approaches for the software implementation of dataflow: the data-driven approach and the demand-driven one. Data-driven. In the data-driven implementation, tokens travel in the interconnection graph and fire according to the actors. The activation of the actors propagates in the graph like a wave starting at the inputs and ending at the outputs, i.e. actors that have no output ports and that are used to 'deliver' the result of the calculation (be it in the form of text, audio, MIDI data, image display, etc.).

In SDF, tokens can be presented asynchronously to the input ports but the actors fire only when all their inputs bear a token. If the graph is homogeneous, then a token is produced on each of the output ports and, subsequently, actors that lie at a distance 1 from the inputs are activated, and so on. Therefore, the functioning of the dataflow graph in time can be seen as a sequence of 'rounds', that is, transactions in which the first token of all input streams is consumed and a token is produced for all output streams (hence the term "synchronous"). In this context, the order of activation of the actors can be fixed a priori, through a static analysis of the graph itself, and can be computed by a simple topological sort of the graph, as long as it is loop-free (also see below).

Both Max's and Pure Data's audio and control graphs are implemented using a data-driven approach. Once the user has laid out graphically the audio graph, the program analyses it statically and, if there are no errors (typically resulting from a feedback connection) an internal representation of it is generated, also establishing a fixed sequence of activations. Things are different for the control graphs: since their behavior depend on the data they receive, their scheduling cannot be fixed statically.

Demand-driven. The demand-driven approach is more convenient to handle DDF. In this approach, the outputs of the graph require a token from their connected actors, which in turn transmit the request to their inputs, so that a wave of requests propagates through the graph, from its outputs to its inputs. Each input of the graph answers the request by sending the requested token, which is then processed, creating a second wave of computations from the inputs to the outputs.

The demand-driven approach is interesting because it may handle easily nonhomogeneous dataflow graphs. It is not by chance that it was chosen a model for the Patchwork family of tools, OpenMusic and PWGL. For instance, in Open-Music's dataflow graphs, each node implements a function. Functions can be non-strict, i.e., they may use only part of the inputs to produce the output. An example is the conditional operator if that returns the value of one of its two inlets following the boolean value present on a third inlet. Handling correctly non-strict functions is necessary for defining recursive functions: if the conditional operator were strict, the retrieval of both inputs would be required and the computation of recursive functions would loop forever, since even in the terminal case all branches would have been computed.

The demand-driven approach makes the implementation of non-homogeneous dataflow easier. In these models, the firing of an actor may consume an arbitrary number of token on each input, and may produce an arbitrary number of tokens on each output. In this case, an actor would request to its inputs the number of tokens it needs. This can be used to simplify the handling of multirate audio graphs.

The Kahn principle: reconciling the operational and the algebraic view

The previous considerations sketch an operational view of the functioning of a dataflow graph: the graph is a machine similar to an electrical circuit and the functioning of the graph amounts to moving tokens along the links and to transform the values of the tokens when passing through an actor.

Another, more abstract, view of the graph has an algebraic flavour. The idea is to assign a variable to each connection from an output port to an input port and to describe the interaction graph by a set of equations linking such variables -one equation for each output port. We can assume that there is only one output port labeled with variable y for an actor a. 6 Then, the equation y = a(x 1 , x 2 , . . . ) represents the relationships between the inputs x 1 , x 2 , . . . and the output y (cf. the diagram below, at left). The symbol a refers to the behavior of actor a and there are several mathematical ways to model this behavior. For instance, a can be a function of the tokens. In this case, the variable denotes the "current token value" instead of the entire stream.

a x 1 x 2 • • • y 1 y 1 = a(x 1 , x 2 , . . . ) * * + g 1 s 1 g 2 s 2 y 1 y 2 y 3      y 1 = g 1 * s 1 y 2 = g 2 * s 2 y 3 = y 1 + y 2
With this interpretation, the set of equations associated to a DFG can be interpreted as an ordinary set of equations between real values. The right side of the diagram above models a simple two-input mixer, with gain g 1 and g 2 . Notice that the set of equations is a set of fixed point equations, that is, each equation takes the form variable = expression-involving-variables .

The interesting point is that, in this example, solving the algebraic equations associated with the DFG gives the same result as the operation of the DFG in terms of tokens movement and tokens transformation (the operational view). However, restricting the behavior of a node to a function of the current input tokens is too restrictive: for instance, this mathematical model cannot represent a node whose behavior depends of an internal memory, like a delay (see next section). But the actor operation in the example above can be interpreted as function acting on entire streams, the operators * and + being the point-wise multiplication and the point-wise addition of the stream's elements.

A DFG where the behavior of each actor can be modeled as a continuous function of the entire input streams to the output streams is said to be pure. It has been postulated by Kahn [START_REF] Kahn | The semantics of a simple language for parallel programming[END_REF], and proven only ten years later by Faustini in [START_REF] Faustini | Extending bach: A family of libraries for real-time computer-assisted composition in max[END_REF], that the operational behavior of a pure DFG computes the least fixed point solution of its associated set of equations. The understanding of this result requires to define precisely what is meant by continuous and least. Intuitively, we can say that a set of equations may have zero or more solutions. This result states that there is at least one solution, and that the graph computes the stream solution that is minimal according to a carefully chosen stream comparison order [START_REF] Mosses | Handbook of Theoretical Computer Science[END_REF].

Feedback loops

The previous example of fixed point equations is not very interesting: these equations remain simple because there is no circular dependencies between variables. Fixed point equations of this kind are easily solved by substituting known variables (here g 1 , s 1 , g 2 and s 2 ) in the expressions at the right hand side of the equations and repeating this process until there is no further unknown variable.

In the example, the first iteration defines variables y 1 and y 2 and the second iteration defines y 3 .

+ delay x 1 x 3 x 2 x 2 = x 1 + x 3 x 3 = delay(x 2 )
The Kahn principle is valid for any pure DFG, including DFG having feedback loops. In the example at left, x 1 is an input of the DFG and the operator delay is on the feedback loop going from the output of + to its input. Here delay is a function shifting the entire stream

s = v 0 • v 1 • v 2 • . . . in time: delay(s) = 0 • v 0 • v 1 • v 2 • . . . . Opera-
tionally, the delay is a memory initially filled with 0.

When a token is present at the input, the delay outputs the value in the memory and then update the memory with the input value. One can convince oneself that this DFG computes the sum of its successive inputs.

The corresponding equations exhibit a self-dependency: if we substitute the definition of x 2 into the right hand side of x 3 , we get x 3 = delay(x 1 + x 3 ) which cannot be solved by substituting the variables but we can look instead at what happens at the level of the stream's elements: let the stream

x i be x 0 i • . . . • x j i • . . . x 0 3 • . . . • x j 3 • • • • = 0 • (x 0 1 + x 0 3 ) • . . . • (x j 1 + x j 3 ) • . . . that is, x 0 3 = 0, x j+1 3 = x j 1 + x j 3
or, in other word, x 3 is the running sum of the successive values of x 1 .

Time in dataflow: synchronous languages

In the previous example, one may notice that delay is a function acting on stream, not a function acting on tokens. This allows the specification of behaviors implying a transfer of information from one token to the next one. However, this is not enough to model the behavior of a node acting to merge to streams.

merge x 1 x 2 y
The merge actor simply transmits the tokens that present themselves at its inputs towards its outputs, in their arrival order. The first problem is to decide what happens when tokens are simultaneously available on the two inputs. One may chose to transmit the token on the first input and to drop the second token. This way, the merge operator has a deterministic behavior.

But even so, it cannot be modeled as a stream function.

The reason is that SDF does not provide enough information on the passing of time. For instance, suppose that stream s represents the value 0 produced every two seconds starting from date 0, while s represents the value 1 produced every two seconds, starting from date 1. Then merge(s, s ) has for result the stream 0

• 1 • 0 • 1 • . . .
Let s be the stream representing the value 1 produce every four seconds, starting from date 1, then we have merge(s, s

) = 0•1•0•0•0•1•0•0•0•1•. . . even if s = s .
Obviously, the lack of temporal information in the stream makes the stream s and s indistinguishable, even if they model two different processes and so there is no function merge on streams.

The problem was recognized in the real-time programming community and lead to the development of synchronous languages like LUSTRE [START_REF] Halbwachs | The synchronous data flow programming language lustre[END_REF]. In this dataflow programming language, the idea is to "align" each stream so the production of the i th value of any stream takes place on the same date. This is achieved by introducing a special token value ⊥ meaning "an actual value is not available". With this token, the synchronized streams s and s are presented by:

s = ⊥ • 1 • ⊥ • 1 • ⊥ • 1 • ⊥ • . . . s = ⊥ • 1 • ⊥ • ⊥ • ⊥ • 1 • ⊥ • . . .
The Kahn principle holds for fixed point equations on these synchronized streams and more actors can be specified as stream functions.

Declarative programming

If we insist on Kahn's principle, this is because it leads to a declarative programming language. It is commonly said that that declarative programming focuses on what the program should accomplish (whereas imperative or procedural programming focuses on how the program should achieve the result). This description is rather vague, and a more effective way to look at it is to characterize declarative programming languages as programming languages making possible equational reasoning, where an entity may always be substituted by its definition. In other word, the statement of the language can be seen as a set of mathematical definitions, that is, a set of fixed point equations, and program execution amounts to finding a solution to these equations.

In this context, a variable in a program is handled exactly as a mathematical variable: a reference to a well defined although possibly unknown value. This departs considerably from the notion of variable in an imperative program where a variable refers to a memory location which can holds various values during the program execution.

By definition, declarative programming enjoys transparential referency: any expression can be replaced with its corresponding value without changing the program's behavior [START_REF] Søndergaard | Referential transparency, definiteness and unfoldability[END_REF].

A program becomes a mathematical object that can be manipulated using classical mathematical methods, for instance to prove program properties for efficient compilation, to replace an expression by an equivalent expression less costly to compute, to rearrange program computations much more freely, possibly to execute some tasks in parallel.

The Kahn principle give us a tool to solve some equations on streams. It also allows us to reason algebraically on the operational properties of a dataflow program.

Dataflow and computer music programming languages

The previous section may seem very technical but they have far reaching consequences in the realm of computer music programming languages. Several languages and systems, such as OpenMusic, PWGL and Faust, are based upon more or less pure SDF:

-The core of OpenMusic and PWGL is a demand-driven implementation of a pure dataflow. However, the language embeds some imperative features that are useful for interacting with users (e.g., fixing some computed value to be reused in later evaluation). Interestingly, a specific version of OpenMusic, OM#, extends the demand-driven execution model towards an hybrid data-and demand-driven execution model which simplify considerably the programming of reactive system [START_REF] Bresson | A reactive extension of the openmusic visual programming language[END_REF].

-Faust [START_REF] Orlarey | Syntactical and semantical aspects of faust[END_REF] is a perfect example of data-driven, pure synchronous dataflow.

Equational reasoning is heavily used in the Faust compiler, for code generation (by program transformation) but also for the automatic parallelisation [START_REF] Orlarey | Parallelization of audio applications with faust[END_REF]. -Synchronous programming-which involves synchronous streams, either in the context of dataflow or in the context of imperative languages-is the model embraced by signal processing languages like CHUCK [START_REF] Wang | Chuck: A strongly timed computer music language[END_REF] or KRO-NOS [START_REF] Norilo | Introducing kronos-a novel approach to signal processing languages[END_REF].

Dataflow programming in Max and Pd

As previously mentioned, Max and PureData implement two different dataflow systems, respectively devoted to audio signals and control messages. The earliest versions of Max only implemented the former system, as Max itself had been originally conceived as a tool for building interfaces controlling external audio hardware. The audio system was only added to Max in the late 1990s, and was so distinctly separated from the 'core' of Max itself that it used to be sold separately under a different name, MSP.

The Max audio graph is a relatively simple case of pure SDF, whose functional nature is somewhat less explicit than that of Faust, but not too different from it. Our discussion will only focus on the control graph, its significantly different paradigm and the consequences this bears with respect to the different applications Max lends itself to, with a specific focus on the implementation of compositional processes.

In what follows, we shall assume in the reader a basic, practical knowledge of Max, and only review some fundamental concepts when needed.

A Max patch can be seen as a set of nodes working asynchronously with respect to each other: if, when and how each module 'fires' depends on the data processed, and, generally speaking, only one message can traverse the patch at any given time. This means that nodes with more than one input link must have mechanisms for storing data for later use. This is accomplished through the socalled 'hot' and 'cold' inlets (that is, input links in the Max jargon): when a hot inlet receives a message, it performs its computation and delivers the result; but when a message is received in a cold one, it gets stored for later use and nothing else happens. Most Max objects have at least one hot inlet, and many have one or more cold inlets.

This structure, which actually involves many other details and is not without exceptions, has a profound consequences: there is no transparential referency in the control DFG.

For example, multiple links ('cords' in the Max jargon) can be connected to a single inlet corresponding to an implicit merge. But there is no notion of synchronous stream in Max: there is no notion of timestamp that can be used to "align" the streams values and to recover transparential referency. Another example of non-transparential referency: sending the same message, that is, outputting a token on some link, does not achieve the same effect if done on the timer thread or on the main thread (because of different message priorities, its subsequent handling may differ).

Pros and cons of different computational models

Max's computational model is motivated by the fact that, unlike the other systems described above, it was not conceived as a programming language but, in its own creator's words [START_REF] Puckette | Max at seventeen[END_REF], as a musical instrument. With respect to this end, Max has the merit of being extremely economical in terms of its basic principles and quite adaptable to very different use cases.

On the other hand, as hinted at above, representing nontrivial algorithms in Max is often more complicated than with other systems. Two of the authors became painfully aware of this complicatedness while working at the cage package [START_REF] Agostini | cage: a High-Level Library for Real-Time Computer-Aided Composition[END_REF], which implements a comprehensive set of typical computer-aided composition operations. cage is entirely composed of abstractions, and during its development the shortcomings of Max programming became so evident that the seeds for the work presented in this article were planted.

The reasons for this difficulty are multiple, and include the following:

-The greater freedom Max grants in building the program graph easily leads to far more intricate patches than functional dataflow models, with spaghetti connections that can grow very hard to analyse. -Typical Max patches often have their state distributed through many objects whose main, individual purpose is not data storage. -Max lacks, or implements in quite idiosyncratic ways, some concepts that are ubiquitous in modern programming languages, such as complex, hierarchical data structures, iteration, data encapsulation, functions and parametrization of a process through other processes.

On the other hand, Max allows to incorporate, on top of its basic paradigm, traits reminiscent of various programming styles, such as imperative, objectoriented and functional. Moreover, it includes various objects enclosing entire language interpreters, thus allowing textual code in various languages to be embedded in a patch.

These features may prove useful when nontrivial processes have to be implemented, as is the case when working in contexts like algorithmic and computeraided composition. Whereas Max was not conceived with these specific applications in mind, it quickly became clear that it could be a valuable environment for them, and several projects have been developed in this sense [START_REF] Winkler | Composing Interactive Music[END_REF][START_REF] Scholl | Musik -Raum -Technik. Zur Entwicklung und Anwendung der graphischen Programmierumgebung[END_REF][START_REF] Didkovsky | Maxscore: Music Notation in Max/MSP[END_REF]. We shall focus on one of them, the bach package, which has been conceived and is maintained by two of the authors.

The bach package

The bach package 7 for Max is an open source library of more than 200 modules aimed at augmenting Max with advanced capabilities of symbolic musical representation. At its forefront are two objects called bach.roll and bach.score, capable of displaying, editing and playing back musical scores composed of both traditional notation and arbitrary time-based data, such as parameters for sound synthesis and processing, textual or graphical performance instructions, file paths and more. 8One of the main focuses of bach is algorithmic generation and manipulation of such scores. To this end, bach implements in Max a tree data structure called llll (an acronym for Lisp-like linked list), meant to represent arbitrary data including whole augmented scores. bach objects and abstractions exchange lllls with each other, rather than regular Max messages, and their majority is devoted to performing typical list operations such as reversal, rotation, search, transposition, sorting and so on.

Generally speaking, bach objects abide by the overall design principles and conventions of Max, but it should be remarked that, whereas standard Max objects can control the flow of lllls in a patcher just like they do with regular Max messages, they cannot access their contents unless lllls are explicitly converted into a Max-readable format, which on the other hand has other limitations (for a detailed explanation, see [START_REF] Agostini | A Max Library for Musical Notation and Computer-Aided Composition[END_REF]). Thus, bach contains a large number of objects that somehow extend to lllls the functionalities of standard Max objects. For example, whereas the zl.rev object reverses a plain Max list, the bach.rev object reverses an llll by taking into account all the branches of the tree, each of which can be reversed as well or not according to specific settings. Whereas it is possible to convert an llll into the Max format and reverse it with zl.rev, in general the result will not be semantically and syntactically correct.

Since its beginnings, bach has been strongly influenced by and related to a number of other existing projects: for an overview of at least some of them, see [START_REF] Agostini | A Max Library for Musical Notation and Computer-Aided Composition[END_REF]. The synthesis of different approaches that lies at the very basis of the conception itself of bach has been validated by a large community of users, who have developed many artistic and research projects in several domains9 , and by the fact that it provides the foundation for the cage and dada10 libraries [12].

In the following sections, we shall review a few programming styles and approaches and see how bach can be helpful with adopting them in Max: namely, we shall show how some fundamentally imperative, functional and objectedoriented traits of Max can be leveraged through the use of specific bach objects and design patterns; moreover, we shall discuss a recent addition to bach, that is, a multi-paradigm programming language called bell and meant to facilitate the expression of complex algorithms for manipulating lllls.

Different programming styles and approaches in Max

Imperative approach

It has been observed that Max is essentially an imperative system in disguise [START_REF] Desain | Putting Max in Perspective[END_REF]: as stated before, any nontrivial program in Max requires to take care of states and the order of operations, and analysing even a moderately complex patch can only be done by following the flow of data and the evolution of states over time. This is complicated by the fact that many objects whose purpose is carrying out specific operations also maintain a state that can be used to store values for later use. For example, most arithmetic operators have two inlets: the left one, called hot, sets the first term of the operation and triggers the calculation; the right one, called cold, only sets the second term of the operation. So, the typical way to perform, say, a sum of two numbers is first setting the right term, and then the left term, thus calculating the result. This somewhat idiosyncratic design can be leveraged to perform more complex tasks in quite a synthetic way. For example (see Fig. 1), a typical way to build a running accumulator is to feed each new number to be accumulated in the hot inlet of a + operator, and feeding back the result in the right inlet, so as to have it ready to be summed to the next incoming value. Likewise, a differentiator can be built by sending each new value to the hot inlet of aobject first and the cold inlet immediately after, so that it is ready to be subtracted from the next incoming value. Whereas this may be convenient for such simple cases, it can become extremely complicated as the complexity of the problem grows. It is easy to build patches in which state is distributed into many seemingly random objects, with spaghetti connections that can only be made sense of by following attentively the flow of every bit of information through the patch graph.

Fig. 1. The typical design of a simple accumulator in Max: the int module stores the current number in a hidden state; when the top button is clicked, the state is output, incremented, and stored in the int module anew. Notice that, as a general rule in Max, the internal state is hidden from the user: at the moment in which the screenshot was taken the internal state had been updated to 8 (as the bottom number displays) although the argument of the int module still shows '0', which represents the initial state. Note also that the functionning here is asynchronous and controled through hot and cold inlets which differs from the synchronous functioning of the DF accumulator in sect. 2.6

On the other hand, it is possible to make this imperative style more explicit by adopting some good practices, like widely using specific objects (such as trigger and bangbang), that can help with keeping the evaluation order under control. Moreover, Max contains two objects whose only purpose is holding data associated with a name: value and pv (for 'private value'), whose role can be seen as corresponding to that of variables in traditional imperative programming languages. Each instance of those objects has a name, and every time it receives a piece of information it retains and shares it with all the other objects with the same name. It is subsequently possible retrieve the stored data from any of them. The value and pv modules differ in their scope: the former's is global, that is, data are shared through all the open patches in the Max session, whereas the latter's is local, in that data are only shared within the same patcher or its subpatchers. Considering the examples in some widespread textbooks [START_REF] Cipriani | Musica Elettronica e Sound Design[END_REF][7] [START_REF] Winkler | Composing Interactive Music[END_REF] and the Max documentation, as well as some informal reckoning of the patches that users share on the official Max forum, it seems to us that these objects are seldom used. One likely reason is that they are virtually never necessary, and tend to make patches larger and slightly less efficient. On the other hand, by combining value and pv with the aforementioned sequencing objects, it is possible to use Max in a much more readable, essentially imperative programming style.

bach implements its own variants of these objects, respectively named bach.value and bach.pv. Besides dealing correctly with lllls, they can open a text editing window if double-clicked, allowing to view and modify the data they hold. Moreover, bach contains an object called bach.shelf, which acts as a container of an arbitrarily large set of lllls, each associated to a unique name. bach.shelf objects can be themselves named, thus defining namespaces: this means that lllls associated to a name within one named bach.shelf object will be shared only with other bach.shelf objects with the same name. Although still somewhat crude (it might be interesting, for example, allowing non-global namespaces), this is a way to improve data localization and data encapsulation, and reduce the proliferation of storage objects in complex scenarios.

Object-oriented approach

The fact that a Max program is built of independent blocks responding to messages they send to each other in consequence of callbacks triggered by events gives it a strong object-oriented flavour, and the Smalltalk influence is both apparent and declared. At a lower level, in fact, each Max object in a patch is an instance of a specific class, with member variables containing the object's state and methods roughly corresponding to the messages it accepts for modifying and/or querying the state.

The two main bach editors, bach.roll and bach.score, comply with this object-oriented approach. However, a distinction can be made about the kinds of messages they accepts: some control and query the object's appearance (background color, zoom level, etc.), whereas others are dedicated to the direct management of the editor's content.

In fact, there are several ways to modify a score. One of the simplest involves dumping its parameters from some outlets, modifying them via appropriate Max and bach modules, and feeding the result into a different editor object.

In contrast, one can send direct messages to the editor, asking for specific elements of the score to be created or modified through the so-called bach inplace syntax, with no output from the object outlets (unless explicitly requested). The operations are immediately performed and the score is updated (see Fig. 4). These messages enable the creation, the edition and the deletion of individual notation items, such as a single measure or a single note, and can actually be seen as methods of the items themselves, arranged according to a precise hierarchy and sharing a certain number of common properties (such as having a symbolic name, being selectable, etc.).

This mechanism is strongly inspired by an object-oriented approach: references to the notation items to be modified are acquired via a selection mechanism, and then messages are sent to them. A set of items can be selected Fig. 2. An implementation in strict imperative style of the sieve of Eratosthenes, an algorithm for finding prime numbers. The patch is a direct translation of the Python code shown in the box. We have chosen not to write very idiomatic Python code for making it closer to pseudocode. In the patch, we have avoided -among the other things -storing data in the cold inlets of objects: every piece of data meant to be reused is stored in pv objects, from which they are retrieved at need. The result is quite redundant, but the structure of calculation is clear. Fig. 3. A more synthetic implementation of the sieve of Eratosthenes. Compared to the example of fig. 2, the patch is more compact but also much less readable.

graphically, or through a query in the form of a message such as sel note if voice == 2 and pitch % C1 == F#0, and then modified by means of messages such as duration = velocity * 10 . Most musical properties can be modified in this way, and the expressions determining the assignation support a standard set of predefined variables, capturing the current state of the object (onset, cent, duration, velocity, index, part, grace, and so on).

In fact, this kind of approach allows much more complex operations than the ones described here, as there are many classes of notation items, each having a large number of properties and related messages. In spite of the richness of the data it can manipulate, though, the in-place syntax is not very flexible, but there are plans to extend it through the bell language (see below).

Moreover, there are available methods to perform routine tasks such as copying/pasting score content or slot 11 information, inserting or deleting pitch breakpoints, modifying portions of score, snapping items to a temporal grid, making selection monophonic, adding or modifying slot content, renaming, distributing elements evenly in time, and so on. Notation objects send notifications whenever their state is changed, so that any of the aforementioned methods can be also triggered by user operations on the score, in a reactive way. Some of these messages work in conjunction with the playback system, so that users can, among other things, retrieve properties of the currently played notes or move the playback cursor.

Functional approach

Max shares some similarities with functional languages, mostly by handling values through a variety of nodes implementing functions on these values. It is then possible to build patches that somehow behave functionally, and whose appearance is extremely similar to that of equivalent ones in a functional graphical system such as PWGL. bach extends the functional traits of Max in a few areas.

As hinted at before, it implements the llll , a tree data type quite similar to a Lisp list, and provides a large number of modules for dealing with lllls. Although, of course, list operators are not inherently functional, they are quite customary in functional languages, and the corresponding bach objects can be connected in a way corresponding to the composition of list functions in functional languages such as Lisp or Haskell.

Secondly, generalized versions of functions such as sort and find require some way to specify, respectively, a custom ordering or an arbitrary search criterion. In several languages, these generalized functions are conveniently implemented as higher-order functions, i.e., functions taking other functions as arguments.

This requires to handle functions like ordinary data. A Max patcher lacks the concept of function, but several bach objects implement a design pattern called the lambda loop (see Fig. 5), whose role is somehow akin to that of higher-order functions.

A lambda loop is a patching configuration in which one or more dedicated outlets of a module output data iteratively to a patch section, which must calculate a result (either a modification of the original data, or some sort of return value) and it to a dedicated inlet of the starting object [START_REF] Agostini | A Max Library for Musical Notation and Computer-Aided Composition[END_REF].

Lambda loops are used by some bach modules directly inspired by functional programming practices, such as bach.mapelem (performing a map operation) and bach.reduce (recursively applying a binary function on elements); all these modules can be helpful to translate programs conceived functionally into Max patches. The number of modules taking advantage of this design pattern is, however, much larger, and include basic operators such as bach.sieve (only letting some elements through) and bach.sort (performing sort operations), but also advanced tools such as bach.constraints (solving constraint satisfaction problems) as well as some of the modules in the cage package.

Textual coding

The approaches described so far are based on the idea that individual objects carry out elementary operations, and they are connected graphically so as to build complex behaviors. Fig. 5. The cross-connected and loop-connected patch cords attached to bach.mapelem, bach.sieve, bach.sort and cage.timewarp modules form several instances of the so-called lambda loop. The left-side example should be straightforward. In the right-side example, the temporal distribution of events in a musical score is altered through the provided transfer function, with time on the X axis and speed on the Y axis. At a superficial level, patches like these appear to be quite similar to how the same processes might be implemented in a functional dataflow system.

A different, but not incompatible, point of view is embedding an algorithm, even a potentially complex one, into a single object by means of textual coding, and subsequently insert it into a patch. In graphical, Lisp-based systems such as OpenMusic and PWGL, this is easily accomplished by inserting graph boxes containing Lisp code in the patcher.

The corresponding, native way to do the same in Max is writing an external object in C. Whereas this was originally meant to be a part of the regular Max workflow, it is undoubtedly a quite complicated task for today's average Max user, requiring to master the C programming language and the compilation chain. Moreover, the write-test-debug cycle requires to restart the whole Max environment at every modification made to the object, and errors in the code are not unlikely to crash Max. Finally, unlike what happens in OM and PWGL, the code for a Max object is required to include a quite heavyweight infrastructure taking care of the communication with the Max environment and only remotely related to the actual problem meant to be tackled.

As expressing algorithms through textual coding can be quite convenient but the C API has the aforementioned drawbacks, over the years various other programming languages have been embedded into Max through higher-level APIs, including Java, JavaScript, Lua, all included in the Max distribution. Although very effective for various kinds of operations, these bindings are not optimal for interacting with bach, for a number of reasons that are detailed in [START_REF] Agostini | bell, a textual language for the bach library[END_REF] and mostly amounting to two areas:

-As mentioned before, the all-encompassing data structure of bach is the llll , which is not easily expressed in any of the above languages. -These bindings require some pieces of quasi-boilerplate infrastructure, such as the explicit management of inlets, outlets and messages sent to the enclosing object, that make the writing of code significantly more complex, compared to the ease and directness of embedding Lisp code in Open Music and PWGL.

On the other hand, Max contains a family of objects, namely expr, vexpr and if, that allow defining textually mathematical expressions and simple conditionals which might otherwise require fairly complicated constellations of objects in a patch. bach adds another member to the family, called bach.expr, allowing to define mathematical expressions to be performed point-wise on lllls.

Whereas the expr family syntax is not a full-fledged programming language, it can be seen as the basis for one. We therefore decided to include in the latest release of bach a new object to the family, called bach.eval, implementing a new, simple programming language conceived with a few, conceptually simple points in mind:

-Turing-complete, functional syntax, in which all the language constructs return values, but also including imperative traits such as sequences, variables and loops. -Full downward compatibility with the expr family.

-Inclusion of list operators on lllls respecting, as far as possible, the conventions and naming of the corresponding bach objects. -Implicit concatenation of elements into lllls, meaning that by simply juxtaposing values (be they literals, or the result of calculations) they are packed together into an llll . In this way, a program can be seen as an llll intermingled with calculations, not unlike what happens by combining the quote operator and unquote macro in Lisp. -Maximum ease of embedding of the object into a Max patcher, with, among the other things, no need for explicit management of inlets and outlets.

The resulting language is called bell (standing for bach evaluation language for lllls, but also paying homage to the historic Bell Labs). A detailed description of its syntax can be found in [START_REF] Agostini | bell, a textual language for the bach library[END_REF], whereas, for the scope of this article, a few examples should suffice (see Fig. 6, 7 and 8).

bell code can be typed in the bach.eval object box or into a dedicated text editor window, loaded from a text file and even passed dynamically to the host object via Max messages. Fig. 6. A comparison between an llll manipulation process described through a snippet of bell code (in the bach.eval object box) and the corresponding implementation within the standard graphical dataflow paradigm of Max. The code should be mostly straightforward for readers familiar with the bach library and a textual programming language such as Python, considering that the [ ... ] paired operator encloses one or more elements into a sublist, according to the general syntax of lllls.

The intended usage paradigm of bach.eval is similar to that of the expr family: bach.eval objects are meant to carry out relatively simple computational tasks, and to be disseminated around the patcher among regular bach and Max objects taking care of the UI, MIDI, DSP, event scheduling and so on.

Snippets of bell language can also be passed to other objects for fine-tuning their behavior, as a replacement for lambda loops. Moreover, an intended (albeit not straightforward) development is to allow bach.score and bach.roll to be Fig. 7. A snippet of bell code approximating a list of midicents to the nearest semitone, and returning the distances from the semitone grid from a different outlet. Here, the code has been typed in a separate text editing window (shown on the right). The $o1 and $o2 pseudovariables assign results to the extra outlets declared in the bach.eval object box. The main, rightmost outlet returning the actual result of the computation (which, in this example, is the last term of the sequence defined by the ; operators, that is, the value of the $l variable as passed to the first extra outlet) is left unused here. The language has several other features not shown here, including named and anonymous user-defined functions with a rich calling mechanism. Fig. 8. An example of usage of bell in combination with bach.roll's in-place syntax: 100 notes are generated in the first voice with random onsets (between 0 and 2 seconds) and random pitches (between middle C and the C two octaves above, on a tempered semitonal grid); then all C's, C 's and D's are selected (i.e. notes whose remainder modulo 1200 is less than or equal to 200), assigned to the second voice, transposed two octaves below, remodulated with a velocity crescendo and distributed equally in time.

scripted in bell, thus allowing far more complex interactions than what is already possible through the syntax described above.

Conclusions and future work

We have presented some historical and theoretical background about the computational models of Max and other related programming languages and environments, and subsequently described how the bach library can be helpful with writing clear and maintainable programs, through some specific features aimed at implementing different programming approaches and styles on top of it. These features are rooted in practical considerations and experience, and allow one to escape the limitations of pure formal models.

More generally, we think that time is ripe for advocating the adoption of more structured and theoretically grounded approaches to working with this successful and widely used tool. We hope that this article may be a step in that direction: further steps should involve, on the one hand, an actual survey of real-life use cases, possibly with the involvement of the community of bach users; a more precise and organic formalisation of good and scalable programming practices in Max, which might prove quite different from the ones typical of more traditional programming languages; and, most likely, the conception and development of new tools to encourage them and facilitate their adoption.

Fig. 4 .

 4 Fig. 4. A very simple example of in-place modification: notes belonging to the second voice and whose onset lies before the middle of the second measure are selected and transposed up a perfect fifth (the image shows both the state of the score before and after the click on the message).

In the usual Max terminology, actors correspond to boxes (object or message) and input and output ports corresponds respectively to inlets and outlets.

We shall talk diffusely about Max in the later chapters, and only introduce it as an example here for readers already familiar with it.

If an actor has multiple output ports, it can be divided into as many actors as outputs, each taking the same inputs and having only one output.

www.bachproject.net

bach.roll and bach.score differ in that the former represents time proportionally, whereas the latter implements a traditional representation of time, with tempi, metri, measures and relative temporal units such as quarter notes, tuplets and so on.

The website of bach showcases some interesting works that have been developed with the library, mostly by people independent of its developers.

The dada library contains interactive two-dimensional interfaces for real-time symbolic generation and dataset exploration, embracing a graphic, ludic, explorative approach to music composition.


Suzanne Bonamour
email: suzannebonamour@protonmail.com

Luis-Miguel Chevin

Denis Réale

Céline Teplitsky

Anne Charmantier

Age-dependent phenological plasticity in a wild bird

Keywords: Phenotypic plasticity, Laying date, Phenology, Aging, Passerines, Wild birds

come

Introduction

Phenotypic plasticity -the capacity of a given genotype to express different phenotypes according to environmental conditions [START_REF] Pigliucci | Phenotypic plasticity: beyond nature and nurture[END_REF] -is a widespread phenomenon in nature [START_REF] Dewitt | Phenotypic plasticity: Functional and conceptual approaches[END_REF]. Theoretical and empirical studies highlight the importance of phenotypic plasticity for population persistence (e.g. [START_REF] Ashander | Predicting evolutionary rescue via evolving plasticity in stochastic environments[END_REF][START_REF] Chevin | Adaptation, plasticity, and extinction in a changing environment: towards a predictive theory[END_REF][START_REF] Reed | Integrating effects of phenotypic plasticity and evolution on population persistence in a changing climate[END_REF]. When plasticity is adaptive, it may allow the population mean phenotype to track an environment-dependent phenotypic optimum, thus minimizing the impact of environmental change on mean fitness and population growth. This is especially true for phenological traits, which determine the timing of key life history events such as reproduction, dormancy/diapause, or dispersal, synchronizing these events with the optimal timing set by a seasonal -and often also noisy -environment (e.g. [START_REF] Visser | Keeping up with a warming world; assessing the rate of adaptation to climate change[END_REF].

Phenological traits have been shown to represent a major phenotypic response to rapid climate change [START_REF] Davis | Evolutionary responses to changing climate[END_REF][START_REF] Parmesan | A globally coherent fingerprint of climate change impacts across natural systems[END_REF][START_REF] Radchuk | Adaptive responses of animals to climate change are most likely insufficient[END_REF][START_REF] Visser | Shifts in phenology due to global climate change: the need for a yardstick[END_REF][START_REF] Walther | Ecological responses to recent climate change[END_REF]. It is also increasingly clear that plastic changes contribute a large proportion of observed phenotypic change in the wild (e.g. [START_REF] Gienapp | Climate change and evolution: Disentangling environmental and genetic responses[END_REF][START_REF] Merilä | Climate change, adaptation, and phenotypic plasticity: The problem and the evidence[END_REF][START_REF] Walther | Ecological responses to recent climate change[END_REF], especially for phenological traits (Anne [START_REF] Charmantier | Climate change and timing of avian breeding and migration: evolutionary versus plastic changes[END_REF][START_REF] Vedder | Quantitative assessment of the importance of phenotypic plasticity in adaptation to climate change in wild bird populations[END_REF].

Life-history traits (e.g. fecundity), in addition to often being phenotypically plastic, also vary with age in many iteroparous species. Empirical studies in vertebrates commonly show patterns of age-dependent reproductive performance, with increasing annual reproductive success in the beginning of life, followed by maximal reproductive performance in middle age, and finally, a decreasing success due to reproductive senescence (e.g. [START_REF] Balbontín | Agerelated change in breeding performance in early life is associated with an increase in competence in the migratory barn swallow Hirundo rustica[END_REF][START_REF] Clutton-Brock | Reproductive success: studies of individual variation in contrasting breeding systems[END_REF][START_REF] Dingemanse | Individual variation in age-dependent reproduction: Fast explorers live fast but senesce young[END_REF][START_REF] Warner | Decades of field data reveal that turtles senesce in the wild[END_REF]. Since plastic phenology is a strong driver of reproductive performance in many species, notably in birds inhabiting temperate forests (e.g. [START_REF] Marrot | Current Spring Warming as a Driver of Selection on Reproductive Timing in a Wild Passerine[END_REF][START_REF] Perrins | Laying date and clutch size in the great tit[END_REF], it is likely that variation with age of phenological reaction norms underlies age-dependent patterns in reproductive success to some extent. If reaction norms vary with age, then understanding the role of plasticity in adaptation to rapid environmental change and population persistence requires integrating the age structure of the population (see e.g. [START_REF] Van De Pol | Fluctuations in population composition dampen the impact of phenotypic plasticity on trait dynamics in superb fairy-wrens[END_REF].

Theoretical studies on the evolution of age-dependent plasticity are still rare. They have focused so far on traits that are established once during development (developmental plasticity, according to [START_REF] West-Eberhard | Developmental plasticity and evolution[END_REF] in binary environments, and predict a decrease of plasticity with age (e.g. [START_REF] Fawcett | Adaptive explanations for sensitive windows in development[END_REF][START_REF] Fischer | The evolution of age-dependent plasticity[END_REF][START_REF] Stamps | Age-dependent changes in behavioural plasticity: insights from Bayesian models of development[END_REF]. Formal theoretical predictions are still missing for traits that change repeatedly in life (labile traits), and with continuous expression under continuous environmental variation. But the general mechanisms responsible for an effect of senescence on plasticity, such as the decrease of selection strength with age [START_REF] Charlesworth | Evolutionary mechanisms of senescence[END_REF][START_REF] Hamilton | The moulding of senescence by natural selection[END_REF][START_REF] Monaghan | The evolutionary ecology of senescence[END_REF][START_REF] Williams | Pleiotropy, natural selection, and the evolution of senescence[END_REF], should lead to a similar decrease in plasticity as individuals get older.

Within-individual variation of plasticity over the lifetime of individuals has been highlighted in some experimental studies, mainly in behavioural traits (e.g. [START_REF] Atwell | Female mate choice plasticity is affected by the interaction between male density and female age in a field cricket[END_REF][START_REF] Ericsson | Long-term and transgenerational effects of stress experienced during different life phases in chickens (Gallus gallus)[END_REF], with highest plasticity in juveniles or young adults followed by decreasing plasticity with age, thus corroborating theoretical predictions. However, evidence is scarce for age-specific plasticity in wild populations. Araya-Ajoy & Dingemanse (2016) compared the seasonal plasticity of aggressiveness in great tits (Parus major) between two age classes, and found that first-year-old breeders showed higher seasonal plasticity than older birds, also aligned with theoretical predictions. A study on phenological trait plasticity in superb fairywrens (Malurus cyaneus) demonstrated that the variation of moult timing with rainfall changed with age (van de [START_REF] Van De Pol | Fluctuations in population composition dampen the impact of phenotypic plasticity on trait dynamics in superb fairy-wrens[END_REF]. Contrary to theoretical predictions, in this study older birds were more plastic than younger ones. Overall, the scarce empirical evidence means we still poorly understand the origin of age-dependent plasticity of labile phenotypic traits over a lifetime. The study of age-specific variation in plasticity in wild populations is an arduous task because of the combined challenges of studying phenotypic plasticity and senescence [START_REF] Nussey | Senescence in natural populations of animals: Widespread evidence and its implications for bio-gerontology[END_REF][START_REF] Nussey | The evolutionary ecology of individual phenotypic plasticity in wild populations[END_REF], both of which demand a long-term study with individual marking and repeated measures on the same individuals. In addition, plasticity estimation requires identifying the main environmental cue(s) explaining within-individual phenotypic variation [START_REF] Gienapp | The choice of the environmental covariate affects the power to detect variation in reaction norm slopes[END_REF]. These challenges explain why age-specific variation of plasticity has been widely neglected so far in empirical studies.

We studied age-specific plasticity of a phenological trait, the egg-laying date, in a wild blue tit population. We used linear mixed models to explore the relationship between age-related plasticity and annual reproductive success across female lifetime. In this species, as in most temperate passerines, laying date varies plastically among years in response to spring temperature (e.g. [START_REF] Porlier | Variation in phenotypic plasticity and selection patterns in blue tit breeding time: Between-and withinpopulation comparisons[END_REF]. This variation allows birds to synchronize their reproductive period with the timing of maximal abundance of caterpillars, which constitute the main nutritive resource for nestlings [START_REF] Blondel | Feeding ecology and life history variation of the blue tit in Mediterranean deciduous and sclerophyllous habitats[END_REF]. Annual reproductive performances also vary with age in blue tits: young birds have low annual reproductive success (partially) due to inexperience [START_REF] Gienapp | Evolutionary dynamics in response to climate change[END_REF], while old individuals suffer from reproductive senescence [START_REF] Auld | Life history of breeding partners alters age-related changes of reproductive traits in a natural population of blue tits[END_REF]. As a result, reproductive success increases and then decreases with age, with most traits peaking around 3 years of age. Since laying date is a plastic trait in response to temperature, age-related variation of reproductive timing and annual reproductive success could be associated with age-specific laying date plasticity with temperature. We expected a nonlinear variation of laying date plasticity with age. Plasticity should first increase in the early years of life, because of maturation and learning processes as suggested by an empirical study of [START_REF] Grieco | Evidence for the effect of learning on timing of reproduction in blue tits[END_REF]. It should then decrease in old ages, because senescence is generally expected to lead to an overall decrease in performance. We expected similar quadratic agespecific variation in reproductive success.

Materials & Methods

Species and data collection

We used a long-term study (initiated by Jacques Blondel in 1975) of a wild Mediterranean population of Blue tit (Cyanistes caeruleus ogliastrae), a small insectivorous and cavity-nesting passerine. Breeding dates were collected every spring on the study site. The population is on the island of Corsica, in an evergreen forest (E-Pirio population, 42°34'N, 08°44'E) dominated by holm oaks (Quercus ilex) (see reviews on the long-term study in [START_REF] Blondel | A thirty-year study of phenotypic and genetic variation of blue tits in mediterranean habitat mosaics[END_REF][START_REF] Charmantier | Mediterranean blue tits as a case study of local adaptation[END_REF]. Blue tits bred in 205 nest boxes (natural cavities are rare in this forest, Charmantier, pers. com.), which were monitored weekly from March to June to record laying date, clutch size and reproductive success. Breeding birds and nestlings were individually marked with a unique numbered metal ring.

We restricted our analyses to first broods of the season only (second broods represent less than c. 1% of the clutches). Age was estimated based on birth year for individuals born in nest boxes, or on plumage patterns for immigrants (see Supporting Information 1 Figure S1 for the number of females in each age class). Based on plumage patterns, captured immigrant females can be classified either as one year old (juvenile plumage), or two years or older (mature plumage pattern). In the present dataset, the exact age was known for c. 60% of females (corresponding to locally born and immigrant females first captured at one year old), while we used minimum age for the remaining 40% (corresponding to immigrant females first captured at two years or older). Dispersal in blue tits mainly happens before the first breeding event (i.e. natal dispersal, [START_REF] Greenwood | The natal and breeding dispersal of birds[END_REF][START_REF] Matthysen | Family movements before independence influence natal dispersal in a territorial songbird[END_REF], and the mortality rate in the focal population was high (about half of the individuals in each age class die every year, [START_REF] Dubuc-Messier | Environmental heterogeneity and population differences in blue tits personality traits[END_REF]. Hence the recruitment in the focal nest-box area of birds older than two years was likely to be uncommon (see Supporting Information 1 Figure S1). This suggests that allocating a minimum age of two years to immigrant females displaying adult plumage should lead to a low error rate in age estimation, as we confirmed by a sensitivity analysis (see Supporting Information 2).

Overall, the dataset contained 1696 laying date observations from 1976 to 2017, for 854 identified females (Supporting Information 1 Figure S1 and Table S1, [START_REF] Bonamour | Data from: Agedependent phenological plasticity in a wild bird[END_REF]. The temperature cue was the average daily temperature between 31 st March and 7 th May, which is the period most correlated with inter-annual laying date variation at the population scale according to sliding-window analyses [START_REF] Bonamour | Phenotypic plasticity in response to climate change : the importance of cue variation[END_REF].

Statistical analyses

We estimated age-dependent laying date plasticity in response to temperature using the following linear mixed model (e.g. [START_REF] Nussey | Environmental conditions in early life influence ageing rates in a wild population of red deer[END_REF], [START_REF] Bouwhuis | Great tits growing old: selective disappearance and the partitioning of senescence to stages within the breeding cycle[END_REF]. To account for the non-independence of data collected on the same female and the same year, we included female identity (𝑖𝑛𝑑 𝑖 ) and year (𝑦𝑒𝑎𝑟 𝑗 ) as random effects. The final term in model 1 is the residual error term 𝜀 𝑖𝑗 . Avian laying date is expressed by females, but can also be seen as a trait shared by the two sexes as some male characteristics may influence the timing of reproduction (e.g. [START_REF] Brommer | Hidden" reproductive conflict between mates in a wild bird population[END_REF]. However, in this population, a previous analysis detected no effect of male identity on breeding time [START_REF] Auld | Life history of breeding partners alters age-related changes of reproductive traits in a natural population of blue tits[END_REF] and we thus restricted analyses to female birds. We also confirmed that there was no difference between the population-and individual-level plasticity (i.e. variation in laying date with temperature was not driven by between-female differences in reaction norm intercept across years), using the within-subject centering method (Supporting Information 3; van de [START_REF] Van De Pol | A simple method for distinguishing within-versus betweensubject effects using mixed models[END_REF].

𝐿𝐷𝑖𝑗 = µ + 𝛼 1 𝑇 𝑗 + 𝛼 2 𝐴 𝑖𝑗 + 𝛼 3 𝐴 𝑖𝑗 2 +
We estimated the effects of age and laying date on annual reproductive success 𝐴𝑅𝑆 (approximated as the number of fledglings per breeding attempt) using the following generalized linear mixed model, All statistical analyses were carried out using the software R (version 3.3.2, R Core Team, 2016), and performed in a Bayesian framework using a Markov Chain Monte Carlo estimation algorithm (R package MCMCglmm, [START_REF] Hadfield | MCMC Methods for Multi-Response Generalized Linear Mixed Models: The MCMCglmm R Package[END_REF]. For all random effects (including the residual variance), we used a weakly informative prior, corresponding to an inverse-Wishart 𝑊 -1 (𝜓, 𝜈) distribution with 𝜓 equal to the phenotypic variance of laying date (or 𝐴𝑅𝑆 variance, depending on the model 1 or 2) divided by the number of estimated variance components. 𝜈 is the degree of belief in the prior and we tested the robustness of results to the prior specification using 𝜈 = 1, 0.2 or 0.02. The default Gaussian noninformative prior in MCMCglmm with mean zero and variance 10 8 was used for the fixed effects.

𝐴𝑅𝑆 𝑖𝑗 = 𝛾 + 𝛽 1 𝐴 𝑖𝑗 +
Models were run for 1,010,000 iterations, including a burn-in period of 10,000 iterations. We ran three chains which were sampled every 1000 iteration to avoid autocorrelation. The maximum autocorrelation between estimates was < 0.05 for fixed and random effects. Convergence of chains was tested using Gelman and Rubin's convergence diagnostic [START_REF] Brooks | General methods for monitoring convergence of iterative simulations[END_REF][START_REF] Gelman | Inference from iterative simulation using multiple sequences[END_REF] and models converged well, with average Gelman's diagnostic 𝑅 ̂ = 1.00 for fixed and random effects, comparing chains from different priors.

Results

Laying date varied within a female's lifetime, in response to both temperature and age (Table 1). Laying date was earlier with warmer springs, with a median value of c. 3 days earlier every 1°C warmer (Table 1, Figure 1a&b). It also varied non-linearly with age, decreasing until age 4 and then increasing (Table 1, Figure 1a&c). Our results suggested that shorter-lived females tend to breed later, but note that the 95% credible interval in the posterior distribution of the 𝐴𝑅𝑆 marginally included zero (Table 1, but see Supporting Information 2 Table S3).

We also found age-dependent plasticity in reproductive phenology. The response of laying date to temperature changed with age, as evidenced by the interaction between temperature and the linear age effect (Table 1). This resulted in reaction norm slopes getting steeper as female age increased, until c. 5 years old (Figure 1b&c). In addition, our results suggested that plasticity declines for older females (after 6 years old, Figure 1c); however small sample sizes for these late age classes resulted in large credible intervals (Table 1, Supporting Information 1 Figure S1). The largest difference in reaction norm slopes was between 1 year-old (i.e. yearling) and 5 year-old females: the estimated median slope of laying date reaction norm with respect to temperature was -3.68 days/°C (± 0.002, pvalue <2.10^16) for yearlings, and -4.94 days/°C (± 0.001, p-value <2.10^16) for 5 year-old females (Figure 1b), leading to a median difference of c. 1.5 days/°C between both age classes.

Annual reproductive success also varied with female age (Table 2). Model 2 revealed a quadratic relationship between annual reproductive success and age, such that young and especially old females displayed lower annual reproductive success than middle-age females (Table 2, Figure 2a).

Annual reproductive success also decreased with laying date (Table 2, Figure 2b). There was no statistical evidence for an interaction between age and laying date (Table 2; preliminary analyses showed no evidence for an interaction between laying date and age-squared). Importantly, the relationship between laying date and reproductive success was negative for all ages except for females older than 5 years old (Figure 2b). Hence, despite low statistical power in old age classes (Supporting Information 1 Figure S1), these results suggest that reproductive success in old females was low independently of their laying date.

Discussion

To our knowledge, our study is the first to report age-dependent phenotypic plasticity of laying date with temperature. Laying date plasticity with spring temperature is a common pattern observed in many avian natural populations (e.g. [START_REF] Dunn | Breeding dates and reproductive performance[END_REF][START_REF] Visser | Temperature has a causal effect on avian timing of reproduction[END_REF]. In temperate regions, this plasticity causes among-year variation in phenology, which allows synchronization between predators (birds) and their preys (in particular caterpillars, see e.g. [START_REF] Dunn | Breeding dates and reproductive performance[END_REF][START_REF] Van Noordwijk | Selection for the timing of great tit breeding in relation to caterpillar growth and temperature[END_REF].

Laying date variation with female age is likewise a well-known pattern in free-living as well as in controlled iteroparous animal populations (e.g. [START_REF] Auld | Life history of breeding partners alters age-related changes of reproductive traits in a natural population of blue tits[END_REF][START_REF] Nussey | Measuring senescence in wild animal populations: Towards a longitudinal approach[END_REF], although the senescent delay in avian breeding phenology was only revealed in the last two decades.

Similarly to previous investigations [START_REF] Auld | Life history of breeding partners alters age-related changes of reproductive traits in a natural population of blue tits[END_REF], model 1 shows that young and old females lay later than middle-age birds (Table 1, Figure 1).

More importantly, model 1 also reveals changes in plasticity with age. The age dependence of laying date reaction norms is complex, as both the slope and intercept vary with female age (Table 1, Figure 1). This leads to a pattern whereby young and old females lay later on average (i.e. higher median reaction norm intercept), and the age-dependent reaction norm slope accentuates the phenological delay between young or old and middle-age females (Figure 1). For instance, in warm springs with temperature 1.5 °C higher than average, the resulting median laying date is ≈ 5 days earlier in 5-year-old than 1-year-old females (Figure 1b). This difference among age classes represents about 13% of the total phenotypic range in laying date in the entire dataset (c. 39 days), while the amongindividual (averaged across years and environments) and among-year effects explain respectively about 28% (c. 11 days) and 36% (c. 14 days) of this range.

Under current environmental conditions, age-dependent laying date plasticity should not have extensive impacts on population dynamics and persistence in our short-lived passerine population, because females of 5 years and older represent only 8% of the total population (Supporting Information 1 Figure S1 and population annual adult survival probability of c. 0.5, Dubuc-Messier et al., 2016). However, warmer springs in the future should lead to higher among-individual variation of laying date, as the influence of age-dependent plasticity on laying date variation becomes more marked (assuming no evolutionary change of laying date reaction norm).

Our results seem consistent with theoretical models of age-dependent plasticity (e.g. [START_REF] Fawcett | Adaptive explanations for sensitive windows in development[END_REF][START_REF] Fischer | The evolution of age-dependent plasticity[END_REF][START_REF] Stamps | Age-dependent changes in behavioural plasticity: insights from Bayesian models of development[END_REF]) despite substantial differences between our blue tit biological model and some assumptions of the theoretical models. As predicted by theoretical studies, plasticity decreased at old ages in our study population. However, the pattern was complex, as we observed quadratic variation of both laying date plasticity (Table 1, Figure 1) and annual reproductive success (Table 2, Figure 2). From a more mechanistic perspective, [START_REF] Fawcett | Adaptive explanations for sensitive windows in development[END_REF] highlight that age-dependent plasticity will evolve if there is variation across the lifetime of either i) cue reliability, ii) the relationship between fitness and the plastic response, or iii) constraints on the expression of phenotypic plasticity. First, we have no a priori reason to expect changes in cue reliability with female blue tit age: spring temperature should predict the caterpillar peak date independently of female age. However, the physiological ability to detect environmental cues such as temperature [START_REF] Caro | The case of the missing mechanism: how does temperature influence seasonal timing in endotherms?[END_REF][START_REF] Visser | Temperature has a causal effect on avian timing of reproduction[END_REF] or photoperiod [START_REF] Dawson | Control of the annual cycle in birds: Endocrine constraints and plasticity in response to ecological variability[END_REF] may change with age. This could explain age-dependent plasticity, since the optimal reaction norm slope increases as a function of cue reliability [START_REF] Gavrilets | The genetics of phenotypic of reaction norm shape V . Evolution of reaction norm shape[END_REF], but little is known about changes in perception abilities with age in birds. Second, the fitness benefits associated with laying date plasticity may vary during female lifetime. For example, their foraging capacity may increase with age, leading to a reduced importance -for annual reproductive success -of the synchronisation between the peak of nutritive resources and bird reproductive timing in older females. In our population, such age-dependent fitness benefits of plasticity could not explain the increasing plasticity before 5 years old. However, the fitness advantage of earlier breeding seems to decrease in old ages (Figure 2b), which could lead to lower fitness benefits to being plastic and induce selection for reduced (assumed costly) plastic capacity in old female birds. Third, a learning process of plasticity early in life may explain variation in laying date plasticity. [START_REF] Grieco | Evidence for the effect of learning on timing of reproduction in blue tits[END_REF] showed that blue tits laid in the same period as their previous breeding season if they were supplied with additional food, but they laid earlier if they were short of nutritive resources. Such a pattern may explain increasing plasticity in young females, especially following warmer springs, when the caterpillar peak is earlier than the average. Finally, plasticity is expected to require resources, especially to acquire information to track environmental changes [START_REF] Dewitt | Costs and limits of phenotypic plasticity : Tests with morphology and life history in a freshwater snail[END_REF], which may lead to constraints on plastic capacity. Hence, yearlings may not have accumulated enough resources during their first winter to adequately modulate their laying date according to temperature, again especially in warmer years when breeding phenology is optimally early. In the same vein, old females suffering from reproductive senescence may not be able to display steeper plasticity because of lack of resources. Further investigations on the physiological conditions of young and old females are needed to better understand proximal causes of age-dependent plasticity.

To plasticity (e.g. [START_REF] Ramakers | Phenological mismatch drives selection on elevation, but not on slope, of breeding time plasticity in a wild songbird[END_REF][START_REF] Van Tienderen | Selection on reaction norms, genetic correlations and constraints[END_REF]) is an exciting perspective.

However, such a study would require a data set much larger than ours based on 42 years of monitoring.

A full understanding of these complex relationships between laying date, age and fitness would also require to investigate selection beyond fledging (e.g. through recruitment success) but also including lifetime reproductive success and/or survival, to integrate the potential fecundity-survival trade-offs.

Conclusion and perspectives

To conclude, this study reveals age-dependent plasticity of laying date in response to spring temperature in a wild blue tit population. Young and old females were less plastic than middle-aged females. Our results suggest that, unlike prime-age females, young females may have not reached their full reproductive capacities, while the older ones may no longer be subject to natural selection on laying date. Such age-dependent effects result in a quadratic variation of laying date plasticity.

Considering the importance of plastic responses for population persistence in a rapidly changing world [START_REF] Chevin | Phenotypic plasticity in evolutionary rescue experiments[END_REF][START_REF] Reed | Phenotypic plasticity and population viability: the importance of environmental predictability[END_REF], within-individual variability of plasticity has to be taken into account in studies of plasticity in the wild. Models of age-structured populations could help to comprehend how age-related plasticity impacts adaptation and population persistence. As chronic stress is known to speed up senescence [START_REF] Hayward | Ageing in a variable habitat: environmental stress affects senescence in parasite resistance in St Kilda Soay sheep[END_REF][START_REF] Monaghan | The evolutionary ecology of senescence[END_REF][START_REF] Ricklefs | The evolution of senescence from a comparative perspective[END_REF], current global change could increase variation of plasticity with age, and its impact could be even stronger for phenological traits for which plasticity is an important component of response to climate change [START_REF] Davis | Evolutionary responses to changing climate[END_REF][START_REF] Parmesan | A globally coherent fingerprint of climate change impacts across natural systems[END_REF][START_REF] Radchuk | Adaptive responses of animals to climate change are most likely insufficient[END_REF][START_REF] Visser | Shifts in phenology due to global climate change: the need for a yardstick[END_REF][START_REF] Walther | Ecological responses to recent climate change[END_REF]. We suggest that age-specific phenological plasticity should be studied in other systems, particularly in long-lived species, to get a fuller understanding of the importance of within-individual variation in plasticity for population persistence in nature.

  𝛼 4 (𝑇 𝑗 𝐴 𝑖𝑗 ) + 𝛼 5 (𝑇 𝑗 𝐴 𝑖𝑗 2 ) + 𝛼 6 𝐴𝐿𝑅 𝑖 + 𝑖𝑛𝑑 𝑖 + 𝑦𝑒𝑎𝑟 𝑗 + 𝜀

𝑖𝑗 (model 1)

where the laying date 𝐿𝐷 (1 = 1 st January) of female 𝑖 in year 𝑗 is explained by several fixed effects: cue temperature 𝑇 𝑗 of year 𝑗 (temperature was mean-centered across years), age 𝐴 𝑖𝑗 and age-squared 𝐴 𝑖𝑗 2 of female 𝑖 in year 𝑗 (with age a continuous variable ranking from 1 to 9 years old). The terms 𝑇 𝑗 𝐴 𝑖𝑗 and 𝑇 𝑗 𝐴 𝑖𝑗 2 are interactions estimating respectively the linear and quadratic age dependence of plasticity in laying date with temperature. We controlled for female longevity by adding an effect of age at last reproduction of female 𝑖, 𝐴𝐿𝑅 𝑖 , modelling a selective disappearance effect on laying date variation (e.g.

  𝛽 2 𝐴 𝑖𝑗 2 + 𝛽 3 𝐿𝐷 𝑖𝑗 + 𝛽 4 (𝐴 𝑖𝑗 𝐿𝐷 𝑖𝑗 ) + 𝑖𝑛𝑑 𝑖 + 𝑦𝑒𝑎𝑟 𝑗 + 𝑟 𝑖𝑗 (model 2) where annual reproductive success 𝐴𝑅𝑆 𝑖𝑗 of female 𝑖 in year 𝑗 is explained by the female age 𝐴 𝑖𝑗 and age-square 𝐴 𝑖𝑗 2 , the laying date 𝐿𝐷 𝑖𝑗 and the interaction between laying date and age (𝐴 𝑖𝑗 𝐿𝐷

𝑖𝑗 ). We included two random effects, female identity (𝑖𝑛𝑑 𝑖 ) and year (𝑦𝑒𝑎𝑟 𝑗 ), and 𝑟 𝑖𝑗 are residuals. Annual reproductive success was not normally distributed (see Supporting Information 1 Figure

S2

), we thus ran the model as a generalized linear mixed model with a Poisson distribution. Females with clutch manipulation and all other experiments that could affect reproductive success were removed from the data set for model 2, reducing the dataset to 1092 laying date observations for 667 identified females.

  evaluate the fitness costs of a late laying date, which partially depends on a lack of plastic response to temperature, we analysed the relationships between laying date, age and a fitness component. We used an estimate of annual reproductive success -the number of fledglings -as fitness component. Results from model 2 and Figure2show that breeding too late decreases annual reproductive success for young and middle-age females but not for the oldest birds. In other words, plasticity of laying date, has no consequences on reproductive success of old females. This suggests that selection for plasticity could decrease with age in this population. Exploring whether the selection on laying date reaction norms changes with age, including the possibility that selection on laying date across environments (i.e. selection depending on temperature) causes indirect selection on its

Acknowledgments

We thank Andy Russel and Patrice David for useful discussions. We also thank Maxime Dubart for useful advice for the statistical analyses. We thank all the people who helped maintain the study site and conduct the blue tit monitoring in the past 45 years, in particular Jacques Blondel, Phillippe Perret, Marcel Lambrechts, Claire Doutrelant, Christophe de Franceschi (who also managed the database), Annick Lucas and Pablo Giovannini. We thank the APEEM, the ONF and Achille Sanroma for field logistics, and the Fango valley MAB reserve.

Funding

This project was funded by a long-term support by the OSU-OREME, and by the European Research Council (Starting grant ERC-2013-StG-337365-SHE to AC).

Data accessibility

Data available from the Dryad Digital Repository: https://doi.org/10.5061/dryad.msbcc2fw8

Ethics

All experimental protocols described here were approved by the ethics committee for animal experimentation of Languedoc Roussillon (305-CEEA-LR-12066 approved in 2012 and 2018) as well as by Regional Institutions (bylaw issued by the Prefecture on 08/12/2015 n° 2015-491). Captures and bird ringing were performed under a personal ringing permit delivered by the CRBPO (Centre de Recherches par le Baguage des Populations d'Oiseaux) to Anne Charmantier (ringing permit number 1907).

Author's contributions

Competing interests

We declare we have no competing interests. 1a) are shown together with the average reaction norm across all females regardless of age (solid line). For a and b, predicted values of laying date were obtained from the posterior mode of predictions across all iterations from model 1. Predictions were estimated for all combinations of temperature (from -2.5 to +1.5 degree around the average cue temperature) and age (from 1 to 9 years old). c) Median reaction norm intercept (in grey) and slope (in black) of laying date with respect to temperature are plotted against female age (over its observed range). The slope was estimated as 𝛼 1 + 𝛼 4 𝐴 𝑖𝑗 + 𝛼 5 𝐴 𝑖𝑗 2 (model 1 and Table 1).

Tables and Figures


Christelle Leung
email: christelle.leung@umontreal.ca

Marie Rescan

Daphné Grulois

Luis-Miguel Chevin

Reduced phenotypic plasticity evolves in less predictable environments

Flow cytometry: We passed a 150 µL sample of each condition through flow cytometry, using the same method as described in the main text. We then randomly selected 30 events characterized as alive Dunaliella salina cells per condition, to keep a balanced sampled size with the microscopy dataset. We then used FSC, SSC and Red-B values, followed by light signal correction using Guava ® EasyCheck™ kit calibrating beads, to assess cells morphology.

Statistical analyses: We tested the concordance of the morphospaces obtained by using the two methods, as proposed by [START_REF] Wang | Comparing spatial maps of human population-genetic variation using Procrustes analysis[END_REF]. We first carried out independent principal component analyses of morphology for flow cytometry and microscopy. We thereafter extracted the centroids on PCA plot for each group of cells, characterized by their population and salinity. Finally, we aligned the centroids' PCA coordinates of flow cytometry morphospace with the microscopy ones using a Procrustean superimposition approach (Gower 1975;Legendre & Legendre 1998). The degree of concordance between the ordinations was assessed with a correlation-like statistic r-PROTEST(Jackson 1995), derived from the symmetric sum of squares, where 1 and 0 denote a perfect vs totally absent concordance, respectively. The significance of this correlation was tested by permutation, using 999 randomizations against the null hypothesis that there is no concordance between the two ordinations (Jackson 1995).

Reduced phenotypic plasticity evolves in less predictable environments Christelle Leung, Marie Rescan, Daphné Grulois & Luis-Miguel Chevin

  Reduced phenotypic plasticity evolves in less predictable environments Christelle Leung, Marie Rescan, Daphné Grulois & Luis-Miguel Chevin Supplementary Material 1: Comparison of flow cytometry vs confocal microscopy methods to assess cells morphology We carried out microscopy images analyses on a small subset of populations, to confirm the accuracy of flow cytometry for assessing cell morphology. As for the main plasticity assay, we first acclimatized four randomly chosen evolved populations to the mean salinity ([NaCl] = 2.4 M) during 10 days. We then transferred each of them to low ([NaCl] = 0.8 M) or high ([NaCl] = 4.0 M) salinity for 10 others days. We finally measured cell morphology using flow cytometry and dragonfly confocal microscopy. Dragonfly confocal microscopy: We sampled ~40µL of cultures from each condition (n = 8, for 4 populations in 2 salinities), and scanned them on a Dragonfly (COM4) spinning disk confocal microscope with 2 cameras EMCCD iXon888 Life (Oxford Instrument -Andor). A total of 100 images was taken under both transmission and confocal fluorescence modes, to assess cells shape and chlorophyll content, respectively. Wavelengths excitation and emission were at 488 nm and 700/775 nm, respectively, for confocal fluorescence. We then used the automatic image analysis software Fiji (Schindelin et al. 2012) to characterize cells morphology. First, we used the function Analyze Particles to isolate cells in each picture, and manually validate each detected particle as an actual D. salina cell. For each particle, we then recorded morphological descriptors including the area and aspect ratio (AR: major/minor axis), the average gray -sum of the gray values of all the pixels in the selection divided by the number of pixels (Grey_Int and Grey_sd for mean and standard error respectively) -for the transmission mode, and fluorescence intensity (Fluo_Int and Fluo_sd for mean and standard error respectively) within the selection. Reduced phenotypic plasticity evolves in less predictable environments Christelle Leung, Marie Rescan, Daphné Grulois & Luis-Miguel Chevin

Figure S2 .

 S2 Figure S2. Ontogenetic trajectories and dynamics of plasticity over time. A. Morphological trajectories in two salinities for each autocorrelation treatment (𝜌𝜌̅ ). Mean cell morphologies with their standard errors, per day and salinity, are calculated by averaging over lines belonging to the same targeted 𝜌𝜌̅ , and represented along the two first PCA axes. Vectors of PC loadings of response variables (FSC, SSC and Red_B grey arrows) were divided by 20 to facilitate graphical representation. Black squares represent cell morphology at the end of acclimation step. B. Trajectories of plasticity over time. Morphological differences between salinities for each treatments were computed as vector at high salinity minus the one at low salinity, for each day (number). Coordinates 0,0 in this morphological space means the absence of plasticity.

Figure S3 .

 S3 Figure S3. Population dynamics in low and high salinities. For each evolutionary treatment (temporal autocorrelation (𝜌𝜌̅ ) or constant salinity at [NaCl] = 2.4M), mean population size (cells × ml -1 ) with their standard errors, per day and salinity, were calculated by averaging over lines belonging to the same strain. Grey diamond is the expected initial population size (2 × 10 4 cells × ml -1 ) inoculated in the new salinity at the beginning of the plasticity assay, and day 1 was measure 4h after this salinity change.

Supplementary information include:

-Supplementary Material 1: Comparison of flow cytometry vs confocal microscopy methods to assess cells morphology.

-Figure S1: Comparison of flow cytometry vs confocal microscopy methods to assess cells morphology.

-Figure S2. Ontogenetic trajectories and dynamics of plasticity over time.

-Figure S3. Population dynamics in low and high salinities.

-Figure S4. Analyses of isogenic populations.

-Figure S5. Influence of the magnitude of environmental transitions for a given environmental predictability.

Supplementary Information References:

Gower, J.C. (1975). Generalized Procrustes analysis. Psychometrika, 40, 33-51. Jackson, D.A. (1995)