함수형 프로그래밍

김용현·2023년 7월 18일
0

[cs]

목록 보기
4/5

프로그래밍 패러다임

프로그래밍 패러다임은 개발자(프로그래머)에게 프로그래밍의 관점을 갖고 결정하게 하는 역할을 의미

어떤 배열 속 요소들에 1을 더한 배열을 반환하기 위해서는 어떤 방법들이 있을까요?

let A = [1, 2, 3]를 사용해서 [2, 3, 4]를 반환하기
  • 가장 먼저 배열 A 자체 내부의 숫자를 1씩 증가시켜서 반환하는 방법이 있을 수 있습니다.
  • 그렇지 않다면, 배열 A를 입력하여 A를 수정하지 않고 [2, 3, 4]를 가진 새로운 배열을 반환하는 방법도 있을 겁니다.

동일한 [2, 3, 4] 배열을 반환하지만 다른 방식을 찾을 수 있으며, 결과가 동일하지만 이 방법들을 자세히 살펴보면 차이가 있음을 확인할 수 있습니다. 예를 들어, 원본 A의 배열에 변화가 발생한다는 점과 그리고 첫 번째 방식을 사용할 경우, 배열 A를 사용하는 다른 함수들에 영향을 준다는 점이 가장 눈에 띄는 차이점 일겁니다. 이렇게 각각의 프로그래밍 방식에는 장단점이 존재하게 됩니다.

전체적으로 특정 스타일의 프로그래밍 방식을 선정하여 진행하는 것을 프로그래밍 패러다임이라고 합니다. 저희가 앞으로 학습할 함수형 프로그래밍 또한 프로그래밍 패러다임 중 한가지 입니다.

함수형 프로그래밍

함수형 프로그래밍은 프로그램의 함수(데이터 처리 과정)를 수학적 함수의 계산처럼 처리하는 방식을 의미

y = x + 1이라는 수학식(함수)의 경우 시간이 얼마나 흐르든, 외부에서 별도의 함수가 계산을 하든 혹은 내가 아니라 다른 사람, 다른 공간에서 계산하는 것과 상관없이 항상 1을 넣으면 2라는 값을 반환합니다. 그리고 이 계산으로 다른 숫자들에 영향을 주지 않기도 하구요. 함수형 프로그래밍은 수학적 함수의 다음과 같은 특징을 반영한 프로그래밍입니다. 누가, 어디서, 언제, 어떻게 사용하든 같은 값을 집어넣었을 때 항상 같은 값만을 반환하는 함수를 제작하도록 말이죠

함수형 프로그래밍으로 설계된 함수는 실행했을 경우, 값이 반환되는 것 이외의 어떠한 변화를 일으키지 않습니다. 덕분에 똑같은 값을 참조하고 있는 다른 함수의 결과에도 아무런 영향을 끼치지 않는다는 것을 확신할 수 있습니다.

이렇게 예상치 못한 변화가 발생하지 않는다는 확신은 프로그램의 동작을 이해하고 예측하기 훨씬 쉽게 만들어주고, 이것이 함수형 프로그래밍의 가장 큰 특징이자 장점 입니다.

함수형 프로그래밍은 특징은 다음과 같은 특징이 있습니다.

불변하는 데이터(Immutable Data)

함수형 프로그램의 원칙 중 하나는 데이터를 함수 밖에서 변형(modify) 하지 않는 다는 것입니다. (단, 함수의 반환 값은 함수 내에서 수행된 작업을 반영).

앞서 살펴본 let A = [1, 2, 3]의 예시가 기억나시나요? 만약 다른 함수 function B가 배열 A를 참조해 A[1]을 반환한다고 가정해봅시다. 저희가 [2, 3, 4]의 값을 얻기 위해, let A = [2, 3, 4]로 바꾸게 된다면, 함수 B는 2라는 숫자 대신 3이라는 숫자를 참조하고 이로 인해 오류가 발생하게 될 것입니다. 이렇게 함수의 동작으로 인해 함수 외부의 배열 A 값이 변하게 되어, 예외나 오류가 발생하는 상황을 부수 효과(Side Effect)라고 합니다.

