2019년 6월 3일 16시 7분 (최근 수정: 2019년 9월 16일 13시 47분)
프로그래밍 언어라는 분야는 무엇을 하는 학문일까? 한 학문을 한 문장으로 요약해서 설명하는 것은 불가능할 뿐만 아니라, 내가 이 질문에 대답하기에 충분한 지식과 경험을 가지고 있지도 않기 때문에 좋은 답변을 하기는 어렵다. 그렇지만, 프로그래밍 언어에 대해서 알아보고자 하면서 그 대상이 무엇인지도 모르고 시작하는 것도 이상하고, 이 질문에 답하려고 노력하는 것이 나에게 도움 되는 일이기도 하기 때문에, 지금까지 2년 반 정도 프로그래밍 언어라는 학문을 경험한 바에 따라 설명을 해보고자 한다.
프로그래밍 언어를 공부한다는 말을 하면, 흔히 들을 수 있는 말 중 하나는 “새로운 프로그래밍 언어를 만드냐”라는 질문이다. 완벽히 틀린 말은 아니다. 새로운 언어를 설계하고 구현하거나, 기존의 언어에 기능을 추가하고 개선하는 것 역시 프로그래밍 언어를 공부한 사람들이 할 수 있는 일 중 하나이다. 하지만, 언어 설계는 프로그래밍 언어라는 분야에서 작은 한 부분에 불과하며, 그보다 훨씬 다양한 일을 할 수 있다.
프로그래밍 언어라는 분야를 어떻게든 한 문장으로 표현해 보자면 “프로그래밍 언어를 바탕으로 전산학의 문제를 풀어나가는 분야”라고 말할 수 있다. 이렇게 써 놓으면 매우 당연한 말 같기는 하다. 예를 들어, 프로그램을 빠르게 실행하는 것이 목표라면, 컴퓨터 구조는 하드웨어를 개선하고, 전산망은 통신 규약을 개선하고, 인공지능은 신경망의 구조를 개선하는 것을 시도할 수 있을 것이다. (프로그램을 빠르게 한다는 목표는 매우 추상적이며, 예로 제시한 각 분야 역시 말한 것보다 훨씬 다양하고 복잡한 일을 하겠지만, 매우 간략한 예시로 보길 바란다.) 이처럼 동일한 한 가지 목표에 대해서 전산학의 분야마다 전혀 다른 해결책을 시도한다. 프로그래밍 언어도 마찬가지로 다른 분야에서도 풀어볼 수 있는 문제에 대해 프로그래밍 언어의 시각으로 접근하고 해결한다.
그러면 프로그래밍 언어의 시각이라는 것은 무엇일까? 나는 많은 경우에 언어의 의미(semantics)를 엄밀하게 정의하는 것이 그 시각의 시작이라고 생각한다. 아래의 Python 코드를 생각해보자.
이 코드를 실행하면 1
과 2
중 무엇이 출력될까? 실제 Python에서는 1
이 출력된다. 첫 줄에서 정의한 변수 x
와 함수 f
안에서 정의한 x
는 다르며, print
를 호출할 때 사용한 인자 x
는 첫 x
와 동일하다고 보는 것이다. 그러나, 누군가는 세 x
가 모두 같은 대상을 가리키며, 따라서 2
가 출력되어야 옳다고 생각할 수도 있다. 두 관점 중 어느 것이 더 옳다고 결정할 수는 없다. 풀려 하는 문제에 따라서 두 의미 중 하나가 더 편할 뿐이다. 그렇지만, 두 의미 중 무엇을 사용할지 엄밀하게 정의되지 않았고, 모두가 하나로 동의하지 않는다면, 프로그램의 오류를 찾는 것도, 프로그램의 성질을 규명하는 것도, 같은 역할을 하는 더 빠른 프로그램으로 변환하는 것도 불가능하다. 그렇기에 프로그래밍 언어에서 많은 경우 시작은 언어의 의미를 엄밀하게 수학적으로 정의하는 것이다. 또, 그렇기 때문에 프로그래밍 언어 수업에서 가장 중점을 두는 것이 언어의 의미를 정의하는 것이라고 생각한다.
실제 프로그래밍 언어 연구자들은 이런 관점을 바탕으로 어떤 문제를 해결하고 있을까? 이 질문에 답하기 위해 가장 좋은 방법은 최신 프로그래밍 언어 학회에 발표된 논문들을 찾아보는 것이다. 마침 2018년 가을 학기 연구학개론 과목을 수강하며 2018년 PLDI에 발표된 논문들의 초록을 읽어보고 어떤 주제가 있는지 정리해 보았기 때문에, 해당 자료를 바탕으로 간단히 써보려고 한다.
PLDI(Programming Language Design and Implementation)는 프로그래밍 언어에서 POPL(Principles of Programming Languages)과 함께 가장 중요하게 생각되는 두 개의 학회 중 하나이다. 이름에서도 알 수 있듯, PLDI는 구현과 응용에 초점을 두고 있고, POPL은 이론에 초점을 두고 있다. 따라서, PLDI 논문들을 바탕으로 정리한 아래 내용은 아무래도 응용 분야에 조금 더 치우쳐 있을 것이고, 일반적인 주제를 다루게 되는 최고 학회 특성상, 프로그래밍 언어 안에서도 특정 분야를 깊게 파고드는 논문은 포함하지 않을 수 있다. 또한, 아래의 분류는 어디까지나 내 자의적인 분류이며, 저 넷 중 하나로 딱 떨어지지 않는 경우나 저 넷 중 어디에도 속하지 않는 경우도 많을 것이다. 어디까지나, 프로그래밍 언어에서는 어떠한 일을 하는지 학부생의 시각에서 정리한 가벼운 글로 읽으면 좋을 것 같다.
타입 체계(type system) 분야에서는 새로운 타입 체계 기능을 제안하거나 새로운 언어를 설계하며, 타입 안전성(type soundness)과 같은 성질을 증명한다. 타입 검사 알고리즘을 새로 제시할 수도 있다. 꼭 복잡한 타입 체계만 다루는 것은 아니며, 도메인 특화 언어를 설계할 수도 있다. 예를 들면, 경쟁 상태를 효과적으로 피할 수 있는 동시성 프로그래밍을 위한 언어를 제시한 논문이 있었다.
프로그램 분석(program analysis)은 프로그램의 종료와 같은 프로그램의 성질을 자동으로 검사하는 것이 목표이다. 크게 정적 분석(static analysis)과 동적 분석(dynamic analysis)으로 나눌 수 있다. 정적 분석은 프로그램을 실행하지 않고 코드에서만 정보를 얻어 해결하는 것을 목표로 하며, 모델 검사, 요약 실행(abstract interpretation), 제약 충족 등의 방법을 사용한다. 동적 분석은 테스팅이나 모니터링을 통해 프로그램 실행으로부터 얻은 결과를 사용한다.
더 정확하거나 빠른 분석을 위해서 기존의 분석 방법을 개선하거나 새로운 분석 방법을 제안하는 것이 중요한 주제 중 하나이며, 정적 분석과 동적 분석 기술을 결합하여 더 좋은 분석 결과를 얻어내는 방법도 시도한다. 또 다른 중요한 주제로는 분석 방법을 특정 분야의 문제를 푸는 데 적용하는 것이 있으며, 정적 분석을 통해 확률적 프로그램의 올바름을 검사하거나 필요한 자원의 양을 유추하는 연구와 병렬 컴퓨팅에서 경쟁 상태를 찾아내거나 디버거에 추가적인 정보를 제공하기 위해 동적 분석을 사용하는 연구가 있었다.
정형 검증(formal verification)은 컴파일러, 프로그램 동작, 하드웨어 등 다양한 대상에 사용되며, 컴파일러가 만들어낸 코드, 프로그램 동작, 하드웨어 동작이 올바르다는 것을 검증하는 것이 목표이다. Coq과 같은 증명 보조 도구가 이 분야에서 활발히 사용된다. 일부 연구자들은 새로운 검증이나 증명 방법을 제안하기도 한다.
프로그램 합성(program synthesis)은 주어진 명세를 만족하는 프로그램을 자동으로 만드는 것을 목표로 하며, 자동 디버깅은 말 그대로 프로그램의 버그를 자동으로 고치는 것이다. 연구자들은 확률적 모델이나 문법으로부터 도움을 받는 등 다양한 새로운 방법을 제안했다.
글을 확인하고 의견을 주신 류석영 교수님과 연구학개론 과목을 진행하신 김주호, 유신, 이성주 교수님께 감사드립니다.