Margarita Arango-Lievano
email: margarita.arango@igf.cnrs.fr

Agustin Anastasia

Freddy Jeanneteau

PROBDNF BIOLOGY AND EMERGING ROLES IN THE CNS: THE UNEXPECTED JOURNEY OF PRONEUROTROPHINS

HAL is

INTRODUCTION

Long considered to be only necessary for the biosynthetic folding of mature BDNF, the prodomain has emerged as a unique signaling molecule functionally distinguishable from its mature counterpart. Henceforth, it is considered that three functional ligands can be derived from the BDNF gene: proBDNF which signals though a complex of p75 NTR and sortilin or SorCS2 (sortilin-related VPS10 domain containing receptor 2), the Met66 prodomain which also activates a p75 NTR /SorCS2 receptor complex, and the mature BDNF which signals via TrkB receptors to elicit independent cellular responses. Here, we first review BDNF processing from the proform to mature BDNF and prodomain, with special focus on the role the latter. In a second part, we organize recent evidence demonstrating the signaling properties of proBDNF focusing on secretion, specific binding properties to its receptors and its biological effect on the central nervous system. Finally, we gather the recent evidence suggesting that the prodomain itself is an independent signaling molecule.

FROM ONE GENE TO THREE LIGANDS:

THE PROCESSING OF PROBDNF

Synthesis and Sorting

Like all neurotrophins, BDNF is synthetized as a large precursor called proBDNF. This precursor is approximately a 32kDa peptide that is glycosylated in the N-terminal prodomain region [START_REF] Mowla | Biosynthesis and post-translational processing of the precursor to brain-derived neurotrophic factor[END_REF][START_REF] Mowla | Differential sorting of nerve growth factor and brain-derived neurotrophic factor in hippocampal neurons[END_REF]. Following synthesis in the endoplasmic reticulum (ER), proBDNF is directed to the secretory pathway. ProBDNF can be cleaved to prodomain and mature BDNF in the Golgi apparatus or in secretion vesicles but, during early development, substantial amounts of proBDNF can escape processing. Contrary to the neurotrophins NGF (nerve growth factor), NT3 (neurotrophin 3) and NT4 (neurotrophin 4) that are secreted in a constitutive manner, BDNF can be secreted via the constitutive or the activity-dependent secretory pathways [START_REF] Mowla | Differential sorting of nerve growth factor and brain-derived neurotrophic factor in hippocampal neurons[END_REF]. Sorting likely occurs in the trans Golgi network (TGN) where proBDNF interact with the type 1 receptor sortilin [START_REF] Chen | Sortilin controls intracellular sorting of brain-derived neurotrophic factor to the regulated secretory pathway[END_REF]. Sortilin is a member of a group of receptors containing a vacuolar sorting protein 10 (VPS10) domain that act like chaperones to target their cargo protein to different cellular compartments [START_REF] Nykjaer | Sortilin: a receptor to regulate neuronal viability and function[END_REF]. By interacting with the prodomain, sortilin acts as a chaperone for intracellular trafficking and directs proBDNF into dense-core vesicles destined to the activity dependent secretory pathway [START_REF] Mowla | Differential sorting of nerve growth factor and brain-derived neurotrophic factor in hippocampal neurons[END_REF][START_REF] Dieni | BDNF and its pro-peptide are stored in presynaptic dense core vesicles in brain neurons[END_REF]. Yet, interaction with sortilin is also necessary to engage BDNF toward the lysosomal pathway [START_REF] Evans | Neuronal brain-derived neurotrophic factor is synthesized in excess, with levels regulated by sortilin-mediated trafficking and lysosomal degradation[END_REF]. Two mechanistic frameworks explain how proBDNF is directed toward secretory or degradation routes. First, targeting of sortilin and its proBDNF cargo to the lysosomal pathway may rely on the cleavage of sortilin by ADAM 10 [6]. Second, targeting of sortilin and its proBDNF cargo to the secretory pathway may require physical interaction with the huntingtin interacting protein 1 (HAP1) [START_REF] Yang | Precursor of brain-derived neurotrophic factor (proBDNF) forms a complex with Huntingtin-associated protein-1 (HAP1) and sortilin that modulates proBDNF trafficking, degradation, and processing[END_REF]. A common human single nucleotide polymorphism (SNP) on the prodomain of BDNF is associated with memory impairment and increased incidence of neuropsychiatric disorders [START_REF] Egan | The BDNF val66met polymorphism affects activity-dependent secretion of BDNF and human memory and hippocampal function[END_REF][START_REF] Dincheva | Impact of the BDNF Val66Met polymorphism on cognition: implications for behavioral genetics[END_REF]. This SNP leads to a nucleotide change from a guanine to an adenine at position 196 (G196A) that results in a valine (Val) to methionine (Met) substitution at codon 66 (Val66Met). The SNP was reported to alter the transport of BDNF mRNA transcripts to dendrites for local synthesis of BDNF [START_REF] Chiaruttini | Dendritic trafficking of BDNF mRNA is mediated by translin and blocked by the G196A (Val66Met) mutation[END_REF]. The Val66Met substitution also disrupts the interaction between the proBDNF and sortilin, resulting in a reduced activity dependent secretion of BDNF [START_REF] Chen | Sortilin controls intracellular sorting of brain-derived neurotrophic factor to the regulated secretory pathway[END_REF][START_REF] Egan | The BDNF val66met polymorphism affects activity-dependent secretion of BDNF and human memory and hippocampal function[END_REF].

Cleavage of ProBDNF into Mature BDNF

Mature BDNF is a 14KDa peptide with well-characterized trophic and plasticity abilities that have been extensively reviewed elsewhere [START_REF] Mcallister | Neurotrophins and synaptic plasticity[END_REF][START_REF] Binder | Brain-derived neurotrophic factor[END_REF]. The prodomain is a 15.5kDa protein recently found to be very abundant in the hippocampus [START_REF] Dieni | BDNF and its pro-peptide are stored in presynaptic dense core vesicles in brain neurons[END_REF][START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF][START_REF] Mizui | BDNF pro-peptide actions facilitate hippocampal LTD and are altered by the common BDNF polymorphism Val66Met[END_REF]. Mature BDNF and the prodomain result from proteolytic cleavage of proBDNF. Several proteases have been shown to cleave proBDNF both in the intracellular and in the extracellular milieu. In some culture conditions, the latter seems to be less prominent than the intracellular cleavage. Indeed, inhibition of the main extracellular proteolytic enzymes did not affect the levels of the secreted prodomain, suggesting that most of the processing occurred intracellularly [START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF]. On the other hand, it has been shown that neuronal activity controls the ratio of extracellular proBDNF/mature BDNF by regulating the secretion of extracellular proteases. All these intraand extracellular enzymes cleave proBDNF at distinct but interdependent sites, generating biochemically undistinguishable mature BDNF and prodomain species. No distinct biological functions of the mature BDNF cleaved by one or the other proteases have ever been reported to our knowledge. The following are the enzymes which have been described to process proBDNF.

Furin and other proconvertases

Following synthesis in the ER, proBDNF can undergo processing directly in the Golgi apparatus by furin or within secretory vesicles of the regulated pathway by other proconvertases [START_REF] Mowla | Differential sorting of nerve growth factor and brain-derived neurotrophic factor in hippocampal neurons[END_REF]. The cleavage of proneurotrophins by furin occurs at the consensus sequence R-X-K/R-R, (RVRR in proBDNF) to produce mature neurotrophins and prodomains. Furin cleaves proBDNF at Arg 128 of the consensus site. The mutation of this consensus site from RVRR to RVAA [START_REF] Yang | proBDNF negatively regulates neuronal remodeling, synaptic transmission, and synaptic plasticity in hippocampus[END_REF] or MVLR [START_REF] Koshimizu | Multiple functions of precursor BDNF to CNS neurons: negative regulation of neurite growth, spine formation and cell survival[END_REF] has been instrumental to produce a cleavage resistant proBDNF insensitive to furin and plasmin, and has been exploited to produce recombinant uncleavable proBDNF to demonstrate its biological activity in vitro and in vivo [START_REF] Yang | proBDNF negatively regulates neuronal remodeling, synaptic transmission, and synaptic plasticity in hippocampus[END_REF][START_REF] Koshimizu | Multiple functions of precursor BDNF to CNS neurons: negative regulation of neurite growth, spine formation and cell survival[END_REF][START_REF] Teng | ProBDNF induces neuronal apoptosis via activation of a receptor complex of p75NTR and sortilin[END_REF][START_REF] Pang | Cleavage of proBDNF by tPA/plasmin is essential for long-term hippocampal plasticity[END_REF]. Other proconvertases, such as PACE4, PC5, and PC7, have been shown to process proBDNF in mature BDNF and prodomain utilizing the same RVRR site [START_REF] Wetsel | Disruption of the expression of the proprotein convertase PC7 reduces BDNF production and affects learning and memory in mice[END_REF][START_REF] Marcinkiewicz | The pro-protein convertase PC1 is induced in the transected sciatic nerve and is present in cultured Schwann cells: comparison with PC5, furin and PC7, implication in pro-BDNF processing[END_REF][START_REF] Seidah | Cellular processing of the neurotrophin precursors of NT3 and BDNF by the mammalian proprotein convertases[END_REF].

Plasmin

