1.1. 표현식 평가하기
Lean을 배우는 프로그래머로서 이해해야 할 가장 중요한 것은 평가가 어떻게 이루어지는지입니다. 평가(evaluation)는 산술에서 하는 것과 마찬가지로 식의 값을 찾는 과정입니다. 예를 들어, 15 - 6의 값은 9이고 2 × (3 + 1)의 값은 8입니다. 후자의 표현식의 값을 찾으려면, 먼저 3 + 1이 4로 치환되어 2 × 4가 되고, 이는 다시 8로 축약될 수 있습니다. 때로는 수학적 표현식에 변수가 포함되기도 합니다. x + 1의 값은 x의 값이 무엇인지 알기 전까지는 계산할 수 없습니다. Lean에서 프로그램은 무엇보다도 표현식이며, 계산에 대해 생각하는 주된 방식은 표현식을 평가하여 그 값을 찾는 것입니다.
대부분의 프로그래밍 언어는 명령형이며, 이 경우 프로그램은 프로그램의 결과를 찾기 위해 순서대로 실행되어야 하는 일련의 문(statement)으로 구성됩니다. 프로그램은 가변 메모리에 접근할 수 있으므로, 변수가 참조하는 값은 시간에 따라 변할 수 있습니다. 가변 상태 외에도, 프로그램은 파일 삭제, 외부 네트워크 연결 생성, 예외 발생 또는 포착, 데이터베이스로부터의 데이터 읽기 등 다른 부수 효과를 가질 수 있습니다. “부수 효과”는 본질적으로 수학적 표현식을 평가하는 모델을 따르지 않는, 프로그램에서 일어날 수 있는 일들을 통칭하는 용어입니다.
하지만 Lean에서는 프로그램이 수학 표현식과 동일한 방식으로 작동합니다. 값이 한 번 주어지면 변수는 재할당될 수 없습니다. 표현식을 평가하는 것은 부작용을 일으킬 수 없습니다. 두 표현식의 값이 같다면, 하나를 다른 하나로 치환하더라도 프로그램이 다른 결과를 계산하지 않습니다. 이는 Lean으로 콘솔에 Hello, world!를 출력할 수 없다는 뜻은 아니지만, I/O를 수행하는 것이 Lean을 사용하는 경험의 핵심 부분은 아닙니다. 따라서 이 장에서는 Lean으로 대화형으로 식을 평가하는 방법에 초점을 맞추며, 다음 장에서는 Hello, world! 프로그램을 작성하고 컴파일하고 실행하는 방법을 설명합니다.
Lean에게 표현식을 평가하도록 요청하려면 편집기에서 표현식 앞에 #eval을 작성하면 되며, 그러면 결과가 다시 보고됩니다. 일반적으로 그 결과는 커서나 마우스 포인터를 #eval 위에 놓으면 확인할 수 있습니다. 예를 들어,
#eval 1 + 2값을 산출합니다
일반적인 수학 표기법과 대부분의 프로그래밍 언어는 함수를 인자에 적용할 때 괄호(예: f(x))를 사용하는 반면, Lean은 함수를 인자 옆에 그대로 나열합니다(예: f x). 함수 적용은 가장 흔한 연산 중 하나이므로, 이를 간결하게 유지하는 것이 중요합니다. 다음과 같이 작성하는 대신
#eval String.append("Hello, ", "Lean!")
"Hello, Lean!"을(를) 계산하려면, 대신 다음과 같이 작성합니다
#eval String.append "Hello, " "Lean!"여기서 함수의 두 인자는 단순히 공백으로 구분되어 함수 옆에 나란히 작성됩니다.
산술 연산의 순서 규칙이 (1 + 2) * 5라는 식에서 괄호를 요구하는 것과 마찬가지로, 함수의 인자를 다른 함수 호출을 통해 계산해야 할 때도 괄호가 필요합니다. 예를 들어, 다음에서는 괄호가 필요합니다
#eval String.append "great " (String.append "oak " "tree")
그렇지 않으면 두 번째 String.append가 "oak "와 "tree"를 인자로 전달받는 함수가 아니라 첫 번째의 인자로 해석되기 때문입니다. 먼저 내부의 String.append 호출 값을 찾아야 하며, 그런 다음 이를 "great "에 덧붙여 최종 값 "great oak tree"를 얻을 수 있습니다.
명령형 언어에는 흔히 두 종류의 조건문이 있는데, 불리언 값에 따라 어떤 명령을 실행할지 결정하는 조건 문(statement)과 불리언 값에 따라 두 표현식 중 어느 것을 평가할지 결정하는 조건 표현식(expression)이 그것입니다. 예를 들어, C와 C++에서 조건문은 if와 else를 사용하여 작성되는 반면, 조건식은 삼항 연산자를 사용하여 작성되며 여기서 ?와 :가 조건과 분기를 구분합니다. Python에서 조건문은 if로 시작하지만, 조건식은 if를 중간에 둡니다. Lean은 표현식 지향 함수형 언어이므로, 조건문은 없으며 조건 표현식만 존재합니다. 이는 if, then, else를 사용하여 작성합니다. 예를 들어,
String.append "it is " (if 1 > 2 then "yes" else "no")다음으로 평가됩니다
String.append "it is " (if false then "yes" else "no")다음과 같이 평가됩니다
String.append "it is " "no"
최종적으로 "it is no"로 평가됩니다.
간결함을 위해, 이와 같은 일련의 평가 단계는 때때로 화살표로 연결하여 표기됩니다:
String.append "it is " (if 1 > 2 then "yes" else "no")String.append "it is " (if false then "yes" else "no")String.append "it is " "no""it is no"1.1.1. 마주칠 수 있는 메시지
Lean에게 인자가 누락된 함수 적용을 평가하도록 요청하면 오류 메시지가 발생합니다. 특히, 다음 예제에서는
#eval String.append "it is "꽤 긴 오류 메시지를 발생시킵니다:
이 메시지는 인자 중 일부에만 적용된 Lean 함수가 나머지 인자를 기다리는 새로운 함수를 반환하기 때문에 발생합니다. Lean은 함수를 사용자에게 표시할 수 없으므로, 이를 요청받으면 오류를 반환합니다.
1.1.2. 연습문제
다음 식들의 값은 무엇입니까? 직접 손으로 계산해 본 다음, Lean에 입력하여 답을 확인해 보십시오.
-
42 + 19 -
String.append "A" (String.append "B" "C") -
String.append (String.append "A" "B") "C"