👣 들어가며
지난 4월 23일부터 인프런 유인동님의 함수형 프로그래밍과 JavaScript ES6+ 강의를 듣는 스터디를 시작했다. 처음에는 단순히 후기 글이 너무 웃겨서 관심이 갔다.
얼마나 강의가 재밌고 유익했으면 저런 창의적인 후기를 남겼을까? 하는 생각이 들며 함수형 프로그래밍에 대해 찾아봤다. 그런데 때마침 회사에서도 함수형 프로그래밍에 대한 바람이 불어서 분기별 목표에 함수형 프로그래밍 접목하는 것을 목표로 적어주신 팀원분들이 많이 보였다.
그리고 유튜브에서도 노마드 코더님이나 드림코딩님, 얄코님의 영상에서 함수형 프로그래밍에 대해 기고한 영상들이 새로운 접근 방법을 알 수 있어서 늘 흥미를 갖고 있었다. 그래서 마침 내가 좋아하는 인프런이고 우리 디프만 동아리에서 아는 사람들과 함께 강의를 들을 수 있었기 때문에 신청했다.
스터디 진행
스터디 진행은 온/오프라인 혼용으로 진행했다. 온라인으로도 스터디를 해보고, 오프라인으로도 스터디를 진행해봤지만, 늘 온라인 스터디는 아쉬움이 많았다. 플랫폼 상의 물리적 한계 때문에 모든 사람이 적극적으로 참여하기 어려웠고, 편한 마음으로 참여할 수 있기 때문에 그만큼 스터디에 대한 책임감이 높지 않았다. 하지만, 모든 사람들을 오프라인으로 모으는 것도 쉽지 않은 것이기 때문에 온라인과 오프라인 모두 진행했다.
강의는 인프런의 함수형 프로그래밍과 JavaScript ES6+를 선택했고, 위의 이유와 함께 가장 믿을만한 강의라고 생각했기 때문이다. 실제로, 유인동님은 꽤 유명하신 분이었다. 매주 섹션을 나눠서 강의를 수강해오고 스터디 요일 때마다 함께 모여서 금주 학습한 내용을 훑어보며 이야기를 나누면서 스터디를 진행했다. 내용을 요약하고 회상하면서 자신이 생각했던 것들을 이야기하고 정보를 공유하는 식으로 서로 공부하고자 하여 이런 방식의 스터디를 선택했다. 한 가지 아쉬운 점은, 오프라인보다 온라인의 비율이 아무래도 매우 높다보니까 내가 적극적으로 참여시키게 하기가 곤란했던 것이다. 하지만, 늘 잘 따라와주려고 노력하는 스터디원분들이 계셔서 다행이었다. 😮💨
그리고 궁금한 점들을 노션 데이터베이스에 기록하면서 다같이 성장하고자 했다. 딩코님께서 활발하게 공유해주셔서 너무 감사했다.
📚 강의를 들으며
어떤 것을 배웠나?
함수형 프로그래밍을 공부하면서 가장 머리속에 맴도는 개념은 go와 pipe, curry를 통한 함수 합성이다. 여러 가지 함수를 조합하여 최종적으로 원하느 결괏값을 얻기 위해서는 함수들의 연관관계를 잘 고려하여 함수를 합성해야 한다. 또한, 가독성있게 코드를 읽을 수 있게 함수를 적절히 구성해주어야 한다. 그러한 니즈를 충족시켜줄 수 있는 것이 go, pipe, curry 함수였다.
예를 들어 go의 소스코드는 다음과 같다.
const curry = f =>
(a, ...fs) => fs.length
? f(a, ...fs)
: (a, ...fs) => f(a, ...fs)
const reduce = curry((f, acc, iter) => {
if (!iter) {
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const a of iter) {
acc = f(acc, a);
}
return acc;
});
const go = (...args) => reduce((a, f) => f(a), args);
늘 프로그래밍을 하다보면, 절차적으로 프로그래밍을 진행했다. 그래서 이러한 절차를 숨기기 위해 함수를 사용하곤 했는데, 함수를 분리하면서 그 함수가 잘 작동할 수 있도록 외부 환경에서의 문제를 파악하고, 함수와 함수 간에 어떻게 반환값과 인자값을 받아낼지 고민하면서 코드를 작성했다. 그리고 내가 사용하는 프로그래밍 방법론이 객체 지향 프로그래밍이어서 함수형 프로그래밍과는 약간은 상반된 위치에서 프로그래밍을 수행해왔다.
그래서 그런지 맨처음에는 머리 속으로 와닿지 않았다. 함수 합성과정이 제대로 이해가지 않았고, 이러한 코드를 내 소스코드에 입힐 수도 있을지 고민이 많이 됐다. 그런데 강의를 계속 수강하다보니까, 함수를 합성하는 것만이 함수형 프로그래밍의 특징은 아니었다. 이터러블한 이터레이터를 반환하는 제너레이터 함수를 사용하여 함수를 합성해 내가 원하는 시점에 함수를 동작시킬 수 있었다. 또한, 평가를 미룬다는 패러다임도 신선하게 다가왔다. 실제로 코드를 작성하다보면, 반드시 필요한 정보를 반환하는 로직이지만, 해당 로직을 수행하는 데 시간이 매우 오래 걸리고 필요한 결과는 수행한 로직의 극히 일부분인 경우가 많은데 이러면 필요없는 곳에서 리소스의 누수가 발생하였다. 그런 점에서 평가를 미루고 함수를 절차적이 아닌 평행하게 수행할 수 있는 함수형 프로그래밍의 접근 방법은 성능 개선에 큰 도움이 될 수 있었다.
지금은 함수 합성의 효율화가 아니라 모나드를 구현하여 안전화를 배우고 있는데, 예측할 수 없는 프로그래밍 환경에서 상당히 필요한 부분이라고 생각한다.
🔥 마무리하며
물론 좋은 부분만 있었던 것은 아니고, 안 좋은 부분도 존재했다. 일단, 개념을 이해하는 데 시간이 오래 걸리기 때문에 개인적으로 한 번만 강의를 듣고서는 온전히 체득하기에 부족했다. 개개인마다 이해하는 데 시간이 걸린다는 것은, 사내 프로젝트에 직접 접목하기 위해서는 그만큼 프로젝트의 리소스를 사용한다는 것이고, 프로젝트에 좋지 않은 영향을 미칠 수 있다. 그래서 미리 팀원들과 함께 학습하여, 다같이 학습을 진행하고 레벨을 맞추는 것이 중요하다.
그렇기 때문에 급진적으로 프로젝트에 접목시키는 것보다는 점진적으로 프로젝트에 스며들도록 하는 방향도 좋을 것이다. 또한, go나 pipe, curry를 헬퍼 함수로 사용하는 것은 단순하게 로직을 도와주는 역할을 하기 때문에, 함수형 프로그래밍의 이론적인 내용보다 실제적인 코드 사용을 먼저 사용하는 것도 좋은 방법이라고 생각한다. 그러고 나서 이론적인 내용과 함께 조금 더 심화된 실습을 함께 진행하면 더 깊이 함수형 프로그래밍을 습득할 수 있을 것이다.
현재 하고 있는 일이 많아서 약간 챌린징한 스터디였지만, 나름대로 얻어가는 부분이 많았다. 절차적/객체 지향 프로그래밍에 갇혀있던 사고방식을 조금 더 확장할 수 있는 물꼬를 틀 수 있었다는 점이 아무래도 장기적으로 프로그래머로서 성장할 수 있는 부분이었다.
고급편도 있던데,,, 고급편도 찍어먹어볼까..?
'Diary > Retrospective' 카테고리의 다른 글
[Retrospective] 2023년 상반기 회고 (2) | 2023.07.01 |
---|---|
[회고] 4월 4일이 되서야 하는 2022년 회고 (4) | 2023.04.04 |