작은 언어는 프로그래밍의 미래입니다
(chreke.com)"Little Language"란?
- '작은 언어'는 특정 문제를 해결하기 위한 목적을 가지고 만들어진 언어들
→ SQL, RegEx, Dhall,..
→ 또한 DSL이라고도 불려짐
작은 언어가 왜 필요할까 ?
- 어플리케이션이 크게 복잡해 지면서 소스코드도 커졌지만 이해하기도 어려워짐
- 신규 입사자 온보딩이 어렵고, 종속성 이해 부족으로 에러가 나기도 하며, 코드 변경이 점점 관리하기 어려워짐
- 지난 10년간 코드 베이스는 100~500배 커졌음
- 리눅스 커널은 1992년 1만 라인으로 시작했지만, 20년이 지나고 3천만 라인이 되었음
- 이런 코드는 "기능이 많아졌기 때문"만은 아님. 우리가 소프트웨러를 만드는 법이 바뀌었기 때문
- 소프트웨어는 피라미드구축과 마찬가지로 마지막 돌을 위해서는 아래에 더 많은 돌이 필요함
트렌드 극복하기
- 최신 OS를 만들기 위해서 꼭 수백만 라인의 코드가 필요할까?
- Alan Kay는 2006년 STEPS 프로그램에서 이 가정에 도전
-
우리는 해결해야 할 문제에 맞는 '언어'를 만드는 것이 문제 해결을 더 쉽게 하며, 솔루션을 더 이해하기 쉬우면서도 작게 만든다고 생각함
- STEPS에서는 Nile 이라는 언어를 만들어서, 44000라인 짜리 Cairo 렌더러를 약 300라인의 코드로 비슷한 기능을 하게 구현
고급 언어는 왜 안될까?
- 그냥 더 높은 수준의 다목적 언어를 만들면 안되는 거야?
- 개인적으로 나는 범용 언어의 표현력에 대한 수확체감(diminishing returns)에 도달했다고 생각
- 더 높은 언어라면 어떤 모습일까? Python을 예로 들어보면, 이미 너무 수준이 높아져서 유사(Pseudo)코드처럼 보임
- 범용 언어가 가지는 문제점은 당신의 문제를 알고리듬으로 번역한 다음, 대상 언어로 알고리듬을 표현해야 한다는 것
- 1986년 Jon Bentley의 Programming Pearls에서 유명한 Donald Knuth 와 Doug Mcllroy를 초대해서, 단어의 빈도를 세는 프로그램을 작성해 달라고 한 바 있는데, Don은 파스칼의 변형인 WEB으로 복잡한 자료구조와 함께 10 페이지에 걸쳐서 작성했음
- 이에 대해 Doug는 6줄짜리 유닉스 파이프 구문으로 tr, sort, uniq, sort, sed 등을 써서 구현
적을수록 좋다 Less is More
- 위의 유닉스 명령은 작은 언어의 또 다른 특성을 보여줌.
"덜 강력한 언어와 더 강력한 런타임" - Gonzalez는 "The end of history for programming" 에서 이런 트렌드를 얘기함
- 사용자 영역의 문제를 런타임 문제로 푸시함
- 프로그램을 순수 수학적 표현과 유사하게 만들고, 런타임의 복잡도를 크게 증가시킴
- 사용자 영역의 문제를 런타임 문제로 푸시함
- 정규표현식과 SQL은 각각 텍스트 검색과 데이터베이스 작업 외에는 아무것도 표현할 수 없음
- 이건 런타임이 없고, 모든 것이 표현가능한 C같은 언어와 대조됨
- 작은 언어는 C가 가진 힘 스펙트럼의 반대편 끝에 서있음
- 컴퓨터 아키텍처가 추상화 될 것만 아니라, 표현할수 있는 프로그램 종류를 제한함으로써, 설계상 Turing-incomplete임
- 매우 제한적으로 들릴수 있지만, 최적화 및 정적분석을 위한 새로운 차원의 가능성을 열어줌
정적 분석
- 덜 강력한 언어는 추론하기가 쉽고, 범용언어보다 더 강력한 보증을 제공할 수 있음
- 예를 들어, Dhall은 설정 파일을 생성하기 위한 "Total Functional Programming Language(전체 함수형 / 강 함수형 언어)"임
- 즉, 무한루프에 빠지는 위험을 없애기 위해, Dhall 프로그램은 "(1) 충돌하지 않고, (2) 한정된 시간에 종료"되는 것을 "보장"
- (1)은 Exception을 던지지 않도록 해서 달성. 실패할수 있는 명령은 Optional 결과값을 리턴함(값이 있거나 없을수 있음)
- (2)는 재귀 정의를 허용하지 않음으로서 달성
- 다른 함수형 언어에서는 재귀가 루프를 구현하는 기본 방법이지만, Dhall은 내장 fold 함수에 의존해야 함
- 일반 루프 구조가 없다는 것은 Dhall이 튜링 완전하지 않다는 것을 의미. 하지만 이것은 범용 목적 언어가 아니므로 그럴 필요가 없음
- 언어가 작으면, 추론이 훨씬 쉬워짐
- 예를 들어 Python 프로그램이 다른 부작용이 없는지 확인하는게 어렵지만, SQL에서는 쿼리가 SELECT로 시작하는 지만 확인하면 됨
- Nile의 경우 STEPS 팀에서는 그래픽 디버거가 필요해서 만들었고, 직접 확인 가능
- Nile은 추론하기 쉬운 작은 언어이기 때문에 이런게 가능함
속도의 필요성
- 더 강력한 프로그래밍 언어는 버그 가능성을 높일 뿐만 아니라, 성능에 해로울 수도 있음
- 예를 들어, 프로그램이 알고리듬으로 표현되지 않는다면, 런타임은 자체적으로 알고리듬을 선택 가능
- 느린 표현들은 빠른걸로 교체가 가능(같은 결과를 낸다는걸 증명한다는 전제하에)
- 예를 들어, SQL 쿼리는 쿼리 실행 방법을 지시하지 않음
- 데이터베이스 엔진이 어떤 쿼리 플랜이 적합할지 자유룝게 판단해서 사용 가능
- 인덱스를 쓸지, 복합 인덱스를 쓸지, 아니면 전체 DB테이블을 스캔할지 등
- 최신 데이터베이스 엔진은 각 컬럼의 값 분포에 대한 통계도 수집하므로, 통계적으로 최적의 쿼리 계획을 즉석에서 선택 가능
- 만약 쿼리가 알고리듬 형태로 나왔다면 이런 것은 불가능
- 데이터베이스 엔진이 어떤 쿼리 플랜이 적합할지 자유룝게 판단해서 사용 가능
- Nile 언어를 매우 간결하게 만든 "비밀 소스"의 하나는 그래픽 렌더링을 위한 Just-in-Time 컴파일러인 "Jitblt"
- STEPS와 Cairo팀이 논의를 통해 많은 Cairo코드가 픽셀 합성 작업을 수작업으로 최적화 하는데 쓰인다는 것을 알게됨
- 이 일은 이론적으로는 컴파일러로 오프로딩 가능한 작업이었음
- Cairo팀의 Dan Amelang이 자원해서 이런 컴파일러를 구현한게 Jitblt
- 그래픽 파이프라인의 최적화 작업을 어떤걸 렌더링할지의 순수한 수학적 설명에서 분리될 수 있다는 것이며,
이로써 Nile이 손으로 최적화된 오리지널 Cairo코드 만큼 빠르게 실행될 수 있었던 것
Small languages, Big Potential (작은 언어, 큰 잠재력)
- 그래서 STEPS는 어떻게 되었을까? 티셔츠에 인쇄될 만큼의 코드로 실행되는 OS를 만들었을까 ?
- STEPS의 최종 결과물은 KSWorld였음
- 문서 편집기과 스프레드시트 편집기를 내장한 완전한 OS
- 17000 라인의 코드
- 티셔츠에 들어가기엔 조금 긴 코드지만, 난 성공이라고 봄
- KSWorld의 생성은 "작은 언어"에 큰 잠재력이 있음을 보여주는 것
- 하지만, 아직 답변 못한 질문들이 많음
- 이런 언어들은 어떻게 서로 대화할까 ?
- 공통 중간 표현으로 컴파일 해야할까?
- 아니면 서로 다른 런타임이 병렬로 존재하고, 표준 프로토콜(유닉스 파이프, TCP/IP같은?)로 통신해야 할까 ?
- 아니면 각 언어가 여러 호스트 언어로 다시 구현이 가능할 만큼 작을까?
- 어쩌면 이런 것을 모두 조합한게 나아가야할 방향일까?
- 어쨌든 나는 우리가 소프트웨어를 구축하는 다른 방법을 생각해 내야한다고 확신함
- 아마도 "작은 언어"들이 그 이야기의 일부가 될 수도 있을 것
- 중요한 것은 더 나은것을 생각해 낼 수 있을 만큼 오랫 동안, 각각의 위에 더 벽돌을 쌓지 말아야 한다는 것
"
우리는 해결해야 할 문제에 맞는 '언어'를 만드는 것이 문제 해결을 더 쉽게 하며, 솔루션을 더 이해하기 쉬우면서도 작게 만든다고 생각함
"
이 부분을 읽고 느낀 점은, 결국 '작은 언어'라 함은 프레임워크와 동일한 의미지 않을까 싶습니다. 자주 사용되는 함수와 디자인 패턴을 강제하여 일종의 문법화를 시킨 '자바스크립트 -> 리액트' 의 사례 처럼요.
그러고 보니 JetBrains에서 만든 MPS(Meta Programming System)라는 DSL 생성 도구를 최근에 발견했습니다.
이게 생각보다 오래 된 물건이더군요. 관심이 가서 좀 더 살펴보려다 이래저래 미뤄두고 있는데, 혹시 이거 써보신 분이 있으면 사용 후기 같은 걸 들을 수 있었으면 좋겠습니다.