처리중입니다. 잠시만 기다려주세요.
TTJ 코딩클래스
정규반 단과 자료실 테크 뉴스 코딩 퀴즈
테크 뉴스
Hacker News 2026.03.23 37

커링(Currying)에 대한 반론: 정말 좋은 패턴인가, 다시 생각해볼 때

Hacker News 원문 보기

함수형 프로그래밍의 "당연한 미덕"에 의문을 제기하다

함수형 프로그래밍(FP)을 공부하다 보면 반드시 만나는 개념이 있습니다. 커링(Currying)이죠. 여러 인자를 받는 함수를 하나의 인자만 받는 함수의 체인으로 변환하는 기법입니다. FP 교과서에서는 거의 예외 없이 "좋은 것"으로 소개되고, Haskell 같은 언어에서는 기본 동작이며, JavaScript 생태계에서도 Ramda나 lodash/fp를 통해 널리 사용됩니다.

그런데 최근 한 개발자가 "A Case Against Currying"이라는 글을 통해 커링이 실제로는 코드 품질을 떨어뜨릴 수 있다는 주장을 내놓았습니다. 단순한 안티 패턴 지적이 아니라, 커링이 근본적으로 가지는 설계적 문제를 체계적으로 분석한 글이어서 살펴볼 가치가 있습니다.

커링이란 무엇인가: 빠른 복습

커링을 간단히 설명하면 이렇습니다. add(a, b)라는 함수가 있다면, 커링된 버전은 add(a)(b)가 됩니다. add(3)을 호출하면 "3을 더하는 함수"가 반환되고, 그 함수에 5를 넘기면 8이 나옵니다.

이것의 장점으로 주로 언급되는 것은 부분 적용(Partial Application)입니다. add(3)이라는 "3을 더하는 함수"를 만들어서 여기저기 재사용할 수 있다는 것이죠. 또한 함수 합성(Function Composition)에서 각 단계에 단일 인자 함수만 사용할 수 있으므로 파이프라인을 깔끔하게 구성할 수 있다는 것도 장점으로 꼽힙니다.

반론의 핵심: 가독성과 의도의 불투명성

이 글이 지적하는 첫 번째 문제는 가독성입니다. processData(config)(validator)(transformer)(data)와 같은 커링 체인을 보면, 각 괄호가 무엇을 의미하는지 즉시 파악하기 어렵습니다. 인자의 순서가 함수 설계에 의해 고정되어 있기 때문에, "이 인자가 왜 먼저 오는지"에 대한 의문이 생기기도 합니다.

일반적인 함수 호출 processData(config, validator, transformer, data)에서는 인자 이름이 명시적으로 보이고, 호출 의도가 한눈에 들어옵니다. 하지만 커링된 버전에서는 중간 단계의 반환값이 "무엇을 하는 함수인지"를 코드만 보고는 알기 어렵습니다. 특히 타입 시스템이 약한 언어에서는 더 심각합니다.

두 번째 문제는 디버깅의 어려움입니다. 커링된 함수 체인에서 에러가 발생하면, 스택 트레이스가 여러 겹의 클로저를 거쳐야 하므로 어디서 문제가 생겼는지 추적하기 까다롭습니다. 일반 함수 호출이라면 하나의 프레임에서 모든 인자를 확인할 수 있지만, 커링된 함수에서는 각 단계의 클로저 스코프를 하나씩 들여다봐야 합니다.

부분 적용은 커링 없이도 가능하다

커링 옹호론의 핵심인 부분 적용에 대해서도 반론이 있습니다. JavaScript를 예로 들면, Function.prototype.bind나 화살표 함수를 사용하면 커링 없이도 부분 적용을 간단히 할 수 있습니다.

const add3 = (b) => add(3, b)는 커링 없이도 "3을 더하는 함수"를 만듭니다. 그리고 이 방식은 어떤 인자를 고정하고 어떤 인자를 열어둘지를 호출자가 자유롭게 선택할 수 있다는 장점이 있습니다. 커링에서는 왼쪽부터 순서대로 인자를 고정해야 하는 제약이 있지만, 명시적 부분 적용에서는 이런 제약이 없습니다.

예를 들어 fetchData(url, method, headers, body) 함수에서 methodheaders만 고정하고 싶다면, 커링으로는 어색하지만 화살표 함수로는 (url, body) => fetchData(url, 'POST', defaultHeaders, body)처럼 자연스럽게 표현할 수 있습니다.

언어별 맥락의 차이

이 논의에서 중요한 것은 언어별 맥락입니다. Haskell에서 커링은 언어 설계에 깊이 통합되어 있고, 타입 시스템이 강력하기 때문에 커링의 단점이 상당 부분 완화됩니다. 타입 추론이 중간 단계 함수의 시그니처를 명확히 보여주고, 컴파일러가 타입 오류를 잡아주기 때문입니다.

반면 JavaScript나 Python 같은 동적 타입 언어에서 커링을 남용하면, 타입 안전장치 없이 중첩된 클로저만 쌓이게 됩니다. TypeScript를 쓰더라도, 커링된 함수의 타입 정의가 복잡해지면서 오히려 타입 시스템의 도움을 받기 어려워지는 경우가 있습니다.

한국 개발자에게 주는 시사점

한국의 프론트엔드 생태계에서 함수형 프로그래밍 스타일은 꽤 인기가 있습니다. React의 커스텀 훅, Redux의 미들웨어, 각종 유틸리티 라이브러리에서 커링 패턴을 자주 접하게 됩니다. 이 글은 "커링을 쓰지 말라"는 것이 아니라, "왜 커링을 쓰는지 의식적으로 선택하라"는 메시지로 받아들이는 것이 적절합니다.

팀 프로젝트에서 커링된 유틸리티 함수를 만들기 전에, 그 함수를 사용할 동료가 호출 방식을 직관적으로 이해할 수 있는지 생각해보세요. 추상화의 우아함보다 팀의 인지 부하를 줄이는 것이 대부분의 실무 환경에서 더 중요합니다.

마무리

모든 패턴에는 트레이드오프가 있고, 커링도 예외가 아닙니다. 핵심은 "커링이 좋냐 나쁘냐"의 이분법이 아니라, 현재 맥락에서 커링이 가져오는 이점이 가독성과 디버깅 비용을 상쇄하는지 따져보는 것입니다.

여러분은 실무에서 커링을 적극적으로 사용하시나요, 아니면 명시적 부분 적용을 선호하시나요?


🔗 출처: Hacker News

이 뉴스가 유용했나요?

이 기술을 직접 배워보세요

파이썬으로 자동화를 시작해보세요

파이썬 기초부터 자동화까지 실전 강의.

파이썬 강의 보기

"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"

실제 수강생 후기
  • 비전공자도 6개월이면 첫 수익
  • 20년 경력 개발자 직강
  • 자동화 프로그램 + 소스코드 제공

매일 AI·개발 뉴스를 받아보세요

주요 테크 뉴스를 매일 아침 이메일로 전해드립니다.

스팸 없이, 언제든 구독 취소 가능합니다.