<What about Functional Programming! 4. 액션에게 계산 빼내기.>

강민수·2023년 1월 22일
0

이번 장은 앞서 살펴본 내용 중, 특히 액션에서 계산을 어떻게 빼내는 지에 대한 방법을 살펴보려고 합니다.

먼저, 책에 나와 있는 에제를 토대로, 해당 코드에 대해 살펴봅시다.

1. 코드 분석.

다음과 같은 쇼핑몰의 카트에 상품을 추가하는 코드가 있다고 가정해 봅시다.

1) 상품 정보 추가 코드.

let shopping_cart = [];  // 장바구니 제품과 금액 합계를 담고 있는 전역 변수. 
let shopping_cart_total = 0;

function add_itme_to_cart(name, price){
	shopping_cart.push({   //카트 배열에 상품 정보 추가.
    name: name,
    price: price
    })
	calc_cart_total();  //장바구니 금액 합계 업데이트.
}

function calc_cart_total(){
	shopping_cart_total = 0;
  	
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price; // 모든 제품 값 더하기.
    }
	set_cart_total_dom() // 금액 합계 반영을 위한 DOM 업데이트.
}

2) 무료 배송비 계산하기.

새로운 요구 사항으로 구매 합계가 20달러 이상이면 무료 배송을 해주고자 합니다. 이때 장바구니에 담긴 합계가 총 20달러를 넘으면, 구매 버튼 옆에 무료 배송 아이콘을 표시해 준다고 합시다.

먼저 지금은 절차적 스타일로 작성하지만, 추후에는 함수형 스타일로 리팩토링하겠습니다.


function update_shpping_icons(){
  const buy_buttons = get_buy_buttons_dom(); // 페이지에 모든 구매 버튼 반복문 적용.
  for(let i =0; i< buy_buttons.lnegth; i++){
  	const button = buy_buttons[i];
    const item = button.item;
    if(item.price + shopping_cart_total >=20){ // 무료 배송 여부 확인. 
    button.show_free_shpping_icon(); // 결정에 따라 무료 배송 아이콘 O/X
    }else{
    button.hide_free_shipping_icon();
    }
  }
}
// 합계 금액이 바뀔 때마다 모든 아이콘을 업데이트하기 위해 calc_cart_total() 함수 마지막에 update_shipping_icons() 호출!
function calc_cart_total(){
	shopping_cart_total = 0;
  	
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price; // 모든 제품 값 더하기.
    }
	set_cart_total_dom() // 금액 합계 반영을 위한 DOM 업데이트.
  	update_shipping_icons(); // 아이콘 업데이트 코드 추가. 
}

3) 세금 계산하기.

다음 요구 사항은 장바구니 금액의 합계가 바뀔 때 마다 세금을 다시 계산해 줘야 합니다.


// 세금 업데이트 함수. 
function update_tax_dom(){
  set_tax_dom(shopping_cart_total * 0.10);
}
// 합계 금액이 바뀔 때마다 세금을 업데이트하기 위해 calc_cart_total() 함수 마지막에 update_tax_dom() 호출!
function calc_cart_total(){
	shopping_cart_total = 0;
  	
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price; // 모든 제품 값 더하기.
    }
	set_cart_total_dom(); // 금액 합계 반영을 위한 DOM 업데이트.
  	update_shipping_icons(); // 아이콘 업데이트 코드 추가. 
  	update_tax_dom(); // 세금 업데이트. 
}

2. 생각해 보기... Stop!

앞선 코드를 통해 어떤 것들을 느끼셨나요?


위 코드들은 동작만을 신경쓴 코드입니다. 따라서 다음과 같은 사안들에 대응하기 어렵습니다.

하나씩 살펴보시죠!

1) 테스트하기 쉽게 만들기.

지금 코드는 비즈니스 규칙을 테스트하기 어렵습니다.

먼저, 현재 절차적 기준에서 만들어진 코드는 다음과 같이 테스트를 만들어야 합니다.

  1. 브라우저 설정하기
  2. 페이지 로드하기.
  3. 장바구니에 제품 담기 버튼 클릭.
  4. DOM이 업데이트될 때까지 기다리기. <- 분명 효율적이지 못 합니다.
  5. DOM에서 값 가져오기.
  6. 가져온 문자열 값을 숫자로 바꾸기.
  7. 에상하는 값과 비교하기.
