명령형(절차형) 프로그래밍의 습관을 지우고 선언형(함수형) 프로그래밍을 수월하게 하기 위한
방법들에 대해 배웠다.
함수형 프로그래밍을 할 때 생각해봐야 할 점
- 이 함수에 어떤 데이터가 필요한가?(인자)를 잘 생각해봐야 함.
- 어떤 값을 만든 후 그 값을 변경해가면서 프로그래밍 해야 함.
⇒ 재사용성이 높고, 유지보수가 쉽다.- 어떻게 할 지보단 무엇을 할 지를 생각하면서 구현해야 함.
for, while, if문을 쓰지 않고 map, filter, reduce함수들을 조합해서 구현해야 한다.
while → range() (i++과 같이 사용할 수 있음)
if → filter()
각 요소 변경 후 할당 → map()
break → take()
누적, 갱신 → reduce()
외부 영향 → each()
return go(
L.range(2, 10), // === for(const i=2; i<10; i++)
L.map(a => go(
L.range(1, 10), // === for(const j=1; j<10; j++)
map(b => b*a) // 여기서부터 작성하면 된다.
))
)
map과 filter를 거치면 reduce를 더 간결하게 쓸 수 있다.
reduce + 복잡함수 + acc
< map + 간단함수 + reduce
= 작은 문제를 해결한 여러 개의 함수를 조합해서 큰 문제를 해결한다.
// users라는 고객들의 정보가 담긴 객체가 있을 때,
// case.1
reduce((total, u) => total+u.age, 0, users)
// case.2
map(a = > a.age, user),
reduce((total, age) => total+age) // 이게 더 낫다
// ↑ ↑
화살표로 가리킨 두 값이 같은 자료형으로 들어올 때 시작 값이 없게 되고, 그렇게 구현하는 것이 좋다.
const users = [
{name: 'AA', age: 35},
{name: 'BB', age: 26},
{name: 'cc', age: 28},
{name: 'CC', age: 34},
{name: 'EE', age: 23},
]
go(users,
L.filter(u => u.name == 'DD'),
L.take(1),
L.map(u=> u.age),
each(console.log) // 아무것도 출력되지 않음
)
절차형의 for, while, if를 map(), filter(), reduce()로 대체하니 가독성이 훨씬 좋아지지만, 직접해보니 생각보다 어떻게 활용할지 감이 안 잡히고 헷갈렸다. 많이 연습해봐야겠다.
처음엔 절차형 프로그래밍이 더 쉽고 굳이 왜 어렵게 함수형 프로그래밍을 해야하는지 의문이었는데 배우면서 직접 코드를 짜보니까 절차형 프로그래밍은 자유롭게 쓰는 줄 글이라면 함수형 프로그래밍은 잘 다듬어지고 요약된 글이라는 느낌이 들었다. 왜 함수형 프로그래밍으로 짠 코드가 고급지다고 하는지 이해가 갔다.
함수형 프로그래밍을 꾸준히 공부하며 고급스럽게 코드를 짜는 습관을 들이려고 한다.