When proBDNF escape intracellular cleavage by furin or other proconvertases, it can be found in the dense-core vesicles destined to the secretory pathway. The existence of secreted proBDNF was the subject of an intense debate that we will discuss later in this chapter, but if secreted, proBDNF can be converted into mature BDNF and prodomain by extracellular proteases. The most prominent of these proteases is plasmin, which is the product of the activation of the inactive plasminogen by tissue-type plasminogen activator (tPA). The specific plasmin cleavage site of proBDNF was identified within the consensus furincleavage sequence of BDNF, but occurring after Arg 125 rather than Arg 128 of the RVRR sequence [START_REF] Gray | Activation of pro-BDNF by the pericellular serine protease plasmin[END_REF]. Interestingly, a SNP has been identified at position 125, which induces an arginine substitution for a methionine that would potentially prevent plasmin processing of proBDNF [START_REF] Koshimizu | Multiple functions of precursor BDNF to CNS neurons: negative regulation of neurite growth, spine formation and cell survival[END_REF]. Several lines of regulation are implicated in this reaction as plasminogen to plasmin conversion is antagonized by Plasminogen activator inhibitor (PAI1), and PAI1 depends on vitronectin to remain active [START_REF] Mou | Tissue-type plasminogen activator-plasmin-BDNF modulate glutamate-induced phase-shifts of the mouse suprachiasmatic circadian clock in vitro[END_REF]. Furthermore tPA is an extracellular serine protease which secretion is stimulated by neuronal activity [START_REF] Shin | Rapid, activity-induced increase in tissue plasminogen activator is mediated by metabotropic glutamate receptor-dependent mRNA translation[END_REF]. The fact that both proBDNF/BDNF/prodomain containing vesicles and tPA are secreted in an activity dependent fashion raises questions about regulation of bio-available tPA. For instance, a reduction of tPA secretion may be enough to favor proBDNF signaling and vice and versa.

Matrix metalloproteinases

ProBDNF can be processed by selected matrix metalloproteinases (MMPs) such as MMP-3 and MMP-7 [START_REF] Lee | Regulation of cell survival by secreted proneurotrophins[END_REF]. Moreover, it has been shown that MMP-9 converts proBDNF into mature BDNF after kindled seizures in the hippocampus [START_REF] Mizoguchi | Matrix metalloproteinase-9 contributes to kindled seizure development in pentylenetetrazole-treated mice by converting pro-BDNF to mature BDNF in the hippocampus[END_REF].

PROBDNF SIGNALING

In order to function as signaling molecule like most neuropeptides, proBDNF must (i) be secreted, (ii) bind to a specific receptor, and (iii) trigger biological functions. Below we will discuss the evidence of how proBDNF fulfill these conditions.

Secretion of ProBDNF

Whether proBDNF can be secreted as a signaling molecule has been the subject of a very intense debate. Observing proBDNF directly in the extracellular milieu of mice is difficult due to the nanomolar concentrations of BDNF and the lack of antibodies that are specific and sensitive enough to identify proBDNF in such quantities. The first evidence of proBDNF secretion was obtained from a pituitary derived cell line (ATt20) infected with a rabies virus expressing recombinant human BDNF. In these conditions proBDNF as well as mature BDNF were found on the culture media of cells [START_REF] Mowla | Differential sorting of nerve growth factor and brain-derived neurotrophic factor in hippocampal neurons[END_REF]. These conditions were useful to demonstrate that it is possible for cells to secrete proBDNF, but were very far from physiological as they rely on overexpression, and did not answer whether endogenous proBDNF could be secreted by neurons. Other cell lines including HEK293 and endothelial cell lines infected with adenovirus encoding for BDNF were used to demonstrate that proBDNF is released in the culture media and readily cleavable extracellularly when exposed to recombinant plasmin. On the contrary, the quantities of extracellular proBDNF increased after treatment of cells with the protease inhibitor aprotinin [START_REF] Lee | Regulation of cell survival by secreted proneurotrophins[END_REF]. Interestingly, high frequency neuronal activity was capable of inducing the secretion of proBDNF alongside with the mature BDNF on hippocampal neurons transduced with a lentivirus for the overexpression of BDNF [START_REF] Nagappan | Control of extracellular cleavage of ProBDNF by high frequency neuronal activity[END_REF]. Despite the demonstration of activity-dependent secretion, the yield of extracellular proBDNF remained low compared to the mature BDNF. The results suggested that (i) extracellular proBDNF is unstable readily cleavable by activity-dependent extracellular proteases [START_REF] Nagappan | Control of extracellular cleavage of ProBDNF by high frequency neuronal activity[END_REF] and that (ii) extracellular proBDNF could have escaped intracellular cleavage due to the overexpression experimental approach. This controversy was supported by evidence arguing against the neuronal secretion of endogenous proBDNF [START_REF] Matsumoto | Biosynthesis and processing of endogenous BDNF: CNS neurons store and secrete BDNF, not pro-BDNF[END_REF].

To avoid overexpression, this study used neuronal cultures from a knock-in mouse featuring a Myc tag fused to BDNF (N terminal region) allowing the expression of the BDNF gene under the endogenous promoters and detection of proBDNF and BDNF by very sensitive reagents against the Myc tag. They found that although endogenous levels of mature BDNF and proBDNF are detectable in neuronal cell lysates, only the mature BDNF was observed in the extracellular space after neuronal activation via NMDA receptors [START_REF] Matsumoto | Biosynthesis and processing of endogenous BDNF: CNS neurons store and secrete BDNF, not pro-BDNF[END_REF]. Notably, this study did not supplement the conditioned media with inhibitors against plasmin or matrix metalloproteinases to preserve secreted proBDNF in culture media. Moreover, they did not utilize mitotic inhibitors to avoid glial cell growth, which are a source of a variety of extracellular proteases. A subsequent study addressed this issue combining a different knockin mouse to label mature BDNF and proBDNF with a C-terminal HA tag and an antibody raised specifically against proBDNF. Endogenous levels of proBDNF were detected in the conditioned media of hippocampal neuronal cultures in the absence of glial cells, and treated with a plasmin inhibitor [START_REF] Yang | Neuronal release of proBDNF[END_REF]. In cultures, at least part of proBDNF secretion was activity dependent [START_REF] Yang | Neuronal release of proBDNF[END_REF]. Whether the secretion of proBDNF has a functional relevance is addressed in the next sections

Receptors for ProBDNF

The affinities of proneurotrophins and mature neurotrophins for different receptors were first explored for proNGF and NGF by Lee et al. [START_REF] Lee | Regulation of cell survival by secreted proneurotrophins[END_REF]. The authors showed that proNGF and mature NGF can bind to P75 neurotrophin receptor (p75 NTR ) and tropomyosin receptor kinase A (TrkA), respectively. ProNGF is a high affinity ligand for P75 NTR (Kd of 1nM) and mature NGF has a high affinity for both TrkA (Kd 1nM) and p75 NTR (Kd 2nM). On the other hand, proNGF has no affinity for TrkA but binds to p75 NTR (Kd of 0.2 nm) hinting that proNGF could have an independent signaling mechanisms through p75 NTR [START_REF] Lee | Regulation of cell survival by secreted proneurotrophins[END_REF]. Sortilin was found to be essential for proNGF/p75 NTR activation making this receptor the first co-receptor to be identified for proneurotrophins [START_REF] Nykjaer | Sortilin is essential for proNGF-induced neuronal cell death[END_REF]. Sortilin binds specifically to the prodomain region of proNGF with high affinity (Kd= 5nM). When sortilin and p75 NTR are co-expressed they exhibit a synergetic effect on proNGF internalization rather than a simple additive effect [START_REF] Nykjaer | Sortilin is essential for proNGF-induced neuronal cell death[END_REF]. Sortilin, p75 NTR and proNGF co-immunoprecipitate after crosslinking suggesting the possibility that proNGF could bind to sortilin and p75 NTR at the same time [START_REF] Nykjaer | Sortilin is essential for proNGF-induced neuronal cell death[END_REF]. Such a dual receptor system was later replicated for proBDNF which can bind to p75 NTR utilizing its mature moiety and to sortilin by its prodomain region [START_REF] Teng | Understanding proneurotrophin actions: Recent advances and challenges[END_REF]. The affinities of proBDNF for its receptors were determined using purified recombinant proBDNF and immobilized sortilin. Sortilin binds with high affinity (Kd of 0.4 nM) to the prodomain region of proBDNF whereas p75 NTR affinity for proBDNF showed a Kd of 20 nM. Interestingly, ProBDNF does not bind to the TrkB receptor [START_REF] Teng | ProBDNF induces neuronal apoptosis via activation of a receptor complex of p75NTR and sortilin[END_REF]. The sortilin-p75 NTR co-receptor system appears to be functionally relevant as binding of proBDNF to sortilin was necessary for p75 NTR mediated cell death induced by this ligand. Abundant in the nervous system [START_REF] Petersen | Molecular identification of a novel candidate sorting receptor purified from human brain by receptor-associated protein affinity chromatography[END_REF], sortilin is predominantly present on intracellular membranes [START_REF] Nielsen | The sortilin cytoplasmic tail conveys Golgi-endosome transport and binds the VHS domain of the GGA2 sorting protein[END_REF], which limits its capacity to transduce proBDNF signal with p75 NTR . Therefore, it is important to understand how sortilin localization to the plasma membrane is regulated. The mammalian homologue of p75 NTR , NRH2 (PLAIDD or NRADD) interacts with sortilin. This interaction reduces its lysosomal degradation, thus favoring the proportion of surface to intracellular sortilin and its association with p75 NTR and proBDNF [START_REF] Kim | NRH2 is a trafficking switch to regulate sortilin localization and permit proneurotrophin-induced cell death[END_REF]. It is important to note that while the first co-receptor to be identified for proneurotrophin signaling through p75 NTR was sortilin, other members of the VSP10 family such as SorCS2 can also act as co-receptors [START_REF] Deinhardt | Neuronal growth cone retraction relies on proneurotrophin receptor signaling through Rac[END_REF]. An independent report confirmed this findings demonstrating that SorCS2 binds to the prodomain region of NGF, BDNF and NT3, as well as to p75 NTR [START_REF] Glerup | SorCS2 regulates dopaminergic wiring and is processed into an apoptotic two-chain receptor in peripheral glia[END_REF].

Biological Roles of ProBDNF

Cell death and survival

