Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[keyword] 1장 - 함수형 길들이기 #2

Open
leejaeseung opened this issue Jun 5, 2023 · 2 comments
Open

[keyword] 1장 - 함수형 길들이기 #2

leejaeseung opened this issue Jun 5, 2023 · 2 comments
Assignees
Labels
keyword 읽은 내용 중 키워드를 선정하고, 해당 키워드와 관련된 설명을 덧붙여 줍니다. 요약 정리

Comments

@leejaeseung
Copy link
Member

leejaeseung commented Jun 5, 2023

주제

'1장 - 함수형 길들이기'을 읽고 내용을 요약하거나,
중요✨ 하다고 생각하는 키워드 및 관련 설명을 코멘트로 달아주세요

연관 챕터

#1

@leejaeseung leejaeseung added the keyword 읽은 내용 중 키워드를 선정하고, 해당 키워드와 관련된 설명을 덧붙여 줍니다. 요약 정리 label Jun 5, 2023
@leejaeseung leejaeseung self-assigned this Jun 5, 2023
@leejaeseung leejaeseung changed the title [keyword] [keyword] 1장 - 함수형 길들이기 Jun 5, 2023
@leejaeseung
Copy link
Member Author

leejaeseung commented Jun 18, 2023

p.25

순수함수에 기반을 두고 이미 검증된 기법과 관례에 따라 구현하면 코드가 점점 복잡해지더라도 헤아리기 쉬운 방향으로 작성할 수 있습니다.

map, filter, reduce 등등 이미 함수적으로 검증된 로직들을 레고처럼 붙였다 뗐다 하며 코드를 작성하게 된다.

명령형 vs 선언형

vs 를 붙여두고 항상 비교해서 반대의 개념같지만, 명령형 코드로 추상화를 시켜서 사용하는게 선언형 코드라고 보면 좋을 듯 하다.
caffeine-library/Domain-Driven-Design#43

p.32

실제로 함수형 프로그래밍은 모든 상태 변이를 근절하자는 건 아니고, 상태 변이를 줄이고 관리할 수 있는 프레임워크를 제공하여 순수/불순 함수를 구분하자는 겁니다.

모든 코드를 순수함수로 짜는 건 불가능하다. (외부 인프라와의 연결은 부수효과를 어쩔 수 없이 일으키기 때문에)
대신, 최대한 부수효과와 순수함수를 분리하자

참조 투명성 : 참조에 투명하다. 즉, 참조를 해 사용할 때 투명하게 함수 내부를 들여다본 것처럼 예측 가능하게 함수를 사용할 수 있다.

참조 투명성 + 불변성 : 함수형의 필수 조건이라고 할 수 있을듯? 함수의 인자로 넘긴 객체가 불변한 객체가 아니라면 그 함수를 참조 투명하다고 볼 수 있을까?

p.40

함수 합성은 고수준의 추상화를 통해 자세한 내막을 밝히지 않아도 코드가 수행하는 전 단계를 일목요연하게 나타냅니다.

고수준의 추상화 : 선언적 코드

call-by-name :

정말 순수한 함수형 프로그래밍에는 예외가 존재하지 않는다 : 예외조차 리턴 값으로 반환할 수 있다.

리액티브 프로그래밍이란? : 연속적인 데이터를 끊김없이 전파하여 사용자에게 즉각적인 리액션을 취할 수 있게 하는 프로그래밍 패러다임?

@ABizCho
Copy link
Member

ABizCho commented Jun 19, 2023

p.26

함수형 프로그래밍의 목표는 '부수효과(side effect)'를 방지하고 '상태변이(mutation of state)' 감소시키기 위해 데이터의 제어 흐름과 연산을 '추상'하는 것이다.


p.27

함수형 프로그램은 여러 함수를 서로 합성하고 평가해서 더 많은 기능을 탑재하는 것이 유일한 목표이다.

var printMessage = run(addToDom('msg'), h1, echo);

printMessage('Hello World');

해당 예제의 run 함수는 매개변수의 세 함수를 체인처럼 연결하여, 한 함수의 반환값이 다른 함수의 입력값으로 전달되게끔 한다.

위의 run 함수의 세 개의 매개변수는 단순 스칼라 값이 아니라, 각각 인자를 갖는 함수형 매개변수로, 작은 함수들을 재료로 새로운 함수를 만들어 내는 것 이라고 이해할 수 있다. 더 작은 조각들로 프로그램을 나누고, 전체적으로 헤아리기 쉬운 형태의 프로그램으로 재조합 하는 것, 모든 함수형 프로그램은 이 기본원리를 따라 작성된다.

