OOP ๋‹ค์Œ์œผ๋กœ ๋– ์˜ค๋ฅด๋Š” ํŒจ๋Ÿฌ๋‹ค์ž„์ธ FP์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž. ๋ฌผ๋ก  FP๋Š” OOP๋ณด๋‹ค ๋จผ์ € ๋“ฑ์žฅํ–ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ‘์ž๊ธฐ ์™œ ๋“ฑ์žฅํ•˜๊ฒŒ ๋˜์—ˆ์„๊นŒ? FP์˜ ์žฅ์ ๊ณผ ๊ฐœ๋…์„ ์ดํ•ดํ•˜๋ฉด์„œ ์•Œ์•„๊ฐ€๋ณด์ž.

Functional Programming

  • ์ž๋ฃŒ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ•™์  ํ•จ์ˆ˜์˜ ๊ณ„์‚ฐ์œผ๋กœ ์ทจ๊ธ‰
  • ์ƒํƒœ์™€ ๊ฐ€๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ํ”ผํ•จ
    • ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค.
  • Side-Effect๊ฐ€ ์—†์Œ
    • ์ž˜๋ชป๋œ code๋กœ ์ธํ•œ ์˜ค์ž‘๋™์˜ ์˜๋ฏธ๊ฐ€ ์•„๋‹˜
    • ์‹คํ–‰ ๊ฒฐ๊ณผ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์ผ์œผํ‚ค๋Š” ๋ชจ๋“  ๊ฒƒ
    • ํ•ด๋‹น ์ฝ”๋“œ์˜ ์‹คํ–‰์œผ๋กœ ์ธํ•ด ๊ฒฐ๊ณผ๊ฐ’์„ ๋ณ€๊ฒฝ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ
  • Function์ด๋ž€?
    • ๋ณ€์ˆ˜ x์™€ y์‚ฌ์ด์˜ ๊ด€๊ณ„ ๋งคํ•‘(์‚ฌ์ƒ)
  • ๋– ์˜ค๋ฅด๋Š” Paradigm
    • OOP์ดํ›„ ๊ฐ€์žฅ ํฐ ํŒจ๋Ÿฌ๋‹ค์ž„ ์ค‘ ํ•˜๋‚˜
    • SDK์—๋„ ๋“ค์–ด๊ฐ€๋Š” ๊ฐœ๋…
    • Functional Programming ์Šคํƒ€์ผ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด์„œ Functional Programming์„ ํ•œ๋‹ค๊ณ  ํ•  ์ˆ˜ ์—†์Œ
    • ๋™์ผํ•œ ๋ฌธ์ œ์˜ ํ•ด๋ฒ•์— ๋Œ€ํ•ด ์ƒˆ๋กœ์šด ์‹œ๊ฐ์ด๋ผ ์ƒ๊ฐํ•ด์•ผ ํ•จ
  • var์™€ loop๊ฐ€ ์—†๋Š” ์ฝ”๋“œ
    • ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—๋Š” ๋ณ€์ˆ˜์™€ loop๊ฐ€ ์—†๋‹ค.

    • ์ด ๊ฐ€์ •์„ ํ•˜๊ณ  ๊ตฌ๊ตฌ๋‹จ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž.

      func gugudan(left: Int, right: Int) {
          if left > 9 || right > 0 {
              return
          }
          print("\(left) x \(right) = \(left * right)")
          
          if right <= 9 {
              gugudan(left: left, right: right+1)
          } else {
              gugudan(left: left + 1, right: 1)
          }}
      }
       
      gugudan(left: 1, right: 1)
    • ์ด๋ ‡๊ฒŒ ์žฌ๊ท€๋กœ ์งœ์•ผ ํ•œ๋‹ค.

      • ์žฌ๊ท€๋Š” Stack Overflow๋‚˜์ง€ ์•Š๋‚˜? ํ•จ์ˆ˜์ฝœ์ด Stack์— ๊ณ„์† ์Œ“์ด๋‹ˆ๊นŒ.
        • Tail Call Optimization(TCO)
        • Tail Call Optimization ์‰ฌ์šด ์„ค๋ช…
          • ์š”์•ฝ
            • Stack์—๋Š” ํ•จ์ˆ˜๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ, ๋Œ์•„๊ฐ€์•ผ ํ•˜๋Š” ์ฃผ์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
            • ๊ทธ๋Ÿฐ๋ฐ, ๋งŒ์•ฝ ํ•จ์ˆ˜ return ๋ถ€๋ถ„์— ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ๋งŒ ํ•˜๊ณ  ์ข…๋ฃŒํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด, ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜๋กœ ๋Œ์•„์˜ฌ ์ด์œ ๊ฐ€ ์—†๋‹ค.
              • ์ถ”๊ฐ€ ๊ณ„์‚ฐ์ด ํ•„์š”์—†๊ธฐ ๋•Œ๋ฌธ
            • ์ด๋Ÿฐ ๊ฒฝ์šฐ, ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜์˜ ๋Œ์•„์˜ฌ ์ฃผ์†Œ๋ฅผ Stack์— ์ €์žฅํ•˜์ง€ ์•Š์•„ ๊ณต๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.
            • ์ด๊ฒƒ์„ Tail Call Optimization์ด๋ผ ํ•œ๋‹ค.
    • ๊ฐ‘์ž๊ธฐ ๋”ฑ, ํ’€๋ ค๊ณ  ํ•˜๋‹ˆ ๊ฐ‘์ž๊ธฐ ๋ฐ”๋ณด๊ฐ€ ๋œ ๊ธฐ๋ถ„์ด ๋“ ๋‹ค.

    • ์‚ฌ๊ณ ์˜ ์ „ํ™˜์„ ํ•ด์•ผ ํ•œ๋‹ค..

