본문으둜 κ±΄λ„ˆλ›°κΈ°

🌈 Chapter 1: ν•¨μˆ˜ν˜• 길듀이기

  • μ΅œκ·Όμ— μœ ν–‰ν•˜κΈ° μ‹œμž‘ν•œ λ¦¬μ•‘ν‹°λΈŒ ν”„λ‘œκ·Έλž˜λ°μ€ 데이터 흐름(data flow)κ³Ό λ³€κ²½ μ „νŒŒ(propagation of change)에 μ΄ˆμ μ„ λ‘”λ‹€.
  • μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ 비동기 λ˜λŠ” 이벀트 쀑심 μ½”λ“œλ₯Ό λ‹€λ£° λ•Œλ„ 이런 뢀뢄이 μ•„μ£Ό μ€‘μš”ν•˜λ‹€.

πŸ“š ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ κ³Όμ—° μœ μš©ν•œκ°€?​

  • FP 사고방식은 μžλ°”μŠ€ν¬λ¦½νŠΈλ§Œμ˜ 맀우 ν‘œν˜„μ μΈ νŠΉμ„±μ„ 가닀듬어, κΉ”λ”ν•˜λ©΄μ„œ λͺ¨λ“ˆμ μΈ, ν…ŒμŠ€νŠΈν•˜κΈ° μ’‹κ³  κ°„κ²°ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 데 도움이 λœλ‹€.
  • μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό ν•¨μˆ˜ν˜•μœΌλ‘œ μž‘μ„±ν•˜λ©΄ λŒ€λΆ€λΆ„μ˜ λ¬Έμ œκ°€ ν•΄κ²°λœλ‹€. μˆœμˆ˜ν•¨μˆ˜μ— κΈ°λ°˜μ„ 두고 이미 κ²€μ¦λœ 기법과 관둀에 따라 κ΅¬ν˜„ν•˜λ©΄ μ½”λ“œκ°€ 점점 λ³΅μž‘ν•΄μ§€λ”λΌλ„ 헀아리기 μ‰¬μš΄ λ°©ν–₯으둜 μž‘μ„±ν•  수 μžˆλ‹€.

πŸ“š ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ΄λž€?​

  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ΄λž€, ν•œλ§ˆλ””λ‘œ ν•¨μˆ˜ μ‚¬μš©μ„ κ°•μ‘°ν•˜λŠ” μ†Œν”„νŠΈμ›¨μ–΄ 개발 μŠ€νƒ€μΌμ΄λ‹€.
  • λͺ©ν‘œλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λΆ€μˆ˜ 효과(Side Effect)λ₯Ό λ°©μ§€ν•˜κ³  μƒνƒœ 변이(mutation of state) λ₯Ό κ°μ†Œν•˜κΈ° μœ„ν•΄ λ°μ΄ν„°μ˜ μ œμ–΄ 흐름과 연상을 좔상(abstract)ν•˜λŠ” 것이닀.
document.querySelector('#msg').innerHTML = '<h1>Hello World!</h1>';
  • μœ„ μ˜ˆμ œλŠ” λͺ¨λ“  κ±Έ ν•˜λ“œμ½”λ”©ν•œ λ‹¨μˆœν•œ ν”„λ‘œκ·Έλž¨μ΄λΌμ„œ λ©”μ‹œμ§€λ₯Ό λ™μ μœΌλ‘œ ν‘œμ‹œν•  수 μ—†λ‹€.
  • ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄ λ‹¬λΌμ§€λŠ” λΆ€λΆ„λ§Œ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όλ©΄ 같은 μ½”λ“œλ₯Ό λ‹€μ‹œ μ‚¬μš©ν•  수 μžˆλ‹€.
function printMessage(elementId, format, message) {
document.querySelector(`#${elementId}`).innerHTML = `<${format}>${message}</${format}>`;
}
  • λ‚˜μ•„μ§€κΈ΄ ν–ˆμ§€λ§Œ μ™„λ²½νžˆ μž¬μ‚¬μš© κ°€λŠ₯ν•œ μ½”λ“œλŠ” μ•„λ‹ˆλ‹€.
  • λ©”μ‹œμ§€λ₯Ό HTML νŽ˜μ΄μ§€ λŒ€μ‹  νŒŒμΌμ— 써보자.
  • λ§€κ°œλ³€μˆ˜κ°€ λ‹¨μˆœν•œ 슀칼라 값이 μ•„λ‹Œ, νŠΉμ • κΈ°λŠ₯을 ν•¨μˆ˜μ— μΆ”κ°€ν•˜μ—¬ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜λŠ”, λ‹€μ‹œ 말해 ν•¨μˆ˜λ₯Ό λ§€κ°œλ³€μˆ˜ν™”ν•˜λŠ” μ „ν˜€ λ‹€λ₯Έ μ°¨μ›μ˜ 과정을 λ– μ˜¬λ €μ•Ό ν•œλ‹€.
var printMessage = run(addToDom('msg'), h1, echo);