이는 본연의 기능은 그대로 간직한 채 코드를 쉽게 변경하기 위해 코드 자체를 매개변수화 하는 것이다.



함수형 프로그래밍은 선언적 (p.28~30)

함수형 프로그래밍은 선언적 프로그래밍 패러다임이다.

선언적 프로그래밍은 (명령형 프로그램과는 달리), 프로그램의 서술부평가부를 분리하여, 내부 메커니즘은 추상한 상태에서 로직이 무엇인지 표현식으로 서술한다.
(+)

  • 서술부 : 함수의 동작을 서술하는 부분으로, 전역레벨에서는 추상화 된다고 이해하면 될 것 같다.
  • 평가부 : FP의 함수는 평가라는 표현으로 호출에 의한 실행을 표현한다.

일반 루프는 함수로 추상하지 않는 한 재사용 자체가 안된다. 따라서, 함수를 매개변수로 받는 일급 고계함수(map,reduce, filter...)로 대체하여 재사용성과 확장성을 높일 수 있고, 이러한 루프를 함수로 추상하는 결과로 ES6의 람다 표현식과 화살표 함수 를 사용할 수 있다.

( + 람다 표현식은 함수의 인자로 전달 가능한 익명 함수를 대체할 수 있는 깔끔한 대체 수단이다)

왜 수동루프를 제거해야 하는가?

  1. 수동루프는 재사용이 어려우며 다른 연산간의 삽입도 어려운 명령형 제어 구조물이다.
  2. 루프는 성격상 반복 시 값이나 상태가 계속 바뀐다. FP는 무상태성불변성을 지향하므로 순수함수를 사용해야 한다.

-> 여기서 언급된 루프의 상태의 변화에 대해, 고계함수의 경우에도 결국 루프의 동작을 수행하는데 무엇이 다른가? 의문이 있었고, 스터디 중 Jason에게 물어보고 논의해보았다. 루프의 상태가 바뀐다는 것은, 전역레벨에서 추상화되지 않아 외부노출되는 루프의 인덱스 및 루프의 명령부에 임의의 작업이 추가되어 반복 진행 중 인덱스가 예측 불가능하게 변할 수 있는 문제를 표현하는 것 이라고 논의를 가졌고, 고계함수는 루프동작과 로직은 각각 추상화 및 모듈화되어 예기치 못한 상태변화에 의해 결과가 영향을 받지 않는다고 이해할 수 있었다.

순수함수와 부수효과 (p.30~35)

함수형 프로그래밍은 순수함수로 구성된 불변 프로그램의 구축을 전제로 한다.

순수함수의 특성

  1. 주어진 입력에만 의존한다. 숨겨진 값이나 외부 상태와 무관하게 작동한다.
  2. 전역 객체, 원본 매개변수 수정 등 함수 스코프 밖에서 어떤 변화도 일으키지 않는다.

-> 이 요건 위배 시 불순, impure한 함수이며, side effect를 일으킬수 있다.

부수효과 발생 상황

  1. 전역범위 접근 및 수정
  2. 함수의 원래 인자값 변경 ( 객체를 레퍼런스로 넘기고 객체에 수정 및 변이를 발생, (ex.배열 Array.sort 메서드 등) )
  3. 사용자 입력 처리
  4. 예외 시 throw처리에 의한 함수 종료
  5. 출력
  6. HTML 문서, 브라우저 쿠키, DB 등 외부소스 접근, 질의, 수정 (심지어는 Date.Time)

-> 하지만 DB 등 필수적인 외부자원 접근을 제거하는 것은 불가능할 수 있다. 따라서 완벽한 불순한 로직 제거는 불가능할 수 있다.
-> 함수형 프로그래밍의 목표는 불순함수의 최소화 및, 불순함수와 순수함수의 분리이다. 따라서 불가피한 경우 분리시켜 관리하는 것으로 해결할 수 있다. 이 때 커링 을 이용할 수 있다.
(+ 커링이란?, 수학과 컴퓨터 과학에서 커링(currying)이란 다중 인수 (혹은 여러 인수의 튜플)을 갖는 함수를 단일 인수를 갖는 함수들의 함수열로 바꾸는 것을 말한다.)



참조투명성과 치환성, (p35 ~ 37)

