핵심 내용 (1p~16p)
1. 부수효과 - 함수를 실행 후 return되는 값 이외에 다른곳에서 일어나는 모든 작용들을 부수효과라고 한다.
2. 함수형 프로그래밍은 액션, 계산 , 데이터로 나뉜다.
액션 : 실행 횟수나, 내부상태를 변경할 때 일어난다 ex)버튼 클릭 같은 것
계산 : 입력값 (데이터를) 가지고 결정하는 것은 계산이다. ex) 이메일을 누구한테 보낼지 결정 하는 것
데이터 : 서버로 전달하는 정적인 값
3. 함수형 사고란?
액션, 계산 , 데이터 나누기
일급추상
핵심내용 (17p~26p)
컷팅 (async await써서 받아올 데이터 다 받아오고 액션 실행)
타임라인다이어그램
핵심내용 (26p~59p)
52p sendIssue함수에서 while함수 사용하여 페이지 네이션 개념으로 이메일을 순차적으로 전송함, 추후 필요할때 사용할 가능성 높음
52p 액션은 호출 시점과 횟수를 기억해라. 호출시점과 횟수에 덜 의존하게 해야 한다.
핵심내용 (59p~87p)
65p에 DOM(view) 업데이트와 비지니스 규식은 분리되어야한다, 전역변수가 없어야한다. (전역벽수를 없앤다는 것은 암묵적 출력, 입력을 없애준다는 것이다. 전역변수를 없애는 방법은 지역변수를 사용하여 리턴해주는 방식으로 사용한다. 그리고 암묵적 입력으로 사용되던 전역 변수를 파라미터로 입력 받으면 된다.)
68p 암묵적 입력과 암묵적 출력을 없애주면 계산이된다.
69p 입력은 인자로, 출력은 return으로 처리한다. 암묵적 입력과 암묵적 출력은 부수효과이다.
69p return으로 출력되지 않는 값은 암묵적 출력이다.
70p 서브루틴 추출하기는 길게 늘여뜨려 작성한 액션 함수를 중간중간 각각을 모듈화 하는 것이다.
핵심내용 (87p~109p)
- 88p 비지니스 요구사항에 맞는 함수인지 생각해라. 예를 들어 장바구니 물품의 총가격이 20이상이면 다음 아이템을 무료 배송인지 확인 하는 함수이다. 이때 이 함수 인자로 item, total을 받아서 20이상인지 확인 하는 함수는 요구사항에 맞지 않다. 장바구니 리스트를 인자로 넘기고 장바구니 리스트의 총 합계를 계산하는 함수에 장바구니 리스트를 인자로 넘기는 형태로 구한다. (잘 생각해보자)
핵심내용 (109p~148p)
p118 카피온 라이트 만들기 방법 with splice() (장바구니 삭제 예시)
p129 연습문제를 보면 함수에 함수를 리턴한다. 리턴되는 함수는 함수 내부에 명령형으로 작성된 코드를 선언형 코드로 바꾼 것이다. (css가 선언형 코드이다.) 즉, 명령형 코드 = how to make 를 코드로 쭉 명령하는 것이고, 선언형 코드는 바로 return 결과 이다.
p132 변경 가능한 데이터를 변경 불가능한 불변 데이터로 바꾸는 법을 알았다고 한다. 이 의미는 함수에 전달한 데이터를 copy한 후 파싱 후 리턴 했기 때문에 원본 데이터는 불변데이터가 된 것이라고 이해했다.
p133 불변데이터로 하면 계속 배열 복사한다고 느린거아니냐고 하는 사람들 있으면 얘기할 자료
p134 얕은 복사와 깊은복사의 차이를 명확히해놓자.
p140 매우 중요한 개념이다. 불변데이터란 중첩된 모든 데이터구조가 변경되지 않아야 불변데이터가된다. 객체를 가지고 있는 배열의 경우 [...array]로 copy하더라도 그안에 객체들은 메모리 주소만 참조 하고있다. 때문에 카피한 객체를 변경하더라고 원본 데이터가 같이 변한다. 이걸 방지하기위해 책에서는 객체배열을 변경할때 배열을 복사 후 for문에서 다시 객체를 복사하여 리턴하는 방식을 사용했다. 내가 회사업무 지원서 생성 폼에서 사용한 map메서드에서 return을 {...obj}로 한것과 같은 방법이다.
p141 얕은 복사를 정리하면 4가지 용어와 한줄로 정리할 수 있다. 중첩된 데이터 구조에서 얕은복사를 하면 최상위 데이터만 복사가 되고 안쪽데이터는 구조적으로 공유된다.
중첩 데이터 구조
최상위 데이터
안쪽 데이터
구조적 공유
핵심내용 (148p~168p)
- p149 방어적 복사 (왜 방어적 복사가 필요한가?)
카피온 라이트 패턴 : 데이터를 바꾸기전에 복사 후 복사한 데이터를 바꾼다. 즉 어떤 데이터가 바뀔지 미리 알고있다.
알수없는 함수를 쓸경우 : 뭔일이 일어날지 예측 불가. 그 이유는 3번 보자.
방어적 복사를 쓰는 이유를 순차적으로 설명해보겠다. 변경 되는 데이터(전역변수)-> 알수없는 함수에 진입 -> 알수없는 함수가 데이터의 참조를 가진다 -> 안전지대 진입(전역변수) -> 알수없는 곳에 참조가 걸려있으니까 뭔일이 일어날지 모름, 그리고 이미 알수없는 함수에 들어갔을 때 데이터는 망가졌다.
해결법 알수없는 함수에 사용할 데이터를 deepCopy -> deepCopy한 데이터를 알수없는 함수에 입력 -> 이제 deepCopy 데이터가 알수없는 함수에서 파싱되어서 변했을 거니까 이걸 다시 deepCopy 진행 -> 전역변수에 할당
p156 webAPI는 이미 방어적 복사를 하고있다. web과 데이터를 주고받기위해서는 json.stringify로 직렬화를 해서 보내야한다.(우리 api manager를 보면 fetch의 body에 stringify해서 보내고있다.) 이렇게 직렬화 json.stringify가 되면은 deepCopy가 된다. 그리고 전달 받는 json 역시 deepCopy된 데이터이다. 어떻게 알지? 응답값을 받아서 쓸때 json.stringify로 직렬화된 데이터를 data.json()으로 바꿔서 쓰고 있으니까! 이렇게 방어적 복사를 하는 것을 비공유 아키텍처라고한다. 서로 어떤 데이터도 참조하고있지 않는 것이다. 마이크로 서비스나 서비스 지향 시스템에서 방어적 복사를 쓰는데 이것이 바로 방어적 복사의 장점이다.
p160 깊은 복사를 위해서 lodash를 사용해라, deepCopy구현 예시 참고
핵심내용 (168p~201p) 계층형 설계 적용법 (직접구현)
p168 소프트웨어 설계란 코드를 만들고 테스트하고 유지보수하기 쉽게하기위해 미적감각을 사용하는 것이다. 여기서 미적감각을 키우기 위해 계층형 설계를 사용해보자.
p170 계층형 설계 감각을 키우기 위한 입력과 출력 (키워드같음)
p171 계층혈 설계 패턴 4가지
- 직접구현 : 약간 서브루틴 추출하기랑 비슷하다. 하나의 함수안에서 다른 추상화계층들의 [다른 추상화계층 : 언어에서 제공하는 기능과 내가 만든 함수] 추상화 계층을 맞출 때 사용한다. 이렇게 직접구현으로 추상화계층을 맞춰주면 실행되는 하나의 함수가 들어오는 인자가 무엇인지 신경쓸 필요가 없게된다. 그리고 직접구현 패턴을 이용하면 호출그래프(다이어그램)을 그렸을 때 같은 추상화계층에 있는 함수들은 아래로 같은 화살표 길이를 갖는다. 직접구현을 정리하자면 직접구현(서브루틴추출)은 추상화단계를 맞추면서 각 함수의 화살표 길이를 줄이는것 같다. 추상화단계를 맞추어놓으면 비슷하게 사용되는 부분들이 보이는데 이러한 부분들도 새로운 함수를 만들어 추상화단계를 만들고, 인덱스에 직접 접근하는 부분[ex)cart[i]] 등도 함수로 뺴서 새로운 추상화 단계로 바꾼다.
p175 호출 그래프(다이어그램) 그리는법
p191~201p 보고 직접구현으로 호출그래프 화살표 길이 줄이는거 다시보기
핵심내용 (201p~213p) 계층형 설계 적용법 (추상화벽)
- 추상화벽 : 입력되는 데이터 구조를 신경쓰지 않아도 되고 추상화벽 위아래 코드들의 의존성을 없애준다.
204p(209p) 추상화벽은 데이터 구조를 몰라도 함수를 사용할 수 있다. 간단하게 추상화벽은 공통모듈이고 이거를 여기저기서 갖다가 쓸 수 있게 만들어놓은 것이다.
206p 객체를 해시맵 처럼 쓰는것이 추가,삭제,검색에서 모두 빠르다.
210p 추상화벽을 이용하면 추상화벽 위에있는 코드와 아래에있는 코드의 의존성을 없앨 수 있습니다.
핵심내용 (213p~220p) 계층형 설계 적용법 (작은 인터페이스)
- 작은 인터페이스 : 새로운 코드를 추가할 위치에 관한 것이다.
p215 예를 들어 다른팀도 사용해야 할 새로운 기능을 추가해야 할 경우 [추상화벽]과 [추상화벽 위] 2곳에 위치시킬 수 있다. 먼저 추상화벽에 새로운 기능을 추가할 경우 언어의 내장기능(for문)등을 활용하여 원하는 기능을 추가시킬 수 있다. 이렇게 작성해도 추상화벽은 잘 유지되지만 추상화벽의 장점을 약화시킨다. 그이유는 a. 다른팀에서 for문과 같은 구체적인 구현에 신경써야 한다. b. 다른팀에서 코드를 변경하고 싶을때 서로 커뮤니케이션 해야한다. c. 추상화벽에 이미 구현된 함수들을 사용할 수 없다. d. 추상화 벽은 서로다른 팀간에 계약이라고 생각해야한다. 추상화벽에 기능이 늘어날 수록 코드를 이해하고 용어를 맞추는데 비용이 많이든다. 추상화벽 위에 기능을 구현할 경우 이러한 단점들을 막을 수 있다.
P218 로그같은 함수는 추상화벽 위에 위치해야한다. 로그를 남기는 행동은 액션 이기 때문에 계산함수에 들어가면 안된다.
핵심내용 (220p~232p) 계층형 설계 적용법 (편리한 계층)
- 편리한 계층 : 호출그래프를 이용해서 비기능적 기능인 재사용성, 유지보수성, 테스트성을 잘 할 수 있게 해보자.
p227 테스트는 직접구현을 많이한 가장 낮은 계층에서 해야 테스트에서 얻은것이 오래간다.
p229 호출 그래프에서 연결된 부분이 적을 수록 변경이 쉽기 때문에 [유지보수성]이 좋다. [테스트 성]은 연결된 부분이 많은 함수를 테스트해야 코드의 영향력을 확인할 수 있다. [재사용성]은 제일 하위계층에 있을수록 재사용성이 좋다.
핵심내용 (232p~268p) 일급 함수
p238 함수이름에 있는 암묵적 인자를 드러내야한다 일급(first-class-value) = 값으로써 배열이나 변수에 담을 수 있다. 그리고 함수의 인자로도 줄 수 있다. 일급이 값이라면 여기서 알수있는 또 하나! 일급 함수는 함수의 인자로써의 함수다.
p240 일급이 아닌 것을 일급으로 바꾸기가 중요하다!
p247 데이터 지향: 이벤트와 엔티티에 대한 사실을 표현하기 위해 일반적인 데이터 구조(배열,객체)를 사용하는 것
p249 정적타입, 동적타입 언어가 뭐가 더 좋은지 고민하지말고 그냥 쓰고 잠이나 더자는게 더 좋다~~ 서로 장단점이 있기 때문에 논쟁이 무의미~
p252에 일급함수와 고차함수에 대해 설명하고있다. 일급함수는 값(인자)으로 전달되는 함수다. 즉 어떠한 함수에 인자로 전달되는 함수이다. 고차함수는 함수를 인자를 전달 받는 함수이다. 일급함수가 없다면 고차함수도 없다.
p254~255 이름에 있는 암묵적인자를 제거해가는게 핵심이다!
p260 자바스립트에서는 인자로 전달하는 함수를 콜백함수, 다른언어는 핸들러 함수라고도 부른다. 이 함수들은 다시말해 일급함수다. 인자를 전달받는 함수는 고차함수이겠죠? . 사실 인자로 전달되는 함수의 이름이 크게 중요하지않다 그냥 이렇게 부르고있다는 것만 알면된다.
p262~265 로깅 함수만드는 아주 중요한 부분, 그리고 왜 콜백으로 감싸서 전달하는지도 나옴. 일단 이유는 코드가 바로 실행되면 안되기때문에 콜백으로 감싸야한다. 콜백으로 감싸면 코드를 용기에 보관 하는 개념이라고 이해하면 된다. 실행을 미루는 가장 일반적인 방법이고 오로지 실행을 시켜야 동작한다.
핵심내용 (268p~289p) 일급 함수 II
p282~p283 내용이 이해가 안감. but 286쪽을 보면 이해되리라~ 함수에 return으로 실행되는 함수를 리턴하는건지 화살표함수를 리턴하는 건지에 따라 다르네~~
핵심내용 (289p~317p) 함수형 반복 (map, filter, reduce 만드는법 다시보기)
p257 forEach
p295 map 함수 만드는 방법
P301 filter 함수 만드는 방법
p308 reduce 함수 만드는 방법
p313 reduce로 만들 수 있는 기능
핵심내용 (317p~354p) 함수형 도구 체이닝 (여기는 다시볼때 한번 보자)
p331 배열을 새롭게 만들어도 GC가 매우 빠르게 처리한다. 병목 현상을 없애기 위해서 스트림 결합을 사용하는데 읽기가 어렵다. 참고하자
p333~p345 팁 어떻게 만드는건지 모르겠음
p346 reduce를 사용하여 로그를 이용해 장바구니 다시만들기! (이벤트 소싱 찾아보기)
p346~p354까지도 그냥 그렇구나 끝
핵심내용 (355p~) 중첩된 데이터에 함수형 도구 사용하기
- p358 앞부분 본문 뒷부분을 가지고있는 함수에서 앞 뒷부분을 함수로 만들고 본문을 콜백으로 받아서 사용하는 법