ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•ด๋ณด๋ฉด ๊ผญ ๋‚˜์˜ค๋Š” ์šฉ์–ด๋“ค์ด ์žˆ๋‹ค. ์ผ๊ธ‰ ์‹œ๋ฏผ, ํ•จ์ˆ˜ ํ•ฉ์„ฑ, ์ปค๋ง ๋“ฑ. ์˜ค๋Š˜์€ ์ด๋Ÿฌํ•œ ๋‹จ์–ด๋“ค์— ๋Œ€ํ•ด์„œ ์ดํ•ดํ•ด๋ณด์ž.

First Class Function

  • function์€..
    • argument๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ

    • returnํ•  ์ˆ˜ ์žˆ์Œ

    • ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Œ

    • anonymous function

    • nested function

    • non-local variable

      func outer() {
          var x = 1
          func inner() { // nested function
              x += 1 // non-local variable
              print(x)
          }
          return inner // function return ๊ฐ€๋Šฅ
      }
    • closure

    • equality

      • Extensional Equality
        • ๋‘ function์ด ๋™์ผํ•œ ์ž…๋ ฅ์— ๋Œ€ํ•ด ๋™์ผํ•œ ์ถœ๋ ฅ์„ ๊ฐ€์ง€๋Š” ๊ฒฝ์šฐ
      • Intensional Equality
        • ๋‘ Function์ด ๋™์ผํ•œ logic์„ ๊ฐ€์ง€๋Š” ๊ฒฝ์šฐ
      • Reference Equality
        • Function ๊ณ ์œ ์˜ Identifier๊ฐ€ ๋™์ผํ•œ ๊ฒฝ์šฐ
      • Swift๋Š” function Equality๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Œ

Function Composition

  • function composition
  • ๋…๋ฆฝ์ ์ธ function ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ๋‚˜๋ˆ„์–ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•
  • ์ฆ‰, ํ•ฉ์„ฑํ•จ์ˆ˜๋ฅผ ๋งํ•จ
  • ๋‹จ์ˆœํ•œ pure function์„ ์ž˜ ๋งŒ๋“ค์–ด๋‘๊ณ , ์กฐํ•ฉ/์žฌํ™œ์šฉํ•˜์—ฌ ํ•ฉ์„ฑ
  • Function ๋‹จ์œ„์˜ ์žฌํ™œ์šฉ์„ฑ์ด ๋†’์•„์ง
  • Code์ฝ๊ธฐ๊ฐ€ ์šฉ์ด
  • function ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์šฉ์ด
  • ๋ฒ„๊ทธ ๊ฐ์†Œ

Partial Application

  • ๋ถ€๋ถ„ ์ ์šฉ
  • Multi-argument function์—์„œ ์ƒ๋žต๋  argument์˜ ๊ฐ’์„, ๋ฏธ๋ฆฌ ์ •ํ•˜์—ฌ ๋” ์ ์€ argument๋ฅผ ๋ฐ›๋Š” function์œผ๋กœ ๋ณ€ํ˜•ํ•˜๋Š” ๋ฐฉ๋ฒ•
    • default value๋Š” ๊ฐ’์— ๋Œ€ํ•ด์„œ ์ •ํ•ด๋‘๋Š” ๊ฒƒ
    • ํ•˜์ง€๋งŒ ์ด๊ฑธ ํ•จ์ˆ˜๋กœ ์ •ํ•ด๋‘๋Š” ๊ฒƒ์„ ๋งํ•จ
import Foundation
 
func guguStringFormat(left: Int, right: Int, expressFormat: String) -> String {
    return String(format: expressFormat, left, right, (left * right))
}
 
func gugustringGenerator(left: Int, expressFormat: String) -> (Int) -> String {
    return { (right: Int) -> String in
        guguStringFormat(left: left, right: right, expressFormat: expressFormat)
    }
}
 
let generator3 = gugustringGenerator(left: 3, expressFormat: "%d x %d = %d")
let result3 = (1...9).map(generator3)
 
print(result3.joined(separator: "\n"))
  • ์ƒ๋‹นํžˆ ์‚ฌ๊ณ ์˜ ์ „ํ™˜์ด ํ•„์š”ํ•จ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

Currying

  • ์—ฌ๋Ÿฌ๊ฐœ์˜ argument๋ฅผ ๋ฐ›๋Š” function์„ ๋‹จ์ผ argument๋ฅผ ๋ฐ›๋Š” function chain์œผ๋กœ ๋ณ€ํ˜•

  • ์‹ค์ œ๋กœ ๋งŒ๋“ค์–ด์„œ generic์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ฐธ ๋จธ๋ฆฌ์•„ํ”„๋‹ค.

  • currying opensource ์žˆ์œผ๋‹ˆ ์‚ฌ์šฉํ•ด๋ณด์ž.

  • ์˜ˆ์‹œ

    func f(a: Int, b: Int) -> Int {
        return a + b
    }
     
    func g(a: Int) -> (Int) -> Int {
        return { (b: Int) -> Int in
            return a + b
        }
    }
     
    print(f(a: 3, b: 4))
    print(g(a: 3)(4))
  • ํ™œ์šฉ๋„

    • ๋‘๋ฒˆ์งธ argument ํ™œ์šฉ์„ ์ง€์—ฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ ์—ฐํ•จ์„ ์ œ๊ณต

      func add(a: Int, b: Int) -> Int {
          return a + b
      }
       
      func curriedAdd(a: Int) -> (Int) -> Int {
          return { (b: Int) -> Int in
              return a + b
          }
      }
       
      let curriedAdd3 = curriedAdd(a: 3)
      let result = [2, 4, 7].map(curriedAdd3)
      print(result) // 5 7 10
    • Factory for functions

      • ์ผ๋ถ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ณ ์ •ํ•ด์„œ ํŠน์ • ์šฉ๋„์˜ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
    • Template Method Pattern

      • template method pattern
        • ๊ฐ์ฒด์˜ ๊ธฐ๋ณธ ๊ณจ๊ฒฉ์„ ๋งŒ๋“ค์–ด๋‘๊ณ (abstract class)
        • ์‹ค์ œ ์‚ฌ์šฉํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์ƒ์†๋ฐ›์•„ ๊ตฌ์ฒดํ™” ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ํŒจํ„ด
      • partial application์„ ์ด์šฉํ•ด ์ด๋ฏธ ์•Œ๋ ค์ง„ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ  ๋‚˜๋จธ์ง€ parameter๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ๋‚จ๊ฒจ๋‘š
    • ๋ฌต์‹œ์ ์ธ ๊ฐ’

      • ์ผ๋ถ€ parameter๋ฅผ ๊ณ ์ •ํ•ด์„œ default parameter์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ฆ