Skip to main
Functional Programming
In JavaScript
Chapter 1 ~ 2시작하기전에…
이 자료는 디컴퍼니의 멤버들이 스터디 활동으로 “Functional Programming In JavaScript” 도서를 공부하는 데 사용하기 위한 목적으로 작성했습니다.
이 슬라이드의 내용은 여러분이 책을 읽기 전에 1, 2 chapter의 대략적인 내용을 15분 내외로 빠르게 파악함으로써 좀 더 쉽게 책 내용을 소화할 수 있도록 도와주는 것을 목표로 합니다.Chapter 1. 함수형 길들이기
● 함수형 사고방식
● 함수형 프로그래밍의 정의 ● 불변성, 순수함수 원리
● 함수형 프로그래밍 기법 및 그것이 설계 전반에 미치는 영향Chapter 1. 함수형 길들이기
● 함수형 사고방식
● 함수형 프로그래밍의 정의 ● 불변성, 순수함수 원리
● 함수형 프로그래밍 기법 및 그것이 설계 전반에 미치는 영향내 자바스크립트 프로그램이...
● 추가 기능을 지원하기 위해 계속 코드를 리펙터링해야 하는가? ● 파일 하나를 고치면 다른 파일도 영향을 받는가? ● 중복이 많은가?
● 함수를 단위 테스트하기 어려운가?
● 체계도 없고 따라가기 어려운 코드인가?나의 목표는...
● 개발 실력을 끌어올리기 ● 코드 품질 높이기
● 이미 너무 복잡해진 코드베이스를 잘 다루기
● 자바스크립트로 저장소와 통신하고 비동기 프로세스를 생성하고 이벤트를 처리하고….나의 목표는...
● 개발 실력을 끌어올리기
● 코드 품질 높이기     즐기면서 프로그래밍하기!
● 이미 너무 복잡해진 코드베이스를 잘 다루기
● 자바스크립트로 저장소와 통신하고 비동기 프로세스를 생성하고 이벤트를 처리하고….Chapter 1. 함수형 길들이기
● 함수형 사고방식
● 함수형 프로그래밍의 정의 ● 불변성, 순수함수 원리
● 함수형 프로그래밍 기법 및 그것이 설계 전반에 미치는 영향함수형 프로그래밍이란?
애플리케이션의 부수효과(side effect)를 방지하고 상태변이(mutation of state)를 
감소하기 위해 데이터의 제어 흐름과 연산을 추상(abstract)하는 것이라고 할 수 있습니다.함수형 프로그래밍 맛보기
   const printToConsole = str => {
       console.log(str);
       return str;
   };
   const toUpperCase = str => str.toUpperCase();
   const echo = R.identity;
   const printMessage = R.compose(printToConsole, toUpperCase, echo);
   assert.equal(printMessage('Hello World'), 'HELLO WORLD');
   function printMessage(elementId, format, message) {
       document.querySelector('#${elementId}').innerHTML = '<${format}>${message}</${format}>';
   }
   printMessage('msg', 'h1', 'Hello World');
   document.querySelector('#msg').innerHTML = '<h1>Hello World</h1>'; 
