개요

함수형 프로그래밍은 자료처리를 순수 함수로 처리하고, side-effect를 제거하는 프로그래밍 패러다임입니다. 그렇다면, 왜 이러한 패러다임이 조명받고 있을까요?


동시성에 대한 문제(side-effect)

하드웨어의 성능이 발전하면서, 멀티 스레딩 기술은 보편화 되었습니다. 하지만, 이에 따라 여러 개의 스레드가 공유 자원에 동시에 접근하면서, 프로그램의 실행 결과가 예측 불가능해지는 문제가 발생했습니다.

아래의 예시 코드를 보면, 두 개의 스레드가 shared 변수에 동시에 접근하여 값을 변경하고 있습니다. 각 스레드의 실행 시점과 순서를 예측할 수 없기 때문에, 상황에 따라 shared의 값이 0, 100, 200, 300 등 다양하게 출력될 수 있습니다. 이를 컴퓨터 과학에서는 side-effect라고 합니다.

var shared = 0

Thread1 {
    shared += 100
}

Thread2 {
    shared += 200
}

print(shared)

/* 
결과 값 --------------------------------------------
- 0: 두 스레드가 모두 실행되기 전에 print문이 실행된 경우
- 100: Thread1만 실행된 후 print문이 실행된 경우
- 200: Thread2만 실행된 후 print문이 실행된 경우
- 300: 두 스레드가 완전히 실행된 후 print문이 실행된 경우
*/

side-effect를 해결하는 가장 간단한 방법은 데이터를 변경하지 않으면 됩니다. 기존 데이터를 변경하지 않으며, 필요 시 기존 데이터를 활용해 새로운 데이터를 만들어 내는 것입니다.

FP는 이를 수행할 수 있는 가장 훌륭한 대안입니다.


함수형 프로그래밍을 위한 Skill

  1. Pure-Function

Pure-Function(순수 함수)란 동일한 input에 대해서 동일한 output을 가지는 함수를 말합니다. 아래의 예시처럼 Pure-Function은 output을 생성하는데 오직 input(파라미터)만을 사용합니다.

// Pure-Function
func pure(_ input: Int) -> Int {
	return input * 3
}

// None Pure-Function
var value: Int = 3

func nonePure() -> Int {
	return value * 3 // 함수 외부 변수 사용
}
  1. High-Order Function

함수를 파라미터로 받거나, 리턴하는 함수를 High-Order Function(고차 함수)라고 합니다. 이를 좀 더 전문적인 용어로 ‘함수를 1급 객체로 활용한다’라고 할 수 있습니다. 대표적으로, Foundation에서 제공하는 map(), filter() 등이 있습니다.

*1급 객체: 1)변수에 저장될 수 있으며, 2)함수의 파라미터로 전달되거나 3)리턴값으로 사용될 수 있는 객체