함수형 프로그램은 외부의 값을 변형 시키지 않기 때문에, 부수효과를 최대한 억제할 수 있다는 가장 특징이 있습니다. 그렇기 때문에, 여러 복잡한 함수들로 이루어진 프로그램의 경우 함수형 프로그래밍을 사용한다면, 예측 불가한 오류를 최소화하고 결과를 쉽게 예측할 수 있습니다.

클로저(Closure)

선언할 당시의 환경을 기억했다가, 나중에 호출될 시 원래의 환경에 따라 호출되는 함수

const closure = (dataA) => {
    return (dataB) => {
        return dataA + dataB
    }
}
const cl = closure(5) // 이 방법을 통해 dataA의 값을 cl 안에서 기억할 수 있다.
cl(10); // 15 return

클로저의 핵심은 dataA를 통해 cl을 선언할 당시의 데이터를 저장할 수 있고, 덕분에 dataA는 class의 private 효과를 가지게 됩니다. 이 때 dataA와 같이 선언할 때 넘기는 데이터를 자유 변수라고 부릅니다.

순수 함수(Pure Function)

순수 함수는 입력된 데이터에만 의존하며, 부수 효과를 일으키지 않는 함수를 뜻합니다. 함수형 프로그래밍은 순수 함수를 구현함으로써, 불변하는 데이터의 특징을 실현할 수 있습니다. 순수 함수의 가장 아름다운 점은 단순함 입니다. 오직 입력된 값(argument)만을 활용하여 반환값을 도출해내고, 이 과정에서 정해진 API 이외의 어떠한 부수효과(환경의 변화)도 일으키지 않는 단순한 구조를 가지고 있습니다.

일급 객체 함수(First Class Functions)

다음과 같은 특징을 지닌 객체를 일급 객체라고 말합니다.

  • 변수나 데이터 구조 안에 담을 수 있다.
  • 파라미터로 전달 할 수 있다.
  • 반환 값으로 사용할 수 있다.
  • 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
  • 동적으로 property 할당이 가능하다

함수형 프로그래밍에서 함수는 일급 객체로 취급이 됩니다. 즉, 일급 객체 함수라는 것은 일급 객체로 취급하는 함수를 의미하게 됩니다.

유지 관리 가능성(Maintainable)

부수 효과가 발생하지 않기 때문에, 뜻밖의 예외가 발생하는 경우가 없게 됩니다. 대규모의 프로그램 개발에 있어 작은 부수 효과가 어떠한 결과를 불러일으킬 지 예측하는 것은 쉽지 않기 때문에, 덩치가 큰 프로젝트일 수록 유지 관리성을 위해 함수형 프로그래밍을 지향하게 됩니다.

모듈화(Modularity)

모듈화는 생산성을 증가시킵니다. 외부 환경 변수로부터 영향을 주고 받지 않기 때문에, 함수형 프로그래밍은 분리하여 모듈화 하기에 굉장히 유용합니다. 또한 분리된 모듈은 테스트의 용이성을 가지기 때문에, 디버깅과 테스트 시간을 줄일 수있습니다.

참조 투명성(Referential Tansparency)

함수의 순수성, 전달인자의 불변성을 유지하면 다음의 참조의 투명성을 기대할 수 있습니다.

  1. 함수 외부에 의존하는 코드가 없기 때문에, 함수를 사용할 때에는 유효한 매개 변수만을 전달하면 됩니다. 이러한 특징을 자기 충족적(self-contained)라고 합니다.
  2. 항상 동일한 입력에 대해 동일한 반환값을 가지는 결정론적(deterministc)인 특징이 있습니다.
  3. 예외를 던지지 않습니다.
  4. 본인 이외의 함수가 예기치 않게 실패하는 조건을 만들지 않습니다.
  5. 데이터 베이스, 파일 시스템, 네트워크 등의 외부 기기로 인해 동작이 멈추지 않습니다.

참조 :

함수형 프로그래밍(위키) https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

함수형 프로그래밍 : https://code-lab1.tistory.com/245

클로저 : https://velog.io/@rnjsrntkd95/%ED%81%B4%EB%A1%9C%EC%A0%80Closure-%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

함수형 프로그래밍: https://velog.io/@phs880623/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

profile
함께 일하고 싶은 개발자가 되기위해 노력 중입니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기