[함수형 자바스크립트] 1.함수형 자바스크립트


객체지향은 가동부를 캡슐화하여 코드의 이해를 돕는다. 함수형 프로그래밍은 가동부를 최소화하여 코드의 이해를 돕는다.

함수형 프로그래밍이란?

요즘 많이 쓰는 프로그래밍 언어 대부분은 네이티브로 또는 API로 함수형 프로그래밍을 지원한다.

함수형 프로그래밍이란 함수 사용을 강조하는 소프트웨어 개발 스타일이다. 함수는 다들 사용하고 있을 것이다. 하지만 그 함수를 사용함에 있어 데이터의 제어 흐름과 연산을 추상하여야 함을 이야기 한다. 그로인해 어플리케이션은 상태의 변이부작용을 줄일 수 있을 것이다.

선언적

함수형프로그래밍은 큰 틀에서 선언적 프로그래밍에 속한다. 내부적으로는 어떻게 구현했는지, 데이터는 어떻게 흘러가는지 밝히지 않은 채 연산/작업을 표현하는 것이다.

[0, 1, 2, 3, 4, 5].map((num) => Math.pow(num, 2))

반복문이라는 명령형 구문을 쓰지 않고 선언적으로 구현하였다.

반복문은 재사용하기도 어렵고, 다른 연산에 끼워 넣기도 어렵다. 또한 반복문은 매 반복시마다 값이나 상태가 계속 바뀌게 된다. 함수형 프로그램은 무상태성과 불변성을 지향하기때문에 전역상태를 바꾸거나 부작용을 일으키지 않는다.

순수함수와 사이드이펙트

함수형 프로그래밍은 순수함수로 구성된 불변 프로그램 구축을 전제로 한다.

순수함수란

  • 숨겨진 값이나 외부상태와 무관하게 작동한다.
  • 함수 스코프 밖의 어떠한 변경도 일으키지 않는다.

함수가 순수하지 않다면 대부분 사이드이펙트를 일으킨다. 함수스코프에 벗어난 무언가를 바꾸거나 참조하기 때문이다.

function showStudent(ssn) {
    let student = db.find(ssn);
    if(student !== null) {
        document.querySelector(`#${elementId}`).innerHTML = `${student.ssn}, ${student.firstname}, ${student.lastname}`;
    }
    else {
        throw new Error('학생을 찾을 수 없습니다.');
    }
}

showStudent('444-44-4444');

이 함수는 입력값으로 제시되지 않은 db와 elementId를 참조하므로 불순하다. 또한 DOM이라는 전역 공유자원을 직접 참조하며, 학생 레코드를 찾지 못해 예외를 던지면 에러를 일으켜 종료될 것이다.

함수형 사고방식과 커링을 이용해 조금 개선해보자.

const find = curry((db, id) => {
    const obj = db.find(id);
    if(obj === null) {
        throw new Error('객체를 찾을 수 없습니다.');
    }
    return obj;
})

const csv = student => `${student.ssn}, ${student.firstname}, ${student.lastname}`;

const append = curry((selector, info) => {
    document.querySelector(selector).innerHTML = info;
})

코드가 선언적으로 변해 읽기 좋아졌다. 또한 DOM을 다루는 함수를 따로 빼내어 순수하지 않은 로직을 순수함수에서 배제했다.

참조 투명성

참조 투명성은 순수함수 상태에서 입력이 같으면 언제나 결과가 같다를 충족하는 성질이라고 볼 수 있다.

불변 데이터 유지

불변데이터는 한번 생성된 이후에 절대 바뀌지 않는다. 원시 자료형은 본래 불변형이지만 배열등의 객체는 불변이 아니어서 내용의 변경으로 인한 사이드이펙트가 발생할 수 있다.

const sortDesc = arr => {
    arr.sort((a, b) => b - a);
};

const arr = [1,2,3,4,5,6,7,8];
sortDesc(arr);

이 경우 Array.sort는 원본 레퍼런스가 가리키는 배열의 원소를 정렬하는 사이드이펙트를 일으킨다. 이건 자바스크립트가 가진 문제점중에 하나인데, 해결하는 방법은 다음에 자세히 살펴보자.

함수형 프로그래밍의 좋은 점

  • 단순한 작업으로 만든다.
  • 흐름체인으로 데이터를 처리한다.
  • 이벤트 중심 코드의 복잡성을 줄인다.

단순한 작업으로 만든다.

함수형 프로그래밍은 사실 분해합성의 상호작용이라고 할 수 있다. 충분한 모듈화를 진행하여 하나의 목적만을 가진 단일성을 유지해야한다.

체이닝하여 처리한다.

로대시의 예를 보자.

_.chain(enrollment)
    .filter(student => student.enrolled > 1)
    .pluck('grade')
    .average()
    .value();

체이닝은 필요한 시점까지 실행을 미룰수 있다. 위의 경우 value()를 실행하기 전까지 체이닝된 함수들은 작동하지 않는다.

복잡한 비동기 앱에서도 신속히 반응한다.

함수형프로그래밍을 이용해서 문제를 해결하려는 노력중에 가장 두드러지는 것 중 하나는 단연 리액티브 프로그래밍이다. 리액티브 패러다임의 가장 큰 장점은 더 높은 쑤준으로 코드를 추상하여 비동기, 이벤트 기반프로그램을 설정하느라 반복되는 코드는 잊고 오직 비즈니스 로직에만 전념할 수 있다.

리액티브 패러디임은 옵저버블이라는 장치를 매개로 움직인다. 옵저버블을 이용하여 데이터 스트림을 구독해서 원하는 연산을 우아하게 합성 및 체이닝하여 처리할 수 있다.

반드시 함수형 프로그래밍과 리액티드 패러다임을 섞어쓸 필요는 없다. 하지만 함수형프로그래밍을 배우다 보면 언젠가 자신도 모르게 리액티브 패러다임과 결합해 있는 자신의 코드를 발견하게 돌 것이다.




© 2017. by isme2n

Powered by aiden