함수형 프로그래밍
함수형 프로그래밍 정의
데이터의 흐름과 값의 변경에 따라 프로그래밍하지 않고 필요한 로직을
함수로 만들어서함수들의 흐름에 따라 프로그래밍하자는 개념
입니다.
프로그래밍 패러다임으로서의 함수형 프로그래밍
-
절차지향 프로그래밍
: 알고리즘과 로직 중심으로 문제 해결이 주목적 예)C,Pascal -
객체지향 프로그래밍
: 데이터와 데이터를 처리하는 메서드를 하나로 묶어 객체를 만들고 객체를 조합해서
프로그래밍 작성, 객체를 만들기위한 추상화, 캡슐화, 상속, 다형성 등의 개념 제공. 예)Java,C++ -
함수형 프로그래밍
: 함수 선언이 최우선, 데이터의 흐름이 아니라 함수의 선언과 선언된 함수의 유기적인 흐름이 주 목적이다. 예)코틀린,스칼라,스위프트 등
함수형 프로그래밍의 주요 원칙
일급객체(First Class Citizen)
로서의 함수
-
함수가 프로그램의 최상위 구성요소라는 의미입니다.
객체지향 프로그래밍의 경우 함수가 클래스 안에 포함되는 개념으로 클래스가 최상위 단위이며 일급 객체입니다. -
함수형 프로그래밍에서는 일급 객체로서 함수를 정의할 수 있어야 합니다. 즉,
클래스를 선언하지 않고도 함수를 정의
할 수 있어야 하며,함수 내에 다양한 구성요소(다른 함수, 클래스)를 포함
할 수 있어야 합니다. -
어떤 함수의 인수로 변수 대신 함수를 전달할 수 있어야 하고, 함수의 반환값 또한 함수를 반환할 수 있어야 합니다. 즉,
함수를 변수처럼 사용할 수 있어야 하고 이를 함수가 일급객체로 이용된다
고 표현 합니다.
순수 함수(Pure Function)
로 정의되는 함수
-
부수효과(Side-Effect)가 발생하지 않는 함수
입니다. -
같은 인수를 전달해서 함수를 호출하면
항상 같은 결괏값을 반환
한다는 의미 입니다. -
이러한 순수 함수가 되려면
함수 내에서 함수 밖의 데이터를 변경하는 작업이 발생하지 않아야 하며
, 별도의 입출력이 발생하지 않아야 합니다.
함수형 프로그래밍에서의 데이터 특징
변경할 수 없는 상수 데이터만 이용하고 함수의 흐름에 따라 프로그래밍 하자는 개념
-
데이터는 변경되지 않으며 프로그램의 상태만 표현한다.(
데이터 불변성
) -
함수에서 데이터는 변경하지 않고 새로운 데이터를 만들어 반환한다.
함수형 프로그래밍의 이점
-
코드가 간결하여 개발 생산성과 유지 보수성이 증대된다.
-
동시성 작업을 좀 더 쉽고 안전하게 구현할 수 있다.
코틀린에서 일급 객체로서의 함수
다양한 구성요소를 포함하는 함수
- 코틀린에서는
함수 자체가 프로그램의 독립적인 구성 단위
일 수 있습니다.(함수 내에 다양한 구성요소를 포함)
ex)
fun superFun() {
val superData = "Hello"
fun subFun1() {
println("superData = $superData")
}
fun subFun2(a: Int, b: Int): Int {
subFun1()
return a + b
}
class SubClass{
fun classFun(){
println("superData = $superData")
}
}
subFun1()
SubClass().classFun()
}
변수처럼 이용되는 함수
-
함수형 프로그래밍에서는 함수가 일급 객체로 이용됩니다. 일급 객체로서의 함수는
함수를 변수처럼 이용할 수 있어야 한다는 개념
도 포합됩니다. -
코틀린에서 함수를 변수에 대입하려면
람다식으로 표현하거나 함수 참조(Function Reference)를 이용
해야 합니다. -
함수 참조는 :: 이라는 연산자를 이용하여 함수를 변수에 대입하는 기법 입니다.
val funval = fun someFun() { // 에러
}
val funval1 = { x1: Int -> // 람다식 이용
println("hello world")
x1 * 10
}
funval1(10)
fun someFun() {
println("i's someFun()")
}
val funval2 = ::someFun //함수 참조 이용
funval2()
람다 표현식
람다 표현식이란?
함수의 축양형인 람다식, 람다 함수는 익명 함수(Anonymous Function)를 지칭하는 용어 입니다.
많은 프로그래밍 언어에서 코드의 간결함을 주목적으로 자주 이용합니다.
람다 함수 선언 형식
{ 매개변수 -> 함수내용 }
람다 함수 선언의 규칙
-
람다 함수는 항상 { }으로 감싸서 표현해야 합니다.
-
{ } 안에 -> 표시가 있으며 ->
왼쪽으로는 매개변수, 오른쪽으로는 함수 내용
입니다. -
람다 함수를 정의할 때 매개변수가 없으면 -> 왼쪽을 생략하거나 -> 자체를 생략할 수도 있습니다.
-
매개변수 타입을 선언해야 하며 추론할 수 있을때는 생략이 가능합니다.
-
함수의 반환값은 함수 내용의 마지막 표현식이다.
ex)
fun sum(x: Int, y: Int): Int = x + y // 일반적인 함수 정의
val sumVal = { x: Int, y: Int -> x + y } // 람다 표현식으로 sumVal에 대입
val sumVal2 = { x: Int, y: Int ->
println("hello")
x + y // 람다함수 내부가 여러줄일때 마지막줄이 리턴값이 된다.
}
val sum1 = { -> 10 + 20 } // 매개변수가 없는 람다
val sum2 = { 10 + 20 } // 매개변수가 없는 람다
fun main() {
{x: Int, y: Int -> x+y}(10,20) //람다함수 정의 하고 바로 호출
}
참조 : 깡샘의 코틀린 프로그래밍