printMessage('Hello World!');
  • μž‘μ€ ν•¨μˆ˜λ“€μ„ 재료둜 μƒˆλ‘œμš΄ ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄λ‚Έλ‹€.
  • μž¬μ‚¬μš©μ„±κ³Ό λ―ΏμŒμ„±(reliability)이 μ’‹κ³  μ΄ν•΄ν•˜κΈ° μ‰¬μš΄, 더 μž‘μ€ μ‘°κ°λ“€λ‘œ ν”„λ‘œκ·Έλž¨μ„ λ‚˜λˆˆ ν›„, μ „μ²΄μ μœΌλ‘œ 더 헀아리기 μ‰¬μš΄ ν˜•νƒœμ˜ ν”„λ‘œκ·Έλž¨μœΌλ‘œ λ‹€μ‹œ μ‘°ν•©ν•˜λŠ” 과정을 λ‚˜νƒ€λ‚Έλ‹€.
  • μž„μ‹œ ν•¨μˆ˜ run μ°Έκ³ 
  • ν•¨μˆ˜ν˜• μ½”λ“œλŠ” 기본적으둜, 마치 μ•Œκ³ λ¦¬μ¦˜μ˜ 초기 쑰건을 μ‘°μ •ν•˜λ“―, λ³Έμ—°μ˜ κΈ°λŠ₯은 κ·ΈλŒ€λ‘œ κ°„μ§ν•œ 채 μ½”λ“œλ₯Ό μ‰½κ²Œ λ³€κ²½ν•˜κΈ° μœ„ν•΄ μ½”λ“œ 자체λ₯Ό λ§€κ°œλ³€μˆ˜ν™”ν•˜λŠ” 것이닀.

🎈 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ 선언적​

  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ 큰 ν‹€μ—μ„œ 선언적(declarative) ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μ— μ†ν•œλ‹€.
  • λ‚΄λΆ€μ μœΌλ‘œ μ½”λ“œλ₯Ό μ–΄λ–»κ²Œ κ΅¬ν˜„ν–ˆλŠ”μ§€, λ°μ΄ν„°λŠ” μ–΄λ–»κ²Œ ν˜λŸ¬κ°€λŠ”μ§€ λ°νžˆμ§€ μ•Šμ€ 채 μ—°μ‚°/μž‘μ—…μ„ ν‘œν˜„ν•˜λŠ” 사상이닀.
  • 아직은 μžλ°”, C#, C++ λ“±μ˜ ꡬ쑰적/객체지ν–₯ μ–Έμ–΄κ°€ μ§€μ›ν•˜λŠ” λͺ…λ Ήν˜• λ˜λŠ” 절차적 λͺ¨λΈμ΄ 더 많이 쓰인닀.
  • λͺ…λ Ήν˜•μœΌλ‘œ μ§  μ½”λ“œ
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for(let i = 0; i < array.length; i++) {
array[i] = Math.pow(array[i], 2);
}
  • λͺ…λ Ήν˜• ν”„λ‘œκ·Έλž˜λ°μ€ μ»΄ν“¨ν„°μ—κ²Œ μ›ν•˜λŠ” μž‘μ—…μ„ μ–΄λ–»κ²Œ ν•˜λŠ”μ§€ μƒμ„Ένžˆ 이λ₯Έλ‹€.
  • 이와 달리 선언적 ν”„λ‘œκ·Έλž˜λ°μ€ ν”„λ‘œκ·Έλž¨μ˜ μ„œμˆ λΆ€μ™€ 평가뢀λ₯Ό λΆ„λ¦¬ν•˜μ—¬, μ œμ–΄ νλ¦„μ΄λ‚˜ μƒνƒœ λ³€ν™”λ₯Ό νŠΉμ •ν•˜μ§€ μ•Šκ³ λ„ ν”„λ‘œκ·Έλž¨ 둜직이 무엇인지λ₯Ό ν‘œν˜„μ‹μœΌλ‘œ λ‚˜νƒ€λ‚Έλ‹€.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(
function(num) {
return Math.pow(num, 2);
}
);
  • 루프λ₯Ό ν•¨μˆ˜λ‘œ μΆ”μƒν•˜λ©΄ ES6λΆ€ν„° μƒˆλ‘œ 선보인 λžŒλ‹€ ν‘œν˜„μ‹(lambda expression) μ΄λ‚˜ ν™”μ‚΄ν‘œ ν•¨μˆ˜(arrow function) λ₯Ό μ“Έ 수 μžˆλ‹€.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((num) => Math.pow(num, 2));
  • 루프λ₯Ό μ œκ±°ν•΄μ•Ό λ˜λŠ” μ΄μœ λŠ” 루프λ₯Ό μž¬μ‚¬μš©ν•˜κΈ°λ„ μ–΄λ ΅κ³  λ‹€λ₯Έ 연산에 λΌμ›Œ 넣기도 μ–΄λ €μš΄ λͺ…λ Ήν˜• μ œμ–΄ ꡬ쑰물이닀.
  • 또 λ£¨ν”„λŠ” 성격상 λ°˜λ³΅ν•  λ•Œλ§ˆλ‹€ κ°’μ΄λ‚˜ μƒνƒœκ°€ 계속 바뀐닀.
  • κ·ΈλŸ¬λ‚˜ ν•¨μˆ˜ν˜• ν”„κ·Έλž¨μ€ λ¬΄μƒνƒœμ„±(statelessness) κ³Ό λΆˆλ³€μ„±(immutability) 을 지ν–₯ν•œλ‹€.
  • λ¬΄μƒνƒœ μ½”λ“œλŠ” μ „μ—­ μƒνƒœλ₯Ό λ°”κΎΈκ±°λ‚˜ ν˜Όμ„ μ„ μΌμœΌν‚¬ κ°€λŠ₯성이 단 1%도 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€.
  • μƒνƒœλ₯Ό 두지 μ•ŠμœΌλ €λ©΄ λΆ€μˆ˜νš¨κ³Όμ™€ μƒνƒœ 변이λ₯Ό μΌμœΌν‚€μ§€ μ•ŠλŠ” μˆœμˆ˜ν•¨μˆ˜(pure function) λ₯Ό 써야 ν•œλ‹€.

