Why Functional Programming matters? 해석

in #kr-dev7 years ago

아래 논문의 Introduction 에 대한 해석입니다.
주관적인 경험이나 견해를 바탕으로 해석한 것임을 알려드립니다.

http://www.cse.chalmers.se/~rjmh/Papers/whyfp.html

앞서 이야기에서의 핵심은 두가지 단어입니다.

모듈라 디자인 : 프로그래밍 생산성 향상의 키 포인트

  • 작은 모듈은 신속히 코딩할 수 있다.
  • 일반적인 모듈은 재사용될 수 있다.
  • 모듈은 독립적으로 테스트되며, 이는 디버깅 시간을 줄여준다.

Glue(글루) : 모듈화 된 프로그램을 합치는 도구

프로그램을 작은 서브 프로그램으로 쪼개는 방법은
이 글루가 동작하는 방식에 의존한다.


구조적 프로그래밍에서
커다란 프로그램을 작은 프로그램을 쪼개고
이를 다시 붙이는 도구(글루)는 [순차, 반복, 분기] 입니다.
이 흐름에 따른 코드를 서브루틴으로 쪼개는 것이 모듈화의 근간입니다.

함수형 프로그래밍에서 Glue 는
정의 그 자체로 함수를 매개변수로 하는 것입니다.

아직 이것이 Glue 라는 생각이 들지 않지요?


리스트 [ [1,2,3,4,5], [6,7,8,9,10] ] 가 있습니다.
이 리스트의 구성원소는 리스트이며 개수는 2개입니다.
이들의 합을 모두 구하는 프로그램을 작성해 봅시다.

자바 코드라면 아래처럼 될텐데요...
첫번째 함수와 두번째 함수가 비슷한 것 같지만, 젼혀 다릅니다.
즉, sumMat 을 sum 을 가지고 만들 수 없다는 뜻입니다.
(이런 것을 모듈성이 떨어진다)라고 표현해도 될 것입니다.

int sum(List<Integer> list) {
    int sum = 0;
    for ( int i = 0; i < list.size(); i++ ) {
        sum += list.get(i);
    }
    return sum;
}

int sumMat(List<List<Integer>> matrix) {
    int sum = 0;
    for ( int i = 0; i < matrix.size(); i++ ) {
        sum += sum(matrix.get(i));
    }
    return sum;
}

public static void main(String[] args) {
    List<List<Integer>> matrix = Arrays.asList(
            Arrays.asList(1, 2, 3, 4, 5),
            Arrays.asList(6, 7, 8, 9, 10) );
    System.out.println(new Structured().sumMat(matrix));
}



어떤 이는
"아!! 저건 자바가 정적 타입의 언어이어서 그래..."
"매개변수에 타입이 들어가 있어서 그렇지..."
"타입 정의가 불필요한 자바스크립트에서는 하나로 가능할거야"
할런지 모릅니다.

자바스크립트로 작성해 봅니다.

function sum(list) {
  var ret = 0
  for (var i = 0; i < list.length; i++)
    ret += list[i]
  return ret
}

function summat(list) {
  var ret = 0;
  for (var i = 0; i < list.length; i++) {
    ret += sum(list[i])
  }
  return ret
}

var matrix = [ [1,2,3,4,5], [6,7,8,9,10] ]
console.log(summat(matrix))


sum 과 summat 을 하나로 할 수 있을까요?
이제 다른 것은 아래 1줄 뿐인데, 달랑 이 1줄 때문에,
두개의 함수를 만들어야 한다니 어이가 없네요.

ret += list[i]
ret += sum(list[i])


커다란 프로그램을 만들 때, 비슷한 함수가 1개 있느냐 2개 있느냐는
유지보수나 확장에 있어서 커다란 차이가 있으며,
LOC 에도 커다란 영향을 미치게 됩니다.
Good programmer 1 - 내가 관리할 수 있는 코드량은? 참고

가만히 보면 summat(list) 를 sum(sum(list))
이런식으로 바꾸면 될 것 같지만,
하지만 구조적 프로그래밍에서는 이러한 글루를 제공하지 않습니다.

함수형 프로그래밍에서 가장 많이 접하는 함수는 map 이라는 함수입니다.
이 함수는 리스트를 인자로 받아서 새로운 리스트를 반환하는 함수입니다.
이 함수의 인자는 함수입니다.

function twice(x) { return x * 2 }
var list = [1,2,3]
console.log(list.map(twice))


map(twice) 는 합성함수입니다.
map 이라는 함수는 함수를 입력받아서 새로운 함수를 리턴하는 함수입니다.
이러한 함수를 high-order function 이라고 합니다.

주어진 문제를 map 을 이용해서 풀어보지요.

var mid_list = matrix.map(function(list) {
    return sum(list)
})
sum(mid_list)


아주 간단히 쓰면 다음과 같이 됩니다.

sum(matrix.map(function(list) {return sum(list)}))


약간 표현이 이상한데 그것은 matrix 와 map 사이의 . 때문입니다.
matrix.map(func) 의 형태에서 . 을 쓰는 것은 객체지향 스타일에 기인합니다.

다시 쓰면, map(matrix, func) 이며 함수만 적으면 map.func 가 됩니다.
(. 은 합성함수 기호)
여기서 func 는 sum 이므로, 위의 결과를 다시 쓰면

sum(map(sum))(list)

가 됩니다.

sum.map.sum 을 도식화하면 아래 그림처럼 익숙한 그림이 됩니다.


함수형 프로그래밍에서는 함수를 결합시키는 방식으로 프로그래밍을 합니다.

논문의 3. Gluing Functions Together 에는,
Cons 와 fold 가 나옵니다. 이 두가지를 합성해서 map 함수가 나옵니다.
filter 도 함수형에서 중요한 primitive 한 함수입니다.
fold 를 reduce 라고도 합니다.

이로서 함수형 프로그래밍의 3형제 map, reduce, filter 가 다 나왔습니다.

Sort:  

I know some Programming ,

2+2=4
retired-judge-builds-neighborhood-pool-keith-davison-2-.jpg

thanks for sharing!.I appreciate you if you upvoted my posts @deshwal

포스팅 감사드립니다.
sum함수를 reduce로 구현하면 코드 총 량을 더 줄일 수 있겠군요!
함수형 프로그래밍은 앞으로 더 많이 쓰일 기술이라 생각합니다. 계속 연재 부탁드릴께요~~

원래 sum 은 reduce 로 만들지요...
map 은 reduce 로 만들고
filter 는 뭐로 만드는지 모르겠네요... map, reduce 를 잘 결합시키면 될 것 같은데요

Coin Marketplace

STEEM 0.28
TRX 0.11
JST 0.034
BTC 66137.63
ETH 3161.38
USDT 1.00
SBD 4.13