[FP study chapter] 4장 - 재사용 가능한, 모듈적인 코드로 [1/2]

horiz.d·2023년 7월 16일
0

horizontal-library/FP 스터디/재사용 가능한, 모듈적인 코드로 [1/2]

4장에서는 함수 합성을 통해 느슨하게 결합된 파이프라인을 만들고...

3장에서는 고수준 함수를 써서 하나의 래퍼 객체를 중심으로 단단하게 결합하였다고 했다.
이는 래퍼 객체 내부에서 구현된 메서드라는 제약이 있었으나, 함수 합성을 통한 파이프라인 구축은 보다 유연한 독립적 컴포넌트, 즉, 외부에서 구현된 것을 사용할 수 있는 것 이라고 이해했다.


함수형 프로그래밍에서 함수란 입력 형식과 출력 형식 간의 수학적 매핑.


메서드 체이닝 (단단한 결합)

메서드 체이닝 예제 중.. : 이 예제는 로대시JS가 제공하는 연산만 쓸 수 있기 때문에 다른 라이브러리 함수를 쉽게 연결할 수 없습니다.

이것이 메서드체이닝이 래퍼 객체를 중심으로 단단하게결합되었기 때문에 발생하는 제한의 예이다.


함수를 파이프라인에 나열 (느슨하고 유연할 결합)

함수형 프로그래밍에서는 메서드 체이닝의 한계에서 벗어나 출신(자신을 소유한 객체)에 관계 없이 어떤 함수라도 유연하게 결합할 수 있습니다. 파이프라인이란 한 함수의 출력이 다음 함수의 입력이 되게끔 느슨하게 배열한 방향성함수 순차열입니다.

  • 이는 객체지향 디자인 패턴 중 파이프 및 필터와 동등한 패턴이라고 한다.
  • 파이프라인은 함수 입출력을 서로 연결지어 느슨하게 결합된 컴포넌트를 만드는데, 이에 따라 함수의 항 수와 형식이 호환되지 않으면 연결될 수 없다.

함수 호환 요건 (형식/인수)

  1. 형식이 호환되는 함수

    • js는 형식이 느슨한 언어이기 때문에 어떤 객체가 실제로 특정 형식처럼 작동하면 그 형식은 그냥 그 객체의 형식으로 본다. 이를 덕 타이핑이라고 부름

    • 자바스크립트는 동적 파견 체제덕분에 형식과 무관하게 객체에서 속성과 메서드를 가져올 수 있다?? -> REF: Dynamic Dispatch를 알면 코드가 빨라진다

  1. 함수와 항수: 항수란 함수가 받는 인수의 개수, 함수의 길이.
    JS에서의 FP는 함수가 취하는 인수 개수의 호환 여부가 더욱 중요하다. (물론 타입 매우 중요함)
    -> 타입의 일치는 아마 타입스크립트로 해결할 수 있는 문제인듯

    FP에서는 함수에 선언된 인수의 개수가 (참조투명성의 당연한 결과로서) 복잡도와 정확히 비례하는 경우가 많다.

이 책에서 권장하는 목표는 함수의 인수를 가능한 한 적게 만드는 것으로 단일책임의 유연하고 다목적의 함수로 만들어내는 것.


함수 커링

튜플은 항수를 줄이는 방법 중 하나이다. 튜플로 함수의 항수를 줄일 순 있지만, 더 나은 대체방안인 함수 커링이 있다. 이는 항수를 추상하는 동시에 모듈성, 재사용성을 높인다.

일반 평가 vs 커리된 평가 차이점

JS에서는 (비커리된)일반 함수를 호출할 때 인수가 모자라도 문제없이 실행시킨다

함수 f(a,b,c)에 대해 f()에 a 인수만 넣어도 js런타임은 빈 매개변수 b,c를 undefined로 자동 세팅 및 실행하는데, 함수 안에서 args 객체에 전적 의존하는 것은 문제를 키울 위험이 있다.


커리된 함수: 모든 매개변수가 명시된 커리된 함수에 일부 인수만 넣어 호출하면, 함수가 실행되는게 아니라 모자란 나머지 인수가 다 채워지기를 기다리는 새로운 함수가 반환된다. 이 끝에 다 채워졌을 때 결국 결과값이 반환된다.

// 수동으로 만드는 커리 함수 구조
function curry(f) { // 커링 변환을 하는 curry(f) 함수
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}

// arrow로 표현한 커리 함수
const func = (a) => (b) => (c) => res

람다JS를 사용해 순수함수형 스타일 개발이 가능. 모든 람다JS의 기능은 전역변수 R을 통해 접근 사용 가능. 이는 curry함수도 지원한다.

R.curry를 쓰면 인수 개수 상관 없이 순수함수형 언어의 자동 커링 장치 모방 가능. 자동 커링은 선언된 인수 개수만큼 중첩된 함수 스코프 인위적으로 생성해줌



커링을 어디에 쓰나?

  1. 함수 팩토리 모방
  2. 재사용 가능한 모듈적 함수 템플릿 구현

1. 함수 팩토리 모방

const fetchStudentFormDb = R.curry(function (db, ssm) {
return find(db, ssn)});

const fetchStudentFormArray = R.curry(function (arr, ssn) {
return arr[ssn]});
// 동적 정의 및 평가지연 (arg1)
const findStudent = useDb ? fetchStudentFromDb(db)
					: fetchStudentFromArray(arr);

// 평가부 (arg2: 공통부분)
findStudent('444-44-4444');

위의 예제는 유용하게 쓰일 것 같아서 기록한다.
(단위 테스트에서 조건부로 사용해도 좋을듯)


재사용 가능한 함수 템플릿 구현

...

무엇보다 커링의 가장 중요한 의의는 다인수 함수를 단항 함수로 바꾼다는 것이다.



부분 적용(partial), 매개변수 바인딩(bind)

partial 함수

작성요망

뜯어서 이해해보기

언어의 핵심을 확장?

지연된 함수에 바인딩?

profile
가용한 시간은 한정적이고, 배울건 넘쳐난다.

0개의 댓글