함수형 프로그래밍의 정의 - part 1

그동안 나는 자바스크립트를 객체지향프로그래밍으로 배워왔다.
그런데 최근 inflearn에서 유인동 강사님의 자바스크립트강좌를 보고 함수형 프로그래밍의 중요성을 깨닫게 되었고,
꼭 내가 앞으로 성공적인 프로그래밍을 하기 위해서 제대로 배워야 겠다는 욕심이 생겼다.
이번에 새로 hexo를 통해 개발공부관련 블로그를 파보았는데 어떤 글부터 써야 할지 고민했었다.
고민 끝에 자바스크립트를 통해 배우는 함수형 프로그래밍을 첫 포스팅주제로 결정하였다!


.
.
.

객체지향이랑 뭐가 다른데?

1
2
3
4
5
6
7
8
9
10
11
12

/* 데이터(객체)기준 */
duck.moveLeft();
duck.moveRight();
dog.moveLeft();
dog.moveRight();

/* 함수 기준 */
moveLeft(dog);
moveRight(duck);
moveLeft({ x: 5, y: 2});
moveRight(dog);

위의 소스를 보면, 위가 객체지향이고, 아래가 함수형언어입니다.

즉, 객체지향은 객체를 기준으로 하는 프로그래밍으로, 데이터(객체)를 먼저 디자인하고 그 데이터에 맞는 메소드를 만드는 식.

함수형은 먼저 함수를 만들고 그 함수에 맞게 데이터 set를 구성하는 식!

객체지향에선 클래스, object, 객체가 일급객체가 되는 반면, 함수형에선 함수자체가 일급객체가 됩니다.


일급객체라는 것은

  • 변수나 데이터 구조(자료구조)안에 담을 수 있다.
  • 파라미터로 전달할 수 있다.
  • 반환값으로 사용할 수 있다.
  • 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.

    위의 조건을 모두 만족해야 한다.


요즘에는 프로그래밍 기법으로 객체지향보다는 함수형을 선호합니다.

요즘 어플리케이션은 대부분 실시간적인 성격이 강해서 전세계에 있는 많은 사람들이 동시에 접속할 수 있도록 해야합니다.

즉, 비동기작업이 문제없이 이뤄져야 하는데요. 그래서 앞으로 개발자들에게 이러한 성격을 가진 어플리케이션을 성공적으로 개발할 수있는 능력이 필요할 거에요.

그러기 위해서 다양한 도구와 개념을 익혀야 하는데 그 중 하나가 함수형 프로그래밍 기술이라고 할 수 있겠습니다..

그외에도 개발자들이 알아야할 도구들이 점점 많아지고 있는 추세입니다. 개발자 길을 택했다면 당연히 감수해야할 부분이라고 할 수 있겠어요!!^^^^ ..

서론이 너무 길었네요. 자, 그럼 본격적으로 왜 함수형프로그래밍이 뭔지 알아보도록 합시다!
렛츠고! ♬
.
.
.
.


함수형 프로그래밍의 정의

.
.

함수형 프로그래밍은 성공적인 프로그래밍을 위해 부수 효과를 최소화하고 조합성을 강조하는 프로그래밍 패러다임이다.

.
.

여기서 부수효과를 최소화한다는 것은 순수함수를 만든다는 것.

순수함수는 들어온 인자가 같으면 항상 동일한 결과를 리턴하는 함수입니다.

함수가 받은 인자 외에 다른 외부상태에 영향을 끼치지도 받지도 않아야 하구요.

또한 리턴값 외에는 외부와 소통하는 것이 없는 함수를 말합니다.

순수함수로만 만들어지면 오류를 줄이고 안정성을 높일 수 있습니다.

조합성을 강조한다는 것은 모듈화 수준을 높인다는 것으로,
순수함수로 모듈화수준을 높이게 되면 생산성이 높은 프로그래밍을 할 수 있습니다.

결론적으로, 생산성이 높은 프로그래밍의 척도는 얼마나 모듈화 수준이 높느냐가 될 수 있겠습니다.

자바스크립트에서도 이러한 함수형 사고 방식으로 프로그래밍하는 것이 가능합니다.


순수 함수란?

쉽게 add라는 함수를 통해 설명하겠습니다.

1
2
3
4
5
6
7
8
/* 순수 함수 */
function add(a, b){
return a + b;
}

console.log(add(10,5)); //동일한 인자를 넣으면 동일한 결과를 내보냄.
console.log(add(10,5)); //그리고 또다른 특징은 평가시점이 중요하지않다는것이다.
console.log(add(10,5)); // 즉, 어느시점에서건 똑같은결과를 가진다.

add함수는 a와 b라는 인자를 받아 a+b라는 리턴값을 내보냅니다.
이처럼 순수함수의 중요한 특징은 동일한 인자를 넣으면 동일한 결과를 내보낸다는 것입니다.
그리고 어느시점에서건 똑같은 결과를 내보냅니다. add(10,5)는 어느시점에서건 15라는 결과값을 내보낼 것입니다.

순수함수가 아닌 경우들

1
2
3
4
5
6
7
8
9
10
11
12
13