While the pro-survival effect of BDNF on central and peripheral neurons is well documented, the role of proBDNF on neuronal survival is cell-type specific. Initial experiments in cultured superior cervical ganglion (SCG) neurons [START_REF] Teng | ProBDNF induces neuronal apoptosis via activation of a receptor complex of p75NTR and sortilin[END_REF], where p75 NTR expression is substantial, revealed that application of recombinant uncleavable proBDNF triggers neuronal cell death [START_REF] Teng | ProBDNF induces neuronal apoptosis via activation of a receptor complex of p75NTR and sortilin[END_REF]. Additionally it has been reported that application of cleavage resistant proBDNF elicits cell death only on granular neurons from the cerebellum but not in hippocampal pyramidal neurons or cholinergic neurons from the basal forebrain that also express high levels of p75 NTR [16, 37] . In the cell types where proBDNF promotes cell death, p75 NTR is necessary for this function, [START_REF] Teng | ProBDNF induces neuronal apoptosis via activation of a receptor complex of p75NTR and sortilin[END_REF][START_REF] Koshimizu | Distinct signaling pathways of precursor BDNF and mature BDNF in cultured cerebellar granule neurons[END_REF]. In SCG neurons, proBDNF binding to sortilin is also implicated in the apoptotic mechanism [START_REF] Teng | ProBDNF induces neuronal apoptosis via activation of a receptor complex of p75NTR and sortilin[END_REF]. ProBDNF, through its interaction with p75 NTR and sortilin, has also been shown to promote caspase-dependent death of motor neurons in culture [START_REF] Taylor | Motoneuron programmed cell death in response to proBDNF[END_REF]. On cerebellar granular neurons c-Jun N-terminal kinases (JNK), caspase 3 and Rac-GTPases activation seem to be implicated in the apoptotic mechanism [START_REF] Koshimizu | Distinct signaling pathways of precursor BDNF and mature BDNF in cultured cerebellar granule neurons[END_REF]. These examples illustrate that while p75 NTR expression is necessary for proBDNF induced cell death it is not sufficient to determine the cell response to the propeptide.

Synaptic potentiation and depression

Mature BDNF is necessary for the establishment of the late phase of long-term potentiation (L-LTP). This has been demonstrated in hippocampal neurons of BDNF hemizygous mice after high frequency stimulation (HFS) establishing that the deficit on the L-LTP can be rescued by the application of recombinant mature BDNF [START_REF] Pang | Cleavage of proBDNF by tPA/plasmin is essential for long-term hippocampal plasticity[END_REF]. This effect mimicked that of the tPA/plasminogen complex previously identified as an activity-dependent protease that converts proBDNF into mature BDNF. Other than BDNF, the NMDA receptor is a prime target of tPA/Plasminogen important for synaptic plasticity [START_REF] Samson | Tissue-type plasminogen activator: a multifaceted modulator of neurotransmission and synaptic plasticity[END_REF][START_REF] Nicole | The proteolytic activity of tissue-plasminogen activator enhances NMDA receptor-mediated signaling[END_REF]. Interestingly, the enhancement of NMDA signaling by tPA may be responsible for the increase of extracellular mature BDNF levels resulting from neuronal activity [START_REF] Rodier | Exogenous t-PA administration increases hippocampal mature BDNF levels. plasmin-or NMDA-dependent mechanism?[END_REF]. Unequivocally, both plasminogen deficient mice and tPA knockout presented L-LTP deficits that are rescued by bath application of mature BDNF [START_REF] Pang | Cleavage of proBDNF by tPA/plasmin is essential for long-term hippocampal plasticity[END_REF]. In light of these arguments, it is particularly interesting to note the opposing effect of proBDNF on synaptic plasticity. Application of cleavage resistant proBDNF to hippocampal slices enhanced NMDA receptor dependent long-term depression (LTD) following low frequency stimulation (LFS) [START_REF] Pang | Cleavage of proBDNF by tPA/plasmin is essential for long-term hippocampal plasticity[END_REF]. As expected, this effect of proBDNF is mediated by p75 NTR , which is expressed on presynaptic terminals, postsynaptic spines and dendritic shafts of the CA1 hippocampal region, consistent with its role on proBDNF-mediated LTD [START_REF] Woo | Activation of p75NTR by proBDNF facilitates hippocampal long-term depression[END_REF]. Hippocampal slices from p75 NTR depleted mice failed to develop LTD after LFS despite normal basal synaptic transmission and neurotransmitter release. Likewise, hippocampal slices from wild type mice that were pretreated with p75 NTR blocking antibodies failed to develop LTD after LFS. These results are consistent with the developmental expression of LTD and p75 NTR , higher in early life (3 weeks) when induced-LTD is stronger, than in mature animals (8weeks).

Neuronal differentiation

Neurite retraction and reduction on dendritic spine density in response to proBDNF application occur in DRG [START_REF] Sun | ProBDNF collapses neurite outgrowth of primary neurons by activating RhoA[END_REF] and SCG [START_REF] Teng | ProBDNF induces neuronal apoptosis via activation of a receptor complex of p75NTR and sortilin[END_REF] neurons as well as in hippocampal [START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF][START_REF] Koshimizu | Multiple functions of precursor BDNF to CNS neurons: negative regulation of neurite growth, spine formation and cell survival[END_REF], cortical [START_REF] Sun | ProBDNF collapses neurite outgrowth of primary neurons by activating RhoA[END_REF], and cholinergic neurons [START_REF] Koshimizu | Multiple functions of precursor BDNF to CNS neurons: negative regulation of neurite growth, spine formation and cell survival[END_REF]. Interestingly, proBDNF can induce neurite retraction most likely through a p75 NTR dependent mechanism, as proBDNF has no effect on neuronal cultures form p75 NTR deficient mice [START_REF] Sun | ProBDNF collapses neurite outgrowth of primary neurons by activating RhoA[END_REF]. The cellular mechanism implicated in proneurotrophins-induced neurite remodeling was first described for proNGF in cultured hippocampal neurons [START_REF] Deinhardt | Neuronal growth cone retraction relies on proneurotrophin receptor signaling through Rac[END_REF]. ProNGF application induces a retraction of the growth cone of a subset of hippocampal neurons expressing p75 NTR within minutes of treatment. The effect is mediated by a complex of p75 NTR and its co-receptor SorCS2 through the RhoA/Rac GTPase system that impinged on the polymerization of the actin cytoskeleton [START_REF] Deinhardt | Neuronal growth cone retraction relies on proneurotrophin receptor signaling through Rac[END_REF]. A similar signaling mechanism converging on small GTPases activation and actin depolymerization was described for growth cone retraction of DRG neurons upon proBDNF incubation. However, the co-receptor for p75 NTR was not studied in this investigation [START_REF] Sun | ProBDNF collapses neurite outgrowth of primary neurons by activating RhoA[END_REF].

In vivo evidence for a biological role of proBDNF

Most studies investigating the possible biological role of proBDNF have been executed in vitro using relatively high concentrations of the recombinant uncleavable protein. Despite demonstrating a consistent effect of the proform on reducing dendritic arborization and enhancing LTD in hippocampal neurons as well as enhancing apoptosis in DRG neurons, the actual relevance of these findings in vivo was still unclear. To answer this question the laboratory lead by Dr. Barbara L. Hempstead came up with an elegant genetic animal model in which, the BDNF gene is replaced by a cleavage resistant mutant (RVRR to RVAA mutation on the cleavage site). The heterozygous version of this knock-in mice (proBDNF/+) expresses one copy of the cleavage-resistant proBDNF and one copy of the wild type BDNF, resulting in a haplo-insufficiency of mature BDNF and an overexpression of proBDNF. To discriminate between the effects of mature BDNF haplo-insufficiency and those triggered by the increased levels of proBDNF, all experiments were conducted comparing the proBDNF/+ heterozygote mice with BDNF +/-mice and wild type controls [START_REF] Yang | proBDNF negatively regulates neuronal remodeling, synaptic transmission, and synaptic plasticity in hippocampus[END_REF]. Using this model, they confirm hippocampal atrophy on proBDNF/+ mice that is significantly stronger than in BDNF+/-mice. By Scholl analysis, they confirmed a reduction in dendritic arborization of granule neurons in the hippocampus that was present in juvenile animals (P30) and became more noticeable in older animals (P105). The effect of BDNF haploinsufficiency was significantly lower than that of proBDNF overexpression supporting an in vivo role of this proneurotrophin. ProBDNF has no effect on granular neuron arbor complexity in p75 NTR deficient mice, confirming the requirement of this receptor for proBDNF actions in vivo. Furthermore, proBDNF induces a significant decrease on dendritic spines density on hippocampal neurons suggesting a role of this ligand on spine elimination or in reducing spinogenesis. Consistent with a loss of dendritic spines, proBDNF/+ mice exhibits impairments of basal synaptic transmission at the Shaffer collateral synapses. ProBDNF/+ mice presents a deficit on LTP following tetanic burst stimulation (TBS) but have normal HFS-induced LTP, which demonstrate a proBDNF specific effect on LTP that was not previously identified with recombinant proBDNF approaches. Finally, confirming previous reports proBDNF/+ mice have enhanced LFS LTD [START_REF] Yang | proBDNF negatively regulates neuronal remodeling, synaptic transmission, and synaptic plasticity in hippocampus[END_REF]. The study carried out by the Hempstead group represents a crucial advance in our understanding of proBDNF roles in the structural and physiological properties of the hippocampus.

The use of proBDNF knock-in mice genetic tool will be instrumental to shed light on how proBDNF can affect major functional aspects of the brain such as memory acquisition and retention, and susceptibility to neuropsychiatric diseases such as depression. Indeed several studies reviewed bellow suggest that proBDNF signaling could be implicated in disease states.

Is proBDNF implicated in disease states?