function update_tax_dom(){
  set_tax_dom(shopping_cart_total * 0.10);
}

세금 계산하기 함수를 테스트한다고 했을 때, 기본적으로 다음과 같은 것들이 필요합니다.

  1. 결괏값을 얻을 방법은 DOM에서 값을 가져오는 방법 뿐이다.
  2. 테스트하기 전에 전역 변숫값을 설정해야 한다.
  3. 테스트해야 할 비즈니스 규칙 = total* 0.10

그렇다면, 테스트를 쉽게 할 수 있는 조건은 없을까요?

해당 조건은 다음과 같습니다.
1. DOM 업데이트와 비즈니스 규칙은 분리되어야 합니다.
2. 전역변수는 없어야 합니다.

2) 재사용하기 쉽게 만들기.

아래 코드는 다른 팀 혹은 동료가 쓴다고 가정했을 때, 사실상 재사용하기 쉽지 않습니다.

function update_shpping_icons(){
  const buy_buttons = get_buy_buttons_dom(); // 페이지에 모든 구매 버튼 반복문 적용.
  for(let i =0; i< buy_buttons.lnegth; i++){
  	const button = buy_buttons[i];
    const item = button.item;
    if(item.price + shopping_cart_total >=20){ // 무료 배송 여부 확인. 
    button.show_free_shpping_icon(); // 결정에 따라 무료 배송 아이콘 O/X
    }else{
    button.hide_free_shipping_icon();
    }
  }
}

크게 3가지 정도로 요약할 수 있습니다.

  1. 전역 변수 의존.
  2. DOM을 사용할 수 있는 곳에서 실행된다고 가정.
  3. 리턴 값 없음.

-> 따라서 이 반대로 실행하면, 재사용이 가능하다는 말이죠!

  1. 전역 변수 의존성 분리.
  2. DOM을 사용할 수 있는 곳에서 실행된다고 가정하지 않기.
  3. 함수가 결괏값을 리턴!

3) 액션, 계산, 데이터 구분.

위의 내용들을 토대로 가장 먼저해야 할 것은 바로. 액션, 계산, 데이터를 구분하는 것입니다.

편의상, 액션:A, 계산:C, 데이터:D로 구분하겠습니다.

구분하면 다음과 같습니다.

let shopping_cart = [];  // A.-> 이 전역 변수는 변경가능하므로 액션!
let shopping_cart_total = 0;  // A.-> 이 전역 변수는 변경가능하므로 액션!

function add_itme_to_cart(name, price)=  // A.-> 이 전역 변수는 변경가능하므로 액션!
	shopping_cart.push({   
    name: name,
    price: price
    })
	calc_cart_total();  
}

function update_shpping_icons(){ // A-> DOM에서 읽는 것은 액션.
  const buy_buttons = get_buy_buttons_dom();
  for(let i =0; i< buy_buttons.lnegth; i++){
  	const button = buy_buttons[i];
    const item = button.item;
    if(item.price + shopping_cart_total >=20){ 
    button.show_free_shpping_icon(); // A-> DOM을 바꾸는 것 역시 액션.
    }else{
    button.hide_free_shipping_icon();  // A-> DOM을 바꾸는 것 역시 액션.
    }
  }
}
function update_tax_dom(){
  set_tax_dom(shopping_cart_total * 0.10);  // A-> DOM을 바꾸는 것 역시 액션.
}

function calc_cart_total(){ // A.-> 전역변수를 바꾸는 것은 액션. 
	shopping_cart_total = 0;
  	
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price; 
    }
	set_cart_total_dom(); 
  	update_shipping_icons(); 
  	update_tax_dom();
}

사실상 이 코드에서 계산이나 데이터는 없습니다. 결국 모든 코드가 액션입니다. 이제 이를 어떻게 함수형 프로그래밍에 적용할 수 있는지 보시죠!.

3. 함수형 프로그래밍 적용.

1) 함수에는 입력과 출력이 있다.

모든 함수는 입력과 출력이 있습니다. 입력은 함수가 계산을 하기 위한 외부 정보입니다. 출력은 함수 밖으로 나오는 정보나 어떤 동작입니다. 함수를 부르는 이유는 결과가 필요하기 때문입니다. 그리고 원하는 결과를 얻으려면 입력이 필요합니다.