//순수함수가 아닌경우 1
var c = 10;
function add2(a, b){
return a + b + c;
}
console.log(add2(10,2)); //22
console.log(add2(10,3));
console.log(add2(10,4));
c= 20;
console.log(add2(10,2)); //32
console.log(add2(10,3));
console.log(add2(10,4));

add2라는 함수는 a와 b를 인자로 받아 a + b + c를 결과값으로 내보냅니다.
여기서 만약 c가 변하지 않는 상수값이라면 add2함수는 순수함수이겠지만
위처럼 중간에 값이 바뀌면 add2의 리턴값도 바뀌게 됩니다. 즉 순수함수조건에 만족하지 못합니다.

1
2
3
4
5
6
7
8
//순수함수가 아닌경우 2
var c = 20;
function add3(a,b){
c = b;
return a + b;
}
console.log(add3(20, 30));
console.log(add3(20, 30));

add3라는 함수는 a와 b라는 인자를 받아와 변수 c에 b값을 할당하고, 리턴값으로 a+b를 내보냅니다.

외부의 값에 영향을 주게 된다면 이 역시 순수함수가 될 수 없습니다.

1
2
3
4
5
6
7
8
9
10

//순수함수가 아닌경우 3

var obj1 = {val : 10};
function add4(obj, b){
obj.val += b;
}
console.log(obj1.val); //10
add4(obj1, 20);
console.log(obj1.val); //30

이번에는 obj1이라는 변수를 선언하고, 이는 val속성값으로 10을 가집니다.
add4라는 함수는 obj와 b라는 인자를 받아와서 obj의 val값에 인자 b의 값을 더해 값에 변화를 줍니다.
console.log(obj1.val);를 하면 obj1의 val값은 10이니까 콘솔에 10이 뜨게됩니다.
하지만 add4(obj1, 20);을 하는순간 obj1의 val값은 10에 20이 더해져 30이 되고,
이 시점 이후에
console.log(obj1.val);은 30으로 바뀝니다.
평가시점이 언제건 상관없이 동일한 값을 넣으면 동일한 값을 내보내야 하는 순수함수의 조건에 만족하지 못하는 것입니다.

그렇다면 3번째 경우를 순수함수로 구현해보겠습니다.

1
2
3
4
5
6
7
8
9
10
//순수 함수인 경우

var obj1 = {val: 10}
function add5(obj, b){
return {val: obj.val + b}
}
console.log(obj1.val); //10
var obj2 = add5(obj1, 20); //30
console.log(obj1.val); //10
console.log(obj2.val); //30

이번에도 위랑 똑같이 obj1이라는 변수를 선언하고, val값으로 10을 주었습니다.
add5는 obj와 b를 인자로 받고 val값을 obj의 val값에 b를 더한 값으로 바꿉니다.
이 경우, add5(obj1, 20);를 해서 obj1의 val값인 10을 불러와 인자 b값인 20을 더한 30이라는 값을 val값으로 설정합니다.
그리고 obj2라는 새로운 변수를 선언하고 {val : 30}을 할당합니다.
그러면 console.log(obj1.val);은 어느 시점에서건 10이라는 똑같은 값을 리턴하고
console.log(obj2.val);도 마찬가지로 30이라는 값에 변화가 없게 됩니다.


함수형 프로그래밍에서 빠질 수 없는 개념인 순수함수에 대해 배워보았어요.
이번에는 순수함수와 함께 아주 중요한 개념인 일급함수에 대해 알아봅시다:)


일급 함수란?

이번에도 이해를 돕기 위해 예제를 통해 공부해 봅시다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* 일급 함수 */

var f1 = function(a){
return a*a;
};
cosole.log(f1);

function f2(f){
return f();
}
console.log(f2(function(){
return 10;
})); //10

console.log(f2(function() {
return 20;
})); //20

일급함수함수를 변화시켜서 값으로 다룰 수 있다는 것을 의미합니다.
그리고 원하는 시점에서 들고 다닐 수 있고, 원하는 시점에 평가할 수도 있는것을 말합니다.

위에서 console.log(f1)을 하면 콘솔창에 function(a){return a*a};가 뜨게 됩니다. 이처럼 변수에 함수를 담을 수 있습니다.

함수 f2는 인자 f를 받아 f()를 리턴합니다. 이때 f에 function(){ return 10; }라는 함수를 담아 호출하면 10이라는 값을 리턴합니다.
f2는 그대로입니다. 하지만 다른 값을 return하고 싶을때 그때그때마다 다른 인자값을 주어 함수를 호출하고 값을 리턴하는 방식입니다.
그니까.. 가만히 있는 함수를 필요할때 원하는 시점에 불러와 결과값을 얻는 것입니다.


첫 포스팅이 끝났어요 !!
일급함수는 순수함수랑 특징이 많이 겹치는데요. 이제 함수를 변수에 담느냐 마느냐에 따라 일급함수이냐 아니냐를 판단할 수 있어요.
굳이 두가지 개념을 분리시킬 필요는 없어보여요. 하하
그냥 ‘함수형 프로그래밍에선 객체지향이 아니라 일급함수!!, 순수함수!!처럼 함수지향적인 프로그래밍이다~ ‘라고만 이해하면 될것같습니다.

다음 포스팅은 map, filter를 함수형 프로그래밍으로 학습해 볼거에요ㅎㅎㅎ

Share