In lieu of an abstract, here is a brief excerpt of the content:

125 Chapter 10 Functional Programming Functional programming is a programming style that emphasizes the combination of functions to produce values as opposed to the sequential evaluation of commands and the modification of variables. One advantage of functional programming is that functional programs are often easier to reason about than non-functional alternatives. This chapter introduces some functional programming concepts and illustrates their use in computing scores. 10.1 Introduction to Functional Programming Lisp was one of the first languages to support functional programming , and by encouraging functional programming, Lisp has had a tremendous impact on many modern languages such as Java, Python, and ML. The main attraction of functional programming is that behaviors of functional expressions do not depend upon the changeable and hidden values of variables or the sequential order of assignment statements. Often, functional programs enjoy the good qualities of mathematical equations, which are designed for communication and expressiveness. Proponents of other styles of programming, particularly ObjectOriented Programming, argue that variables and assignment statements are actually features that allow programs to more naturally model real-world objects that do in fact change over time. In our experience , functional programming, object-oriented programming, and other programming paradigms all have advantages and disadvantages . The best approach often depends on the problem at hand. SAL is a bit of a compromise. It is built above a Lisp implementation and therefore has access to the functional programming features of Lisp. However, SAL has a much greater emphasis on sequential execution and assignment to variables, so it does not strongly encourage functional programming. The occasional need to access special Lisp forms such as progn and setf could be seen as a weakness of SAL. 10.2 Mapping a Function over a List One powerful concept of functional programming is the use of functions as parameters. In other words, we can have functions of functions , also called higher-order functions. The primitive mapcar al- 126 Chapter 10 ⋅ Functional Programming lows you to apply a function to each element of a list. The applied function may be another primitive or a user-defined function. mapcar is thus a higher-order function. In SAL, when you pass a function to a function, the passed function is normally a quoted symbol. The template for mapcar is mapcar(quote(function), list) Recall that the primitive sqrt returns the square root of its input. Example 10.2.1: sqrt function SAL> print sqrt(25.0) 5 Since mapcar allows you to map a function onto a list, we can take the square root of each element of a list by passing sqrt to mapcar. Example 10.2.2: mapcar and sqrt SAL> print mapcar(quote(sqrt), {25.0 36.0 81.0}) {5 6 9} Notice the syntax of mapcar. The function passed to mapcar must be quoted. The inputs to the passed function are given as a list. Recall in Example 8.2.2, we wrote a user-defined function that used #? to determine if a MIDI note is within the range of the MIDI specification. Example 10.2.3: test-range (as presented in Chapter 8) define function test-range(pitch) begin return #?(pitch 127, quote(too-high), quote(in-range))) end Using mapcar, we can determine if an entire list of MIDI notes is in range. Example 10.2.4: mapcar and test-range SAL> print mapcar(quote(test-range), {0 -5 129 127 54}) {IN-RANGE TOO-LOW TOO-HIGH IN-RANGE IN-RANGE} [18.117.148.105] Project MUSE (2024-04-25 09:41 GMT) 10.2 Mapping a Function over a List 127 Since returning a list that describes the range status of a list of MIDI notes may not be helpful in composing music, we alter our function in Example 10.2.4. Any MIDI note outside the range of the MIDI specification is recalculated to fall in range. The new function, called rangify, is defined in Example 10.2.5. Example 10.2.5: rangify define function rangify(note) begin return #?(note 127, 127, note)) end The function rangify uses an algorithm that returns 0 for all MIDI notes less than 0 and 127 for all MIDI notes greater than 127. rangify is one of many algorithms that may be used to correct for values that fall outside of the range of the MIDI specification. In Example 10.2.6, we map the function rangify onto a list of values . Notice all values less than 0 return 0 and all values...

Share