68 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			68 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								title: Function Composition
							 | 
						||
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Function composition
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Function composition is the pointwise application of one function to the result of another. Developers do it in a manual manner every day when the nest functions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```javascript
							 | 
						||
| 
								 | 
							
								compose = (fn1, fn2) => value => fn2(fn1(value))
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								But this is hard to read. There is a better way using function composition. Instead of reading them from inside out:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```javascript
							 | 
						||
| 
								 | 
							
								add2AndSquare = (n) => square(add2(n))
							 | 
						||
| 
								 | 
							
								``` 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								We can use a higher order function to chain them in an ordered way.
							 | 
						||
| 
								 | 
							
								```javascript
							 | 
						||
| 
								 | 
							
								add2AndSquare = compose( add2, square)
							 | 
						||
| 
								 | 
							
								``` 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A simple implementation of compose would be:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```javascript
							 | 
						||
| 
								 | 
							
								compose = (f1, f2) => value => f2( f1(value) );
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								To get even more flexibility we can use the reduceRight function:
							 | 
						||
| 
								 | 
							
								```javascript
							 | 
						||
| 
								 | 
							
								compose = (...fns) => (initialVal) => fns.reduceRight((val, fn) => fn(val), initialVal);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Reading compose from left to right allows a clear chaining of higher order functions. Real world examples are adding authentications, logging and context properties. It's a technique that enables reusability on the highest level. Here are some examples how to use it:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```javascript
							 | 
						||
| 
								 | 
							
								// example
							 | 
						||
| 
								 | 
							
								const add2        = (n) => n + 2;
							 | 
						||
| 
								 | 
							
								const times2      = (n) => n * 2;
							 | 
						||
| 
								 | 
							
								const times2add2  = compose(add2, times2);
							 | 
						||
| 
								 | 
							
								const add6        = compose(add2, add2, add2);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								times2add2(2);  // 6
							 | 
						||
| 
								 | 
							
								add2tiems2(2);  // 8
							 | 
						||
| 
								 | 
							
								add6(2);        // 8
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You might think this is advanced functional programming and it's not relevant for frontend programming. But it's also useful in Single Page Applications. For example you can add behavior to a React component by using higher order components:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```javascript
							 | 
						||
| 
								 | 
							
								function logProps(InputComponent) {
							 | 
						||
| 
								 | 
							
								  InputComponent.prototype.componentWillReceiveProps = function(nextProps) {
							 | 
						||
| 
								 | 
							
								    console.log('Current props: ', this.props);
							 | 
						||
| 
								 | 
							
								    console.log('Next props: ', nextProps);
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  return InputComponent;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// EnhancedComponent will log whenever props are received
							 | 
						||
| 
								 | 
							
								const EnhancedComponent = logProps(InputComponent);
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								In conclusion function composition enables reusability of functionality at a very high level. If the functions are structured well it enables developers to created new behavior based upon existing behavior.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It also increases readability of implementations. Instead of nesting functions you can cleary chain functions and create higher order functions with meaningful names.
							 |