What is functional programming?
Functional programming is a style of programming that is characterized by:
- Short functions — In the purest form of functional programming, each function is a single expression. In Python, this can be implemented through
- Stateless functions — Functions that rely only on the arguments that were passed to them, and not on the state of the program. In other words, no use of global variables and object properties.
- Functions without side effects — Functions that do not affect the state of the program. Phrased differently, function do not alter the objects that are passed to them, and only communicate with the outside world through their return values.
In addition to these basic characteristics, functional programming is generally characterized by secondary characteristics, such as:
- Heavy use of iterators (such as
DataMatrix!), and standard iterator functions such as
- Heavy use of higher-order functions, or functions that operate on other functions.
Functional programming is excellently suited for numerical computing. Many libraries for numeric computing, such as
numpy, implicitly use a (mostly) functional style of programming.
Functional programming with DataMatrix
Below is an example of how you can manipulate DataMatrix objects using purely functional programming. This example is exaggerated to make a point; good code is generally a sensible mixture of functional and procedural programming styles.
In general, all functions in
datamatrix.series are suitable for functional programming.
from datamatrix import DataMatrix, operations as ops # Initializes and returns a DataMatrix init_dm = lambda: \ ops.setcol( ops.setcol( DataMatrix(length=8), 'x', range(8) ), 'y1', [-1, 0, 1, 0, -1, 0, 1, 0] ) # Adds a column to a DataMatrix and returns it add_y2 = lambda dm: \ ops.setcol( dm, 'y2', ops.map_( lambda y: abs(y)*2, dm.y1 ) ) # Filters rows from the DataMatrix filter_by_y1 = lambda dm: \ ops.filter_( lambda y: y >= 0, dm.y1 ).dm # A main function that does everything main = lambda: \ filter_by_y1( add_y2( init_dm() ) ) # Go! print(main())
+---+---+----+----+ | # | x | y1 | y2 | +---+---+----+----+ | 1 | 1 | 0 | 0 | | 2 | 2 | 1 | 2 | | 3 | 3 | 0 | 0 | | 5 | 5 | 0 | 0 | | 6 | 6 | 1 | 2 | | 7 | 7 | 0 | 0 | +---+---+----+----+