[Software Engineering] 함수형 프로그래밍

KWANWOO·2022년 2월 7일
0
post-thumbnail

함수형 프로그래밍(Functional Programming)

현재 안드로이드를 위주로 공부를 하고 있는데 여기서 사용하는 코틀린 이라는 언어는 함수형 프로그래밍 언어이다. 이 글에서는 함수형 프로그래밍에 대해 정리했다.

프로그래밍 패러다임의 구분

명령형 프로그래밍: 무엇(What)을 할 것인지 나타내기보다 어떻게(How) 할 건지를 설명하는 방식

  • 절차지향 프로그래밍: 수행되어야 할 순차적인 처리 과정을 포함하는 방식 (C, C++)
  • 객체지향 프로그래밍: 객체들의 집합으로 프로그램의 상호작용을 표현 (C++, Java, C#)

선언형 프로그래밍: 어떻게 할건지(How)를 나타내기보다 무엇(What)을 할 건지를 설명하는 방식

  • 함수형 프로그래밍: 순수 함수를 조합하고 소프트웨어를 만드는 방식 (클로저, 하스켈, 리스프)

1. 함수형 프로그래밍이란?

명령형 프로그래밍을 기반으로 개발된 소프트웨어의 크기가 커지면 복잡하게 엉켜있는 스파게티 코드를 유지보수하는 것이 매우 어렵다.

함수형 프로그래밍은 거의 모든 것을 순수 함수로 나누어 문제를 해결하는 기법으로, 작은 문제를 해결하기 위한 함수를 작성하여 가독성을 높이고 유지보수를 용이하게 해준다.

유명한 책인 클린 코드(Clean Code)의 저자 Robert C.Martin은 함수형 프로그래밍을 대입문이 없는 프로그래밍이라고 정의하였다.

Functional Programming is programming without assignment satements

2. 함수형 프로그래밍의 특징

부수 효과가 없는 순수 함수를 1급 객체로 간주하여 파라미터로 넘기거나 반환값으로 사용할 수 있으며, 참조 투명성을 지킬 수 있다.

부수효과란?

  • 변수의 값이 변경됨
  • 자료 구조를 제자리에서 수정함
  • 객체의 필드값을 설정함
  • 예외나 오류가 발생하며 실행이 중단됨
  • 콘솔 또는 파일 I/O가 발생함

1급 객체란 다음과 같은 것들이 가능한 객체를 의미한다.

  • 변수나 데이터 구조 안에 담을 수 있다.
  • 파라미터로 전달 할 수 있다.
  • 반환값으로 사용할 수 있다.
  • 할당에 사용된 이름과 무관하게 고유한 구별이 가능하다.

참조 투명성(Referential Transparency)이란?

  • 동일한 인자에 대해 항상 동일한 결과를 반환해야 한다.
  • 참조 투명성을 통해 기존의 값은 변경되지 않고 유지된다.(Immutable Data)

부수 효과(Side Effect)들을 제거한 함수들을 순수 함수(Pure Function)라고 한다.
함수형 프로그래밍에서 사용하는 함수는 이러한 순수 함수들이다.

  • Memory or I/O의 관점에서 Side Effect가 없는 함수
  • 함수의 실행이 외부에 영향을 끼치지 않는 함수

순수 함수를 사용하면 함수 자체가 독립적이고 부수 효과가 없기 때문에 스레드에 안정성을 보장받을수 있으며 스레드에 안정성을 보장받아 병렬 처리를 동기화 없이 진행할 수 있다.

또한 함수형 프로그래밍에서 함수는 1급 객체로 취급받기 때문에 함수를 파라미터로 넘기는 등의 작업이 가능하다.

3. 함수형 프로그래밍의 장단점

1) 함수형 프로그래밍의 장점

  • 높은 수준의 추상화를 제공한다
  • 함수 단위의 코드 재사용이 수월하다
  • 불변성을 지향하기 때문에 프로그램의 동작을 예측하기 쉬워진다

2) 함수형 프로그래밍의 단점

  • 순수함수를 구현하기 위해서는 코드의 가독성이 좋지 않을 수 있다
  • 함수형 프로그래밍에서는 반복이 for문이 아닌 재귀를 통해 이루어지는데 (deep copy), 재귀적 코드 스타일은 무한 루프에 빠질 수 있다
  • 순수함수를 사용하는 것은 쉬울 수 있지만 조합하는 것은 쉽지 않다

4. 코틀린의 함수형 프로그래밍

1) 순수 함수

아래 코틀린 코드는 순수 함수의 예시이다.이 함수는 매개 변수 a, b에 대해서 항상 a+b의 값을 반환한다. 또한 함수 내부에서 함수 외부의 변수를 변경하지도 않는다.

fun sum(a : Int, b: Int) : Int {
	return a+b
}

반면 아래 코드는 grade 함수의 반환값이 무엇인지에 따라서 process 함수가 실행될 수도 있고 안 될 수도 있다. 즉, check 함수의 실행 결과를 예측하기 어렵다. 이런 함수는 순수함수가 아니다.

fun check() {
	val test = User.grade()
	if (test != null) process(test)
}

2) 람다식

람다식은 이름이 없어도 함수 역할을 할 수 있는 익명 함수의 하나의 형태이다. 람다식은 화살표 표기법으로 사용하고 고차함수에서 매개변수로 넘기거나 결과 값으로 반환될 수도 있다.

val multi = {x: Int, y: Int -> x * y}

3) 고차 함수

고차함수는 다른 함수를 인자로 사용하거나, 함수를 결과값으로 반환하는 함수를 의미한다. 일급 객체 혹은 일급 함수를 서로 주고 받을 수 있는 함수가 고차함수가 되는 것이다.

  • highFunc 함수는 { x, y -> x + y } 람다식을 인자로 받는 고차 함수이다.
fun main() {
	println(highFunc( { x, y -> x + y}, 10, 20)
}

fun highFunc(sum : (Int, Int) -> Int, a : Int, b : Int) : Int = sum(a, b)

[Kotlin 기본 문법5 - 함수] 포스팅에서 코틀린의 함수형 프로그래밍을 위한 기본 문법에 대한 자세한 내용을 확인할 수 있다. (아래 링크 첨부)

Kotlin 기본 문법5 - 함수

함수형 프로그래밍을 잘 지키며 코드를 작성하자!!!

안드로이드 개발을 공부하면서 코틀린이라는 언어를 사용하고 있는데 함수형 프로그래밍 언어임에도 불구하고 익숙하지 않아서 함수형 프로그래밍을 제대로 하지 않고 있는것 같다ㅠㅠ 우선 이번 기회에 함수형 프로그래밍이 무엇인지에 대해 공부했으니 앞으로는 이러한 내용들을 잘 고려해 가며 코드를 작성해 봐야겠다!!!!✌✌

📄 Reference

profile
관우로그

0개의 댓글