๊ธฐ๋ณธ์ ์ธ ์„ธ ์ข…๋ฅ˜์˜ Function

  • Pure Function
    • ๋™์ผํ•œ input์— ๋Œ€ํ•ด ํ•ญ์ƒ ๋™์ผํ•œ output์„ ๋ฐ˜ํ™˜
    • Parameter์ด์™ธ์— ์—ฐ์‚ฐ์— ํ•„์š”ํ•œ ์ •๋ณด๊ฐ€ ์—†๋‹ค.
      • ๋ณ€ํ™”ํ•˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ ธ์™€์„œ ์“ด๋‹ค๋˜๊ฐ€ ํ•˜๋Š” ํ–‰์œ„ ๊ธˆ์ง€
    • input๋œ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ
      • ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ
    • Side-Effect๊ฐ€ ์—†๋‹ค.
      • ์‹คํ–‰์ด ์™ธ๋ถ€์— ์˜ํ–ฅ์„ ๋ผ์น˜์ง€ ์•Š๋Š”๋‹ค.
    • Thread์— ์•ˆ์ „ํ•˜๊ณ , ๋ณ‘๋ ฌ ๊ณ„์‚ฐ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • Anomymous Function
    • Closure, Block
  • Higher-Order Function
    • Function์„ Parameter๋กœ ๋ฐ›๋Š” function
    • Function์„ return value๋กœ ์‚ฌ์šฉํ•˜๋Š” Function
    • Closure๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š” Function๋“ค์€ Higher-Order Function
  • ์˜ˆ์‹œ
    import Foundation
     
    // Anonymous function
    let inRange: (Int) -> Bool = { (_ value: Int) -> Bool in
        return value <= 9
    }
     
    // Pure Function
    func print(left: Int, right: Int) {
        print("\(left) x \(right) = \(left * right)")
    }
     
    // higher Order Function
    func gugudan(left: Int, right: Int, checker: (Int) -> Bool) {
        if checker(left) == false || checker(right) == false {
            return
        }
        print(left: left, right: right)
        
        if checker(right + 1) {
            gugudan(left: left, right: right+1, checker: checker)
        } else {
            gugudan(left: left + 1, right: 1, checker: checker)
        }
    }
     
    gugudan(left: 1, right: 1, checker: inRange)