끊임없이 검증하라

나에게 당연할지라도

Fadet's box

잡담1_함수형 프로그래밍에 대한 고찰(feat. 수학)_1

fadet 2022. 3. 21. 02:17

* 이 포스트는 개발 지망생이 학습을 위해 작성한 것으로 개발자들이 보기에 부적절할 수 있음을 알립니다.

* 제목에 수학이라고 썼지만 포스트에서 다루는 내용은 어릴때 배우는 고등수학 기초를 다룹니다.


다른 공부를 진행하다 뜬금없이 함수형 프로그래밍에 꽂혔습니다. 그리고 관련 자료를 찾아보면서 생각이 정리되는 느낌을 받아 너무 기뻤다는...(사실 이 정리한 내용이 맞는가는 끝없는 교차검증을 겪어야할 것이지만) 그 생각을 한 번 초보자의 입장에서 끄적여볼까싶어 해당 포스트를 작성합니다.

 

# 포스트 유입 키워드에 '프로그래밍 수학'이 유독 많아 추가합니다. 아마 프로그래밍을 입문함에 있어 자신이 수학에 약한데 고민인 분이 많아 이런 키워드로 검색한다고 생각하는데 결론부터 말하자면 잘하면 좋은데 못해도 상관없음 정도일 것 같네요. 왜냐하면 보통 많은 사람들이 수학을 말하면 대부분 시험 문제 풀던 고등 수학이거든요. 개발자들에게 진짜 필요한 수학의 가치는 논리적인 사고입니다.

 

과학이라는 것이 현실의 대상을 연구하는 학문이라면 수학이라는 것은 논리적인 사고를 연구하는 학문입니다. 논리학과 다른 점은 둘의 본질은 비슷하지만 수학은 논리적인 사고를 수라는 개념을 도입하여 진행하는 것이라 받아들이시면 됩니다. 이제 다시 수학 얘기로 돌아가서 제 주관적으로 개발자라면 고등 수학은 못해도 되지만 논리적인 사고는 끊임없이 해야한다고 생각합니다. 일단은 이 주제에 대해서는 말을 줄이고 다시 처음 질문으로 돌아가겠습니다.

 

당연히 네카라쿠배라 불리는 유니콘에 들어가기 위해선 알고리즘같은 컴퓨터 수학을 공부해야합니다. 하지만 이 키워드를 검색하시는 시점에선 이런 큰 기업에 들어가려는데 수학 때문에 겁먹을 이유가 전혀 없다고 생각하는게 애초에 이런 테스트를 보기 전에 우선 포트폴리오부터 통과해야합니다. 포트폴리오를 구성할때 개인 프로젝트를 하니 당연히 개발 실력이 우선 있어야 컴퓨터 수학이니 그런 걱정을 할 수 있습니다. 이제 질문이 개발에 있어서 수학 실력이 큰 비중을 차지하는가로 바뀔텐데 그에 대한 제 답은 아까와 같습니다. 제가 공부하면서 봐온 수많은 실력있는 개발자들 중 문과인 분들도 엄청 많으며(문과 수학 비하아닙니다. 다만 문과에서 수학에 쏟을 수 있는 시간 자체가 많다고는 생각하지 않기에 하는 말입니다) 수학 못한다고 하는 분들(몇몇 분은 기만이긴 하지만)도 많습니다. 다만 개발자가 갖춰야하는 실력 1순위는 코드 타이핑하는 기술이 아닌 설계 능력이라고 생각합니다. 이 설계 능력은 논리적인 사고를 갖춰야하며 그러므로 논리의 학문인 수학을 잘하면 당연히 유리할 것이라 생각합니다. 연차가 있으신 개발자분들은 수학 전공이 아니더라도 꾸준한 코드 설계를 바탕으로 무의식적인 논리력 향상을 겪으리라 생각하구요.

 

1. 궁금증

