Conceptly
← 전체 목록
🎯

First-Class Function

함수 활용함수를 값처럼 다루는 언어의 성질

일급 함수는 언어가 함수를 숫자나 문자열 같은 '평범한 값'으로 취급한다는 뜻입니다. 그래서 함수를 변수에 담고, 다른 함수에 넘기고, 반환값으로 돌려받고, 배열이나 객체 안에 넣어 둘 수 있습니다. 포인트는 문법이 멋지다는 게 아니라, 동작 자체를 데이터처럼 주고받을 수 있다는 데 있습니다. 이 성질이 있어야 고차 함수, 콜백, 함수 합성 같은 함수형 패턴이 자연스럽게 성립합니다.

아키텍처 다이어그램

🔗 관계 다이어그램

점선 애니메이션은 데이터 또는 요청의 흐름 방향을 나타냅니다

왜 필요한가요?

함수를 값처럼 다룰 수 없는 언어에서는 동작을 바꾸고 싶을 때마다 거대한 switch 문이나 조건 분기를 늘어놓기 쉽습니다. 정렬 기준을 바꾸거나 이벤트 처리 방식을 교체하려 해도, 함수를 넘기는 대신 다른 함수 이름을 직접 고르는 쪽으로 흘러갑니다. 공통 구조를 추출하고 싶어도 그 안에 들어갈 '행동'을 밖에서 주입할 수 없으니 비슷한 코드가 계속 복제됩니다. 결국 추상화의 폭은 함수를 값으로 옮길 수 있느냐에 크게 좌우됩니다.

왜 이런 방식이 등장했나요?

초기 명령형 언어들은 함수를 '실행되는 블록'으로만 취급했습니다. 포인터로 함수 주소를 넘기는 방식이 있었지만 일반 값과 같은 문법으로 다루기는 어려웠습니다. Lisp 계열 언어는 처음부터 함수를 값으로 보는 설계를 택했고, 이 발상이 수십 년 뒤 JavaScript, Python, Ruby 같은 주류 언어로 퍼졌습니다. 특히 JavaScript가 웹 전역에서 쓰이면서 이벤트 처리, 비동기 콜백, 배열 메서드 같은 맥락에서 함수를 인자로 넘기는 스타일이 일상이 됐습니다. 오늘날 대부분의 모던 언어는 일급 함수를 기본 제공하며, 이것이 없으면 고차 함수와 함수형 스타일 전체가 성립하지 않습니다.

내부적으로 어떻게 동작하나요?

일급 함수는 특별한 메커니즘이라기보다 언어의 타입 시스템이 함수를 값의 한 종류로 인정하는 것입니다. JavaScript에서 const greet = function(name) { return 'Hi ' + name; }라고 쓰면 greet은 함수를 가리키는 변수이고, 다른 변수처럼 재할당하거나 배열에 넣거나 객체 속성으로 저장할 수 있습니다. 함수를 인자로 받는 다른 함수에 넘기면 그 함수 안에서 호출할 수 있고, 함수가 함수를 반환하면 호출 결과가 새로운 동작 단위가 됩니다. 이 유연함 덕분에 '무엇을 할지'를 호출 시점에 결정하는 동적 행동 조합이 가능해집니다.

코드로 보면

함수를 값으로 다루기

// 변수에 할당
const add = (a, b) => a + b;

// 인자로 전달
function apply(fn, x, y) {
  return fn(x, y);
}
apply(add, 2, 3);  // 5

// 반환 값으로 돌려줌
function makeMultiplier(n) {
  return (x) => x * n;
}
const double = makeMultiplier(2);
double(5);  // 10

// 배열, 객체에 담기
const handlers = {
  click: (e) => console.log('clicked'),
  hover: (e) => console.log('hovered')
};
handlers.click(event);

add는 변수에 담긴 함수이고, apply는 함수를 인자로 받아 호출합니다. makeMultiplier는 함수를 만들어 반환하며, handlers는 함수를 객체 값으로 담고 있습니다. 네 경우 모두 함수가 다른 값과 똑같이 다뤄집니다.

경계와 구분

일급 함수와 고차 함수는 서로 붙어 다니지만 층위가 다릅니다. 일급 함수는 언어가 제공하는 성질입니다. '함수를 값처럼 쓸 수 있다'는 가능성입니다. 고차 함수는 그 성질을 실제로 활용하는 함수의 유형입니다. 함수를 인자로 받거나 반환하는 함수를 말합니다. 일급 함수가 없는 언어에서는 고차 함수를 만들 수 없고, 일급 함수가 있어도 그것을 쓰지 않으면 고차 함수는 등장하지 않습니다. 일급 함수는 재료이고, 고차 함수는 그 재료로 만든 패턴입니다.

언제 쓰나요?

일급 함수는 이벤트 시스템, 컬렉션 처리, 라우팅, 플러그인 구조처럼 동작을 나중에 꽂아 넣어야 하는 곳에서 바로 힘을 발휘합니다. 버튼 핸들러를 등록할 때도, 정렬 규칙을 바꿀 때도, URL별 처리 함수를 테이블에 담아 둘 때도 결국 '행동을 값처럼 다룬다'는 전제가 깔려 있습니다. 프론트엔드의 render prop이나 builder 함수도 같은 맥락입니다. 데이터를 주고받는 것만으로는 부족하고, 동작 자체를 저장하고 전달해야 할 때 일급 함수가 설계의 기본 재료가 됩니다.

콜백 전달전략 선택라우팅 테이블미들웨어 체인