[TIL] 함수형 프로그래밍

OROSY·2021년 11월 3일
1

TIL

목록 보기
17/18
post-thumbnail

🧮 함수형 프로그래밍

지금은 기술 면접 준비를 하면서 저에게 부족했던 웹, 브라우저, 자바스크립트, 리액트 등의 동작 원리에 대해서 깊이 있게 공부하려고 노력하는 중입니다. 그 중에서 당연히 요즘 계속해서 중요성을 강조하고 있는 함수형 프로그래밍에 대해서 알아보도록 하겠습니다.

함수형 프로그래밍에 대해서 깊이 이야기를 나누면서, 함께 객체 지향 프로그래밍(OOP)에 대해서도 언급을 당연하게도 피할 수 없기에 함께 알아보도록 하겠습니다.

🗣 함수형 프로그래밍 언어?

함수형 프로그래밍에 대해서 언급하기 전에 그렇다면 함수형 프로그래밍으로 코드를 짜야 한다면, 언어를 새로 배워야하는 것일까요? 함수형 프로그래밍을 채용한 언어로는 Scala, Clojure, Groovy, Erlang, Kotlin, C#, Java (1.8이상부터 지원) 등으로 더 많습니다.

그러나 함수형 프로그래밍을 도입한다는 것은 함수형 프로그래밍을 채택한 언어로 바꾸는 것이 아닙니다. 기존 우리가 사용하던 객체지향 프로그래밍 이라는 패러다임에서 함수형 프로그래밍 이라는 패러다임으로 바꾸는 것이라고 할 수 있죠.

당연하게도, 함수형 프로그래밍으로 패러다임을 바꾼다고 해서 객체지향 프로그래밍을 완전히 버리는 것이 아닙니다. 중요한 건 자신이 지금 개발하는 프로그램에서 어떤 패러다임이 제일 효율이 높고 프로그램이 어떤 방식으로 확장되든 쉽게 파괴되지 않을지 생각하고 선택하는 것이죠.

프론트엔드 개발에서는 UI 라이브러리인 React를 예로 들 수 있는데, 현재 React는 Class Component의 개발 방식에서 Functional Component로 많이 넘어가게 된 상황입니다. 이러함과 맞물려 채용 조건에서도 React-Hooks를 요구하는 회사들이 많아졌음을 확인할 수 있습니다.

그렇다면, 이제 본격적으로 함수형 프로그래밍에 대해 알아보도록 할까요?

🎮 함수형 프로그래밍

위에서 말한 것처럼 함수형 프로그래밍 방식과 객체 지향 프로그래밍 방식이 대비되어 비교될 수 있는 개념이기는 하지만 완전히 반대되는 개념은 아닙니다.

함수형 프로그래밍 방식은 불변성과 순수함수를 지키고 최대한 선언형 방식의 프로그램이 되도록 지켜야할 규칙을 따르는 것입니다. 함수형 프로그래밍에서도 객체 지향 프로그래밍에서 나오는 3대 개념인 캡슐화, 추상화, 다형성이 필요하다면 사용됩니다.

함수형 프로그래밍에서 사용되는 함수들은 몇 가지 뚜렷한 특징이 있습니다.

  1. 인풋아웃풋이 있어야 합니다.
  2. 외부 환경(변수)으로부터 철저히 독립적입니다.
  3. 같은 인풋에 있어서 언제나 동일한 아웃풋을 제공합니다. 순수함수

객체 지향 프로그래밍은 여러 함수들이 손을 대는 외부 변수에 오류가 생기면, 차질이 생길 수밖에 없습니다. 이는 함수형 프로그래밍에 비해 문제의 소지가 더 많다는 뜻이 될 것입니다.

함수형 프로그래밍이 주목받게 된 주요 요인 중 하나가 이와 같은 Side Effect(부작용)에 의한 문제로부터 보다 자유롭다는 것입니다. 여기서 말하는 부작용, 부수효과는 어떤 함수의 동작에 의해 프로그램 내 특정 상태가 변경되는 상황을 말합니다. 변경된 상태는 관련된 다른 동작들에게 영향을 미치게 되겠죠.

함수형 프로그래밍은, 함수의 동작에 의한 변수의 부수적인 값 변경을 원천 배제함으로써 이런 종류의 오류를 방지하는 것입니다. 문제의 소지가 있는 일은 하지 않는 코딩 방식이라는 것입니다.

외부 변수를 사용하더라도, 그 본체에 접근해서 변경하는 것이 아니라 인자로 넣어 사본으로 복사해가서 작업을 하기 때문에 어떤 작업을 하든 부작용은 일어나지 않습니다.

물론, 고정값만 쓰면서 소프트웨어를 만들 수 있다는 것은 아닙니다. 아무런 상태 변화를 일으키지 않는다는 말이 아니며, 모든 것을 100% 함수형 기준에 맞추는 것은 당연히 어려울 것입니다.

하지만 적어도 일정 단위의 작업에 있어서는 부수효과 없이 안정적이고 예측 가능한 프로그램을 짜는 것이 함수형 프로그래밍인 것입니다. 프로세서의 발전 속도가 사용자의 필요에 뒤쳐지면서 멀티코어를 이용한 멀티 프로세싱이 중요해진 오늘날 함수형 프로그래밍은 더더욱 주목받고 있습니다.