아래 함수를 살펴보면서 어떤 입력과 출력이 있는지 살펴보시죠.

const total = 0;
function add_to_total(amount){ // 인자는 입력.
	console.log("old total: " + total);// 전역변수 토탈을 읽는 것은 입력. 
	total+=amount; // 전역 변수를 바꾸는 것은 출력.
 	return total; // 리턴 값은 출력. 
}

입력과 출력은 명시적이거나 암묵적일 수 있다.

인자는 명시적인 입력입니다. 그리고 리턴 값은 명시적인 출력입니다. 허나, 암묵적으로 함수로 들어가거나 나오는 정보도 있습니다.

const total = 0;
function add_to_total(amount){ // 인자는 명시적 입력.
	console.log("old total: " + total);// 전역변수 토탈을 읽는 것은 암묵적 입력. 
	total+=amount; // 전역 변수를 바꾸는 것은 암묵적 출력.
 	return total; // 리턴 값은 명시적 출력. 
}

함수에 암묵적인 입력과 출력이 있으면 액션이 됩니다.

함수에서 암묵적 입력과 출력을 없애면 계산이 됩니다. 암묵적 입력은 함수의 인자로 바꾸고, 암묵적 출력은 함수의 리턴값으로 바꾸면 됩니다.

함수형 프로그래머는 암묵적 입력과 출력을 부수효과라고 부릅니다. 부수 효과는 함수가 하려고 하는 주요 기능(리턴값을 계산하는 일)이 아닙니다.

  1. 명시적 입력
  • 인자.
  1. 암묵적 입력
  • 인자 외 다른 입력.
  1. 명시적 출력
  • 리턴값.
  1. 암묵적 출력.
  • 리턴값 외 다른 출력.

테스트와 재사용성은 입출력과 관련 있습니다.

일전에 살펴본 조건들을 다시 살펴봅시다.

1) DOM업데이트와 비즈니스 규칙은 분리되어야 합니다.

DOM을 업데이트하는 일은 함수에서 어떤 정보가 나오는 것이기 때문에 출력입니다. 하지만 리턴 값이 아니기 때문에 암묵적 출력입니다. 사용자가 정보를 볼 수 있어야 하기 때문에 DOM업데이트는 어디선가 해야 합니다. 따라서 이런 암묵적 출력은 함수의 리턴 값으로 바꿀 수 있습니다.

2) 전역변수에 의존성을 분리해야 합니다.

전역변수를 읽는 것은 암묵적 입력이고 바꾸는 것은 출력입니다. 따라서 암묵적 입력은 인자로 바꾸고 출력은 리턴값으로 바꾸면 됩니다.

3) 함수가 결괏값을 리턴해야 합니다.

암묵적 출력 대신 명시적인 출력을 사용해야만 합니다.

2) 액션에서 계산 빼내기.

기존의 코드를 한 번 바꿔보도록 합시다.

1) 1차 분리.

기존 코드

function calc_cart_total(){
	shopping_cart_total = 0;
  	
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price;
    }
}
set_cart_total_dom(); 
update_shipping_icons(); 
update_tax_dom();

바꾼 코드

function calc_cart_total(){
	calc_total();
  	set_cart_total_dom(); 
	update_shipping_icons(); 
	update_tax_dom();
}

function calc_total(){
	shopping_cart_total = 0;
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price;
    }

}

빼낸 코드를 새로운 함수로 만들고 이름을 붙여줬습니다. 그리고 원래 코드에 빼낸 부분은 새로 만든 함수를 호출하도록 고쳤습니다. 하지만, 새 함수는 아직 액션입니다. 계속해서 새 함수를 계산으로 바꿔가겠습니다.

방금 한 리팩토링은 서브루틴 추출하기라고 할 수 있습니다. 기존 코드에서 동작은 바뀌지 않았습니다.

2) 2차 분리(액션 -> 계산)

새로 만든 함수는 아직 액션이기 때문에 계산으로 바꿔야 합니다. 계산으로 바꾸려면 먼저 어떤 입력과 출력이 있는 지 확인해야 합니다. 이 함수에는 출력 두 개와 입력 하나가 있습니다.