사실 최근 뭐 빅데이터 처리에 기가막히다느니 함수형 프로그래밍을 잘하면 연봉이 높다느니하는 그런 얘기에 관심이 있어서 이런 포스트를 쓰는 것은 아니고 본격적으로 내용을 다루기 전에 내 얘기를 좀 해보려고 합니다. 수학과 물리를 좋아하여(사실 기초학문의 상식 정도를 배우고 좋아한다고 착각했던) 수학, 물리학과를 전공한다고 큰소리쳤던 어릴때의 저는 제가 알던 고등수학과 상상하던 대학수학의 갭을 뼈저리게 느꼈기에 몇 개월도 채우지 못하고 도망쳤었습니다. 그래도 고등수학을 나름 좋아하였고 20대 초중반 수학 과외로 용돈도 꽤나 벌었었기에 어디가서 수학과 관련된 주제가 나오면 관심을 가졌습니다. 그런 저에겐 개발 언어를 처음 접하고 느낀 가장 큰 의문점이 있었고 그것은 '함수'라는 것이었습니다.

 

본질적으로 수학에서의 함수는 어려운 개념 나열도 필요 없이 '대응 관계'로 정의됩니다. 그런데 개발에서 처음 만난 C라는 녀석이 함수랍시고 던져준 놈을 봤을때 느꼈던 괴리감이란.... 함수라면 반드시 입력이 있을땐 출력이 있어야하는 것 아니었나요? 하지만 프로그래밍에서의 함수는 시작부터 void를 선언함으로써 수학에서의 함수가 아님이 자명했습니다. '아니 출력값이 없는데 어떻게 함수지?'라는 제 생각은 JAVA와 RDBMS의 패러다임 불일치를 뛰어넘는 괴리를 일으켰고 결국 1학년때 컴공을 전공하다 다른 길로 빠지는 결정적인 계기가 되었던 것 같습니다. 물론 다른 이유가 더 컸지만...

 

2. 다시 처음부터

그렇게 몇 년간 개발과는 동떨어진 일을(따지고 보면 개발은 아니지만 기획 등 컴퓨터와는 늘 붙어있었습니다. 이건 추후에 얘기하는 것이 나을 것 같습니다)하다 제 길이 아니었음을 깨닫고 다시 개발 공부를 시작한 저는 사실 머릿 속으로는 아직도 옛날에 느꼈던 패러다임 불일치로 인한 어딘가의 답답함을 해갈하지 못하였다고 해야하나? 어쨋든 공부는 하지만 한켠으론 답답한 무언가가 해소되지 못하고 있었습니다. 그런데 오늘 유튜브에 구독해뒀던 노마드코더 채널의 영상을 하나 보고 찾아본 자료들 덕분에 그 응어리들이 많이 풀어졌습니다. 사실 함수형프로그래밍(이후 FP)에 대해선 기존 CS관련 공부를 진행하며 주워듣긴 했었고 관심이 생겨 관련 영상도 본적이 있었습니다. 하지만 그때는 함수형프로그래밍의 특성을 대충 훑어본 것이 다였는데 오늘 찾아본 것은 과거의 나에게 '왜 그때 대충 넘어갔었냐 바보야'라고 할 정도로 크게 다가왔습니다. 

 

3. 함수

원래 무언가 희열을 느끼기 위해선 그만큼의 역경을 겪어야합니다. 게임을 할때 적이 강하면 강할수록 영화를 볼 때 상황이 꼬이면 꼬일수록 최종장에서 느끼는 희열은 강렬한 것처럼 말이죠. 하지만 지금 그런 것들은 이미 몇 년 동안 제 안에서 숨어지내왔으니 이 글을 보는 사람들에겐 미안하지만 내가 느낀 바를 빌드업 없이 바로 얘기하려 합니다.

 

수학에서는 합성 함수라는 개념이 있다는 것을 다들 배웠을 것입니다. 함수형 프로그래밍이란 것이 크게보면 그 합성 함수를 프로그래밍으로 구현한 방식이라는 것을 알게된 순간, 프로그래밍의 '함수'를 강요받던 순간부터 지금껏 꼬인 개념들이 정리되는 느낌이었습니다. 물론 함수형 프로그래밍이 더 심오하고 많은 개념이 있어 저 한마디만으로 설명할 수 없다는 것을 알지만 저 문장을 쓰게됨으로 JAVA에서 함수를 메서드로, 람다식이 익명 객체라는 것을 암기하던 것이 더이상 암기가 아닌 이해의 영역으로 바뀌게 되었기 때문입니다.

 

합성 함수는 f(x)와 g(x)가 합성되었을때 f·g를 구하면 x가 중간 과정에서 어떤 값을 갖는지 알 필요 없이 y값을 얻을 수 있습니다. 이 말을 프로그래밍 관점으로 바꿔보면 param을 입력한 뒤 일일이 어떻게 변화가 되는지(status)를 내가 확인할 필요가 없다는 것일텐데요.

 