참조투명성은 순수함수를 정의하는 더욱 공식적 방법이다.
여기서 순수성이란 **함수의 인수와 결과값 사이 순수한 매핑관계`를 말한다.
따라서, 함수가 동일 입력에 대해 동일 결과를 낼 경우 참조투명한 함수라고 말할 수 있다.

함수가 의존하는 상태, 즉, 외부 자원등을 제거하고 함수 시그니처에 정규 매개변수로 명시하는 방법을 사용하여 순수성을 제고할 수 있다.

참조 투명성은 전적으로 개발자의 숙제로 남는다.

참조투명한 함수는 항상 옳은 결과를 내며 에러가 날 수 없다.
참조투명하다는 것은 결과 예측이 가능하고, 로직 파악이 용이하며, 항상 옳은 결과를 내놓기 때문에 시스템의 상태를 머릿속으로 그려볼 수 있으며(멘털 모델), 코드를 재작성 혹은 치환화더라도 원하는 결과를 예측 및 얻을 수 있으므로 헤아리기 쉽다.

또한, 100% 순수함수의 경우 프로그램의 함수를 수식화 하여 표현할 수 있다. 이런 참조 투명성을 통해, 거의 수학적인 형태로 프로그램을 헤아릴 수 있다.



복잡한 작업 분해 유도 (p.39 ~ 40)

함수형 프로그래밍은 고수준(전역레벨 쯤?)에서 보면 분해와 합성간의 상호작용이며, 모듈적 효율적이다.
이 때, 작업단위(unit)는 바로 함수 자신이다.

FP에서 모듈화는 단일성의 원리와 밀접한 관련이 있다.
함수는 저마다 한가지 목표를 바라봐야 한다.

( + 이에 대해 Jason과 의논해 본 결과, FP의 작업단위 함수 분리는 OOP의 단일책임 원칙과 비슷하다고 보았으며, 사실 OOP와 FP는 서로 배타적인 패러다임이 아니며 FP는 OOP를 어느정도는 품고 있다는 사실을 이해할 수 있었다. 다만, 함수형 프로그램은 더욱 프로그램적인 입장에서 고려하기 때문에, 순수 기능단위로 작업을 분리한다는 것이 조금 다를 수 있다는 것을 인지했다.)

단순 함수를 엮어 붙이기 위해(합성) 반드시 입출력을 맞춰줘야 한다. 이에 따라, f ( g( x ) ) 합성함수의 경우, g의 반환값과
f의 인자의 개수와 형식(타입)을 일치 시켜야 한다. 이를 통해 f와 g는 느슨하고, 형식 안전한 관계가 맺어진다.

함수 합성은 고수준의 추상화를 통해 자세한 구현을 보여주지 않고(black box) 전 단계를 일목요연하게 나타낸다.



데이터를 매끄럽게 체이닝 처리, ( p41 ~ 42)

체인 은 같은 객체를 반환하는 순차적인 함수호출이다.

로대시JS, 람다JS등 함수형JS도구에는 이를 위한 고계함수가 구현되어 있으며, 리액티브JS에서도 활발히 사용된다.

함수 체인은 필요한 시점까지 실행을 미루는 지연 평가(느긋한 평가, Lazy evaluation, 수직적)를 수행한다.

(+ 지연평가Call By Need로 작동하며, 즉시 평가되어 수평적으로 불필요한 값을 처리하지 않고, 수직적으로 개별 item에 대해 모든 체인을 수행하며 나아간다. 이에 따라 불필요한 items까지 로직을 처리하지 않으며, cpu 및 메모리의 절약을 제고할 수 있다. )

복잡한 비동기 앱에서도 신속하게 반응, ( p43 ~ 45 )

외부 소스 조회 등에 사용되는 콜백 패턴은 성공/실패 로직이 중첩된 형태로 흩뿌려져 있기 때문에 코드의 선형 흐름이 깨지며 동작을 파악하기 어렵다. 반면, FP의 응용분야 리액티브 프로그래밍에선 고차원의 코드 추상화, 비동기,이벤트 기반 프로그램처리를 위한 보일러 플레이트를 없애고(추상화하여 재사용), 비즈니스 로직에만 전념할 수 있게 한다.

@ABizCho ABizCho self-assigned this Jul 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
keyword 읽은 내용 중 키워드를 선정하고, 해당 키워드와 관련된 설명을 덧붙여 줍니다. 요약 정리
Projects
None yet
Development

No branches or pull requests

2 participants