shopping_cart_total 전역 변숫값을 바꾸는 것이 출력이고 shopping_cart 전역 변숫값을 읽어오는 것이 입력입니다.

여기에 있는 입력과 출력은 모두 암묵적이므로 명시적인 입력과 출력으로 바꿔야 계산이 됩니다.

function calc_total(){
	shopping_cart_total = 0; // 출력
  	for(let i = 0; i< shopping_cart.length; i++){ // shopping_cart = 입력
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price; // shopping_cart_total = 출력.
    }

}

출력은 모두 같은 전역 변숫값을 바꿉니다. 그래서 같은 리턴 값을 사용해 바꿀 수 있습니다. 전역 변수 대신 지역 변수를 사용하도록 바꾸고, 지역변숫값을 리턴하도록 하겠습니다. 그리고 원래 함수는 새 함수의 리턴 값을 받아 전역 변수에 할당하도록 고치겠습니다.

1. 암묵적 출력 제거.

현재 코드

function calc_cart_total(){
	calc_total();
  	set_cart_total_dom(); 
	update_shipping_icons(); 
	update_tax_dom();
}

function calc_total(){
	shopping_cart_total = 0;
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	shopping_cart_total+=item.price;
    }

}

암묵적 출력을 없앤 코드.

function calc_cart_total(){
	shopping_cart_total = calc_total(); // 함수를 호출하는 쪽에서 리턴 값을 받아 전역변수의 값에 할당하도록 고칩니다.
  	set_cart_total_dom(); 
	update_shipping_icons(); 
	update_tax_dom();
}

function calc_total(){
	let total = 0; // 지역 변수로 변경. 
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	total+=item.price; // 지역변수 사용.
    }
	return total; // 지역변수 리턴. 
}

암묵적 출력 두 개를 없앴습니다. 이제 입력을 처리합니다.

2. 암묵적 입력 제거.

현재 코드

function calc_cart_total(){
	shopping_cart_total = calc_total(); // 함수를 호출하는 쪽에서 리턴 값을 받아 전역변수의 값에 할당하도록 고칩니다.
  	set_cart_total_dom(); 
	update_shipping_icons(); 
	update_tax_dom();
}

function calc_total(){
	let total = 0; // 지역 변수로 변경. 
  	for(let i = 0; i< shopping_cart.length; i++){
    	let item = shopping_cart[i];
      	total+=item.price; // 지역변수 사용.
    }
	return total; // 지역변수 리턴. 
}

암묵적 출력을 없앤 코드.

function calc_cart_total(){
	shopping_cart_total = calc_total(shopping_cart); // shopping_cart를 인자로 전달. 
  	set_cart_total_dom(); 
	update_shipping_icons(); 
	update_tax_dom();
}

function calc_total(){
	let total = 0; // 지역 변수로 변경. 
  	for(let i = 0; i< cart.length; i++){ // 전역 변수 대신 인자를 만들어 사용합니다!
    	let item = cart[i];
      	total+=item.price; // 지역변수 사용.
    }
	return total; // 지역변수 리턴. 
}

이제 calc_total() 함수는 계산입니다. 모든 입력은 인자이고 모든 출력은 리턴값입니다.

이처럼 액션에세 계산을 잘 빼낼 수 있습니다. 또, 기존 위에서 언급한 조건에도 모두 만족합니다.

3. 액션에서 또 다른 계산 빼내기.

add_item_to_cart() 함수에서도 계산은 빼낼 수 있습니다. 앞에서 한 것처럼 빼낼 부분을 찾고 함수로 빼서 입력과 출력을 명시적으로 바꿉니다.

장바구니를 바꾸는 코드에서 계산을 빼내 봅시다. 이 코드는 계산으로 빼내기 좋습니다. 새 함수로 만들겠습니다.

현재 코드

function add_item_to_cart(name, price){
	shopping_cart.push({
    	name: name, 
    	price: price
    })
   	calc_cart_total();
}

바꾼 코드.

function add_item_to_cart(name, price){
	add_item(name, price);
   	calc_cart_total();
}
function add_item(name, price){
	shopping_cart.push({
    	name: name, 
    	price: price
    })
}

계산으로 빼낸 코드를 add_item()이라는 새 함수로 만들었습니다. 이 함수가 동작하려면 name과 price인자가 필요합니다.

