[TS] 순수함수와 배열

로선생·2022년 6월 19일
0

타입스크립트

목록 보기
13/14

함수형 프로그래밍에서 함수는 '순수함수'라는 조건을 만족해야 한다.
그러나 타입스크립트의 Array 클래스에는 순수 함수 조건에 부합하지 않는 메서드가 많다.
따라서 배열의 메서드를 사용할 땨는 해당 메서드가 어떤 특성이 있는지 살펴야 한다.

함수형 프로그래밍이란?
함수형 프로그래밍은 하나의 프로그래밍 패러다임으로 정의되는 일련의 코딩 접근 방식이며, 자료처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임을 의미한다.

참조: https://mangkyu.tistory.com/111

순수함수란?

순수함수는 부수효과가 없는 함수를 말한다.
부수효과란 고유한 목적 이외에 다른 효과가 나타나는 것을 의미하며 부작용이라고도 한다.
부수효과가 있는 함수를 불순함수라고 한다.

다음과 같은 조건을 충족해야 한다.

  • 함수 몸통에 입출력 관련 코드 없어야 한다
  • 함수 몸통에서 매개변숫값을 변경시키지 않는다.
  • 함수는 몸통에서 만들어진 결과를 즉시 반환한다.
  • 함수 내부에 전역 변수나 정적 변수를 사용하지 않는다.
  • 함수가 예외를 발생시키지 않는다.
  • 함수가 콜백함수로 구현되었거나 함수 몸통에 콜백함수를 사용하는 코드가 없다
  • 함수 몸통에 비동기 방식 동작 코드가 없다.

다음과 같은 함수는 불순함수이다.
1) 몸통에서 매개변수로 받은 배열이 내용이 달라지고
2) 두 번째 예시는 외부 변수를 활용했기 때문이다.

function impure1(array: number[]): void{
array.push(1)
array.aplice(0, 1)
}

let g = 10
function impure2(x: number){
return x + g
}

타입 수정자 readonly

순수함수 구현을 쉽게 하기 위해 자바스크립트는 readonly 키워드를 제공한다.
해당 타입으로 선언된 매개변숫값을 변경하려는 시도가 있으면 문제가 있음을 알려주고, 불순함수를 방지한다.

function pure(array: readonly number[]){...}

const 키워드가 있는데 또 readonly가 필요한가? 라는 의문이 들 수 있으나,
타입스크립트에서 인터페이스, 클래스, 함수의 매개변수 등은 let이나 const 키워드 없이 선언한다.
따라서 심벌에 const 효과를 주려면 readonly라는 타입 수정자가 필요하다.

깊은 복사와 얕은 복사

프로그래밍 언어에서 어떤 변숫값을 다른 변숫값으로 설정하는 것을 복사라고 하는데,
깊은 복사와 얕은 복사 두 종류가 있다.

순수 함수를 구현할 때는 매개변수가 불변성을 유지해야 하므로, 깊은 복사를 실행해 매개변숫값이 변경되지 않게 해야한다.
깊은 복사는 대상 변숫값이 바뀔 때, 원본 변수값은 그대로인 형태로 동작한다.
다음은 깊은 복사의 예시이다.

let origin = 1
let copied = origin
copied += 2
console.log(origin, copied) // 1, 3

origin 변수값은 변하지 않는다. 이것이 깊은 복사이다.
타입스크립트에서 number와 boolean은 깊은 복사 형태로 동작한다.

그러나 객체와 배열은 얕은 복사 방식으로 동작한다.

let origin = [5, 3, 9, 7]
let copied = origin
copied[0] = 0
console.log(origin, copied) // [0, 3, 9, 7], [0, 3, 9, 7]

전개연산자

전개연산자를 이용하면 깊은 복사를 할 수 있다.

let origin = [5, 3, 9, 7]
let copied = [...origin]
copied[0] = 0
console.log(origin, copied) // [5, 3, 9, 7], [0, 3, 9, 7]

sort메서드를 순수 함수로 구현하기

sort메서드는 원본 배열의 내용을 변경하며 오름 혹는 내림차순으로 정렬해준다.
다음 함수는 readonly를 활용하여 입력 배열을 유지한 채 정렬할 수 있도록 깊은 복사를 활용했다.

const pureSort = <T>(array: readonly T[]):T[] => {
	let deepCopied = [...array]
    return deepCopied.sort()
}

가변인수 함수와 순수 함수

함수를 호출할 때 인수의 개수를 제한하지 않은 것을 가변 인수라고 한다.

export const mergeArray = <T>(...arrays) => {}

타입에 상관 없이 동작하게 하기 위해 제네릭 타입으로 구현하였다.
배열의 입출력을 만들고 싶다면 다음과 같이 만든다.

export const mergeArray = <T>(...arrays: T[][]): T[] => {}

마지막으로 순수함수로 구현하려면 매개변수의 내용을 훼손하지 말아야 한다.

export const mergeArray = <T>(...arrays: readonly T[][]): T[] => {}

순수함수를 고려하면 자바스크립트 배열이 제공하는 많은 메서드를 사용할 수 없다. 그런데 이런 메서드들은 전개 연산자 등의 메커니즘을 활용하면 순수함수 형태로 간단하게 구현할 수 있다.

profile
이제는 이것저것 먹어요

0개의 댓글