BDNF is a neurotrophin, which deregulation has been implicated in several neuropsychiatric and neurodegenerative disorders, ranging from depression, cognitive impairment, Alzheimer's, Parkinson's and Huntington's disease among others. The emergence of proBDNF as an independent signaling molecule bears the question of whether the regulation of proBDNF processing and its cognate receptor complex expression could also mediate some aspects of the nervous system pathology. To this regard, proBDNF signaling has been associated with seizures-induced cell death in mice. Several studies have reported an increased expression of proneurotrophins and p75 NTR following drug-induced status epilepticus (SE) in rodents [START_REF] Vondran | p75NTR, but not proNGF, is upregulated following status epilepticus in mice[END_REF][START_REF] Volosin | Induction of proneurotrophins and activation of p75NTR-mediated apoptosis via neurotrophin receptor-interacting factor in hippocampal neurons after seizures[END_REF]. SE induction provokes neuronal cell death in the hippocampus through a p75 NTR -mediated mechanism [START_REF] Volosin | Induction of proneurotrophins and activation of p75NTR-mediated apoptosis via neurotrophin receptor-interacting factor in hippocampal neurons after seizures[END_REF][START_REF] Troy | Mechanisms of p75-mediated death of hippocampal neurons. Role of caspases[END_REF]. SorCS2 and both proNGF and proBDNF are upregulated in the hippocampus of rats following SE [START_REF] Volosin | Induction of proneurotrophins and activation of p75NTR-mediated apoptosis via neurotrophin receptor-interacting factor in hippocampal neurons after seizures[END_REF] while in mice, proNGF is not [START_REF] Vondran | p75NTR, but not proNGF, is upregulated following status epilepticus in mice[END_REF], suggesting that these proneurotrophins could mediate p75 NTR dependent cell death. While proneurotrophins appear to be important in the early phase of these models of SE, mature BDNF signaling through TrkB is also implicated as inactivation of this receptor's activity following SE is sufficient to inhibit de development of chronic spontaneous seizures [START_REF] Liu | Transient inhibition of TrkB kinase after status epilepticus prevents development of temporal lobe epilepsy[END_REF]. Moreover, SE induces a TrkB to p75 NTR receptor switch that contributes to the seizure-induced cell death; however, these studies propose that mature BDNF, but not proBDNF, are responsible for p75 NTR activation and neurodegeneration in this pathological condition [START_REF] Unsain | Brain-derived neurotrophic factor facilitates TrkB down-regulation and neuronal injury after status epilepticus in the rat hippocampus[END_REF][START_REF] Unsain | Status epilepticus induces a TrkB to p75 neurotrophin receptor switch and increases brain-derived neurotrophic factor interaction with p75 neurotrophin receptor: an initial event in neuronal injury induction[END_REF].

So far, only one study has explored the use of proBDNF as a potential biomarker for disease with negative results. Yoshida et al. explored whether mature BDNF of proBDNF could be used as biomarkers for major depressive disorder (MDD). Using specific antibodies for proBDNF and mature BDNF, they tested peripheral blood of MDD patients and age and gender matched controls, and found a significant decrease on mature BDNF but no changes on proBDNF [START_REF] Yoshida | Decreased serum levels of mature brain-derived neurotrophic factor (BDNF), but not its precursor proBDNF, in patients with major depressive disorder[END_REF]. The neuronal upregulation of p75 NTR is a feature of several other pathological conditions including ischemia [START_REF] Kokaia | Focal cerebral ischemia in rats induces expression of P75 neurotrophin receptor in resistant striatal cholinergic neurons[END_REF]and Alzheimer disease [START_REF] Mufson | Cortical neurons express nerve growth factor receptors in advanced age and Alzheimer disease[END_REF] but whether proBDNF is the ligand on those conditions is still to be determined.

PRODOMAIN SIGNALING

The prodomain of BDNF itself is detectable in vivo and has been recently found to be a secreted independent ligand [START_REF] Dieni | BDNF and its pro-peptide are stored in presynaptic dense core vesicles in brain neurons[END_REF][START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF][START_REF] Mizui | BDNF pro-peptide actions facilitate hippocampal LTD and are altered by the common BDNF polymorphism Val66Met[END_REF] from mature BDNF and proBDNF. Below we describe the main findings of this newly described active peptide.

Secretion of the BDNF Prodomain

According to the sorting and cleavage system of BDNF described before, the prodomain of BDNF is foreseen to be released from neurons. A careful electron microscopy study of the adult hippocampus revealed that the prodomain is indeed present in presynaptic secretory dense-core vesicles along with the mature form of BDNF [START_REF] Dieni | BDNF and its pro-peptide are stored in presynaptic dense core vesicles in brain neurons[END_REF]. This finding suggests that the prodomain is likely to be released in the synaptic cleft, co-secreted with mature BDNF and unprocessed proBDNF. A recent report confirmed that the prodomain in isolation is detected extracellularly [START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF]. The experimental approach of this report utilized cultured hippocampal neurons in conditions to reduce glia contamination, collected the conditioned media, and detected the endogenous prodomain secreted utilizing specific monoclonal antibodies. In this study, the prodomain was secreted in an activity-dependent manner after depolarization of the cultured neurons. Incubation of the hippocampal neuron cultures with a plasmin inhibitor and/or MMP inhibitor II (which inhibits MMP1, 3, 7 and 9) to prevent extracellular cleavage of secreted proBDNF did not alter significantly the levels of the secreted prodomain in the media, in basal conditions or after depolarization [START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF]. Interestingly, both the Val66 and Met66 prodomains can be secreted after depolarization with potassium chloride; however, the levels of secreted Met66 prodomain are significantly lower as compared with the Val66 prodomain. This finding is in agreement with previous studies which showed that the Val66Met polymorphism leads to a decrease in the trafficking of BDNF to secretory vesicles and the subsequent impairment of activity-dependent release of mature BDNF [START_REF] Chen | Sortilin controls intracellular sorting of brain-derived neurotrophic factor to the regulated secretory pathway[END_REF][START_REF] Egan | The BDNF val66met polymorphism affects activity-dependent secretion of BDNF and human memory and hippocampal function[END_REF][START_REF] Chen | Genetic variant BDNF (Val66Met) polymorphism alters anxietyrelated behavior[END_REF].

Biological Roles of the Prodomain

As the BDNF prodomain has been very recently identified as an independent ligand, its effects on neuronal survival have not yet been reported. Next, we will review the reported biological functions of the prodomain.

Neuronal morphology

In a recent study, Anastasia et al. explored whether the prodomain elicit an independent biological function [START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF]. To do so, they explored the structure and properties of the most frequent prodomain (with a valine in position 66 in 75% of the global population) and the prodomain carrying Val66Met substitution (present in 25% of the population). This substitution within the prodomain sequence is the result of a common human polymorphism associated with memory impairment and associated risk of depression and anxiety [START_REF] Egan | The BDNF val66met polymorphism affects activity-dependent secretion of BDNF and human memory and hippocampal function[END_REF][START_REF] Dincheva | Impact of the BDNF Val66Met polymorphism on cognition: implications for behavioral genetics[END_REF][START_REF] Chen | Genetic variant BDNF (Val66Met) polymorphism alters anxietyrelated behavior[END_REF][START_REF] Hajek | Reduced hippocampal volumes in healthy carriers of brain-derived neurotrophic factor Val66Met polymorphism: meta-analysis. The world journal of biological psychiatry : the official[END_REF]. As described above, the proposed mechanism of action for this substitution in neuropsychiatric disorders susceptibility is a loss of function of mature BDNF, which is the consequence of a decrease activity dependent secretion [START_REF] Egan | The BDNF val66met polymorphism affects activity-dependent secretion of BDNF and human memory and hippocampal function[END_REF]. Anastasia et al. proposes an additional mechanism to explain the polymorphism impact on human behavior, in which the Val66Met substitution alters the conformation of the prodomain and confers a gain of function to the Met66 prodomain affecting neuronal morphology. Specifically, they found that the Met66 prodomain (but not the Val66) is capable of interacting with SorCS2 to induce growth cone retraction in hippocampal neurons. Interestingly this new function of the prodomain appears to be dependent on p75 NTR expression as the Met66 prodomain is inert on p75 NTR deficient cells [START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF]. But how p75 NTR signaling is required for the Met66 prodomain is still unclear as neither the Val66 nor the Met66 prodomains interact with this receptor [START_REF] Anastasia | Val66Met polymorphism of BDNF alters prodomain structure to induce neuronal growth cone retraction[END_REF].

LTD and LTP

In light of the facilitation of LTD induced by proBDNF, Mizui et al. explored the implication of the isolated prodomain in hippocampal neuronal plasticity, more precisely on LFS-induced LTD. They demonstrate that the BDNF but not the NGF prodomain facilitates LFS-induced LTD, an effect that also depends on p75 NTR [START_REF] Mizui | BDNF pro-peptide actions facilitate hippocampal LTD and are altered by the common BDNF polymorphism Val66Met[END_REF]. Interestingly, the Met66 prodomain shows the opposite effect and inhibits LFS-induced LTD, but the implication of p75 NTR on the Met66 prodomain effect was not explored. These results are consistent with a previous study describing a deficit on LFS-induced LTD in hippocampal slices of BDNF met/met mice [START_REF] Ninan | The BDNF Val66Met polymorphism impairs NMDA receptordependent synaptic plasticity in the hippocampus[END_REF], which suggest that the prodomain could be responsible for this effect. The LFS protocol elicits NMDA dependent LTD that relies, in part, on trafficking of AMPA receptor subunits. Mizui et al. demonstrate that the Val66 prodomain facilitates LTD by promoting the surface expression of GluN2B NMDA receptor subunit and the endocytosis of AMPA receptors, while the Met66 prodomain blocks it. These results imply a general effect of the Met66 prodomain on NMDA signaling [START_REF] Mizui | BDNF pro-peptide actions facilitate hippocampal LTD and are altered by the common BDNF polymorphism Val66Met[END_REF]. The deficient NMDA-dependent LTP of the BDNF met/met [START_REF] Ninan | The BDNF Val66Met polymorphism impairs NMDA receptordependent synaptic plasticity in the hippocampus[END_REF] mice supports also this hypothesis. Unfortunately the effect on the Met66 prodomain in hippocampal LTP has not yet been reported.