그리고 빼낸 코드 부분은 새로 만든 함수를 호출하도록 했습니다.

이 작업은 앞에서도 언급한 함수 추출하기 리팩토링입니다. 새로 만든 함수는 아직 액션입니다. 전역 변수인 shopping_cart 배열을 바꾸기 때문이빈다. 이제 계산으로 바꿔봅시다.

1) 암묵적 입력, 출력 찾기.

add_item() 함수는 전역 변수를 읽기 때문에 입력입니다. 또 push() 함수로 전역변수인 배열을 바꾸는 것은 출력이죠.

🎗️기억하기
전역 변수를 읽으면 함수 안으로 데이터가 들어오기 때문에 입력!!!
전역 배열을 바꾸면 함수 밖으로 데이터가 나가기 때문에 출력!!!

2) 암묵적 입력 제거.

현재 코드

function add_item_to_cart(name, price){
	add_item(name, price);
   	calc_cart_total();
}
function add_item(name, price){
	shopping_cart.push({
    	name: name, 
    	price: price
    })
}

암묵적 입력을 없앤 코드.

function add_item_to_cart(name, price){
	add_item(shopping_cart, price); //전역 변수를 인자로 넘김.
   	calc_cart_total();
}
function add_item(cart ,name, price){ // 인자 추가.
	cart.push({ //전역변수 대신 인자를 사용. 
    	name: name, 
    	price: price
    })
}

호출하는 쪽은 전역 변수를 인자로 넘기도록 고칩니다. 암묵적인 입력을 인자로 바꿔 명시적인 입력이 되었습니다.

3) 암묵적 출력 제거.

우리가 확인한 출력은 shopping_cart에 있는 배열을 바꾸는 부분입니다. 이 값을 바꾸는 대신 복사본을 만들고 복사본에 변경된 값을 추가해 리털해야 합니다.

현재 코드

function add_item_to_cart(name, price){
	add_item(shopping_cart, price);
   	calc_cart_total();
}
function add_item(cart ,name, price){ 
	cart.push({
    	name: name, 
    	price: price
    })
}

암묵적 출력을 없앤 코드.

function add_item_to_cart(name, price){
	shopping_cart =  // 원래 함수에서는 리턴 값을 받아 전역변수에 할당. 
      add_item(shopping_cart, name, price);
   	calc_cart_total();
}
function add_item(cart ,name, price){
  	const new_cart = cart.slice();
	new_cart.push({ //전역변수 대신 인자를 사용. 
    	name: name, 
    	price: price
    })
  	return new_cart;
}

복사본을 만들고 복사본에 제품을 추가해서 리턴했습니다. 그리고 호출하는 코드에서는 리턴값을 받아 전역 변수에 할당했습니다. 이제 암묵적 출력값이 리턴값으로 바뀌었습니다.

이제 계산으로 바꾸는 작업은 끝났습니다. add_item() 함수는 암묵적 입력이나 출력이 없는 계산입니다.

4. 더 생각해 보기.

이번에는 앞선 내용을 토대로 더 생각해 볼 지점들을 하나씩 살펴보겠습니다.

Q1. 코드가 더 많아진 것 같습니다. 코드가 더 적어야 좋은 것 아닌가요?

A. 일반적으로 더 적은 코드가 좋은 것은 맞습니다. 우리가 고친 코드는 더 많아진 것은 사실입니다.

새로운 함수를 만들면 최소 두 줄이 더 늘어납니다. 함수 선언 부분과 함수를 닫는 구문입니다. 하지만, 시간이 지나면서 함수로 분리한 것에 장점을 얻을 수 있습니다.

벌써 몇 가지 좋은 점이 있습니다. 코드를 테스트하기 쉬워졌고 재사용하기 좋아졌습니다.

Q2. 재사용성을 높이고 쉽게 테스트할 수 있는 것이 함수형 프로그래밍으로 얻을 수 있는 전부인가요?

A. 아닙니다!

함수형 프로그래밍으로 재사용하기 좋고 테스트하기 쉬운 코드를 만들 수 있지만 그것이 전부가 아닙니다. 이 외에도 동시성이나 설계, 데이터 모델링 측면에서 좋은 점들에 대해 더 있습니다. 이 부분은 추후 더 살펴보죠.