🎈 μˆœμˆ˜ν•¨μˆ˜μ™€ λΆ€μˆ˜νš¨κ³Όβ€‹

  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ μˆœμˆ˜ν•¨μˆ˜λ‘œ κ΅¬μ„±λœ λΆˆλ³€ ν”„λ‘œκ·Έλž¨ ꡬ좕을 μ „μ œλ‘œ ν•œλ‹€.
  • μˆœμˆ˜ν•¨μˆ˜ νŠΉμ„±
    1. 주어진 μž…λ ₯μ—λ§Œ μ˜μ‘΄ν•  뿐, 평가 도쀑 λ˜λŠ” 호좜 κ°„ 변경될 수 μžˆλŠ” μˆ¨κ²¨μ§„ κ°’μ΄λ‚˜ μ™ΈλΆ€ μƒνƒœμ™€ λ¬΄κ΄€ν•˜κ²Œ μž‘λ™ν•œλ‹€.
    2. μ „μ—­ κ°μ²΄λ‚˜ 레퍼런슀둜 μ „λ‹¬λœ λ§€κ°œλ³€μˆ˜λ₯Ό μˆ˜μ •ν•˜λŠ” λ“± ν•¨μˆ˜ μŠ€μ½”ν”„ λ°–μ—μ„œ μ–΄λ–€ν•œ 변경도 μΌμœΌν‚€μ§€ μ•ŠλŠ”λ‹€.
var counter = 0;
function increment() {
return ++counter;
}
  • μžμ‹ μ˜ μŠ€μ½”ν”„μ— μ—†λŠ” μ™ΈλΆ€ λ³€μˆ˜ counterλ₯Ό 읽고 μˆ˜μ •ν•˜λ―€λ‘œ λΆˆμˆœν•˜λ‹€.
  • μ™ΈλΆ€ μžμ›μ„ μƒλŒ€λ‘œ 데이터λ₯Ό 읽고 μ“°λŠ” ν•¨μˆ˜λŠ” λΆ€μˆ˜νš¨κ³Όλ₯Ό λ™λ°˜ν•œλ‹€.
  • μ—¬κΈ°μ„œ counterλŠ” μ•”μ‹œμ  μ „μ—­ λ³€μˆ˜λ₯Ό 톡해 μ ‘κ·Όν•˜λŠ”λ°, this ν‚€μ›Œλ“œλ₯Ό 거쳐 μΈμŠ€ν„΄μŠ€ 데이터에 μ ‘κ·Όν•˜λŠ” 것 μ—­μ‹œ λΆ€μˆ˜νš¨κ³Όκ°€ μœ λ°œλœλ‹€.
  • λ‹€μŒμ€ λΆ€μˆ˜νš¨κ³Όκ°€ λ°œμƒν•˜λŠ” 상황이닀.
    1. μ „μ—­ λ³€μˆ˜μ—μ„œ λ³€μˆ˜, 속성, 자료ꡬ쑰λ₯Ό λ³€κ²½
    2. ν•¨μˆ˜μ˜ μ›λž˜ 인수 값을 λ³€κ²½
    3. μ‚¬μš©μž μž…λ ₯을 처리
    4. μ˜ˆμ™Έλ₯Ό μΌμœΌν‚¨ ν•΄λ‹Ή ν•¨μˆ˜κ°€ λΆ™μž‘μ§€ μ•Šκ³ (catch) κ·ΈλŒ€λ‘œ μ˜ˆμ™Έλ₯Ό 던짐(throw)
    5. ν™”λ©΄ λ˜λŠ” 둜그 νŒŒμΌμ— 좜λ ₯
    6. HTML λ¬Έμ„œ, λΈŒλΌμš°μ € μΏ ν‚€, DB에 질의
  • 이렇듯 무쑰건 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ λͺ¨λ“  μƒνƒœ 변이λ₯Ό κ·Όμ ˆν•˜μžλŠ” 건 μ•„λ‹ˆκ³ , μƒνƒœ 변이λ₯Ό 쀄이고 관리할 수 μžˆλŠ” ν”„λ ˆμž„μ›Œν¬λ₯Ό μ œκ³΅ν•˜μ—¬ 순수/뢈순 ν•¨μˆ˜λ₯Ό κ΅¬λΆ„ν•˜μžλŠ” 것이닀.
  • λ‹€μŒ μ˜ˆμ œλŠ” SSN으둜 학생 λ ˆμ½”λ“œλ₯Ό κ²€μƒ‰ν•˜μ—¬ λΈŒλΌμš°μ €μ— ν‘œμ‹œν•˜λŠ” λͺ…λ Ήν˜• ν”„λ‘œκ·Έλž¨μ΄λ‹€.
