Next  |  Prev  |  Up  |  Top  |  JOS Index  |  JOS Pubs  |  JOS Home  |  Search


Pattern Matching in FAUST

In FAUST, pattern matching is used in functional rewriting rules:

  f(pattern) = expression;
where f is any valid function name, and both pattern and expression are arbitrary expressions in the FAUST language. Such a definition specifies a rewriting rule: When f(pattern) is recognized in any function definition, it is replaced by expression. Pattern matching is commonly supported in functional programming languages such as Haskell [6], a language that influenced the design of FAUST.

Pattern-matching allows different function-definitions for different argument-patterns. For example, the following use of pattern-matching defines different amplitudes and frequencies for a simple additive synthesizer [5]:

import("stdfaust.lib");
amp(0) = 1.0; // amplitude of fundamental frequency
amp(1) = 0.5; // amplitude of first harmonic
amp(2) = 0.3;
freq(i) = (i+1)*440;
partial(i) = amp(i) * os.osc(freq(i)); // osc defined in oscillators.lib
process = sum(i, 3, partial(i));
The `0' in amp(0) above is referred to as a single-value pattern, as are `1' and `2' in the next two lines. Each single-value pattern matches only one value exactly. The `i' in freq(i) above may be called a free variable in the pattern (consisting of only that variable), and it matches anything at all (any block diagram in the FAUST language).

Pattern-matching can be used to define functions recursively. A simple example is the recursive definition of factorial:

  fact(0) = 1;
  fact(n) = n * fact(n-1);
  process = fact(4); // output signal = 24,24,24,...
While FAUST function definitions can appear in any order, lexical order matters for pattern definitions. Thus, in the above factorial example, the rewrite rule using the single-value pattern 0 is tried first, while the one using the variable pattern n matches for any block diagram (which should, in our intended use, and to avoid an infinite loop, evaluate to an integer each sample). If the first two lines are interchanged in the above example, an infinite loop is obtained at compile time.

Another example [5] is the fold operator:

fold(1,f,x) = x(0);
fold(n,f,x) = f(fold(n-1,f,x),x(n-1));
Then in the additive synthesis example above, sum(i, 3, partial(i)) can be replaced by fsum(3,partial) where fsum(n) = fold(n,+).

More general expressions can appear in a pattern definition, as described in §2.23.5 below.



Subsections
Next  |  Prev  |  Up  |  Top  |  JOS Index  |  JOS Pubs  |  JOS Home  |  Search

Download aspf.pdf
[Comment on this page via email]

``Audio Signal Processing in Faust'', by Julius O. Smith III
Copyright © 2023-08-16 by Julius O. Smith III
Center for Computer Research in Music and Acoustics (CCRMA),   Stanford University
CCRMA