printMessage 함수를 분리해서 재사용성 개선하기
더 작은 조각으로 나누고 전체적으로 헤아리기 쉬운 형태로 선언적으로 다시 조합하기선언적 패러다임
프로그램의 서술(description)과 평가(evaluation)를 분리하여, 제어 흐름이나 상태 변화를 
특정하지 않고도 프로그램 로직이 무엇인지를 표현식(expression)으로 나타냅니다. 
* 선언적 프로그래밍 예 : 
var sq = [0, 1, 2, 3].map(num => Math.pow(num, 2)); //-> [0, 1, 4, 9]Chapter 1. 함수형 길들이기
● 함수형 사고방식
● 함수형 프로그래밍의 정의
● 불변성, 순수함수 원리
● 함수형 프로그래밍 기법 및 그것이 설계 전반에 미치는 영향순수함수
주어진 입력에만 의존하고 외부 상태와 무관하게 작동하며, 함수 범위 밖에서 어떤 
변경도 일으키지 않는 함수를 순수함수라고 부릅니다.부수효과 (Side effects)
요즘 같이 복잡하게 발전한 프로그램에서 상태변이가 없을 수는 없습니다. 다만, 
상태변이를 줄이고 가시적인 부수효과로 관리해야 합니다.
* 부수효과(side effect)의 예
- 전역 범위에서 변수, 속성, 자료구조 
변경
- 함수의 원래 인수 값을 변경
- 사용자 입력을 처리
- 예외가 발생하면 붙잡지 않고 던짐
- 화면 또는 로그파일에 출력
- HTML 문서, 브라우저 쿠키, DB에 질의
Functional Programming in Scala (2015) (https://apprize.info/programming/scala_2/3.html)좀 더 현실적인 예시
 function showStudent(ssn) {
     let student = db.find(ssn);
     if(student !== null) {
         let studentInfo = ‘${student.ssn},${student.firstname},${student.lastname}’;
         console.log(studentInfo);
         return studentInfo;
     }
     else {
         throw new Error('학생을 찾을 수 없습니다!');
     }
 }
 assert.equal(showStudent('444-44-4444'), '444-44-4444,Alonzo,Church');
  const find = curry((db, id) => {
      let obj = db.find(id);
      if(obj === null) {
          throw new Error('객체를 찾을 수 없습니다!');
      }
      return obj;
  });
  const csv = student => `${student.ssn},${student.firstname},${student.lastname}`;
  const append = curry((source, info) => {
      source(info);
      return info;
  });
  const showStudent = run(
      append(console.log),
      csv,
      find(db)
  );
  assert.equal(showStudent('444-44-4444'), '444-44-4444,Alonzo,Church');
1. 외부 변수 db를 통해 데이터에 접근
2. 학생을 찾지 못해서 예외를 던지면 
전체 프로그램이 종료됨.
1. 재사용 가능한 단위로 나뉨
2. 관리할 코드의 크기가 줄어듬
3. 선언적 처리 단계로 가독성 향상
4. 순수하지 않은 로직을 
순수함수에서 분리함
showStudent  프로그램을 분해하여 개선참조 투명성과 치환성
   const find = curry((db, id) => {
       let obj = db.find(id);
       if(obj === null) {
           throw new Error('객체를 찾을 수 없습니다!');
       }
       return obj;
   });
   const csv = student => `${student.ssn}, ${student.firstname}, ${student.lastname}`;
   const append = curry((source, info) => {
       source(info);
       return info;
   });
   const showStudent = run(
       append(console.log),
       csv,
       find(db)
   );
   assert.equal(showStudent('444-44-4444'), '444-44-4444, Alonzo, Church');
find 함수에서 개체를 찾지 못하면 
예외를 내는 분기를 통해서 함수가 
일관된 반환값을 보장하도록 해서 
전체 함수의 결과를 예측 
가능하도록 유도
어떤 함수가 동일한 입력을 받았을 때 
동일한 결과를 내면 이를 참조 투명한 
함수라 합니다.
이런 식으로 구축한 프로그램은 외부 
상태의 영향을 받지 않으므로 입력 
값을 변경해서 코드를 재작성하거나 
치환하기 쉬운 특성을 가집니다.불변 데이터 유지하기
자바스크립트에서 기본형(primitive type)은 처음부터 불변입니다. 그러나 배열 등의 
객체는 불변이 아니어서 함수 인수로 전달해도 원래 내용이 변경되는 부수효과가 
발생할 수 있습니다. 
// mutable
var list = [0, 1, 2, 3];
list.add(10);
print(list); // => [0, 1, 2, 3, 10]
// immutable
const immutableList = [0, 1, 2, 3];
immutableList.add(10); // error!!!
immutableList.plus(10);
print(immutableList); // => [0, 1, 2, 3]
print(immutableList.plus(10)); // => [0, 1, 2, 3, 10]Chapter 1. 함수형 길들이기
● 함수형 사고방식
● 함수형 프로그래밍의 정의와 필요성
● 불변성, 순수함수 원리
● 함수형 프로그래밍 기법 및 그것이 설계 전반에 미치는 영향애플리케이션을 분해하기
프로그램을 작은 조각들로 쪼갭니다. 필요하면 더 단순한 pure function으로 쪼갭니다.
showStudent
find
csv
append
Pure function #1
...
...쪼개진 조각을 합성하기
이렇게 쪼개진 작은 조각들을 합성(compose)으로 다시 합칩니다. 
출처 : 합성함수의 정의와 성질 
(https://j1w2k3.tistory.com/495)
참고자료. 수학에서 말하는 합성체인으로 연결하기
같은 객체를 반환하는 순차적인 함수의 호출을 체인이라고 합니다. 코드를 
간결명료하게 작성하기 위해서 합성과 함께 많이 사용되는 방법 중 한 가지입니다.
_.chain(enrollment)
  .filter(student => student.enrolled > 1)
  .pluck('grade')
  .average()
  .value();앞으로 학습할 중요한 원칙들
● 예측가능 : 순수, 선언적
● 안전 : 불변성
● 투명 : 일급 객체
● 모듈화 : 합성, 클로저한 가지 더 : 리액티브 프로그래밍과의 궁합
함수형 사고를 통해서 ‘우리가 수행하는 연산이 불변’이고, ‘비즈니스 로직을 개별 
함수로 쪼개는’ 노력을 지속하다 보면, 결국은 리액티브 프로그래밍과 혼용하게 되며, 
이는 지금까지의 프로그래밍 관련 난제들을 새로운 방식으로 접근하게 하는 패러다임 
전환을 가져올 것입니다.Chapter 2. 고계 자바스크립트
● 자바스크립트가 함수형 언어로 적합한 이유
● 자바스크립트는 다중 패러다임 개발이 가능한 언어
● 불변성 및 변경에 대한 정책
● 고계함수와 일급 함수
● 클로저와 스코프 개념
● 클로저의 활용Chapter 2. 고계 자바스크립트
● 자바스크립트가 함수형 언어로 적합한 이유
● 자바스크립트는 다중 패러다임 개발이 가능한 언어
● 불변성 및 변경에 대한 정책
● 고계함수와 일급 함수
● 클로저와 스코프 개념
● 클로저의 활용왜 자바스크립트인가?
다양한 곳에 많이 쓰이니까…
자바스크립트는 모바일 애플리케이션, 웹사이트, 웹 서버, 데스크톱, 임베디드 
애플리케이션, 심지어 DB에 이르기까지 응용분야가 넓은 웹 세상을 대표하는 언어입니다.객체지향 언어로서의 자바스크립트
자바스크립트는 클래스 상속을 지원하지는 않지만, 객체 간의 프로토타입 관계를 
통해서 하위형(subtype) 또는 파생형(derived type)이라 불리는 객체를 형식화합니다. 
ES6부터는 좀 더 나은 가독성을 제공하기 위해서 class나 extends와 같은 키워드를 
지원합니다.함수형 언어로서의 자바스크립트
상태(state)란 어느 한 시점에 찍은 모든 객체에 저장된 데이터의 스냅샷인데, 
자바스크립트 객체는 매우 동적이어서 언제건 속성을 추가, 삭제, 수정할 수 있습니다. 
자바스크립트의 이런 자유도는 프로그래머들에게 제공하는 장점도 많지만, 중대형 
규모의 프로그램에서는 때로 관리하기 어려운 문제를 발생하는 경우가 많습니다.함수형 vs 객체지향
함수형 객체지향형
합성 단위 함수 객체 (클래스)
프로그래밍 스타일 선언적 명령형
데이터와 기능 독립적인 순수함수가 느슨하게 결합 클래스 안에서 메서드와 단단히 결합
상태 관리 객체를 불변값으로 취급 인스턴스 메서드를 통해 객체를 변이시킴
제어 흐름 함수와 재귀 루프와 조건 분기
스레드 안전 동시성 프로그래밍 가능 캡슐화하기 어려움
갭슐화 모든 것이 불변이라 필요 없음 데이터 무결성을 지키기 위해서 필요함Chapter 2. 고계 자바스크립트
● 자바스크립트가 함수형 언어로 적합한 이유
● 자바스크립트는 다중 패러다임 개발이 가능한 언어
● 불변성 및 변경에 대한 정책
● 고계함수와 일급 함수
● 클로저와 스코프 개념
● 클로저의 활용값 객체 패턴
객체의 동등성이 오직 값에 따라 결정되는 객체로서 일단 값 객체를 선언한 이후엔 그 
상태는 절대 변하지 않습니다. 
(문자열, 숫자 외에도 tuple, pair, point, zipCode, coordinate, money, date 같은 형식)
불변성을 구현하기 위해서 메소드에서 사본을 새로 만들어 반환하는 방법을 
사용하기도 합니다.가동부를 깊이 동결하기
Object.freeze() 함수는 숨겨진 메타속성인 writable 속성을 false로 설정하는 방법으로 
객체 상태를 바꾸지 못하도록 동결합니다. 
단, 객체를 동결해도 내부 객체의 속성까지는 동결되지 않는데, 이렇게 최상위 객체만 
동결되는 것을 얕은 동결(shallow freeze)이라고 합니다. 객체를 확실하게 동결하려면 
객체의 중첩구조를 일일이 수작업으로 동결해야 합니다.객체 그래프를 렌즈로 탐색/수정하기
상태를 관리하고 복사하는 방법을 알고 있는 내부 저장소 컴포넌트를 이용하여 상태가 
업데이트되면 매번 새 객체를 만들어 반환하는 방법으로 작동합니다. 
렌즈를 사용하려면 Ramda.js라는 자바스크립트 라이브러리를 사용하면 됩니다. 
렌즈는 최상위 객체뿐만 아니라 중첩된 객체들의 속성까지 지원합니다.Chapter 2. 고계 자바스크립트
● 자바스크립트가 함수형 언어로 적합한 이유
● 자바스크립트는 다중 패러다임 개발이 가능한 언어
● 불변성 및 변경에 대한 정책
● 고계함수와 일급 함수
● 클로저와 스코프 개념
● 클로저의 활용First class (일급 시민)
일급 시민(객체)은... 
1. 변수에 담을 수 있습니다.
2. 인자로 전달할 수 있습니다.
3. 반환 값으로 전달할 수 있습니다.
자바스크립트에서 함수는 일급 객체인 동시에 일급 함수입니다. 런타임에 생성 
가능하며 익명으로도 생성할 수 있습니다.// 기본적인 함수의 정의입니다.
function helloWorld() {
 return "Hello, bleak world";
}
// 자바스크립트에서 함수는 변수에 할당할 수 있습니다.
var helloWorld = function helloWorld() {
 return "Hello, bleak world";
}
// 함수를 익명으로 생성하는 것도 가능합니다.
var helloWorld = function () {
 return "Hello, bleak world";
}
// 자바스크립트에서는 함수도 객체이므로 속성을 지정할 수도 있습니다.
helloWorld.id = 42;
// 함수를 객체 내의 메소드 형식으로 지정할 수 있습니다.
var person = {
 hello: function () {
   return "Hello";
 }
}
// 일반적인 함수와 동일하게 호출할 수 있습니다.
person.hello();
First class function 예시
Learning Functional JavaScript: First-class Functions | packtpub.com (https://www.youtube.com/watch?v=W-LN6_l2o_E)Higher-order function (고계함수)
함수를 인수 또는 반환 값으로 취급하는 함수를 고계(higher-order) 함수라고 합니다. 
다른 모든 함수들은 일차(first order) 함수입니다.// 먼저 동물들의 이름과 종류를 예시로 활용한다.
var animals = [
 { name: 'Fluffykins', species: 'rabbit' },
 { name: 'Caro',       species: 'dog' },
 { name: 'Hamilton',   species: 'dog' },
 { name: 'Harold',     species: 'fish' },
 { name: 'Ursula',     species: 'cat' },
 { name: 'Jimmy',      species: 'fish' }
]
// 익숙한 절차적 프로그래밍으로 강아지를 걸러내보면...
var dogs = [];
for (var i=0; i<animals.length; i++) {
 if (animals[i].species === 'dog')
   dogs.push(animals[i]);
}
// 합성을 활용하는 방법으로 바꿔보면... 
var dogs = animals.filter(function(animal) {
 return animal.species === 'dog';
});
// 좀 더 작은 조각으로 나누어 여러 가지로 활용해보자...  
var isDog = function (animal) {
 return animal.species === 'dog';
}
var dogs = animals.filter(isDog);
var otherAnimals = animals.reject(isDog);
Higher-order function 예시
Higher-order functions - Part 1 of Functional Programming in JavaScript (https://www.youtube.com/watch?v=BMUiFMZr7vk)클로저와 스코프
클로저(closure)는 함수를 선언할 당시의 환경에 함수를 묶어둔 자료구조입니다. 함수 
선언부의 물리적 위치에 의존하므로 정적(static) 스코프 혹은 어휘(lexical) 
스코프라고도 합니다.// 최초 호출 시간을 기록하고 결과로 함수를 반환하는 함수
function stopWatch() {
 var startTime = Date.now();
 // 최초 호출 이후로 경과한 시간을 표시하는 내부 함수
 function getDelay() {
   var elapsedTime = Date.now() - startTime;
   alert(elapsedTime);
 }
 // 내부 함수인 getDelay 함수를 반환
 return getDelay;
}
// stopWatch() 함수를 호출하고 결과로 반환된 함수를 변수에 할당
var timer = stopWatch();
// 시간이 소요되는 작업
for (var i=0; i<1000000; i++) { Math.random() * 10000; }
// stopWatch()의 결과로 반환된 함수를 호출하기
timer();
timer
stopWatch
getDelay
startTime This is a closure!
Understanding closures (in under 10 minutes!) (https://www.youtube.com/watch?v=rBBwrBRoOOY)
클로저와 스코프 예시전역 스코프의 문제점
함수형 프로그래밍에서는 관찰 가능한 어떤 변화도 함수에서 전파되는 것을 
금기시하는데, 전역 스코프에서는 한줄 한줄이 그런 변화를 일으키는 원인이 될 수 
있으므로, 여하한 경우에도 전역 변수는 삼가야 합니다.이름 찾기 순서
자바스크립트 런타임은 변수를 감싼 가장 가까운 스코프에서 시작해 바깥 스코프 
방향으로 찾습니다.호이스팅
자바스크립트 엔진에서는 코드를 실행할 때 컴파일 과정에서 변수와 함수의 선언부를 
현재 스코프의 최상단으로 끌어올리는 기능이 있는데 이를 호이스팅이라고 합니다. 
옮기는 순서는 함수 선언문 > 변수 선언문 순서입니다. 결과적으로 [변수 선언부 > 함수 
선언부 > 각종 조건문, 분기문 등]의 실행 코드들 순으로 실행됩니다. 
참고 : 자바스크립트 호이스팅(hoisting) 개념 (https://blog.naver.com/sinjoker/221507371077)클로저 응용하기
특정 객체를 정의할 때 자신을 감싸고 있는 함수의 지역변수에 접근하는 메소드를 
가지고 있도록 함으로써 프라이빗 변수를 모방할 수 있습니다. 함수의 지역변수 자체는 
노출하지 않는다는 점을 활용하는 방법으로 꽤 그럴싸하게 프라이빗 변수처럼 쓸 수 
있습니다. 
추가로, 클로저를 이용하면 서버 측 비동기 호출을 체이닝을 통해서 중첩되지 않은 
평탄한 코드로 만들거나, forEach 구문을 활용하여 가상의 블록 스코프 변수를 
생성하는 등 자바스크립트만의 독특한 함수 체제를 멋지게 활용할 수 있습니다.Thank you!
Homepage : http://www.decompany.ioAlpha version : https://www.polarishare.com
fullscreen

Functional Programming In JavaScript : Ch1-2

chrislee
Jul 9, 2019
$ FREE00

share공유

이 자료는 디컴퍼니의 멤버들이 스터디 활동으로 “Functional Programming In JavaScript” 도서를 공부하는 데 사용하기 위한 목적으로 작성했습니다. 이 슬라이드의 내용은 여러분이 책을 읽기 전에 1, 2 chapter의 대략적인 내용을 15분 내외로 빠르게 파악함으로써 좀 더 쉽게 책 내용을 소화할 수 있도록 도와주는 것을 목표로 합니다.

linkedin sns icon

Creative Commons License
-1