function showStudent(ssn) {
let student = db.find(ssn); // db 쑰회
if(student !== null) {
document.querySelector(`#${elementId}`).innerHTML = `
${student.ssn},
${student.firstname},
${student.lastname}
`;
}
else {
throw new Error('학생을 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
}
}

showStudent('444-44-4444');
  • 이 ν•¨μˆ˜λŠ” ν™•μ‹€νžˆ μžμ‹ μ˜ μŠ€μ½”ν”„λ₯Ό λ²—μ–΄λ‚˜ λͺ‡ 가지 λΆ€μˆ˜νš¨κ³Όλ₯Ό 파μž₯을 μΌμœΌν‚¨λ‹€.
    • λ³€μˆ˜ dbλ₯Ό 톡해 데이터에 μ ‘κ·Όν•˜λŠ”λ°, ν•¨μˆ˜ μ„œλͺ…μ—λŠ” 이런 λ§€κ°œλ³€μˆ˜κ°€ μ—†κΈ° λ•Œλ¬Έμ— μ™ΈλΆ€ λ³€μˆ˜μ΄λ‹€.
    • elementIdλŠ” κ·Έ 값이 μ–Έμ œλΌλ„ κ·Έ 값이 μ–Έμ œλ“ μ§€ λ°”λ€” 수 μžˆλŠ” μ „μ—­ λ²ˆμˆ˜λ‹€.
    • HTML μš”μ†Œλ₯Ό 직접 고치기 λ•Œλ¬Έμ— κ·Έ 자체둜 가변적인, μ „μ—­ 곡유 μžμ›μ΄λ‹€.
    • 학생 λ ˆμ½”λ“œλ₯Ό 찾지 λͺ»ν•΄ μ˜ˆμ™Έλ₯Ό λ˜μ§€λ©΄ 전체 ν”„λ‘œκ·Έλž¨μ˜ μŠ€νƒμ΄ 툭 ν’€λ¦¬λ©΄μ„œ μ’…λ£Œλ  것이닀.
  • κ·Έλ ‡κΈ° λ•Œλ¬Έμ— ν•¨μˆ˜ν˜•μœΌλ‘œ κ΅¬ν˜„λΆ€λ₯Ό κ°œμ„ ν•  수 μžˆλ‹€.
    • κΈ΄ ν•¨μˆ˜λ₯Ό ν•˜λ‚˜μ˜ λͺ©μ μ„ 가진 짧은 ν•¨μˆ˜λ‘œ 각각 λΆ„λ¦¬ν•œλ‹€.
    • ν•¨μˆ˜κ°€ ν•΄μ•Ό ν•  μž‘μ—…μ— ν•„μš”ν•œ 인수λ₯Ό λͺ¨λ‘ λͺ…μ‹œν•˜μ—¬ λΆ€μˆ˜νš¨κ³Ό 개수λ₯Ό 쀄인닀.
  • 컀링을 μ‚¬μš©ν•˜μ—¬ 단항 ν•¨μˆ˜(unary function) 둜 λ‚˜λˆˆλ‹€.
var find = curry((db, id) => {
let obj = db.find(id);
if(obj === null) {
throw new Error('객체λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
}
return obj;
});

var csv = student =>
`${student.ssn}, ${student.firstname}, ${student.lastname}`;

var append = curry((selector, info) => {
document.querySelector(selector).innerHTML = info;
});
  • λΆ€μˆ˜νš¨κ³Όλ₯Ό μ€„μž„μœΌλ‘œμ¨ μ™ΈλΆ€ 쑰건 변화에 덜 μ·¨μ•½ν•œ ν”„λ‘œκ·Έλž¨μ΄ λ˜μ—ˆλ‹€.
  • ν•¨μˆ˜κ°€ μΌκ΄€λœ λ°˜ν™˜κ°’μ„ 보μž₯ν•˜λ„λ‘ ν•΄μ„œ 전체 ν•¨μˆ˜ κ²°κ³Όλ₯Ό 예츑 κ°€λŠ₯ν•œ λ°©ν–₯으둜 μœ λ„ν•˜λ©΄ μ—¬λŸ¬λͺ¨λ‘œ 이둜운데 이것을 μ°Έμ‘° 투λͺ…μ„±(referential transparency) μ΄λΌλŠ” μˆœμˆ˜ν•¨μˆ˜ λ³Έμ—°μ˜ νŠΉμ§•μ΄λ‹€.

🎈 μ°Έμ‘° 투λͺ…μ„±κ³Ό μΉ˜ν™˜μ„±β€‹

  • μ°Έμ‘° 투λͺ…성은 μˆœμˆ˜ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λŠ” μ’€ 더 곡식적인 방법이며, μ—¬κΈ°μ„œ μˆœμˆ˜μ„±(purity) μ΄λž€ ν•¨μˆ˜μ˜ μΈμˆ˜μ™€ 결괏값 μ‚¬μ΄μ˜ μˆœμˆ˜ν•œ 맀핑 관계λ₯Ό μ˜λ―Έν•œλ‹€.
  • λ”°λΌμ„œ μ–΄λ–€ ν•¨μˆ˜κ°€ λ™μΌν•œ μž…λ ₯을 λ°›μ•˜μ„ λ•Œ λ™μΌν•œ κ²°κ³Όλ₯Ό λ‚΄λ©΄ 이λ₯Ό μ°Έμ‘° 투λͺ…ν•œ ν•¨μˆ˜λΌκ³  ν•œλ‹€.
  • μ°Έμ‘° 투λͺ…ν•œ ν•¨μˆ˜λ‘œ λ§Œλ“€λ €λ©΄ 이 ν•¨μˆ˜κ°€ μ˜μ‘΄ν•˜λŠ” μƒνƒœ, 즉 μ™ΈλΆ€ λ³€μˆ˜λ₯Ό μ œκ±°ν•˜κ³  ν•¨μˆ˜ μ„œλͺ…에 μ •κ·œ λ§€κ°œλ³€μˆ˜λ‘œ λͺ…μ‹œν•΄μ•Ό ν•œλ‹€.
// λ³€κ²½ μ „
var counter = 0;

function increment() {
return ++counter;
}

// λ³€κ²½ ν›„
var increment = counter => counter + 1;
  • 이런 ν•¨μˆ˜λŠ” μ½”λ“œλ₯Ό ν…ŒμŠ€νŠΈν•˜κΈ° 쉽고 전체 λ‘œμ§μ„ νŒŒμ•…ν•˜λŠ” 것도 쉽닀.

🎈 λΆˆλ³€ 데이터 μœ μ§€ν•˜κΈ°β€‹

  • λΆˆλ³€ λ°μ΄ν„°λŠ” ν•œλ²ˆ μƒμ„±λœ ν›„μ—λŠ” μ ˆλŒ€ 바꾸지 μ•ŠλŠ”λ‹€.
  • 배열을 μ •λ ¬ν•˜λŠ” κ°„λ‹¨ν•œ μ½”λ“œμ΄λ‹€.
var sortDesc = arr => {
arr.sort(
(a, b) => b - a
);
};

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9,];
sortDesc(arr); // [9, 8, 7, 6, 5, 4, 3, 2, 1]
  • 얼핏 보기에 λΆ€μˆ˜νš¨κ³Όμ™€ μ „ν˜€ 무관해 λ³΄μ΄μ§€λ§Œ, λΆˆν–‰νžˆλ„ μƒνƒœμ  ν•¨μˆ˜μΈ Array.sortλŠ” 원본 λ ˆνΌλŸ°μŠ€κ°€ κ°€λ¦¬ν‚€λŠ” λ°°μ—΄μ˜ μ›μ†Œλ₯Ό μ •λ ¬ν•˜λŠ” λΆ€μˆ˜νš¨κ³Όλ₯Ό μΌμœΌν‚¨λ‹€.
  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€, μ™ΈλΆ€μ—μ„œ κ΄€μ°° κ°€λŠ₯ν•œ λΆ€μˆ˜ νš¨κ³Όκ°€ 제거된 λΆˆλ³€ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜κΈ° μœ„ν•΄ μˆœμˆ˜ν•¨μˆ˜λ₯Ό μ„ μ–Έμ μœΌλ‘œ ν‰κ°€ν•˜λŠ” 것이닀.
  • ν•¨μˆ˜λ₯Ό 순수 μ—°μ‚°μ˜ κ΄€μ μ—μ„œ 데이터λ₯Ό μ ˆλŒ€ λ³€κ²½ν•˜μ§€ μ•ŠλŠ” κ³ μ •λœ μž‘μ—… λ‹¨μœ„λ‘œ 바라본닀면 잠재적인 λ²„κ·ΈλŠ” μ€„κ²Œ 될 것이닀.

πŸ“š ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ˜ 쒋은 점​

  • FP둜 κ°œλ°œν•œ μžλ°”μŠ€ν¬λ¦½νŠΈ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μ–΄λ–€ 점이 μ’‹μ„κΉŒ
    • κ°„λ‹¨ν•œ ν•¨μˆ˜λ“€λ‘œ μž‘μ—…μ„ λΆ„ν•΄ν•œλ‹€.
    • 흐름 체인으둜 데이터λ₯Ό μ²˜λ¦¬ν•œλ‹€.
    • λ¦¬μ•‘ν‹°λΈŒ νŒ¨λŸ¬λ‹€μž„μ„ μ‹€ν˜„ν•˜μ—¬ 이벀트 쀑심 μ½”λ“œμ˜ λ³΅μž‘μ„±μ„ 쀄인닀.

🎈 λ³΅μž‘ν•œ μž‘μ—…μ„ λΆ„ν•΄ν•˜λ„λ‘ μœ λ„β€‹

  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ κ³ μˆ˜μ€€μ—μ„œ 보면, 사싀상 뢄해와 ν•©μ„±κ°„μ˜ μƒν˜Έμž‘μš©μ΄λΌ ν•  수 μžˆλ‹€.
  • μ΄λŸ¬ν•œ μ–‘λ©΄μ„± 덕뢄에 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž¨μ€ λͺ¨λ“ˆμ μœΌλ‘œ, 효율적으둜 λ™μž‘ν•œλ‹€.
  • λͺ¨λ“ˆμ„±μ˜ λ‹¨μœ„, 곧 μž‘μ—… λ‹¨μœ„λŠ” ν•¨μˆ˜ μžμ‹ μ΄λ‹€.
  • FPμ—μ„œ λͺ¨λ“ˆν™”λŠ” 단일성(singularity) 의 원리와 λ°€μ ‘ν•œ 관련이 μžˆλ‹€.
  • λͺ¨λ¦„지기 ν•¨μˆ˜λŠ” μ €λ§ˆλ‹€ ν•œ 가지 λͺ©ν‘œλ§Œ 바라봐야 ν•œλ‹€λŠ” 사상이닀.
  • 두 ν•¨μˆ˜λ₯Ό ν•©μ„±ν•˜λ©΄ 첫 번째 ν•¨μˆ˜μ˜ κ²°κ³Όλ₯Ό λ‹€μŒ ν•¨μˆ˜μ— λ°€μ–΄ λ„£λŠ” μƒˆλ‘œμš΄ ν•¨μˆ˜κ°€ νƒ„μƒν•œλ‹€.
var showStudent = compose(append('#student-info'), csv, find(db));

showStudent('444-44-4444');
  • composeν•¨μˆ˜λŠ” ν•¨μˆ˜ν˜• μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λͺ¨λ“ˆμ„±κ³Ό μž¬μ‚¬μš©μ„±μ„ ν•™μŠ΅ν•˜λŠ” 데 맀우 κ°λ³„ν•œ 의미λ₯Ό μ§€λ‹Œλ‹€.
  • ν•¨μˆ˜ν˜•μœΌλ‘œ ν•©μ„±ν•œ μ½”λ“œλŠ” 전체 ν‘œν˜„μ‹μ˜ 의미λ₯Ό κ°œλ³„ 쑰각의 μ˜λ―Έμ—μ„œ μΆ”λ‘ ν•  수 μžˆλ‹€.
  • λ˜ν•œ, ν•¨μˆ˜ 합성은 κ³ μˆ˜μ€€μ˜ 좔상화λ₯Ό 톡해 μžμ„Έν•œ 내막을 λ°νžˆμ§€ μ•Šμ•„λ„ μ½”λ“œκ°€ μˆ˜ν–‰ν•˜λŠ” μ „ 단계λ₯Ό 일λͺ©μš”μ—°ν•˜κ²Œ λ‚˜νƒ€λ‚Έλ‹€.
  • composeλŠ” λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό 인수둜 λ°›μœΌλ―€λ‘œ κ³ κ³„ν•¨μˆ˜(higher-order-function) 라고 ν•œλ‹€.

🎈 데이터λ₯Ό λ§€λ„λŸ½κ²Œ μ²΄μ΄λ‹ν•˜μ—¬ μ²˜λ¦¬β€‹

  • ν•¨μˆ˜ν˜• 라이브러리λ₯Ό μ΄μš©ν•˜λ©΄ μ–΄λŠ μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œμ νŠΈλΌλ„ λ‹€μ–‘ν•œ κ³ κ³„ν•¨μˆ˜λ₯Ό 마음껏 κ°€μ Έλ‹€ μ“Έ 수 μžˆλ‹€.
  • ν•¨μˆ˜ν˜• 라이브러리: λ‘œλŒ€μ‹œJS(Lodash), λžŒλ‹€JS(Ramda)
  • 두 라이브러리의 곡톡점은 ν•¨μˆ˜ 체인을 μ‘°λ¦½ν•œλ‹€.
  • 체인(chain) 은 같은 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 순차적인 ν•¨μˆ˜ ν˜ΈμΆœμ΄λ‹€.
  • λ‹€μŒμ€ ν•™μƒλ“€μ˜ 평균 점수λ₯Ό κ³„μ‚°ν•˜λŠ” μ˜ˆμ œμ΄λ‹€.
let enrollment = [
{ enrolled: 2, grade: 100 },
{ enrolled: 2, grade: 80 },
{ enrolled: 1, grade: 89 },
];

// λͺ…λ Ήν˜•
var totalGrades = 0;
var totalStudentsFound = 0;
for(let i = 0; i < enrollment.length; i++) {
let student = enrollment[i];
if(student !== null) {
if(student.enrolled > 1) {
totalGrades +=student.grade;
totalStudentsFound++;
}
}
}

var average = totalGrades / totalStudentsFound; // 90
  • 각 λ‹¨κ³„μ—μ„œ ν•΄λ‹Ήν•˜λŠ” ν•¨μˆ˜λ₯Ό λ‘œλŒ€μ‹œJS둜 묢으면 λ‹€μŒκ³Ό 같은 ν•¨μˆ˜ 체인이 ν˜•μ„±λœλ‹€.
  • ν•¨μˆ˜ 체인은 ν•„μš”ν•œ μ‹œμ κΉŒμ§€ 싀행을 λ―Έλ£¨λŠ” λŠκΈ‹ν•œ 평가(lazy evaluation) λ₯Ό μˆ˜ν–‰ν•œλ‹€.
  • λ‹€λ₯Έ 데에선 μ „ν˜€ μ“Έ 일이 μ—†λŠ” 일련의 μ½”λ“œλ₯Ό μ „λΆ€ μ‹€ν–‰ν•˜μ§€ μ•Šμ•„λ„ λ˜λ‹ˆ CPU λΆ€ν•˜κ°€ 쀄어듀어 μ„±λŠ₯이 쒋아진닀. μ΄λ ‡κ²Œ ν•˜λ©΄ λ‹€λ₯Έ ν•¨μˆ˜ν˜• 언어에 κΈ°λ³Έ νƒ‘μž¬λœ ν•„μš” μ‹œ 호좜(call-by-need) λ™μž‘μ„ 효과적으둜 λͺ¨λ°©ν•  수 μžˆλ‹€.
_.chain(enrollment)
.filter(student => student.enrolled > 1)
// 객체둜 κ΅¬μ„±λœ λ°°μ—΄μ—μ„œ 객체의 νŠΉμ • ν‚€μ—λŒ€ν•œ 값을 μΆ”μΆœν•  λ•Œ μ‚¬μš©ν•œλ‹€. version 4 deleted??
.pluck('grade')
.average()
.value(); // 90

🎈 λ³΅μž‘ν•œ 비동기 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλ„ μ‹ μ†ν•˜κ²Œ λ°˜μ‘β€‹

  • λ¦¬μ•‘ν‹°λΈŒ νŒ¨λŸ¬λ‹€μž„μ˜ κ°€μž₯ 큰 μž₯점은, 더 높은 μˆ˜μ€€μœΌλ‘œ μ½”λ“œλ₯Ό μΆ”μƒν•˜μ—¬ 비동기, 이벀트 기반 ν”„λ‘œκ·Έλž¨μ„ μ„€μ •ν•˜λŠλΌ λ°˜λ³΅λ˜λŠ” νŒλ°•μ΄ μ½”λ“œλŠ” μ•„μ˜ˆ 잊고 λΉ„μ§€λ‹ˆμŠ€ λ‘œμ§μ—λ§Œ 전념할 수 있게 ν•΄μ€€λ‹€λŠ” 점이닀.
  • 또 ν•¨μˆ˜λ₯Ό 체인으둜 λ¬Άκ³  ν•©μ„±ν•˜λŠ” FP의 λŠ₯λ ₯을 μ΅œλŒ€ν•œ μ΄λŒμ–΄λ‚Ό 수 μžˆλ‹€.
  • λ‹€μŒ μ˜ˆμ œλŠ” μ–΄λ–€ ν•™μƒμ˜ SSN이 μ˜¬λ°”λ₯Έ λ²ˆν˜ΈμΈμ§€ κ²€μ€‘ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.
var valid = false;
var elem = document.querySelector('#student-ssn');
elem.onkeyup = function(event) {
var val = elem.value; // λΆ€μˆ˜ 효과
if(val !== null && val.length !== 0) {
val = val.replace(/^\s*|\-|\s*$/g, ''); // μž…λ ₯ 데이터 μ •μ œ/λ³€κ²½
if(val.length === 9) {
console.log(`μ˜¬λ°”λ₯Έ SSN: ${val}!`);
valid = true; // λΆ€μˆ˜ 효과
}
}
else {
console.log(`잘λͺ»λœ SSN: ${val}!`);
}
};
  • μœ„ μ½”λ“œλŠ” λ³΅μž‘ν•΄λ³΄μ΄κ³ , λΉ„μ§€λ‹ˆμŠ€ 둜직이 λͺ¨λ‘ ν•œκ³³μ— μ§‘μ€‘λ˜μ–΄ μžˆμ–΄ λͺ¨λ“ˆμ„±λ„ κ²°μ—¬λ˜μ–΄ μžˆλ‹€.
  • 무엇보닀 이 ν•¨μˆ˜λŠ” μ™ΈλΆ€ μƒνƒœμ— μ˜μ‘΄ν•˜λŠ” 탓에 μž¬μ‚¬μš©μ΄ μ–΄λ ΅λ‹€.
  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ— κΈ°λ°˜μ„ λ‘” λ¦¬μ•‘ν‹°λΈŒ ν”„λ‘œκ·Έλž¨μ€ μˆœμˆ˜ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ map, reduce처럼 많이 μ“°λŠ” μ—°μ‚°μœΌλ‘œ 데이터λ₯Ό μ²˜λ¦¬ν•  수 있고 λžŒλ‹€ ν‘œν˜„μ‹μ˜ 간결함을 λˆ„λ¦΄ 수 μžˆλ‹€λŠ” 이점이 μžˆλ‹€.
  • λ¦¬μ•‘ν‹°λΈŒ νŒ¨λŸ¬λ‹€μž„μ€ μ˜΅μ €λ²„λΈ”(observable) μ΄λΌλŠ” μ•„μ£Ό μ€‘μš”ν•œ μž₯치λ₯Ό 맀개둜 μ›€μ§μ΄λŠ”λ°, μ˜΅μ €λ²„λΈ”μ„ μ΄μš©ν•˜λ©΄ 데이터 μŠ€νŠΈλ¦Όμ„ κ΅¬λ…ν•΄μ„œ μ›ν•˜λŠ” 연산을 ν•©μ„± 및 μ²΄μ΄λ‹ν•˜μ—¬ μ²˜λ¦¬ν•  수 μžˆλ‹€.
Rx.Observable.fromEvent(document.querySelector('#student-ssn'), ('keyup'))
.pluck('srcElement', 'value')
.map(ssn => ssn.replace(/^\s*|\-|\s*$/g, ''))
.filter(ssn => ssn !== null && ssn.length === 9)
.subscribe(validSsn => {
console.log(`μ˜¬λ°”λ₯Έ SSN ${validSsn}!`);
})
  • κ°€μž₯ μ£Όλͺ©ν•΄μ•Ό ν•  뢀뢄은, μˆ˜ν–‰ν•˜λŠ” λͺ¨λ“  연산이 μ™„μ „ν•œ λΆˆλ³€μ΄κ³  λΉ„μ§€λ‹ˆμŠ€ λ‘œμ§μ€ λͺ¨λ‘ κ°œλ³„ ν•¨μˆ˜λ‘œ λ‚˜λ‰˜μ—ˆλ‹€λŠ” 점이닀.
  • ꡳ이 λ¦¬μ•‘ν‹°λΈŒ/ν•¨μˆ˜ν˜•μ„ μ„žμ–΄ μ“Έ ν•„μš”λŠ” μ—†μ§€λ§Œ, ν•¨μˆ˜ν˜•μœΌλ‘œ μ‚¬κ³ ν•˜λ‹€ 보면 두 가지λ₯Ό ν˜Όμš©ν•˜κ²Œ λ˜μ–΄ κ²°κ΅­ ν•¨μˆ˜ν˜• λ¦¬μ•‘ν‹°λΈŒ ν”„λ‘œκ·Έλž˜λ°(FRP) μ΄λΌλŠ” μ•„ν‚€ν…μ²˜μ— λˆˆμ„ 뜨게 λœλ‹€.
  • 객체지ν–₯ 섀계λ₯Ό FPκ°€ μ™„μ „νžˆ λŒ€μ²΄ν•˜λŠ” κ²ƒμΌκΉŒ?
    • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ„ μ½”λ“œμ— μ μš©ν•˜λŠ” 건 μ „λΆ€λ₯Ό μ–»κ±°λ‚˜ μ „λΆ€λ₯Ό μžƒλŠ” μ‹μ˜ μ ‘κ·Ό 방법이 μ•„λ‹ˆλ‹€.
    • FPλŠ” λΆˆλ³€μ„±κ³Ό 곡유 μƒνƒœλ₯Ό μ—„κ²©ν•˜κ²Œ ν†΅μ œν•˜λ―€λ‘œ λ©€ν‹°μŠ€λ ˆλ“œ ν”„λ‘œκ·Έλž¨λ„ 보닀 μ§κ΄€μ μœΌλ‘œ μž‘μ„±ν•  수 μžˆλ‹€.

πŸ“š λ§ˆμΉ˜λ©°β€‹

  • μˆœμˆ˜ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œ μ½”λ“œλŠ” μ „μ—­ μƒνƒœλ₯Ό λ°”κΎΈκ±°λ‚˜ 깨뜨릴 일이 μ „ν˜€ μ—†μœΌλ―€λ‘œ ν…ŒμŠ€νŠΈ, μœ μ§€λ³΄μˆ˜κ°€ 더 μ‰¬μš΄ μ½”λ“œλ₯Ό κ°œλ°œν•˜λŠ” 데 도움이 λœλ‹€.
  • ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ€ μ½”λ“œλ₯Ό μ„ μ–Έμ μœΌλ‘œ μž‘μ„±ν•˜λ―€λ‘œ 헀아리기 쉽고 전체 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 가독성 μ—­μ‹œ ν–₯μƒλœλ‹€. 또 ν•¨μˆ˜μ™€ λžŒλ‹€ ν‘œν˜„μ‹μ„ μ‘°ν•©ν•˜μ—¬ κΉ”λ”ν•˜κ²Œ μ½”λ”©ν•  수 μžˆλ‹€.
  • μ—¬λŸ¬ μ›μ†Œλ‘œ κ΅¬μ„±λœ μ»¬λ ‰μ…˜ λ°μ΄ν„°λŠ” map, reduce 같은 연산을 ν•¨μˆ˜ 체인으둜 μ—°κ²°ν•˜μ—¬ λ¬Ό 흐λ₯΄λ“― λ§€λ„λŸ½κ²Œ μ²˜λ¦¬ν•  수 μžˆλ‹€.