Until now, the effect of the Val66Met polymorphism was mainly explained by a loss of function of mature BDNF consequence of a decrease on activity dependent BDNF secretion [START_REF] Chen | Genetic variant BDNF (Val66Met) polymorphism alters anxietyrelated behavior[END_REF]. These recent publications exploring the biological function of the BDNF prodomain independently of mature BDNF and proBDNF, describe gains of functions for the Val66Met polymorphism, raising the question of which BDNF ligands are contributing more to the phenotypic characteristics of the Met66 human carriers.

CONCLUSION

Substantial evidence supports the idea that proBDNF function goes beyond being a synthesis precursor for mature BDNF. Therefore, factors such as synthesis, sorting, release and processing of proneurotrophins, as well as their cognate receptors availability, could be potent modulators of homeostasis in the nervous system. The concomitant expression of proBDNF and p75 NTR in the hippocampus during early post-natal periods and its subsequent decrease in adulthood is a good example of developmental shift between functions of the proBDNF, mature BDNF and its prodomain. The implication of proBDNF in pathological states remains to be demonstrated.


David Janin
email: janin@labri.fr

Screaming in the IO Monad A Realtime Audio Processing and Control Experiment in Haskell

Keywords: CCS Concepts, Software and its engineering → Semantics, Domain specific languages, • Applied computing → Media arts, Realtime Programming, Monad Streams, Synchronous Audio Processing, Asynchronous Audio Control

We investigate in this paper the applicability of the notion monad streams to media stream programming, and, more specifically, audio processing and control. Simply said, a monad stream is sort of a list guarded by a monad action that returns either nothing when the stream is over, or, otherwise, just the current value of the stream and the guarding action of its continuation.

Applied to the IO monad, it appears that monad streams can be used for modeling both input streams and output streams, with full control of the possibly synchronism between input and output streams in stream functions. This allows for defining both synchronous or asynchronous functions, or any combination of both notions.

In the abstract, this opens quite intriguing and generic solutions towards programming systems that are globally asynchronous and locally synchronous (GALS). In the concrete, applied to real-time audio, this allows for combining, in a fairly simple and unified way, both (synchronous) audio processing and (asynchronous) audio control.

As far as performance are concerned, our proposal allows non-trivial transformation of audio streams at 44100 Hz with a 10 ms latency, a performance comparable to functional programing languages dedicated to real-time audio processing such as Faust.

Introduction

Motivation and Problems. Music programing with audio processing is a matter of streaming signals from inputs through various programmed transformation and control devices, possibly with feedback loops, towards outputs.

While audio transformation devices are generally synchronous, say governed by some fixed sampling rate, control devices may well be asynchronous, control parameters being produced by, say, human interactions. The resulting programing style, sometimes called globally asynchronous and locally synchronous (GALS), was identified a while ago [START_REF] Teehan | A Survey and Taxonomy of GALS Design Styles[END_REF].

For this kind of programing, we consider the possibility of using a lazy functional programing language such as Haskell [START_REF] Hudak | A History of Haskell: Being Lazy With Class[END_REF] -a possibility often regarded as irrelevant, the garbage collector of Haskell preventing, a priori, highfrequency IO processing.

It occurs that, a posteriori, this is not only feasible, but with performances comparable to dedicated real-time audio processing and control languages such as Faust [START_REF] Orlarey | Faust: an Efficient Functional Approach to DSP Programming[END_REF], still preserving many features of Haskell language: its laziness and its polymorphic types.

Main Result. More precisely, we consider some simple notion of monad streams that allow for defining both input and output stream in a single and simple formalism, in such a way that both synchronous and asynchronous stream transformation functions, and their combinations, can easily be implemented.

As a result, we obtain a fairly flexible library for audio processing and control, fully implemented in Haskell, that only uses the external Jack audio connection kit for defining connection with the underlying system. Experiments show that non trivial audio processing and control with 44100 Hz audio signals can be achieved with a 10ms latency -a latency considered to be unnoticeable by a general audience.

Overview of the Main Ideas. A monad stream is essentially defined as a monad action that, when executed, returns either nothing, when the stream is over, or the current value of the stream and a monad action that guards the access to the remainder of that same stream.

Thanks to the capacity offered by monad programing to execute and/or produce monad actions (see below), a monad stream can thus be viewed, depending on the way monad actions are handled in a function from stream to stream, as one of the following:

(1) an input stream when the execution of each monad stream action allows for accessing to the stream of input values, (2) an output stream, when the production of each monad stream action tells how the associated output value shall be accessed later on. Saying so, we follow the somewhat naive but fruitful point of view that a bind expression m > > = f is both a monad action produced by binding m with f , as well as the action describing the execution of action m with its returned value passed to f as argument. Of course, such a point of view is just false with an arbitrary monad, but it does make sense in monads such as the IO monad where the bind is strict.

As we shall see later in the text, applied to the IO monad, programming a synchronous IO function between streams is then simply a matter of (inductively) describing how each input monad stream action is transformed into a corresponding output monad stream action, much like in a synchronous Mealy machine [START_REF] Mealy | A Method for Synthesizing Sequential Circuits[END_REF] (see also [START_REF] Eilenberg | Automata, Languages and Machines[END_REF] p 299). The fact that the monad stream type constructor is a functor provides examples of one state Mealy machines. Multi-state Mealy machines are also easily definable thanks to a loop operators.

Quite strikingly, such a principle is applicable both to lazy or eager functional programing languages. Indeed, a monad stream is (essentially) an action to be executed, not an executed action. In other words, monad stream can also be understood as a way to encode lazy stream, as implicitly defined in Haskell, into an eager programming language such as, say, OCaml [START_REF] Rémy | Using, Understanding, and Unraveling the OCaml Language From Practice to Theory and Vice Versa[END_REF].

Moreover, as such a laziness is explicitly encoded in monad stream, the programmer keeps full control on the synchrony between input and output streams when defining a (recursive) function over streams. There is no forced correspondence between the rank (or rather the nesting depth) of input monad stream actions performed in some recurrence step and the rank (or rather the nesting depth) of the output monad stream actions produced in that same recurrence step.

As a consequence, monad streams also allow for defining a wide range of partially asynchronous functions over streams in the sense that:

(1) the input streams are not necessarily red at the same rate, (2) the output stream is produced at a rate that may depend on all, some or none of the rate at which the input streams are received.

As a typical example of a fully synchronous stream function, one can zip two input streams into a single one. On the opposite side, as a typical example of a fully asynchronous stream function, one can merge two monad streams into a single one by sorting their values according to their availability, thanks to some simple concurrency features extending our proposal.

For convenience, most utility functions we shall define in this paper are illustrated by block diagrams of the form depicted in Figure 1. More precisely, we shall define functions over streams whose output stream is (essentially) produced at the same rate as the rate of its synchronous inputs, the produced values possibly depending on some parameter values received from its asynchronous inputs.

Also, it must be mentioned that most discussed types and transformations are detailed throughout with (essentially) complete Haskell code. This first illustrates the simplicity of our proposal. Moreover, as the proposed code is detailed in non-compact form, this code shall still be understood by readers not familiar with Haskell and its numerous libraries -libraries that we essentially do not use, aside from Haskell prelude, so that we keep full control on performance issues.

Organization of the Paper. Monad streams are briefly presented in Section 2. Basic examples of standard input and output turned into streams are detailed. The notion of synchronous functions we consider is defined in Section 3 together with various examples.

The notions of monad and monad stream references are presented in Section 4. This first allows for freely and safely duplicating monad streams. This also yield some examples of function over streams with asynchronous features in Section 5.

Examples of typical audio processing and control functions are presented and discussed in Section 6, and connection to the audio connection kit (Jack) is then described in Section 7. This essentially amounts to transforming the synchronous stream functions we wish to play into the transition function of its underlying Mealy machine operational model -a transition function used as a callback by the audio driver. Performance issues and tuning are eventually discussed.

Connections with related works are then discussed in Section 8 before concluding in Section 9.

In this paper we shall use a parameterized notion of streams that essentially yields two kind of streams:

(1) the monad streams parameterized by a monad type constructor m (in this section), (2) the monad reference streams parameterized by a monad reference type constructor Ref m (see Section 4). More precisely the parametrized stream type is defined by:

newtype Stream f a = Stream ({ next :: f (Maybe (a, Stream f a)) })
with a type function f :: * → * and a type a : * as parameters.

Defining the length of a parameterized stream as the number of nested next action that defines it, we shall soon observe, with stdinStream example below, that such a length is not only a dynamic value but it may be infinite as well.

Although the evaluation of next s for some stream s depends on the choice of the type function f , it shall return, in all cases, the immediate future of the stream, defined by:

(1) either Nothing when stream s terminates, [START_REF] Bernardy | Linear Haskell: Practical Linearity in a Higher-order Polymorphic Language[END_REF] or Just (a, sc) when stream s produces value a and continues as stream sc. A monad stream is then defined as any stream parameterized by a monad functor.

Standard Input Output Example. As a simple stream programming example, reading a stream from the standard input ( stdin) can be written as follows: In this example, the stream terminates when EOF is received from the standard input.

Conversely, printing a stream to the standard output (stdout) can be written as follows:

streamStdout :: Stream IO Char → IO () streamStdout (Stream m) = do c ← m case c of Nothing → return () Just (a, s) → do putChar a streamStdout s
Observe that its the execution of the IO monad action streamStdout s that will make the monad action in stream s to be performed. In other words, following Elliot's terminology [START_REF] Elliott | Push-pull functional reactive programming[END_REF], monad streams must be pulled for they are lazy data structures. This constrasts with synchronous language families with push semantics of functions over signals.

Continuing our IO examples, echoing the standard input on the standard output can then be defined by: echoStdIO :: IO () echoStdIO = streamStdout stdinStream It is worth noting that the above IO action runs in constant space when compiled with ghc. In other words, although a monad stream computation may be non terminating as above, on-the-fly processing can be defined over streams without any memory leaks.

Functor Instance. As another simple programing example over a monad stream, the following functor instance allows application of a function to every element of a stream given as input:

