javascript

함수형 언어, 자바스크립트

함수형 언어의 목표 :

애플리케이션의 부수효과(side effect)를 방지하고

상태 변이(mutation of state)를 감소하기 위해 데이터의 제어 흐름과 연산을 추상하는 것

 Expressions Vs Statement 

Expression(표현식)은 값을 평가(evaluate)하는 식을 의미한다.

함수형 언어에서 제어 흐름이나 상태 변화를 특정하기 않고 프로그램 로직을 나타내기 위해 Expression을 사용할 수 있다. 즉 Expression으로 함수를 선언할 수 있다. 

람다 표현식( arrow function in js)에서 expression을 계산한 값이 곧 함수의 반환값이 된다. 이는 lazy function(느긋함 함수)라고도 불린다. 

Statement(구문)는 일정 효과를 얻기 위한 명령이나 액션을 의미한다.

예시1) javascript fat-arrow function

var increment = counter => counter + 1;

 부수효과(Side Effects)와 순수함수 

부수효과가 없는 함수가 순수함수라고 할 수 있다.

물론 불가피하게 부수효과가 발생되는 경우가 있기 때문에 순수함수로만 프로그래밍한다는 것은 어렵지만 런타임시 예상불가능한 값을 가져올 부수효과 일어날 가능성을 없애고, 상태 변이를 줄이며 순수함수와 불순함수를 구분하여 프로그래밍하면 훨씬 유연하고 생산성 높고 가독성이 높은 프로그래밍을 할 수 있다.

순수함수의 조건은 다음과 같다 

  • 평가 도중 또는 호출 간 변경될 수 있는 숨겨진 값, 외부 상태와 무관하게 작동 
/*fun 함수가 parameter를 변경한다고 가정*/
a = 10;
b = a + fun(&a);

예시2) 

b = a + fun(&a)라는 식에서 +는 교환법칙이 성립하는 연산자이므로 a가 연산 초기값이고 이후 a의 값을 변경한 값을 더하는지 혹은 a의 값을 변경하는 fun함수를 계산하고 이후 a를 계산하는지가 명확하지 않다.

이를 부수효과라고 하며 언어는 이를 방지하기 위해 연산 순서를 정해두기도 한다.

 

  • 전역 객체, 레퍼런스로 전달된 매개변수 수정 등의 스코프 바깥의 변경을 일으키지 않음
var counter = 0;

function increment(){

	return ++counter;
}

...

 

예시3)

increment()는 전역 변수의 레퍼런스를 변경하기 호출 도중 counter의 값은 언제라도 변할 수 있기 때문에

최종적으로 increment()를 실행했을 때 return값을 알 수 없다.

참조 투명성 

참조 투명성이란 함수가 동일한 입력을 받을 때 동일한 결과를 내는 경우를 말한다. 예시 2의 경우 increment()함수를 여러번 호출할 때마다 리턴값이 달라지게 된다. 이런 경우 전체로직을 파악하는 것이 어렵다. 

아래의 코드에서 result1과 result2의 결과가 같을 때, fun()함수가 참조투명성이 있다고 할 수 있다.

이를 치환성이라고 부르기도 한다.  

result1 = (fun(a) + b ) / (fun(a) - c); 
temp = fun(a)
result2 = (temp + b) / (temp - c);

예시 4)

모듈적인 코드 작성

  • 합성
var increment = counter => counter + 1;
var plus2 = run(increment, increment);
print(plus2(0));

예시5)

  • 체인
let enrollment = [
	{enrolled: 2, grade: 100},
    {enrolled: 2, grade: 80},
    {enrolled: 1, grade: 89},
]

_.chain(enroolment)
	.filter(student => student.enrolled > 1)
    .pluck('grade')
    .average()
    .value();

예시6)