이번 챕터에서는 선언형과 명령형 프로그래밍의 차이를 중점으로 살펴본다.
먼저 명령형 프로그래밍이란 좀더 cpu 친화적인 저수준 구현 방식이고 선언형은 명령형 방식 위에서 동작하는 인간에게 좀 더 친화적인 고수준 구현 방식이다.
예제 코드를 살펴 보면서 명령형과 선언형 프로그래밍의 차이를 느껴보자
//명령형
let sum = 0
for (let val = 0; val <= 100;)
sum += val++
console.log(sum) //5050
//선언형
//fold.ts
export const fold = <T>(array: T[], callback: (result: T, val: T) => T, initValue: T) => {
let result: T = initValue
for (let i = 0; i < array.length; i++) {
const value = array[i]
result = callback(result, value)
}
return result
}
//delartive-sum.ts
//입력 데이터 생성(1~100까지의 배열)
let numbers: number[] = range(1, 100 + 1)
//입력 데이터의 가공
let result = fold(numbers, (result, value) => result + value, 0)
console.log(result)
두 방식의 차이를 보면 명령형은 시스템 자원의 효율을 최우선으로 작성되었고 선언형 함수는 데이터 생성과 가공 과정을 분리하여 함수를 재사용함으로써 문제를 해결한다.
다음 명령형프로그래밍으로 작성한 코드는 데이터 생성과 가공을 동시에 한다.
let oddSum = 0
for (let val = 1 val <= 100; val += 2)
oddSum += val
console.log(oddSum)
이에 반해 선언형 프로그래밍은 데이터 생성과 가공을 별도로 만들어야 함으로 먼저 홀수 만있는 데이터를 생성하고 그 다음에 합을 구한다.
//filter.ts
export const filter = <T>(array:T[], callback : (value:T, index?: number) => boolean) : T[] => {
let result: T[] = []
for (let index = 0; index < array.length; ++index) {
const value = array[index]
if (callback(value, index))
result = [...result, value]
}
return result
}
//declartive-odd-sum.ts
import { range } from "../day01/range";
import { filter } from "./filter";
import { fold } from "./fold";
//입력 데이터 생성(1~100까지의 배열)
let numbers: number[] = range(1, 100 + 1)
//홀수 만 생성
const isOdd = (n:number) : boolean => n % 2 != 0
//입력 데이터의 가공
let result = fold(filter(numbers, isOdd), (result, value) => result + value, 0)
console.log(result)
let squareSum = 0
for (let val = 1; val <= 100; ++val)
// 명령형은 데이터 자체를 바로 가공한다.
squareSum += val * val
console.log(squareSum) // 338350
선언형을 이용하려면 map 함수가 필요하다.
//map.ts
export const map = <T,Q>(array : T[], callback : (value : T, index ?: number) => Q) : Q[] => {
let result: Q[] = []
for (let index = 0; index < array.length; ++index) {
const value = array[index]
result = [...result, callback(value, index)]
}
// map 배열을 반환한다.
return result
}
map함수를 이용하면 다음과 같이 이용할 수 있다.
import { range } from "../day01/range";
import { fold } from "./fold";
import { map } from "./map";
let numbers: number[] = range(1, 100 + 1);
let result = fold(
map(numbers, value => value * value),
(result, value) => result + value, 0
)
console.log(result)
명령형은 데이터 생산과 가공이 동시에 이루어진다.
선언형은 데이터 생산과 가공이 분리되어 있다.
앞서 별도로 만든 map, filter, 메서드는 이미 내장되어 있다.
다음 시간에 알아보자.