함수형 프로그래밍이란?

김형주·2021년 9월 2일
0

아무래도 주니어도 못된 내가 이런 글을 쓰는 것이 조금은 이상해보일지도 모르겠지만, 이러저러 공부를 하다보니 한자 적어보자는 취지에서 적게되었다. 물론 지금은 취준을 하는 시기고, 기술면접을 대비하는 면도 없지 않아 있지만, 이런 생각들이 모이면 언젠가 내게 강한 무기로 다가오지 않을까하는 생각에서다. 글을 5-6시간 쓰면 모르겠지만, 1시간 안에 짧게 글로 작성하려고 한다.

프로그래밍 패러다임

패러다임이라는 것은 일종의 생각이나 사고의 틀이라고 생각하면 된다. 그동안 패러다임의 전환과 같은 다양한 광고카피를 봐왔지만 패러다임이라는 용어에는 익숙해지지 못했던 것 같다. 그래서 위키를 찾아 간단하게 정리해보고자 한다.

패러다임

한 시대의 사람들의 견해나 사고를 근본적으로 규정하고 있는 인식의 체계. 또는, 사물에 대한 이론적인 틀이나 체계. 순화어는 `틀'.

이를 통해 간단하게 생각해보자면 프로그래밍 패러다임이라는 것은 프로그래머가 어떤 관점에서 코드를 작성할 지를 결정하는 하나의 틀이라고 생각하면 된다. 코드를 어떤 생각을 가지고 작성하는지에 관한 문제라고 생각한다. 가장 근대에 와서는 명령형 프로그래밍그리고 선언형 프로그래밍 이 두가지 패러다임이 가장 메인스트림의 형태를 띠고 있는 패러다임이다.

명령형 프로그래밍

명령형 프로그래밍은 기본적으로 코드를 작성하는 것이 원하는 결과를 달성해나가는 과정에만 중심을 두는 프로그래밍 패러다임이다. 그렇기 때문에 무엇(What)을 달성할 것인지 나타내는 것보다 어떻게(How)할 것인지를 설명하는 사고에 가깝다. 간단하게 예제 코드를 만들어보자.

var str = '111111211111'
let answer = ''
var target = '2'

for(let i = 0; i < str.length; i++){
  if(str[i] === target){
    	answer += '1';
  	} else {
     	answer += str[i] 
    }
}

위의 코드는 str이라는 대상 문자열에서 2라는 타겟을 찾아 1로 바꾸어 만들어주는 과정을 담고 있다. 중간 중간 target이나 answer등의 변수명을 통해서 목적의 방향성을 이야기하지만, 코드만 한번 보고 목적을 파악하는 것은 어렵다. 따라서, 최종적으로 어떤 목적을 두고 프로그래밍을 한 것인지에 대한 것을 주석으로 남겨두어야 코드를 쉽게 읽을 수 있다.

선언형 프로그래밍

그렇다면 선언형 프로그래밍은 어떨까? 선언적 프로그래밍은 명령형 프로그래밍과 다르게 달성하는 세세한 과정(How)보다 목표한 바가 무엇이고, 어떻게 이루어지는지 결과(What)에 대한 것을 중심에 두는 프로그래밍 패러다임이다. 그렇기 때문에 세부적인 과정은 간략화되어 과정보다 결과물에 좀더 집중한 결과물을 만들 수 있다. 이번엔 선언형 프로그래밍의 예시 코드를 살펴보자.

var str = '111111211111'
1. str[str.indexOf('2')]='1'
2. str.replace('2','1')

위에서 하나하나 살펴보며 찾아서 무엇을 바꿀지에 대한 것을 일일히 명령해줬다면, 해당 과정을 간략화된 단어 몇개로 코드가 어떻게 어떤 결과물을 만들어내는지 직관적으로 이해할 수 있다. 이건 새로운 명령을 만들지 않고, 추상화되어있는 일련의 과정을 사고로 결과물을 만들어내는 코드로 구성되어있다. 두 가지 방법을 각각 간단하게 보면 첫번째는 '2'의 인덱스를 찾아서 해당 인덱스의 값을 '1'로 바꾸어준다.가 되고, 두번째는 '2'라는 문자열을 찾아서, '1'로 바꾸어준다.라는 방식으로 주석도 없이 간결하게 코드를 이해할 수 있다.

그렇다면 함수형 프로그래밍이란?

함수형 프로그래밍이란 선언형에서 뿌리를 뻗어나온 패러다임인데, 말 그대로 함수가 프로그래밍 전반의 중심이 되도록 하는 패러다임이다. 위의 선언형 프로그래밍을 보면 JavaScript 내장 메서드를 이용해서 연산이 이루어지고 있다.

indexOf('2')메서드는 때려죽여도, 문자열 내부의 2index값만 가져올 것이고, replace('2','1')는 미친듯이 때려도 처음 만난 2의 값을 1로 바꾸기만 할 것이다.

함수형 프로그래밍이란 함수의 기능은 본연의 기능으로 유지하면서, 작성하는 프로그래밍 패러다임이다.

함수형 프로그래밍의 컨셉

1. 변경 가능한 상태를 불변상태(Immutable)로 만들어, SideEffect를 없애자.

어렸을 때 수학책에서 봤던 함수를 살펴보면 f(x) = y 뭐가 들어가든 같은 결과가 나오게끔 만들어진다. 위의 함수는 x를 넣으면 때려죽여도 y값만 출력하게된다. 여기서 중요한 것은 함수 내부의 상태는 어떤 상황에서도 유지되고 결과값은 항상 동일해야 한다는 것이다. 내부에 어떤 상황도 만들지 않기 때문에 결과예측이 틀리는 경우는 없다.

//순수함수
function func1(a,b){
 return a+b; 
}
--------------------------
  
state ='add';

function func2(a,b){
  //상태에 따른 결과값 변경
  if(state === 'add'){
    return a+b;
  } else {
   	return a-b; 
  }
}

위의 코드를 보면 명확하게 알 수 있다. 첫번째 함수는 어떤 외부 상황이나 내부 상황에 의해서 값이 변동되지 않고 동일하게 두 전달인자의 합만을 반환한다. 하지만 두번째 함수는 외부의 state 혹은 내부의 상황에 따라서 a+b 혹은 a-b를 출력한다. 함수형 프로그래밍의 가장 핵심은 외부에 영향을 받지 않고, 상황에 따라 변동하지 않는 순수함수가 되어야한다는 것이다. 순수함수에 대한 이야기는 다음에 담도록 하겠다.

SideEffect

Side Effect란, 본래 의도와 다르게 다음과 같은 변화 혹은 변화가 발생하는 작업을 말한다.

  • 변수의 값이 변경됨
  • 자료 구조를 제자리에서 수정함
  • 객체의 필드값을 설정함
  • 예외나 오류가 발생하여 실행이 중단됨
  • 콘솔 또는 파일 I/O가 발생됨

2. 모든 것은 객체이다.

함수형 프로그래밍에서 모든 것은 객체다. 클래스 외에 함수 또한 객체이기 때문에 함수를 값으로도 할당할 수 있고, 파라미터로 전달결과 값을 반환할 수 있다. 위 3가지를 모두 지키는 객체를 1급 객체라고 한다. 함수형 프로그래밍 언어에서는 위 3가지 조건을 모두 만족 시켜 1급 객체가 된다. 1급 객체에 대한 것도 다른 글로 남기겠다.

3. 코드를 간결하게 하고, 가독성을 높여 로직에 집중시키자.

Lambda 및 Collection, Stream과 같은 API를 통해 보일러 플레이트를 제거하고, 내부에 직접적인 함수 호출을 통해 가독성을 높일 수 있다. 일을 위한 일이 줄어 실제 구현할 로직에만 집중할 수 있다.

4. 동시성 작업을 보다 쉽고 안전하게 구현하자.

위에 설명한 immutable 값을 사용해, 여러 쓰레드에서 접근을 하더라도 SideEffect가 발생하지 않는다. 또한 Lock이나, UnLock같은 보호장치도 필요하지 않다.

마치며

기본적으로 함수형 프로그래밍 언어인 JavaScript를 통해 여러 경험을 할 수 있었다. 내가 원하는 결과를 만들어 내기위해서 중간에 진행해야했던 많은 명령형 코드들을 추상화시켜서 가볍게 만들 수 있었고, C++이나 C언어를 할때와는 다르게 편리성을 크게 느끼기도 했다. 그런만큼 여전히 이전 언어에서 사용하던 불필요한 과정들을 자꾸만 해서 코드가 가독성이 떨어지고, 결과 예측이 어렵게 되고 하던 다양한 과정을 느꼈다. JavaScript를 좀 더 자세하게 공부해서 함수형 프로그래밍, 즉 만들어진 바퀴를 어떻게 더 잘 활용할 것인가를 지속적으로 고민해야된다.

이렇게 글을 쓰고나니 이전에 공부한 것들을 적던 때랑은 또 다르게 느껴진다. 이런 글들이 쌓여 언젠가 내 무기가 될 것이라고 생각하니 타자를 치는 손이 훨씬 가볍게 느껴진다. 물론 쓰면서 100% 이해되지 않은 부분도 많지만, 공부해나가다보면 언젠가 확실히 이해해서 다른 사람에게도 명쾌하게 설명할 수 있지 않을까? 물론 코드스테이츠를 하면서 공부했던 부분들도 있어서 이해가 조금 더 쉽긴했지만 아직 가야할 길이 멀게만 느껴진다. 힘내자.

profile
만물에 관심이 많은 잡학지식사전이자, 새로운 도전을 꿈꾸는 주니어 개발자 / 잡학지식에서 벗어나서 전문성을 가진 엔지니어로 거듭나자!

0개의 댓글