instance Monad m ⇒ Functor (Stream m) where fmap f (Stream m) = Stream $ do c ← m case c of Nothing → return Nothing Just (a, mc) → return $ Just (f a, fmap f mc)
Observe that every input action is mapped to an output action. Such a kind of function will later be called synchronous.

The behavior of fmap is conveniently described by the block

• • a b f Figure 2. The fmap f block diagram diagram depicted in Figure 2.
Observe that1 , the weaker constraint Functor m suffices for turning Stream m into a functor. Indeed, one can put

fmap f (Stream m) = Stream $ fmap (fmap (λ(a, sc) → (f a, fmap f sc))) m
The proposed version, within the monad m, also aims at illustrating the notion of synchronous stream function we shall see in the next section.

Monad Streams vs Monad

Actions. An interesting feature of monad streams is that they can be retrieved from monad actions. More precisely, there is the function:

toStream :: Monad m ⇒ m (Stream m a) → Stream m a toStream m = Stream $ m > > = next
that shows monad streams are closed under monad actions. This implies, for instance, that any function:

f :: a → m (Stream m b)
that produces a monad stream via some monadic computation can be turned into the function toStream • f :: a → Stream m b that stays within monad stream types. As a consequence, although monad streams are (deeply) built with monad actions, most functions acting on monad streams can be defined within monad streams as illustrated by the various (pure) stream combinators defined throughout.

Horizontal Monoid Structure. Monad streams can be combined one after the other in the following manner, yielding a monoid instance.

instance Monad m ⇒ Monoid (Stream m a) where mempty = Stream (return Nothing) ( ) (Stream m) s = Stream $ do c ← m case c of Nothing → next s Just (a, sc) → return $ Just (a, sc s)
Observe that the second monad stream is necessarily delayed until the first monad stream terminates. In other words, the second stream is implicitly buffered. This says that, in most cases, such a horizontal product shall only be used with a finite and bounded length first argument. With a left stream c of constant length d, the mapping λs → c s is still synchronous in some sense made precise in the next section. The resulting block diagram is depicted in Figure 3.

• • a a delay c

Figure 3. The delay block diagram

Monad Stream vs Lazy Lists. The monoid instance above illustrates the fact that monad streams can be seen as an alternative encoding of lazy lists. In particular, monad streams can be infinite.

Observe however that such a encoding of laziness does not rely on the underlying programing language semantics. Indeed, similar monad stream types can be defined in a programing language with eager evaluation such as OCaml, the monad action type m a simply replaced by, say, the function type s → (s, a) for some (monad) state type s.

Synchronous Monad Stream Processing

Here, we review some more function examples over streams that we call synchronous. Synchronous Stream Functions. There are various ways to define synchronous functions, as for instance done the Synchronous language family [START_REF] Benveniste | The Synchronous Languages Twelve Years Later[END_REF][START_REF] De Simone | The Synchronous Hypothesis and Synchronous Languages[END_REF] or as detailed by the author when developing the notion of timed domains [START_REF] Janin | Spatio-temporal domains: an overview[END_REF].

In this paper, we shall rely on the rather intuitive (and special case) definition that a synchronous function over streams shall essentially behave like a Mealy machine, that is, a function that reads in a synchronized way all its (stream) inputs and produces its (stream) output at the same rate.

As streams have to be "pulled" for their actions to be executed and their values to be read, the above intuition can be rephrased as follows: a function over streams is said to be synchronous when, for every input and for every possible rank n, the execution of the nth monad action in the output stream of that function implies the execution of the nth actions of each of its input streams (therefore all preceding actions as well) and no more.

Additionally, a stream function obtained from a synchronous function by delaying its output by a stream of constant length d as above is called d-synchronous.

Simple Synchronous Function Examples. Both stream functions id and fmap f are synchronous in the sense above. Moreover, in both these cases, the output stream terminates when the input stream terminates. The function λs → c s with a monad stream c of known length d is d-synchronous.

Synchronous Zip. Another typical example of a synchronous function is the zip function defined over streams by:

zipStream :: Monad m ⇒ Stream m a → Stream m b → Stream m (a, b) zipStream = zipStreamWith (λa → λb → (a, b)) with zipStreamWith :: Monad m ⇒ (a → b → c) → Stream m a → Stream m b → Stream m c zipStreamWith f (Stream m 1 ) (Stream m 2 ) = Stream $ do c 1 ← m 1 c 2 ← m 2 case (c 1 , c 2 ) of (Just (a 1 , sc1), Just (a 2 , sc2)) → return $ Just (f a 1 a 2 , zipStreamWith f sc1 sc2) → return Nothing
The block diagram of the function zipStreamWith f is depicted in Figure 4. Observe that, in such a zip, the output terminates, whenever on the input stream terminates. This is indeed allowed by our definition of synchronicity.

• • • a b c f
Constant Streaming. As a simple application example of the synchronous zip, the function constSync takes two streams as input and returns the first one.

constSync :: Monad m ⇒ Stream m a → Stream m b → Stream m a constSync = zipStreamWith const
Given a monad stream s, one may think that constSync s essentially behave like const s. However, the later makes no synchronization between the input and the output stream, and, even worse, does not execute the monad actions of the second stream at all, therefore its side-effects. These two functions truly have distinct behaviors. More on (implicit) Monad Stream Clocks. Every monad stream induces a clock, the clock ticks being defined by the execution of the nested monad actions embedded in that stream.

• • • a b a const
In the zipStreamWith code given above, one can observe that streams are zipped by waiting each time on the slowest action to terminate. This waiting is even biased by waiting first for the action m 1 to terminate before running the second action m 2 . It follows that the implicit clock of the resulting stream is the (element wise) upper bound of the implicit clocks of the input streams.

In other words, when defining synchronous processing, we somehow assume that all inputs streams are essentially synchronized on the same clock. However, strictly speaking, this assumption is false as illustrated by the following stream functions:

repeatN :: Monad m ⇒ Int → a → Stream m a repeatN n a = Stream • return $ if (n ⩽ 0) then Nothing else Just (a, repeatN (n âĹŠ 1) a) takeN :: Monad m ⇒ Int → Stream m a → Stream m a takeN n s = zipStreamWith cons s (repeatN n ())
that takes , somehow in a synchronous way, the first n values of an input stream with, say, any input governed clock, while the clock of the stream produced by repeatN n () only depends on how fast it is read. A a result, with monad streams, there is no explicit system clock synchronizing all streams. This apparently quite differs from the notion of synchronicity proposed and implemented in the synchronous language family [START_REF] De Simone | The Synchronous Hypothesis and Synchronous Languages[END_REF], even though the resulting global behaviors are quite similar.

Stream Loops. Much like in the state monad, there is a loop function that allows for defining arbitrary synchronous function defined as a Mealy machine.

loopStream :: Monad m ⇒ s → ((a, s) → m (b, s)) → Stream m a → Stream m b loopStream s f (Stream m) = Stream $ do c ← m case c of Nothing → return Nothing Just (a, sc) → do (b, s ′ ) ← f (a, s) return $ Just (b, loopStream s ′ f sc)
More precisely, given a Mealy machine defined via state type s, input type a, output type b, initial state s 0 :: s, and (deterministic) transition function delta :: (a, s) → (b, s), the stream function loopStream s 0 (return • delta) just encodes such a Mealy machine depicted in Figure 6. with delayBy delaying its input stream by the one value stream defined by its argument.

• • • • • • a s b s delta delayBy s 0
Observe that in loopStream type, we more generally define transition function with type (a, s) → m (b, s). In the IO (concurrent) monad, this allows for defining more efficient implementation of transition functions. A non-trivial application of such a possibility is illustrated in Section 7 when transforming any synchronous IO stream function into its (implicit) transition function.

Monad Stream References

When handling IO with monad streams, as with stdinStream defined above, an important issue is that, a priori, such a stream should not be shared by two (threaded) independant IO monad action. Indeed, two running actions sharing a copy of stdinStream will not share the same sequence of inputs but, instead, will receive one of the subsequence resulting from the distribution of the original sequence between these two actions.

The notions of monad references and monad stream references define in this section offer a fairly generic way to cope with such an issue.

Monad Reference. Simply said, a monad reference is a reference to a location, uniquely associated to a running monad action, that, upon termination of that action, shall contain the value returned by that action and shall be freely read by any action possessing that reference.

Such a notion is conveniently described by the following class type: where:

(1) Ref m is the type of references to running action, (2) forkToRef forks an action and (immediately) returns a reference to that action, (3) readRef returns (and possibly waits for) the value returned by a referenced action, (4) tryReadRef immediately returns nothing if the referenced action is not terminated or just its returned value otherwise, (5) and parReadRef returns the value of one of the first terminated referenced actions. In the case that the two actions are already terminated or are terminating at the same time, the output of parReadRef may be non deterministic.

Conditional Cut. As a first application example of monad references, the following function runs a monad action and a monad stream, the termination of the action yielding a cut of the input stream.

MonadRef m ⇒ StreamRef m a → Stream m a readStreamRef (Stream v) = Stream $ do c ← readRef v return $ case c of Nothing → Nothing Just (a, rc) → Just $ (a, readStreamRef rc)
Clearly, while a stream s shall not be shared by independent actions, for it may contain monad actions with non sharable side effects, the stream readStreamRef r obtained after forking the stream s can be freely shared. Indeed, reading a stream reference has no side effect on the referenced stream value.

Standard Input Output Example Continued.

There are various ways of defining a MonadRef instance for the IO monad. Haskell's async library defined by Simon Marlow [START_REF] Marlow | Parallel and Concurrent Programming in Haskell[END_REF] gives one possibility.

The following instance, simply obtained by defining references to IO actions as mutable variables containing their returned value, is simple enough to be described in full detail.

instance MonadRef IO where type

Ref IO = MVar forkToRef m = do v ← newEmptyMVar ← forkIO (m > > = putMVar v) return v readRef = readMVar tryReadRef = tryReadMVar parReadRef r 1 r 2 = do v ← newEmptyMVar ← forkIO (readRef r 1 > > = return • Left > > = tryPutMVar v > > return ()) ← forkIO (readRef r 2 > > = return • Right > > = tryPutMVar v > > return ()) takeMVar v
Then, continuing our standard IO example, one can check that the action:

echoStdIOviaRef :: IO () echoStdIOviaRef = do r ← forkStreamToRef stdinStream streamStdout (readStreamRef r)
that echoes the standard input to the standard output much like echoStdIO defined above still runs with constant memory space even though it is now defined via the forking of the input stream. Such an example illustrate the power of monad streams and monad references that, when properly used, fully preserve the garbage collector to avoid any memory leaks.

Asynchronous Monad Stream Control

Aside synchronous stream processing, there is also the need for asynchronous stream control: series of control values (or events) that are received at a much lower and irregular frequency than the synchronous stream to be processed.

Thanks to the notion of monad references defined above, various asynchronous functions over stream are definable.

Asynchronous Control. A first, quite involved example is a function that transforms an input stream depending on a parameter received asynchronously.

streamMap :: MonadRef m ⇒ (a → m b) → Stream m (a → m b) → Stream m a → Stream m b streamMap f (Stream mf ) (Stream m) = Stream $ do rf ← forkToRef mf r ← forkToRef m c ← parReadRef rf r case c of Left (Just (g, sf )) → next $ streamMap g sf (Stream $ readRef r) Right (Just (a, s)) → do b ← f a return $ Just (b, streamMap f (Stream $ readRef rf ) s) → return Nothing
Observe that the output stream ends whenever one of the two input stream ends. The corresponding block diagram is depicted in Figure 8. Observe that, as already done for

:: MonadRef m ⇒ Stream m a → Stream m a → Stream m a merge (Stream m 1 ) (Stream m 2 ) = Stream $ do r 1 ← forkToRef m 1 r 2 ← forkToRef m 2 c ← parReadRef r 1 r 2 case c of Left Nothing → readRef r 2 Right Nothing → readRef r 1 Left (Just (a, mc1)) → return $ Just (a, merge mc1 (Stream $ readRef r 2 )) Right (Just (a, mc2)) → return $ Just (a, merge (Stream $ readRef r 1 ) mc2)
Clearly, the outcome of such a function is possibly nondeterministic since each execution of parReadRef r 1 r 2 may induce a race with nondeterministic outcome.

Of course, such a function is of no use for synchronous programing as required with audio processing. What could be the meaning of the merge of two audio signal ? However, such a merge function can be used below for merging two independent streams of control values.

Audio Processing and Control

We are now ready to define functions more specifically dedicated to audio processing and control. Below, we review several archetypal examples of this.

Oscillators. As a first example, one can define an sinusoidal signal at a given period described in number of samples by osc :: Int → Stream IO Sample osc n = oscN 0 n where oscN ::

Int → Int → Stream IO Sample oscN n k = Stream $ do let v = sin (2 * pi * fromIntegral (mod n k) /fromIntegral n) return $ Just (v, oscN (n + 1) k)
where Sample is in Jack interface just a type synonim for CFloat. Observe that the actual frequency in Hz of such an sinusoidal shall only be defined by the reading speed of the resulting stream. Forward Action. A delay line followed by some summing of samples is a typical device for defining (simple) low cut or high cut filter. They can be defined as follows: Retro Action. A retro action (or retro feedback) is another typical device for defining a pass band filter.

feedForward :: Int → a → (a → a → b) → Stream IO a → Stream IO b feedForward n a 0 f s = toStream $ do ch ← newChan writeList2Chan ch (take n (repeat a 0 )) let delta (u, ch) = do v ← readChan ch writeChan ch u let w = f u v seq w $ return (f u v, ch) return $ loopStream ch delta s • • • • • a a b f delayByN n a 0
feedBack :: Int → b → (a → b → b) → Stream IO a → Stream IO b feedBack n b 0 f s = toStream $ do ch ← newChan writeList2Chan ch (take n (repeat b 0 )) let delta (u, ch) = do v ← readChan ch let w = f u v seq w $ writeChan ch w return (w, ch) return $ loopStream ch delta s
Observe that such a code is essentially the same as above up to the fact that, in this case, it is the output value w that is re-injected into the FIFO parameter ch.

In both case, the content of the channel is used as the state of the underlying Mealy machine defined by the transition function delta. Worth being noticed, we use the type Chan in this function instead of the type List for it appears it is way more efficient as far as performance are concerned. This fully justifies the choice made in function loopStream to have a transition function of type (a, s) → m (a, s). Stereo vs Mono Streams. Turning two mono streams into a stereo streams is simply achieved by the zipStream function already described above.

Last, we need to connect our stream function to the underlying system. For such a purpose, we shall use the Haskell interface to the fairly flexible and cross-plateform Jack audio connection kit.

For audio processing programs, we expect to use stream function, that is, synchronous functions of the form: The purpose of this section is to shows that, in the IO monad, one can actually converts any synchronous function into such a step function, hiding its underlying memory state into the IO monad.

From

Step Functions to Synchronous Functions. Observe that the other direction, defining a synchronous stream function from a step function, is easy. Indeed, this can be achieved by:

mapToStream :: Monad m ⇒ (a → m b) → Stream m a → Stream m b mapToStream f (Stream m) = Stream $ do c ← m case c of Nothing → return Nothing Just (a, sc) → do b ← f a return $ Just (b, mapToStream f sc)
Clearly, the resulting function is synchronous.

FIFO vs Monad Streams. In the IO monad, converting any synchronous stream function into its corresponding step function is achieved by means of creating two communication channels:

(1) one from the step function input to the stream given as argument to the stream function, (2) one from the stream resulting from that application, to the output of the step function.

These communication channels are conveniently and efficiently encoded by means of FIFO channels (Chan). The connection diagram induced by such a translation of stream functions into step functions is depicted in Figure 12. The difficulty in drawing such a picture is that the IO monad is (almost) everywhere around, the snake-like arrow describing not functions, but, instead, IO communication between certain typed value. From FIFOs to Input Streams. Turning a FIFO into a stream can simply be done as follows.

makeStreamFromChan ::

Chan a → Stream IO a makeStreamFromChan ch = Stream $ do a ← readChan ch return $ Just (a, makeStreamFromChan ch)
Observe that the frequency of the produced infinite stream depends on the frequency at which values are put in the FIFO.

From Output Streams to FIFOs. Conversely, turning an output stream into a FIFO can be done by:

makeChanFromStream :: Int → a → Stream IO a → IO (Chan a) makeChanFromStream n ia s = do ch ← newChan writeList2Chan ch (take n (repeat ia)) ← forkIO $ dropStreamToChan ch s return ch where dropStreamToChan ch (Stream m) = do c ← m case c of Nothing → return () Just (a, mc) → seq a $ (writeChan ch a) > > dropStreamToChan ch mc
In the above signature, we also take an integer n and an initial value a in order to initialize the FIFO with n times the initial value n. This allows for inserting some delay buffering to the expected function.

Observe that, after such an initial delay, the frequency at which the argument stream will be traversed depends on the frequency at which the returned FIFO will be read by a readChan action.

Observe also that the function dropStreamToChan is forked so that, when used, feeding and reading the FIFO channel are mostly desynchronized actions.

Extracting

Step Function. Last, turning a stream synchronous function into its corresponding step function can be done as follows:

streamToMapN :: Int → b → (Stream IO a → Stream IO b) → IO (a → IO b) streamToMapN n b f = do inChan ← newChan outChan ← makeChanFromStream n b $ f (makeStreamFromChan inChan) return (λa → seq a $ writeChan inChan a > > readChan outChan)
The first integer argument is the length of the buffer (in number of samples).

It is quite a striking fact that streamToMapN manages to re-create and handle the implicit Mealy machine state of its stream function argument. Making an explicit extraction of the Mealy machine induced by a streaming function would be fairly involved and would necessitate both the code of that function and a precise operational model.

Connection with Jack. Last, connection with Jack audio connection kit, via the Jack Haskell interface implemented by Thielemann et al., is simply achieved by:

playWithJack :: Int → (AudioSStream → AudioSStream) → IO () playWithJack n f = streamToMapN n (0, 0) f > > = mainStereo
where AudioSStream is just a type synonym of IO streams of stereo samples and mainStereo is one the main function provided by the interface to connect a Haskell defined audio transformation to Jack audio server.

Performance Issues and Parameter Tuning. The integer parameter in playWithJack defines the size of the delay buffer, internal to our Haskell code, between sample inputs and sample outputs. Such a buffering is essential for achieving good performance. Indeed, it allows for desynchronizing input-reading from Jack server and output-writing to Jack server. Experiments shows that, at 44100 Hz, a 128 samples buffer length suffices. An additional buffer size is defined on Jack server. It defines the frequency at which Jack server is calling a Haskell function as a callback. Again, experiments show that, at 44100 Hz, a 128 samples buffer length suffices.

Together, this eventually yields to running audio processing and control programs written is Haskell, essentially with no loss of samples, with a cumulative latency of 11.6 ms, twice the 5.8 ms latencies induced by the two buffers of 128 samples size.

To the best of our knowledge, no existing library written in Haskell yet reaches such a performance level together while offering such a level of abstraction.

Related Works

In this paper, we use the presentation of monad stream defined by the author [START_REF] Janin | A Timed IO monad[END_REF] that develop the notion of timed extension of a monad. The present paper can be seen as an experiment in using that notion in the untimed case.

One can observe that such a type Stream m a is isomorphic to the type ListT m a where ListT is the Haskell (nondeprecated) monad transformer defined in List package. Although isomorphic, our treatment of that type is fairly distinct. Indeed, the flavor of sequentiality induced by guarding the list tail by monad actions (especially in the IO monad) is essentially ignored in the above package that relies on the horizontal monoid structure induced by appending lists.

More precisely, in both synchronous or asynchronous settings, appending two input monad streams hardly make any sense. In the synchronous setting, delays, zips and maps covers most of our need and, in the asynchronous setting, it is rather the vertical monoid structure of streams, induced by the function merge, that is useful.

