정의
Procedual (절차적) → Object Oriented (객체지향) → Functional (함수형) 순서로 발전되어왔다.
명령형 프로그래밍 (How) (Procedual, Object Oriented)
1. Pure Function (순수 함수)
// X 순수 함수
let num = 1;
function add(a) {
return a + num;
}
위와 같은 예제에서는 add
라는 함수 안에서 전역으로 선언된 변수인 num
을 참조하기 때문에 순수함수하고 볼 수 없다.
// O 순수 함수
function add(a, b){
return a+b;
}
const result = add(2,3);
위와 같이 add
의 함수가 프로그램 실행에 영향을 미치지 않고, 입력 값에 대해서만 값의 변환이 있으므로 순수함수이다.
2. Stateless, Immutability (비상태, 불변성)
// Stateless, Immutability 불만족
let person = {name: "yuseogi", age: "24"}
function increaseAge(person) {
person.age = person.age + 1;
return person;
}
위와 같은 예제는 increaseAge
함수에서 전역으로 선언된 person
의 age
속성을 변경하므로 불변성 유지를 못한다.
// Stateless, Immutability 만족
const person = {name: "yuseogi", age: "24"}
function increaseAge(person) {
return {...person, age: person.age+1};
// ...person : 객체 복사
// age: person.age+1 : ...person을 통해 복사한 객체에 새로운 값 할당
}
위처럼 객체의 값을 바꾸기 위해서는 데이터의 복사본을 만들어, 그 복사본을 사용해 작업을 진행하고 반환한다.
3. Expressions (선언형 함수)
// 명령형 프로그래밍
let numbers = [1,2,3];
function multiply(numbers, multiplier) {
for (let i = 0; i < numbers.length; i) {
numbers[i] = numbers[i]*multiplier;
}
}
위의 예시에서는 for문을 사용해서 배열의 각 요소에 multiplier를 곱해주는 명령형 프로그래밍이다.
함수형 프로그래밍에서는 마찬가지로 if, switch, for
등 명령문을 사용하지 않고, 함수형 코드로 사용해야한다.
// 선언형 프로그래밍
function multiply(numbers, multiplier) {
return number.map((num) => num*multiplier);
}
위의 예시는 for
문을 map
으로 대체했고, Javascript에서는 filter, map, take, reduce
등의 함수형 코드를 지원한다.
4. First-class, High-order functions (1급 객체, 고차 함수)
함수형 프로그래밍에서는 함수가 1급 객체가 된다. 1급 객체의 특징은 다음과 같다.
// 1급 객체
const addTwo = (num) => num + 2;
const multiplyTwo = (num) => num * 2;
const transform = (numbers) => numbers.map(addTwo).map(multiplyTwo);
console.log(transform([1, 2, 3, 4])); // [6, 8, 10, 12]
위의 예시에서는 함수를 변수에 할당하거나 반환하는 1급 객체로서의 특징을 보여준다.
함수형 프로그래밍에서는 함수가 고차 함수가 된다. 고차 함수의 특징은 다음과 같다.
// 고차 함수
const addInform = (name) => (age) => age + name;
const yuseogi = addInform("유석");
console.log(yuseogi("24")); // 24유석
위의 예제 처럼 함수의 반환 값으로 다른 함수를 사용하거나, 함수의 반환값으로 또 다른 함수를 사용 할 수 있어야 한다.
장점
단점
Java 8으로 update되면서, Java에서도 함수형 프로그래밍이 가능해졌다.
Java의 객체 지향은 명령형 프로그래밍이고, 함수형은 선언형 프로그래밍이다.
둘의 차이는 문제해결의 관점
이다.
Java에서 활용할 수 있는 함수형 프로그래밍
import java.util.Arrays;
import java.util.List;
public class stream {
public static void main(String[] args) {
List<String> myList = Arrays.asList("a", "b", "c", "d", "e");
// 기존방식
for(int i=0; i<myList.size(); i++){
String s = myList.get(i);
if(s.startsWith("c")){
System.out.println(s.toUpperCase());
}
}
// stream API를 이용한 방식
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.forEach(System.out::println);
}
}