오늘 오랜만에 친구를 만나서 수다 좀 떨다가 왔습니다. 당연 하루 정도 날라갔어요. 빨리 해야 되는데. ㅠ.ㅠ
그리고, 나름 먹튀를 본 듯 합니다. 대답해 줬더니 글이 없어요. 보류에도 없는 듯 하고. ㅠ.ㅠ
질문 글도 아니고, 나누면서 나도 좀 기억해 보자는 의미로 글을 쓰지만, 먹튀를 보니 본인 삭제 금지를 걸고 싶어 졌습니다.
틀리면 어떻하지 이거 흑역사 되는 건가? .... ㅠ.ㅠ
일단, 제목 보시면 mind blown, 제 정신이 아닌 거죠. ..... WWDC 비디오, advanced swift를 보는데 진짜로 저런 내용이 나옵니다.
이거 보면 멍~~~ 하실 겁니다. 뭐 이런 건데.. 진짜 멍 하더군요. 일단, 신기한 것부터 시작해 봅시다.
1. syntax
함수 이름 같은 걸 이용해서 짜기 쉽고, 읽기 쉽게 만들 수 있다는 겁니다. 예를 들면 이런 거죠.
println("You aren't sure how to pull \(an ~ object).")
>PULL MUD
You aren't sure how to pull mud.
>PULL ORANGE
You aren't sure how to pull an orange.
보시면 알겠지만, 시현을 하면서 mud game을 짜고 있더라구요. 그 짧은 시간에 게임 하나를 뚝딱..
암튼, an ~ object 라는 syntax를 만들어 쓸 수 있습니다. an도 함수고 ~ 도 함수고 object는 struct 아니면 class겠죠.
읽기는 좋은데, 만들기는 어렵고.. 영어 읽기 쉽게 만든다고 우리가 읽기 쉬울까요? 그래도, 신기하네요.
2. generic programming
자 이제 쓸데없이 있지도 않은 상상 속의 동물 "여친"이나 생각하는 brain을 날려 버릴 때가 됐습니다. ㅋㅋㅋ...
(그러나, 현실에는 아내가 있죠. 아내는 존재합니다.)
진짜 멍~~~ 했거든요. 이거 혹시 흑역사 되는지 모르겠네. ㅠ.ㅠ
func fibonacci(n: Int) -> Double {
return n < 2 ? Double(n) : fibonacci(n - 1) + fibonacci(n - 2)
}
let phi = fibonacci(45) / fibonacci(44) // 1.61803399... 11 sec
값은 1.618.. 뭐 이런 거고 11초가 걸린답니다. 준수하네. 11초 정도는 기다릴 수 있습니다....
(도대체 뭘로 돌린 거야? 내 맥이 고물인 거야? 11초는 개*.. 스크립트로 돌려서 그런 건가?. 그럴 거야. ㅠ.ㅠ)
(너무 오래 걸리네요. 174911 times 에서도 답이 안 나와요. ㅠ.ㅠ)
만.. 천재적인 애플 직원을 그럴 수 없다는 군요. 그래서..
var fibonacciMemo = Dictionary<Int, Double>()
func fibonacci(n: Int) -> Double {
if let result = fibonacciMemo[n] {
return result
}
let result = n < 2 ? Double(n) : fibonacci(n - 1) + fibonacci(n - 2)
fibonacciMemo[n] = result
return result
}
let phi = fibonacci(45) / fibonacci(44) // 0.1 sec 보다.. 빠른 듯.
이런 식으로 짜면, 중간 과정을 저장해 놓기 때문에 반복과정을 없애서 무지 빠르게 계산이 된다는 겁니다.
진짜 그렇습니다. 무지 빠르네요. 근데, 까탈스럽기로 유명한 애플 직원이 이건 좀 아니라는 겁니다.
let fibonacci = memoize {
fibonacci, n in
n < 2 ? Double(n) : fibonacci(n - 1) + fibonacci(n - 2)
}
memoize? 드디어 핵심이 나왔습니다. fibonacci 좀.. 멍 하잖아요. 근데, 이건 더 멍~~~~. memoize
func memoize<T: Hashable, U>( body: (T) ->U ) -> (T)->U {
var memo = Dictionary<T, U>()
return { x in
if let q = memo[x] { return q }
let r = body(x)
memo[x] = r
return r
}
}
(돌리다 뻑 났습니다. 오... 이거 위험한 코드구나, 역시 외계어는 위험..)
(맥도 맛이 갈 수 있네요.. ㅠ.ㅠ 속도가 ㅠ.ㅠ 메모리가 16GB 인데 15.99GB를 쓰고 있네요. 뭐냐?)
아무튼, 뻑이 난 관계로 다시 시도하기가 좀 무서워서 돌려 보지는 않고 계속 쓰겠습니다.
그러니까 이게 generic 인데, 함수를 받아서 함수를 내어 놓는 거죠. 흠.. generic인데 함수를 받아서 함수를 내어 놓는다.
이거 c++ generic에서도 하긴 하나요? 가물거리네. 뭔가 더 외계어인거 같은데,
그래서 이게 가능합니다.
let parsePropertyList = memoize { (s: String) in s.propertyList() }
참고로 memoization은 속도를 높이는 기술인데, 계산 결과를 저장해 놨다가 같은 계산을 요구하면 저장된 결과를 이용하는 걸 말하는 거랍니다.
오... 그렇구나. 암튼, generic 답게 다른 함수도 만들어 내어 놓는군요... 오... 난 이게 더 이상해. ㅠ.ㅠ
아무튼, 그래서 재귀 함수가 나오면 막 쓰면 되는 겁니다. 팩토리얼도 돌려봅시다.
let factorial = memoize { x in x == 0 ? 1 : x * factorial(x - 1) }
근데 이게 문제가 있다는 군요. 이유가 처음이 이상하다는 군요. 그래서, 이렇게 고치면 됩니다.
var factorial: (Int)->Int = { $0 }
factorial = memoize { x in x == 0 ? 1 : x * factorial(x - 1) }
문제는 이걸 그냥 넘어갈 애플 직원이 아니죠. (외계인인 듯..)
func memoize<T: Hashable, U>( body: ((T)->U, T)->U ) -> (T)->U { // generic, T는 Hashable 프로토콜을 만족해야 한다.
// body라는 변수는 형이 (함수, 변수)->변수 인 함수.
// 리턴 값은 (T)->U 인 함수
var memo = Dictionary<T, U>() // 저장 공간 선언
var result: ((T)->U)! // forced unwrapping
result = { x in // closuer, trailing
if let q = memo[x] {return q } // optional binding, 있으면 저장 값 리턴
let r = body(result, x) // 넘겨 받은 closure, body
memo[x] = r // 결과 저장
return r // 리턴
} // 이런 closuere를 trailing으로 가지고 있는 함수를
return result // 리턴합니다.... ??????
}
let factorial = memoize { factorial, x in x == 0 ? 1 : x * factorial(x - 1) } // ??????????????????????
잉?????????????????? 아..... 외계어구나.
아무튼 이게 여러분의 머리를 날려 버릴 거라군요. ..
왜 날라가는지 모르겠다구요? 이미 날라간 겁니다. ㅠ.ㅠ
이런 게 많답니다. 잘 쓰면 엄청 좋답니다. 메뉴얼에 있다네요.
반절쯤 읽었는데.. 없던데.. 뒷 부분인가? 어쩐지 class까지 다 나왔는데 반절밖에 안 나갔더라.. ㅠ.ㅠ
저 위에 쓴 코드를 이해할려면 이런 걸 알아야 합니다.
1. type deduction : swift는 type safe 언어임에서 type 생략이 가능합니다. type에 대한 힌트만 있다면..
2. trailing closure : closure는 objective c 에서는 block 다른 언어에서는 lambda 같은 건데, 이걸 뒤로 빼는 거죠. 읽기 쉬우라고..
근데, 난 더 읽기 어려어요.. closure인지 함수인지 헷갈리는데..
3. generic : c++ 쓰거나 하면 아시겠죠. java는 대충 공부해서 있는지 없는지 잘 모르겠네요.
4. protocol : Hashable 이 protocol 입니다.
5. optional : optional과 그냥 type을 호환해서 쓸려면 !로 풀어야 합니다.
그러니까, 이런 걸 다 알면 외계어를 읽을 수가.. 있겠죠. 난 몰라서 멍~~~ 할 뿐인 거야.
다섯개 다 아는데도 코드가 뭔 소린지 모르고, 멍~~~ 하다고 생각되는 건 내 착각일 거야. 그럴거야. ㅠ.ㅠ
마지막으로 swift model이라고 설명이 나오는데.. 약간 뜬 구름 잡는 거라, 쓰는데 별로 필요 없는 내용입니다.
swift가 추구하는 "이상" 쯤 될 듯 합니다.
결론은.. 멍~~~ 하네요.