사실 여러 패러다임을 통해 각 패러다임이 가진 문제를 다른 패러다임으로 해결하는 방법또는 고찰이 들어있을 줄 알았으나 함수형의 대한 설명만 너무 많아 실망한 책
- 시작하기 전에..
- 객체지향의 반복자 패턴과 함수형의 일급 함수의 조합은 명령형 패러다임의 제네레이터와 서로 상호 호환되며 새로운 프로그래밍 방식을 제시한다
- 일급 함수: 함수를 값처럼 다루어 인자로 전달하거나 반환값으로 사용할 수 있는 함수
- 고차 함수: 하나 이상의 함수를 인자로 받거나 반환하는 함수
- 이터레이터(반복자) 패턴: 객체지향의 디자인 패턴 중 하나로 컬렉션의 요소를 순차적으로 접근하는 규약 제시
- 이터러블: 이터레이터를 반환하는 메서드를 가지는 객체
- 제네레이터: 명령형 스타일로 이터레이터를 작성할 수 있게 해주는 문법
- 이터레이터에 대해 next() 함수 호출이 되면 제네레이터 함수 본문이 yield 상태가 되기 전까지 실행된다
- 리스트 프로세싱: 코드를 리스트로 다루는 함수형 문법
- 함수의 조합으로 이터레이터를 효율적으로 다룰 수 있게 해주는 함수형 문법
- 반복자 패턴의 지연성은 지연 평가가 가능한 객체를 생성할 수 있게 해주고, 일급 함수는 고차 함수를 정의 할 수 있게 한다 → 이를 통해 리스트 프로세싱을 효율적으로 구현 가능
- 함수형 프로그래밍
- 메타 프로그래밍: 프로그램이 자기 자신이나 다른 프로그램을 데이터처럼 바라보며 분석, 변형, 생성, 실행하는 프로그래밍 기법 → 코드 조각을 데이터로 생각하여 처리할 수 있음
- 구조 분해 할당은 지연 연산을 통해 필요 시에 연산이 수행될 때 더 강력하다
- 커링: 여러 인자를 받는 함수를 인자 하나 씩 받는 함수들의 연쇄로 표현하는 기법
- 리스트의 필터링, 리듀스 등 데이터를 제거(축소)하는 함수는 지연 연산을 통해 필요한 만큼만 연산이 가능하다
- 패턴
- 변형-누적: map-reduce 를 통해 변형 후 최종 결과를 도출하는 방식
- 중첩-변형: map 내부에서 다시 map을 통해 외부 컬렉션의 각 요소를 처리하면서 내부적으로 다른 변형을 수행하는 경우
- 반복자-효과: map-foreach 를 통해 지연평가를 이용하면서 부수 효과를 발생시키는 패턴
- 필터-중단: filter-take 를 통해 조건에 따라 일부 데이터만 선택하여 소비하는 패턴
- 분할-평탄: chunk-flat 으로 일정 크기로 분할하여 처리한 뒤 다시 결과를 합칠 때 유용
- 해시-매치: indexBy, GroupBy 처럼 데이터를 키로 맵핑하거나 그룹화, 카운팅, 변환 작업에 활용
- 비동기 프로그래밍
- 비동기 프로그래밍에서 중요한 것은 에러를 핸들링하는 것이 아닌 에러가 제대로 발생되도록 설계하는것
- 에러를 내부에서 처리하지 않고 호출자에게 위임함으로써 코드의 책임을 명확히 하고 다양한 상황에서 적합한 에러 처리 방식을 지원 할 수 있다
- 멀티 패러다임
- 함수형: 고차 함수와 리스트 프로세싱으로 데이터 변환을 우아하게 처리 → 로직 문제 해결에 용이
- 객체 지향형: 복잡한 계층 구조나 상태를 명확하게 표현 → 구조 문제 해결에 용이
- 명령형: 흐름 제어와 직관성을 제공하여 가독성이 높음 → 쉬운 표현을 통해 이해력 향상
- 초기에는 간단한 함수 형태로 문제를 해결한 뒤 기능적 요구 사항이나 복잡성이 늘어날 때 점진적으로 클래스를 도입하고 추상화를 높이는 방식이 실용적
- 현대 언어에서는 콜백 함수를 인자로 주고 받는 것만으로도 객체 지향의 클래스 상속/인터페이스 구현을 통해 하려고 하던 작업을 쉽게 구현할 수 있다
- 쉬운 문제를 함수형이나 객체지향으로 해결하는 것 보다 명령형이 더 가독성 있고 쉽게 변경할 수 있을 때도 있다
- 인터페이스는 규약을 제시하여 다양한 클래스가 동일한 형식의 동작을 구현하도록 유도하기 위함
- 상속은 공통 기능을 직접 구현한 뒤 적절히 확장하는데 초점을 둠
- Unit과 Void는 의미 있는 결과를 반환하지 않는 함수를 표현하기 위한 점은 동일하나 구현 방식이나 정적 분석 수준에서 차이는 존재한다