자바스크립트의 비밀스러운 삶: 커링 vs. 부분 적용

발행: (2025년 12월 15일 오후 01:13 GMT+9)
6 min read
원문: Dev.to

Source: Dev.to

실용적인 접근법: 부분 적용 (Partial Application)

// A standard, multi‑argument function
function multiply(a, b) {
    return a * b;
}

// Manually creating partial application via a closure factory
function createMultiplier(factor) {
    // We "lock in" the 'factor' argument here
    return function (number) {
        return number * factor;
    };
}

// Usage
const double = createMultiplier(2); // We applied '2' to the first spot
console.log(double(10)); // 20

Partial Application은 수동 기법입니다: 일반 함수의 일부 인자를 미리 채워 새로운 함수를 만들고, 남은 인자를 기다리게 합니다.

Original Function: [ Slot A ] [ Slot B ] [ Slot C ]

Partial Application:
We choose to fill Slot A now.
Resulting Function: [ 10 ] [ Slot B ] [ Slot C ]

구조적인 접근법: 커링 (Currying)

커링은 함수 시그니처의 구조적 변환입니다. 다중 인자 함수를 일련의 단일 인자 함수 체인으로 바꿉니다.

const formatUrl = protocol => domain => path => `${protocol}://${domain}/${path}`;
// Partial Application – manual process
// We can fill any arguments we want, in any order we design
const addFive = (b, c) => add(5, b, c);

// Currying – structural transformation
// It forces a rigid chain: one arg at a time
const curriedAdd = a => b => c => a + b + c;

// You MUST call it like this:
curriedAdd(1)(2)(3);

체인을 깨려고 하면 실패합니다:

// This won't work as expected with a truly curried function:
// It returns a function expecting 'path', it does NOT use 'myblog.com' as the domain yet!
formatUrl('https', 'myblog.com');

비유: 샌드위치 메이커 vs. 조립 라인

부분 적용 샌드위치 메이커

일반적인 샌드위치 레시피에 , 고기, 치즈가 필요합니다. 오늘 사용할 빵이 사워도우라는 것을 안다면, 미리 사워도우 조각을 준비해 둡니다. 이렇게 빵 인자를 수동으로 “부분 적용”하면 이후 단계가 빨라집니다.

커리된 조립 라인

세 개의 스테이션을 가진 산업용 샌드위치 공장 로봇을 상상해 보세요:

  1. 스테이션 1만 받으며 결과를 스테이션 2에 전달합니다.
  2. 스테이션 2고기만 받으며 결과를 스테이션 3에 전달합니다.
  3. 스테이션 3치즈만 받습니다.

빵과 고기를 동시에 스테이션 1에 넣을 수 없습니다; 조립 라인은 한 번에 하나의 인자만 흐르게 강제합니다.

라이브러리가 커링을 사용한 이유

커링을 사용하면 특화된 빌더를 쉽게 만들 수 있기 때문입니다:

// Create a builder specifically for secure sites
const secureUrl = formatUrl('https');

// Create a builder specifically for OUR site
const myBlogUrl = secureUrl('myblog.com');

// Generating links is clean:
const post1 = myBlogUrl('post-1');
const post2 = myBlogUrl('post-2');

커리된 formatUrl은 조립 라인의 어느 단계에서든 멈출 수 있게 해 주어, 새로운 정의 없이 재사용 가능한 부분 함수를 생성합니다.

흔한 함정: 혼합 패턴

// Not truly curried (breaks the single‑argument chain)
const add = a => (b, c) => a + b + c; // returns a function taking TWO args

// Truly curried (maintains single‑argument chain)
const curriedAdd = a => b => c => a + b + c; // each returns a function taking ONE arg

첫 번째 예시는 하이브리드이며, 진정한 커링은 함수당 하나의 인자만 받는 패턴을 끝까지 유지합니다.

Margaret’s Cheat Sheet

부분 적용을 사용할 때:

  • 표준 JavaScript를 작성할 때.
  • 특정 사용 사례에 맞게 함수를 특화할 때 (예: createMultiplier).
  • 유연성이 필요할 때 (예: 첫 번째 세 번째 인자를 고정하고 두 번째는 열어두는 경우).

커링을 사용할 때:

  • 함수형 라이브러리를 사용할 때 (예: Ramda, Lodash/fp).
  • 최대한의 합성을 원할 때 (데이터를 체인으로 파이프할 때).
  • 함수의 다양한 특화 버전을 자동으로 생성하고 싶을 때.

일상적인 JavaScript에서는 부분 적용이 자주 등장하지만, 진정한 커링은 드뭅니다—하지만 두 개념의 차이를 이해하면 상황에 맞는 도구를 선택하는 데 도움이 됩니다.

Back to Blog

관련 글

더 보기 »

JavaScript에서 일급 함수

소개 개발자들이 JavaScript를 배우면서 “first‑class functions”라는 용어가 토론과 문서에서 자주 등장합니다. JavaScript에서 함수는 …

JavaScript에서 함수 합성

소개: 함수 합성(Functional composition)은 함수 파이프라인(function pipelines)이라고도 하며, 간단한 함수를 연결하여 보다 가독성이 높고 모듈화된 코드를 만들 수 있게 합니다. 정의...