💻 프로그래밍

Lambda Function

람다 함수

익명 함수. Python lambda, JS arrow function. 간결한 함수 정의.

📖 상세 설명

람다 함수(Lambda Function)는 이름 없이 정의되는 익명 함수(Anonymous Function)로, 일회성 또는 간단한 연산을 위해 사용됩니다. 전통적인 함수 정의 방식과 달리, 람다 함수는 한 줄 또는 간결한 표현식으로 작성되어 코드의 가독성과 생산성을 높여줍니다. Python에서는 lambda 키워드를, JavaScript에서는 화살표 함수(=>)를 통해 람다 함수를 표현합니다.

람다 함수의 개념은 1930년대 수학자 알론조 처치(Alonzo Church)가 개발한 람다 대수(Lambda Calculus)에서 유래했습니다. 람다 대수는 계산 가능성을 연구하기 위한 형식 체계로, 함수의 정의와 적용을 수학적으로 표현합니다. 이 개념이 1950-60년대 LISP를 시작으로 프로그래밍 언어에 도입되었고, 현재는 대부분의 현대 언어가 람다 함수를 지원합니다.

람다 함수의 핵심 원리는 세 가지입니다. 첫째, 익명성(Anonymity)으로 함수에 이름을 부여하지 않아도 됩니다. 둘째, 일급 객체(First-class Citizen)로서 변수에 할당하거나 다른 함수의 인자로 전달할 수 있습니다. 셋째, 클로저(Closure) 특성으로 정의된 시점의 외부 스코프 변수를 캡처하여 사용할 수 있습니다.

실무에서 람다 함수는 map(), filter(), reduce() 같은 고차 함수와 함께 데이터 변환에 광범위하게 활용됩니다. 이벤트 핸들러, 콜백 함수, 정렬 기준 정의 등 일회성 함수가 필요한 모든 상황에서 코드를 간결하게 만들어줍니다. 또한 AWS Lambda 같은 서버리스 컴퓨팅 플랫폼은 람다 함수의 개념을 확장하여, 서버 관리 없이 코드를 실행할 수 있는 클라우드 서비스를 제공합니다.

💻 코드 예제

# Python 람다 함수 예제

# 기본 람다 함수 정의
square = lambda x: x ** 2
print(square(5))  # 출력: 25

# 여러 인자를 받는 람다 함수
add = lambda a, b: a + b
print(add(3, 7))  # 출력: 10

# map()과 함께 사용
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  # 출력: [1, 4, 9, 16, 25]

# filter()로 짝수만 추출
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # 출력: [2, 4]

# 정렬 기준으로 사용
users = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]
sorted_users = sorted(users, key=lambda u: u['age'])
print(sorted_users)  # Bob이 먼저 (나이순 정렬)
// JavaScript 화살표 함수 (람다 함수)

// 기본 화살표 함수
const square = (x) => x ** 2;
console.log(square(5));  // 출력: 25

// 여러 인자를 받는 화살표 함수
const add = (a, b) => a + b;
console.log(add(3, 7));  // 출력: 10

// map()과 함께 사용
const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(x => x ** 2);
console.log(squared);  // 출력: [1, 4, 9, 16, 25]

// filter()로 짝수만 추출
const evens = numbers.filter(x => x % 2 === 0);
console.log(evens);  // 출력: [2, 4]

// 이벤트 핸들러로 사용
document.querySelector('#btn').addEventListener('click', (e) => {
    console.log('버튼이 클릭됨!', e.target);
});

// Promise 체인에서 활용
fetch('/api/users')
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => console.error(err));
// Java 람다 표현식 (Java 8+)

import java.util.*;
import java.util.stream.*;

public class LambdaExample {
    public static void main(String[] args) {

        // 기본 람다 표현식 (Runnable)
        Runnable task = () -> System.out.println("Hello Lambda!");
        task.run();

        // Comparator 람다로 정렬
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        names.sort((a, b) -> a.compareTo(b));

        // Stream API와 함께 사용
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // map: 제곱 계산
        List<Integer> squared = numbers.stream()
            .map(x -> x * x)
            .collect(Collectors.toList());
        System.out.println(squared);  // [1, 4, 9, 16, 25]

        // filter: 짝수만 추출
        List<Integer> evens = numbers.stream()
            .filter(x -> x % 2 == 0)
            .collect(Collectors.toList());
        System.out.println(evens);  // [2, 4]

        // forEach로 출력
        numbers.forEach(n -> System.out.println(n));
    }
}

🗣️ 실무에서 이렇게 말하세요

💬 회의에서 (콜백 리팩토링 논의)
"이 API 호출 부분에 별도 함수를 만들기보다는, 람다 함수로 인라인 처리하면 코드가 훨씬 간결해질 것 같습니다. map과 filter 체인으로 데이터 변환 로직을 깔끔하게 표현할 수 있어요."
💬 면접에서 (람다와 일반 함수 차이)
"람다 함수와 일반 함수의 핵심 차이는 세 가지입니다. 첫째, 람다는 익명이라 재사용보다는 일회성 로직에 적합합니다. 둘째, 람다는 표현식 기반이라 복잡한 로직보다 단순 변환에 효과적입니다. 셋째, 클로저 특성으로 외부 스코프 변수를 캡처할 수 있어 고차 함수와 함께 사용할 때 강력합니다. Python에서는 단일 표현식만 가능하고, JavaScript 화살표 함수는 this 바인딩이 일반 함수와 다른 점도 중요합니다."
💬 코드 리뷰에서 (가독성 피드백)
"이 람다 함수가 3줄 이상 되니까 오히려 읽기 어려워졌네요. 람다는 한 줄에 끝나는 간단한 로직에만 쓰고, 이렇게 복잡한 경우는 명시적인 함수로 분리해서 의도를 명확하게 드러내는 게 좋을 것 같습니다."

⚠️ 흔한 실수 & 주의사항

복잡한 로직에 람다 사용

람다 함수에 조건문, 반복문, 예외 처리 등 복잡한 로직을 넣으면 가독성이 급격히 떨어집니다. 람다는 단순한 변환이나 필터링에만 사용하고, 복잡한 로직은 명시적인 함수로 정의하세요.

디버깅 어려움

람다 함수는 이름이 없어서 스택 트레이스에서 '<lambda>'로만 표시됩니다. 에러 추적이 어려우므로, 중요한 비즈니스 로직에는 디버깅과 테스트가 용이한 명명된 함수를 사용하세요.

과도한 중첩과 체이닝

람다를 여러 겹으로 중첩하거나 map-filter-reduce를 과도하게 체이닝하면 코드 이해가 어렵습니다. 적절히 중간 변수를 사용하거나 단계별로 분리해서 가독성을 확보하세요.

올바른 사용법

람다 함수는 정렬 키, 간단한 콜백, 단순 데이터 변환 등 일회성이고 한 줄로 표현 가능한 로직에 사용하세요. "이 람다를 읽는 데 3초 이상 걸린다면 함수로 분리"하는 것이 좋은 기준입니다.

🔗 관련 용어

📚 더 배우기