클로져 시작하기 책을 보다가
번역이 구조분해라구 된 Destructuring
를 같이 토의도 해보고 했다. 이거 꽤 많이 씀.
전형적인 되도는 프로세스를 만드는 함수를 짜보자.
1 2 3 4 5 6 7 8 9 10 11 12 13
| (defn foldr [f init coll] (if (empty? coll) init (f (first coll) (foldr f init (rest coll))))) (defn foldr* [f init coll] (if (empty? coll) init (let [[h & t] coll] (f h (foldr f init t)))))
|
reduce
함수와 조금 다른 옛 이름의 foldr
함수를 구현해 보았다. (let [[h & t] coll] ...
부분이 구조 분해가 일어나는 부분.
기본적으로는 패턴매칭을 이용하고 있으므러 다른 언어로도 구현해보자
스킴의 하나인 racket
은 정신나간 매크로확장을 많이 하는 동네라서 찾아보면 온갖 매크로가 다 튀어나온다.
스킴으로는 클로져의 경우와 반대로 이름이 reduce
인 foldl
을 구현해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| (define (reduce f init coll) (if (null? coll) init (f (reduce f init (cdr coll)) (car coll)))) (define (reduce* f init coll) (if (null? coll) init (match-let ([(list h t ...) coll]) (f (reduce* f init t) h)))) (define (reduce** f init coll) (match coll ['() init] [(list h t ...) (f (reduce** f init t) h)])) (define/match (reduce*** f init coll) [(f init '()) init] [(f init (list h t ...)) (f (reduce*** f init t) h)])
|
결국 함수선언부 패턴매칭까지 오게 되는데 라켓에는 뭔가 뭘 좋아할지 몰라서 다 준비했다는 식으러 문법확장이 너무 지나치게 많이 일어나는 것 같은 감이 있다.
덤으러 이런건 자바스크립트에서도 된다.
1 2 3 4 5 6 7 8
| function foldr(f, init, coll) { if( coll.length == 0 ) { return init; } else { let [h, ...t] = coll; return f( h, foldr(f, init, t)); } }
|
생각해보면 이런거 하기 가장 좋은 플랫폼은 하스켈 아닌가?