공부해봅시당
[CS 기초] 고차함수 본문
고차 함수(Higher-order function)는 함수형 프로그래밍의 핵심 개념 중 하나로, 함수를 인자로 받거나 함수를 결과로 반환하는 함수를 의미
이런 성질을 가진 함수는 프로그램의 추상화 수준을 높여주며, 보다 유연하고 재사용 가능한 코드를 작성할 수 있게 해줌
고차 함수의 예제를 먼저 살펴보고 특징과 장단점에 대해 알아보도록 하겠음
고차 함수 예제
자바스크립트
자바스크립트와 같은 함수형 프로그래밍 언어에서 고차 함수는 매우 중요한 역할을 함
자바스크립트에서 고차 함수의 한 예는 Array 객체의 map, filter, reduce 같은 메소드
이 메소드들은 각각 함수를 인자로 받아 배열의 각 요소에 적용함
기본예제
// 함수를 인자로 받는 고차 함수 예
function filter(arr, predicate) {
const result = [];
for (const item of arr) {
if (predicate(item)) {
result.push(item);
}
}
return result;
}
// 함수를 반환하는 고차 함수 예
function greaterThan(n) {
return m => m > n;
}
const greaterThan10 = greaterThan(10);
console.log(greaterThan10(11)); // true
위의 예시에서 filter는 배열과 함께 "어떤 조건에 부합하는지"를 확인하는 함수를 인자로 받고 있음
greaterThan는 주어진 숫자보다 큰 숫자를 판별하는 함수를 생성하여 반환
이 두 예시는 모두 고차 함수의 전형적인 사용 사례
예제1
// 고차 함수 예제: 함수를 인자로 받아 해당 함수를 배열의 모든 요소에 적용하는 함수
function map(arr, fn) {
const result = [];
for (const item of arr) {
result.push(fn(item)); // 전달받은 함수(fn)를 각 요소에 적용
}
return result;
}
// 간단한 함수를 정의하고, 이를 map 함수에 인자로 전달
function square(x) {
return x * x;
}
const numbers = [1, 2, 3, 4];
const squares = map(numbers, square);
console.log(squares); // [1, 4, 9, 16]
이 예에서 map은 고차 함수
이 함수는 배열과 함께 함수 square를 인자로 받고, 이 square 함수를 배열의 각 요소에 적용한 결과를 반환함
예제2
// 고차 함수 예제: 함수를 반환하는 함수
function makeMultiplier(multiplier) {
return function (x) {
return x * multiplier;
};
}
const double = makeMultiplier(2);
const triple = makeMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
여기서 makeMultiplier 함수는 고차 함수
이 함수는 새로운 함수를 만들어 반환하며, 반환된 함수는 makeMultiplier에 전달된 multiplier 값으로 인자를 곱함
자바
자바로 예를 들면, 자바에서 고차 함수는 일반적으로 인터페이스를 사용해 구현됨
자바 8부터는 람다 표현식과 함께 사용할 수 있는 Function, Consumer, Supplier, Predicate 등과 같은 함수형 인터페이스가 도입됨
다음은 자바에서 Function<T, R> 인터페이스를 사용하는 고차 함수의 예제
Function<T, R> 인터페이스는 T 타입을 인자로 받고 R 타입을 반환하는 추상 메소드 apply를 하나 가지고 있음
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class HigherOrderFunctionExample {
// 고차 함수: Function 인터페이스를 사용하여 함수를 인자로 받고 새로운 리스트를 반환
public static <T, R> List<R> map(List<T> list, Function<T, R> function) {
List<R> result = new ArrayList<>();
for (T item : list) {
result.add(function.apply(item)); // 전달받은 함수를 각 요소에 적용
}
return result;
}
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4);
// 람다 표현식을 사용하여 map 함수에 함수를 인자로 전달
List<Integer> squaredNumbers = map(numbers, x -> x * x);
System.out.println(squaredNumbers); // [1, 4, 9, 16]
}
}
이 예제에서 map 메소드는 리스트와 함수를 인자로 받고, 그 함수를 리스트의 각 요소에 적용한 새로운 리스트를 반환하는 고차 함수
main 메소드에서는 map 메소드에 정수의 제곱을 계산하는 람다 표현식을 전달하여 각 숫자의 제곱으로 이루어진 새로운 리스트를 생성하고 있음
자바에서 고차 함수를 더 활용하기 위해서는 Stream API를 사용하는 것도 좋은 방법
Stream은 많은 고차 함수들을 메소드 형태로 제공하며, 람다 표현식과 함께 강력한 데이터 처리 기능을 수행할 수 있게 해줌
고차 함수의 특징
함수를 인자로 받음
고차 함수는 다른 함수를 인자로 받아 그 함수에 대한 작업을 수행할 수 있음
예를 들어, 배열의 모든 요소에 특정 함수를 적용하는 map 함수가 있음
함수를 결과로 반환함
고차 함수는 실행 결과로 새로운 함수를 만들어 반환할 수 있음
이를 통해 상태를 유지하거나, 설정을 인코딩하는 등의 작업을 할 수 있음
코드의 재사용성 증대
고차 함수를 사용하면 특정 연산을 일반화하여 다양한 상황에서 재사용할 수 있음
함수의 추상화
고차 함수를 사용함으로써, 상위 수준의 로직을 설계할 수 있으며, 이를 통해 더 강력하고 표현력 있는 프로그래밍이 가능해짐
고차 함수의 장점
추상화
고차 함수는 반복되는 패턴을 추상화함으로써 코드의 중복을 줄이고, 가독성을 높임
모듈성
작은 함수 단위로 코드를 분리하여 각각의 함수가 독립적인 기능을 수행하도록 함으로써, 코드의 모듈성을 향상시킴
재사용성
일반적인 작업을 수행하는 고차 함수를 정의함으로써, 다양한 상황에서 필요한 행동을 재사용할 수 있음
함수 컴포지션
고차 함수를 이용하면 작은 함수들을 서로 결합하여 더 큰 기능을 하는 함수를 만들 수 있음
고차 함수의 단점
복잡성
고차 함수를 사용하면 코드의 추상화 수준이 높아지고, 때로는 코드의 복잡성이 증가할 수 있음
학습 곡선
고차 함수는 개념 자체가 초보자에게는 다소 난해할 수 있으며, 이해하고 사용하는 데 시간이 걸릴 수 있음
성능 고려
고차 함수는 추가적인 함수 호출을 필요로 하기 때문에, 성능에 민감한 상황에서는 오버헤드를 고려해야 할 수도 있음
'STUDY > CS' 카테고리의 다른 글
[CS] '명령형' 프로그래밍 vs '선언적' 프로그래밍 (1) | 2024.02.12 |
---|---|
[CS 기초] Groovy란? (0) | 2023.11.06 |
[CS 기초] 정적 스코프(Static Scope) vs 동적 스코프(Dynamic Scope) (0) | 2023.11.06 |
[CS 기초] 렉시컬 스코프, 스코프 체인, 클로저의 관계 (1) | 2023.11.06 |
[CS 기초] 스코프(Scope) (0) | 2023.11.06 |