투명한 기부를 하고싶다면 이 링크로 와보세요! 🥰 (클릭!)
바이낸스(₿) 수수료 평생 20% 할인받는 링크로 가입하기! 🔥 (클릭!)
함수형 프로그래밍에 대한 첫 단계를 시작한다.
대체(substitution) 모델이라고 부르는 평가를 위한 (기본적인) 모델이 있는데, 이는 나중의 세션에 중요하다. 주의하도록 하자.
자 이제 시작 해 보자.
모든 non-trivial(특수한? 중요한?) 언어는 언어의 기본적인 원소를 나타내는 원시(primitive) 표현식을 제공한다.
또한, 표현식을 결합하거나 추출하는 방법도 있다. 추출이란 표현식의 이름을 도입한 다음 그 이름을 기준으로 표현식을 참조할 수 있음을 의미한다. (Scala에 대한 맥락을 모른다면 이 문장을 아직은 바로 이해하기 힘들 수도 있다)
함수형 프로그래밍에 접근하는 한 가지 방법은, 함수형 프로그래밍을 계산기같이 바라보는 것이다.
실제로 대부분의 함수형 언어에는 interactive shell이 있는데, (read eval print loop을 의미하는 REPL이라고도 불린다) 표현식을 입력할 수 있는 쉘이 있고, 이 표현식을 평가한 결과가 응답된다.
scala에서는 repl을 scala라고 치면 시작할 수 있다. (이 코스에서는 scala 대신 sbt console를 사용한다.)
이제 Evaluation을 살펴보자. 이러한 표현식이 어떻게 계산되었을까?
1. 가장 왼쪽의 연산자를 사용 (x + y - z 의 경우 + 부터 사용)
2. 해당 연산자의 피연산자를 계산함 (+의 피연산자는 x와 y)
3. 피연산자에 연산자를 적용함
예)
가장 왼쪽의 * 연산자를 사용.
피연산자를 계산함 (2 -> 2 & pi -> 3.14159)
피연산자에 연산자를 적용함 (2 * 3.14159 -> 6.28318)
함수의 인수도 왼쪽에서 오른쪽으로 계산한다.
동시에 함수 응용 프로그램을 함수의 오른쪽의 그것으로 대체한다. (다음의 계산 과정으로 바꾼다는 의미인 듯?)
함수의 이전 매개변수를 실제 인수로 바꾼다.
절차에 대한 예시이다.
sumOfSquares(3, 4) => square(3) + square(4)
의 과정이 right hand side (우변)로 대체하는 과정이라고 표현하고 있다.
또한 square(3) 이 3 * 3 이 되는 과정도 그렇게 표현한다.
이런 표현식 계산을 substitution model이라고 한다.
주요 아이디어는 계산을 줄여가면서 value로써 표현해가는 과정에 있다.
이 재 작성하는 단계는 대수적 단순화를 수행하는것과 유사하다. 또한, 모든 알고리즘을 표현할 수 있다는 사실은 튜링머신을 표현하는 것과 동일하다.
이 substitution model 은 함수형 프로그래밍의 기초가 되는 람다 칼큘러스에서 공식화되어 있다.
다만 이 모든 과정은 side-effect가 없는 상황에서만 동작한다.
side-effect란 c가 c++이 되는 등의 행위 (즉 변수의 값이 변하는 행위)이다.
그렇지만, 모든 표현식이 value로 변환되지 않을 수도 있다. (무한 loop를 생각 해 보자)
두가지 평가 전략이 있는데, 그 중 하나는 call-by-value이고 또 다른 하나는 call-by-name이다. 두 방법 모두 다음 조건을 만족한다면, 같은 값으로 바뀐다.
- pure function으로 이루어져 있어야 한다.
- 모든 evaluation은 종료되어야 한다.
call-by-value 는 모든 함수는 한번만 계산된다는 장점을 가진다.
call-by-name은 함수의 인자가 function body에서 사용되지 않으면 계산되지 않는다는 장점을 가진다.
위의 예시를 보자.
test(3+4, 8)의 경우 call by value가 더 빠르게 값을 계산한다.
test(7, 2*4)의 경우 call by name이 더 빠르게 값을 계산한다.