Compared to more generic proposals, as already observed by Perez et al. [START_REF] Perez | Functional Reactive Programming, Refactored[END_REF], stream monads provide a efficient way to instanciate FRP approaches [START_REF] Courtney | The Yampa arcade[END_REF][START_REF] Elliott | Functional Reactive Animation[END_REF][START_REF] Elliott | Push-pull functional reactive programming[END_REF]. Programing with stream monads is also quite related with FRPNow [START_REF] Van Der Ploeg | Practical principled FRP: forget the past, change the future, FRPNow![END_REF].

It shall be mentioned that Perez et al. use a version of monad streams distinct from ours, defined by data Stream ′ m a = Stream ′ { next ′ :: m (a, (Stream ′ m a)) } Their proposal is more general than ours since our notion of streams can be recovered from theirs by composing Maybe with m. However, with our specialization, we stress on the fact that streams may terminate: a feature that may lead to delicate issue when not properly addressed.

Comparing our proposal to the general FRP approaches, it must be mentioned that the API induced by our approach strongly differ from the one defined in FRP [START_REF] Elliott | Functional Reactive Animation[END_REF][START_REF] Elliott | Push-pull functional reactive programming[END_REF]. Indeed, in our approach, we make no distinction between stream values and events. Instead, it is more a matter of distinguishing synchronous and asynchronous treatments in functions over streams, and distinguishing streams that shall be treated as synchronous or asynchronous ones.

One advantage of such our approach, though not yet secured by any typing constraints, is that one is not tempted to define asynchronous treatments on streams that are supposed to be run in a synchronous way. As an illustrative example, functions zipStream and mergeStream shall never be used on the same kind of streams.

A long standing approach for handling asynchronism amounts to encoding an asynchronous stream Stream m a by a synchronous one Stream m (Maybe a) that yields Just a when there is a change of control value, of Nothing when there is not. This is an approach classically followed in synchronous systems governed by one global clock [START_REF] Benveniste | The Synchronous Languages Twelve Years Later[END_REF][START_REF] De Simone | The Synchronous Hypothesis and Synchronous Languages[END_REF] as well as, to the best of our understanding, in recent FRP approaches [START_REF] Perez | Functional Reactive Programming, Refactored[END_REF]. While such an approach is unavoidable at circuit (or OS kernel) level, it may yield an unnecessary load of processing at system level, control signal mostly containing the value Nothing.

Worth being mentioned, as a generalization of the above, there is the wormholes approach [START_REF] Winograd-Cort | Effects, Asynchrony, and Choice in Arrowized Functional Reactive Programming[END_REF][START_REF] Winograd-Cort | Settable and non-interfering signal functions for FRP: how a first-order switch is more than enough[END_REF] where every stream Stream m a can be lifted to a stream of type Stream m [a]. While preserving inputs arrival order, this fairly flexible approach allows for contracting or expanding data depending on the frequency one aim at achieving. However, the streaming the empty list may also yield an unnecessary load of data at system level.

Our proposal extends the alternative for encoding asynchronous functions by relaying on the notion of monad references and concurrent wait. Asynchronism is then efficiently handled by ghc runtime.

A type quite similar to our notion monad stream references, that is, our type Stream MVAR a, is already defined and used pretty much in the same way by Marlow when defining unbounded FIFO communication channel [START_REF] Marlow | Parallel and Concurrent Programming in Haskell[END_REF].

The efficiency of the resulting compiled code seems to rely on the fact that ghc optimizes quite efficiently programs that uses (even implicit) continuations : a programing style that arises fairly often when handling monad streams or monad stream references.

Worth being mentioned, our desire to achieve efficient and fully understood audio processing prevents us from reusing existing Haskell libraries. As a matter of fact, aside the Jack/Haskell interface package, we essentially use basic features that are available in Haskell's prelude, and some of its concurrent features: multithreading capacity (forkIO), mutable variables (MVar) and FIFO channels (Chan).

As far as audio is concerned, the main and most efficient functional programming language for realtime audio processing available nowadays is probably Faust [START_REF] Orlarey | Faust: an Efficient Functional Approach to DSP Programming[END_REF]. This language is thus the most relevant yardstick for examining the qualities of our proposal.

In terms of performance, Faust is, a priori, way more efficient than our proposal for it is currently compiled into optimized C code. Experiments show that audio processing we performed in Haskell is more expensive by some (small) factor compared to Faust.

Still, thanks to our multithreaded implementation, audio processing is performed on a dedicated core, the resulting cost of connecting audio streams with audio drivers being comparable with the one achieved with Faust. Moreover, thanks to Haskell language, our monad stream approach is polymorphic and can probably be applicable to many other media types. Observe that audio processing is probably the most demanding media type both in terms of frequency and admissible latency.

In terms of programing API, Faust eases the programmer task by offering a rather abstract view on signals, promoting a data flow programing style based of some number of primitive blocks to be assembled at will. Non programmer experts can use it quite easily.

On the contrary, yet in its infancy, our approach still necessitates explicit description of monad stream traversal. This clearly requires more expertise in programming. However, as illustrated by the simplicity of the numerous function code examples given throughout our paper, such an expertise may remain quite low.

Conclusion

We have thus proposed and implemented a version of monad streams that allows for combining both high-frequency synchronous transforms, as needed in audio processing, as well as asynchronous low-frequency parameterization of these synchronous transforms, as needed in audio system control.

The notion of monad streams induces a fairly versatile interface for both synchronous and asynchronous programing. It is even quite striking how efficient the resulting library is. This is due to both the fact that, despite our functions being pure and defined in safe Haskell, we make a rather heavy though quite transparent use of the IO monad, and the ghc compiler optimizes especially well continuation programing style.

The Haskell library resulting from the present paper shall eventually be available with open source license on some publicly accessible platform.

However, as far as software engineering is concerned, our proposal is truly at an early stage. For instance, as already mentioned, it would probably be worth distinguishing streams that are to be used in a synchronous way from streams that are to be used in an asynchronous way. For such a purpose, one could define a generic data type for stream functions that, as depicted in block diagrams throughout our presentation, have explicit synchronous and/or asynchronous inputs.

Such a distinction could open a way towards an extension of arrow programing [START_REF] Hughes | Programming with Arrows[END_REF]. Indeed, the basic operator ( * * * ) in Arrow class suggests that, when applied to signal processing, arrows are acting synchronously on signals. On the contrary, the basic operator (+ + +) in the ArrowChoice class suggests that, when applied to signal processing, arrows are acting asynchronously on signals. Adding explicit distinction between synchronous and asynchronous inputs might lead to the definition of a finer model of streams programing.

Anyhow, nothing yet ensures in our proposal that a given function input stream is treated in a synchronous or asynchronous way, and, in both cases, that the function does not encode a behavior with intrinsic memory leaks. There clearly lays the possibility of designing a type system for functions over streams that would enforce adequate synchronous or asynchronous usage and traversal of monad streams inputs.

Temporal logic typing as already proposed for FRP [START_REF] Jeffrey | LTL Types FRP: Linear-time Temporal Logic Propositions As Types, Proofs As Functional Reactive Programs[END_REF][START_REF] Jeltsch | Categorical Semantics for Functional Reactive Programming with Temporal Recursion and Corecursion[END_REF][START_REF] Krishnaswami | Higher-Order Functional Reactive Programming without Spacetime Leaks[END_REF]] might be a starting point for such a purpose. However, we also suspect that linear types could be of some interest [START_REF] Bernardy | Linear Haskell: Practical Linearity in a Higher-order Polymorphic Language[END_REF][START_REF] Paykin | The Linearity Monad[END_REF]. Indeed, as already discussed in Section 4, monad streams shall not be shared in general as input. On the contrary, monad stream references can be freely shared. A linear type system could accurately model such a distinction.

Figure 1 .

 1 Figure 1. The block diagram of a typical stream function with horizontal (left) synchronous input of as, vertical (top) asynchronous input of cs and horizontal (right) output of bs.

  stdinStream :: Stream IO Char stdinStream = Stream $ do c ← hIsEOF stdin if c then return Nothing else do a ← getChar return $ Just (a, stdinStream)

Figure 4 .

 4 Figure 4. The zipStreamWith f block diagram.

Figure 5 .

 5 Figure 5. The zipStreamWith const block diagram.

Figure 6 .

 6 Figure 6. The loopStream s 0 (return • delta) block diagram.

class

  Monad m ⇒ MonadRef m where type Ref m :: * → * forkToRef :: m a → m (Ref m a) readRef :: Ref m a → m a tryReadRef :: Ref m a → m (Maybe a) parReadRef :: Ref m a → Ref m b → m (Either a b)

Figure 7 .

 7 Figure 7. The block diagram of takeStreamUntil m.

Figure 8 .

 8 Figure 8. The block diagram of streamMap f sf . loopStream function, we allow ourselves transformation functions of type a → m b. Again, this allows for using more efficient implementations of stream transformation functions.Vertical Monoid Structure. Perhaps the most striking example of an asynchronous function is the following function that merges two streams according to the termination time of the underlying actions.

  merge

mergeStream : : Figure 9 .

 :9 Figure 9. The block diagram of mergeStream.

Figure 10 .

 10 Figure 10. The block diagram of feedForward n a.

Figure 11 .

 11 Figure 11. The block diagram of feedBackward n a.

g : :

 : Stream m a → Stream m b with input sample type a and output sample type b. However, the Haskell interface to Jack expects instead step functions of the form: f :: a → m b that shall maps every (new) input sample a to the action f a that returns the corresponding output sample b.

Figure 12 .

 12 Figure 12. A stream function g and its step function f created via FIFO channels.

As noticed by one anonymous referee

Acknowledgments

This work has benefited from many discussions with Simon Archipoff and Bernard Serpette, and some help from Donya Quick, who all deserve our great thanks. We also feel deeply in debts towards anonymous referees for their tolerance and open mind in reviewing a first quickly written draft that eventually got considerably improved thanks to their numerous, accurate and fruitful remarks.