기록하기

[TypeScript] 선언형 프로그래밍과 명령형 프로그래밍 본문

TypeScript

[TypeScript] 선언형 프로그래밍과 명령형 프로그래밍

_parkdaxun 2023. 9. 18. 12:25

명령형 프로그래밍이란?

입력 데이터를 얻고 가공한 다음, 결과를 출력하는 형태, 주로 for문을 사용해서 구현한다.

 

명령형 프로그래밍 예시

let sum = 0
for(let val=1; val<=100;)
    sum += val++
console.log(sum)

 

선언형 프로그래밍이란?

일괄된 문제 해결 구조에 집중한다. for문을 사용하지 않고 모든 데이터를 배열에 담는다. 그리고 문제가 해결될 때까지 끊임없이 또 다른 형태의 배열로 가공하는 방식으로 구현한다.

 

1. 문제를 푸는데 필요한 모든 데이터를 배열에 저장

2. 입력 데이터 배열을 가공해 출력 데이터 배열 생성

3. 출력 데이터 배열에 담긴 아이템 출력

 

선언형 프로그래밍 예시

1. 데이터를 배열로 생성하기

import {range} from './range'

let numbers : number[] = range(1, 100+1)
console.log(numbers)

 

2. fold: 배열 데이터 접기

폴드는 [1, 2, 3, ...] 형태의 배열 데이터를 가공해 5050과 같은 하나의 값을 생성하려고 할 때 사용한다. 배열의 아이템 타입이 T라고 할 때 배열은 T[ ]로 표현할 수 있는데, 폴드 함수는 T[ ] 타입 배열을 가공해 T 타입 결과를 만들어준다.

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
}

 

3. 함수 재사용하기

명령형 방식은 시스템 자원의 효율을 최우선으로 하는 반면, 선언현 방식은 폴드처럼 범용으로 구현된 함수를 재사용하면서 문제를 해결한다.

import {range} from './range'
import {fold} from './fold'

let numbers : number[] = range(1, 100+1)

let result = fold(numbers, (result, value) => result + value, 0)
console.log(result)

 

'범용적이고 재사용 가능'이라는 관점에서 다른 예시 

1부터 100까지 숫자 중 홀수만 더하는 문제

 

명령형 프로그래밍 예시

let oddSum = 0

for(let val=1; val<=100; val+=2)
	oddSum += val
console.log(oddSum)

 

선언형 프로그래밍 예시

1. filter : 조건에 맞는 아이템만 추려내기

함수형 프로그래밍에서 흔하게 보이는 filter라는 이름의 함수는 입력 배열을 가공해서 조건에 맞는 값만 추려내는 기능을 한다.

export const filter = <T>(array: T[], callback: (value:T, index?: number) => boolean): T[] => {
    let result: T[] = []
    for(let index: number=0; index <array.length; ++index) {
        const value = array[index]
        if(callback(value, index))
            result = [...result, value]
    }
    return result
}

 

2. 함수 사용하기

import {range} form './range'
import {fold} from './fold'
import {filter} from './filter'

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)