그렇다면, 함수형 프로그래밍의 대표적인 특징에 대해서 자세히 알아봅시다.

1. 함수형 프로그래밍은 "선언형"이다.

대부분의 프로그래밍은 명령형으로 진행됩니다. 반면, 선언형이것은 저것이다처럼 매우 단순하게 선언만 해주면 됩니다.

위에서 언급했듯이 함수형 방식으로 짜인 함수, 순수함수들은 인풋만 똑같으면 절대 다른 요인에 의한 변수가 없습니다. 그러니까 어떠한 프로세스로 연결된 함수들에 인풋을 넣으면, 무조건 동일한 아웃풋이라고 할 수 있는 것입니다.

명령형에서는 변수에 대해서만 이것은 저것이다식으로 생각하고 함수는 이를 처리하는 행위적인 개념으로만 다가왔을 것입니다. 이제는 함수도 변수처럼 생각할 수 있어야 하는 것입니다.

함수를 값으로 보고 프로그래밍을 하는 것입니다.

2. 함수도 "값"이다.

이렇게 함수형은 들어가는 인자 그리고 나오는 리턴 값이 있어야하며, 다른 아무런 부수적 변화도 주지 말아야 합니다. 당연하게도 함수 자체로는 결과값이 나오지 않습니다. 예를 들어, 숫자를 넣어주면 2를 곱해서 리턴해주는 함수가 있다고 생각해봅시다. 어떤 숫자든 인자로 들어가야 손에 잡히는 2를 곱한 숫자가 나오게 됩니다.

하지만 어쨌든, 이 함수가 인풋으로 하는 일은 일정하기 때문에 언제든 숫자만 인자로 붙여주면 그 인자로써 절대 예측 가능한 숫자 값을 내게 될 상태라는 '값'으로 이 함수를 바라볼 수 있는 것입니다. 물론, 순수함수라면 말입니다.

그렇다면, 함수를 값으로 바라봐서 무엇을 하려는 것일까요?

3. 고차함수

인풋이 있는 함수는 특정 값을 인자로 받습니다. 함수를 값으로 볼 수 있다면, 함수도 다른 함수에 인자로 넣어줄 수 있을 것입니다.

아래의 예시를 보면, 이해하실 수 있을 것입니다.

var calc = function (num1, num2, op) {
  return op(num1, num2);
}

// 화살표 함수 버전
const calc = (num1, num2, op) => op(num1, num2);

const add = (num1, num2) => num1 + num2;
const multiply = (num1, num2) => num1 * num2;
const power = (num1, num2) => Math.pow(num2, num1);

calc(2, 3, add);
calc(2, 3, multiply);
calc(2, 3, power);

이처럼 인자로 다른 함수를 받아 결과값을 내보내는 함수를 고차함수라고 합니다. 값은 인자로 주어질 뿐 아니라 결과값으로 반환되기도 합니다. 다른 함수를 반환하는 함수도 고차함수에 속합니다.

const calcWith2 = (op) => (num) => op(2, num);

const add = (num1, num2) => num1 + num2;
const multiply = (num1, num2) => num1 * num2;

const add2 = calcWith2(add);
const multiply2 = calcWith2(multiply);

add2(3); // 5
multiply2(3); // 6

위의 고차 함수도 어려워 보이지만, 실제로 뜯어보면 어렵지 않습니다. add2(3)의 값은 5로 add2는 두 값을 더하는 함수를 인자로 받아 calcWith2라는 함수를 호출하는 것입니다. 결국, 이는 add(2, 3)으로 값이 5가 되는 것이죠.

이렇게 프로그램이 동작하는 중에 함수가 만들어지는 것이 바로 함수형 프로그래밍의 진수라고 할 수 있을 것 같습니다. 이렇게 다른 함수를 인자로 받거나 결과로 반환되는 고차 함수를 이용하여 더 유연하고 다채로운 프로그래밍이 가능해질 것입니다.


오늘은 함수형 프로그래밍에 대해서 간단히 정리를 해보았습니다. 깊이 들어갈수록 쉽지 않은 개념이라는 건 더욱 확실해지는 것 같습니다만, 지금까지 React로 프로젝트를 진행하면서 데이터의 불변성이나 순수함수를 강조하고, 코드의 가독성, 함수의 재사용성에 대해 개념만 듣고, 왜 이러한 방식으로 코딩을 해야하는지 원리를 파악하지 못한 채 코드를 작성했던 것 같습니다.

이번 기회로 함수형 프로그래밍에 대해 알게된 좋은 계기가 되었네요. 혹시 틀린 내용이 있다면 언제든지 말씀해주시기 바라겠습니다! 그럼 또 다른 내용으로 찾아뵙겠습니다👋👋👋

참고 사이트

제멋대로 생각해보는 함수형 프로그래밍
[얄코] 함수형 프로그래밍이 뭔가요?
React 와 함수형 프로그래밍 Functional Programming vs OOP

profile
Life is a matter of a direction not a speed.

0개의 댓글