프로그래밍에서 개발자들의 큰 어려움은 코드가 길어짐에 따른 status 추적의 어려움일 것입니다. 어디서 Exception이 발생하고 어디서 버그가 시작될지 코드가 길어지면 status를 추적하기 힘들 것입니다. 이것을 FP를 통해 획기적으로 개선할 수 있습니다! 내가 입력한 Param이 중간 명령을 만나면 어떤 상태로 변화할지 계속하여 추적할 일을 엄청나게 줄여줄 것입니다.(수학에서의 합성함수도 복잡해지면 함수의 위상을 추적하여 문제를 해결하듯이 함수형 프로그래밍도 아예 안하진 않겠지만요...) 

 

아래 블로그의 말을 인용하여 FP의 특성은 수학의 순수함수를 프로그래밍에 적용하기 위해 거는 제약은

  1. 동일한 인풋(인자)에는 항상 동일한 결과를 내야한다.
  2. 함수 외부의 상태를 변경하거나, 외부의 상태에 영향을 받아서는 안된다

결국 FP에서 중요한 이 제약은 함수가 유일한 결과값을 반환하는 수학의 세계에서는 지극히 당연한 일이며 수학에는 status라는 개념이 없기에 side effect가 일어날 수 있는 가능성은 없습니다. 불변성이니 참조 투명성이니 응집도가 높다느니 하는 다양한 FP의 특성들이 어릴때 배웠던 간단한 고등수학에서의 함수를 생각하면 당연한 얘기고 이 제약은 단지 수학적인 개념을 프로그래밍에서 사용하기 위해 붙인 말들에 불과할 것입니다.

 

4. 정리

코드에는 크게 선언형, 명령형 코드가 존재하고 프로그래밍에는 절차지향, 객체지향이라는 프로그래밍 방식이 존재합니다. FP에서 함수에 대한 insight를 얻었기에 역으로 명령형 코드는 어떤 설계에서 유리하고 객체지향의 패러다임은 무슨 장점이 있는지 더욱 가깝게 다가오는 것에 더해 기존에 코드를 짤 때 return 값과 refer 타입에 대한 집착 아닌 집착이 있었던 것이 약간은 사라지지 않았으려나요...(기존엔 메서드를 거치면 무의식적으로 상태 추적보다는 함수를 보듯 결과 위주로 코드를 해석했었는데 JAVA 코딩에서 무의식적인 수학적 사고를 배제함으로 객체들간의 관계에 더욱 집중할 수 있을 것 같습니다)

 

사실 spring boot를 학습하고 있는 지금 저에게는 이런 insight는 당장에 필요 없을지 모릅니다. 하지만 더 이상 JAVA에서 메서드를 함수라고 부르지 않고, Lambda를 더욱 편리하게 사용할 수 있는 소소한 도움을 얻었고 이후 개발 공부를 더 하다보면 더 큰 도움을 얻을 수 있을 것입니다. 사실 아직 insight에 대한 감정이 가라앉지 않아 FP,에 대한 본격적인 공부도 하지 않았고 관련 자료도 더 많이 찾아보지 않아 부족한 것이 많은 채로 자야될 시간에 허접한 포스트를 올리기에 나중에 이 글을 봤을때 매우 창피할 것 같습니다. 향후 관련 내용을 더욱 학습한다면 이 글에 이어 포스트하겠지만 이 글과는 성격이 조금 다를 것 같습니다. 이 글은 그만큼 저에게 이 개념이 크게 다가왔다는 반증이랄까요?

 

사실 이번 글의 대부분 내용은 아래 refer의 post 리뷰 글이라고 해도 될 정도기에 이 포스트를 읽으신 분이라면 아래 refer의 영상과 블로그를 참고하시면 좋을 것 같네요.

 

refer

노마드코더_반드시 함수형프로그래밍을 배워야할까? : https://www.youtube.com/watch?v=7aEQLvvnQIY

수학에서 기원한 프로그래밍 패러다임 : https://evan-moon.github.io/2019/12/29/about-pure-functions/

'Fadet's box' 카테고리의 다른 글

글 리뷰_1_'백엔드 개발자를 꿈꾸는 학생개발자에게'  (0) 2022.10.05
블로그 첫 글  (0) 2022.02.05