본문 바로가기
android/Kotlin

Kotlin 과 Fp(funtion programing)의 관계

by junmong 2020. 4. 12.

Fp(Function Programing) 란 OOP(Object Oriented Programig)와 전혀 다른 개념이 아니다.

 

OOP를 잘 이해하고 있어야 Fp를 잘 사용 할 수 있다.

Immutable 한 자료구조를 사용해 SideEffect를 최소화.

상태를 바꾸기 보다는 변경 불가능한 데이터와 순수 함수를 이용 한 프로그래밍.

모든 것은 객체다.(함수도 객체)

 

  •    var  
  •    variable
  •    read/write
  •    java normal variable

 

  •    val 
  •    value
  •    readOnly
  •    java final variable

val immutable : String = "immutable"

var mutable : String = "mutable"

 

immutable = "test"  //error

mutable = "test"   //ok

 

val value : Int

value = 3    //ok

value = 4   //error

 

  • Variable  
  • 함수형 프로그래밍을 해보고 싶거나 SideEffect를 피하고 싶다면 var 보다는 val을 사용하는 습관이 좋다.
  • 변수 선언시 : 타입을 생략 하면 컴파을러가 추론한다. 하지만 명시적으로 타입을 선언해 주는게 가독성이나 유지보수 측면에 좋다
  • ;(세미콜론) 은 한줄에 여러 변수를 선언하지 않는다면 생략가능 하다.

Function 사용법

 

1. fun add(x: Int, y: Int) : Int {

      return x + y 

}

2. fun add(x: Int, y: Int): Int = x + y  // 함수의 Body 가 한줄인 경우

 

  • fun 키워드 사용
  • 함수의 반환 타입을 생략 할수 없다. 생략이 가능 한 경우는 반환 타입이 Unit 일 경우에만 생략이 가능 하다.
  • Unit 은 java의 Void와 비슷하게 생각하면 되지만 실제로는 Unit은 Singleton 객체이다.
  • 리턴 타입을 생략하면 default 로 반환타입은 Unit이 된다.
  • ;(세미클론)은 생략가능
  • 함수의 Body가 한줄인 경우 {...} 대신  = 로 대신 할 수 있다.

 

First - Class citizen

객체의 인자로 전달 할 수 있어야 한다.
fun function(param: () -> Unit){
       param()
}
function({ println("Hello , World")  })
객체의 반환값으로 변환 할 수 있어야 한다.
fun function(): () -> Unit {
       return {println("Hello, World")}
}
자료구조에 넣을 수 있어야 한다.
fun function(): () -> Unit{
       return {  println("Hello, World")  }
}
val value = function()

 

PureFunction

fun PureFunction(str: String): String{
       return str + "Test"
}
println(pureFunction("Kotlin"))   // kotlinTest
println(pureFunction("Kotlin"))   // kotlinTest
println(pureFunction("Kotlin"))   // kotlinTest
println(pureFunction("Kotlin"))   // kotlinTest
val strBuilder = StringBuilder()
fun nonePureFunction(str: String): String{
      return str + strBuilder.appned("Test").toString()
}
println(nonePureFunction("kotlin"))  // kotlinTest
println(nonePureFunction("kotlin"))  // kotlinTestTest
println(nonePureFunction("kotlin"))  // kotlinTestTestTest
println(nonePureFunction("kotlin")) // kotlinTestTestTestTest

 

Higher-Order Function

fun simpleHighOrderFunction(sum: (Int, Int) -> Int, a: Int, b: Int ): Int{
      return sum(a,b)
}
fun simpleHighOrderFunction(a: Int, b: Int): () -> Int{
       return { a + b }
}
함수를 파라미터로 전달 받거나, 함수를 리턴하는 함수를 말한다.

 

/* java */
interface Calcable{
     int calc(int x , int y); 
}
public class Sum implements Calcable{                 =  Calcable calcSum = new Sum();
   @Override                                                          =  int resultSum = calcSum.calc(1,5); // 6
     public int calc(int x, int y){
        return x + y; 
   }
}
public class Minus implements Calcable{              =   Calcable calcMinus = new Minus();
   @Override                                                          =   int reusltMinus = calcMinus.calc(5,2);  //3
    public int calc(int x, int y){
      return x - y;
  }
}
public class Product implements Calcable{           = Calcable calcProduct = new Product();
     @Override                                                        = int resultProduct = calcProduct.calc(4,2);   // 8
       public int calc(int x,int y){
          return x * y; 
   }
}
/* Kotlin */
fun simpleHighOrderFunction(sum: (Int, Int) -> Int, a: Int, b: Int): Int{
  return sum(a, b)
}
val sum: (Int, Int) -> Int = { a, b -> a + b }
val product: (Int, Int) -> Int = { a, b -> a * b}
val minut: (Int, Int) -> Int = { a, b -> a - b }

println(simpleHighOrderFunction(sum, 1, 5))  // 6
println(simpleHighOrderFunction(product, 5, 2))  // 10
println(simpleHighOrderFunction(minus, 4, 2))  // 8
Anonymous Function
val value = sum(5,10,{ x, y -> x + y })
fun sum(x: Int, y: Int, function: (Int, Int) -> Int) :Int{
      return function(x, y)
}
CallByValue
val function: () -> Unit = { println("Lezhin") }
fun callByValue(): Unit{
     return function()
}
callByValue()  // Lezhin

val function: () -> Unit = { println("Lezhin") }
fun callByValue(): () -> Unit{
     return function()
}
callByName()    // nothing
callByName().invoke()  // Lezhin
callByNmae()()     // Lezhin

val function: () -> Unit = {
    // 엄청 복잡하고 엄청 리소스가 많이 들고 엄청 오래걸리는 연산
    println("OTL")
}

fun firstClassCitizenFunction(func: () -> Unit, flag: Boolean){
   if (flag){
     func()
  } else{
      println("finish")
  }
}
firstClassCitizenFunction(function, false)  // finish
상황에 따라 특정 함수를 호출 할 수도 있고 호출 하지 않을 수 있다면 함수의 평가를 Lazy 하게 효율적으로 처리 할 수 있다.
실습
type이 Int인 변수 a, b, c 3개와 Int 3개를 입력받아 Int를 모두 더한 값을 반환하는 익명함수를 갖는 함수

fun sumInts(x: Int, y: Int, z: Int, function: (Int, Int, Int) -> Int): Int{
     return function(x,y,z)
}

 

'android > Kotlin' 카테고리의 다른 글

Kotlin DI 라이브러리 Koin  (0) 2020.05.26
Kotlin Collections  (0) 2020.04.19
Kotlin StandardLib  (0) 2020.04.17
Kotlin Expression  (0) 2020.04.16
Kotlin Class  (0) 2020.04.13