Q3. 앞에서는 다른 곳에서 쓰기 위해 계산을 분리했습니다. 다른 곳에서 쓰지 않더라도 계산으로 분리하는 것이 중요한 것인가요?

A. 물론입니다. 함수형 프로그래밍의 목적 중에 어떤 것을 분리해서 더 작게 만들려고 하는 것도 있습니다. 작은 것은 테스트하기 쉽고 재사용하기 쉽기 때문입니다.

Q4. 계산으로 바꾼 함수 안에서 아직도 변수를 변경하고 있습니다. 함수형 프로그래밍에서느 모든 것이 불변값이라고 했는데 아닌가요?

A. 좋은 질문입니다. 불변값은 생성된 다음에 바뀌면 안 되는 값입니다. 하지만 생성할 때는 초기화가 필요합니다. 만약 초기값이 있어야 하는 배열이 필요하고 이후에 바꾸지 않는다고 해도 초깃값을 넣기위해 시작 부분에 값을 배열에 넣어줘야 합니다.

지역변수를 변경하는 곳은 나중에 초기화할 값으로 새로 생성합니다. 지역변수이기 때문에 함수 밖에서는 접근할 수 없습니다. 그리고 초기화가 끝났다면 그 값은 리턴해야 합니다. 이처럼 값이 바뀌지 않으려면 원칙이 필요한데 자세한 내용은 추후 다루겠습니다.

5. 계산 추출 단계별 정리.

이제 다시 계산에서 추출 단계별로 다시 정리해 보겠습니다. 액션에서 계산을 빼내는 작업은 반복적인 과정입니다.

1. 계산 코드를 찾아 빼냅니다.

빼낼 코드를 찾습니다. 코드를 추출해 새로운 함수를 만들어 리팩토링합니다. 새 함수에 인자가 필요하다면 추가합니다. 원래 코드에서 빼낸 부분에서 새 함수를 부르도록 바꿉니다.

2. 새 함수에 암묵적 입력과 출력을 찾습니다.

새 함수에 암묵적 입력과 출력을 찾습니다. 암묵적 입력은 함수를 부르는 동안 결과에 영향을 줄 수 있는 것을 말합니다. 암묵적 출력은 함수 호출의 결과로 영향을 받는 것을 말합니다.

함수 인자를 포함해 함수 밖에 있는 변수를 읽거나 데이터베이스에서 값을 가져오는 것은 입력입니다.

리턴값을 포함해 전역변수를 바꾸거나 공유 객체를 바꾸거나, 웹 요청을 보내는 것은 출력입니다.

3. 암묵적 입력은 인자로 암묵적 출력은 리턴값으로 바꿉니다.

한 번에 하나씩 입력은 인자로 출력은 리턴값으로 바꿉니다. 새로운 리턴값이 생겼다면 호출하는 코드에서 함수의 결과를 변수에 할당해야 할 수도 있습니다.

여기서 인자와 리턴값은 바뀌지 않는 불변값이라는 것이 중요합니다. 리턴값이 나중에 바뀐다면, 암묵적 출력입니다. 또 인자로 받은 값이 바뀔 수 있다면 암묵적 입력입니다. 물론 추후에는 불변 데이터에 대해 다루면서 이런 것을 어떻게 강제할 수 있는 지 배우겠습니다. 지금은 바뀌지 않는다고 가정합니다.

5. 정리.

지금까지 배운 내용을 토대로 한 번 계산에 대해 정리해 보겠습니다.

  • 액션은 암묵적인 입력 또는 출력을 가지고 있다.
  • 계산의 정의에 따르면, 계산은 암묵적인 입력이나 출력이 없어야 합니다.
  • 공유 변수(like 전역변수)는 일반적으로 암묵적 입력 또는 출력이 됩니다.
  • 암묵적 입력은 인자로 바꿀 수 있습니다.
  • 암묵적 출력은 리턴값으로 바꿀 수 있습니다.
  • 함수형 원칙을 적용하면 액션은 줄어들고 계산은 늘어난다는 것을 확인했습니다.

다음 장에서는 액션에 대해 더 살펴보겠습니다.

profile
개발도 예능처럼 재미지게~

0개의 댓글