rokdocs
v0.1

0.4. 언어와 표준 라이브러리의 경계

이 문서는 언어가 정의하는 것과 표준 라이브러리가 정의하는 것 사이의 경계를 선언합니다. 이 경계는 rok 사양의 핵심 결정에 해당하며, 이후의 모든 사양 문서는 이 경계를 전제로 작성됩니다.

0.4.1. 언어가 정의하는 것

언어 사양이 직접 다루는 범위는 다음 다섯 가지로 나뉩니다.

1. 로직 흐름

첫째 범주는 값을 흘려보내는 구문과 그 의미입니다. 여기에는 분기, 반복, 패턴 매칭, 예외 처리, 라벨 점프가 포함되며, 비동기와 생성자(generator) 의 구문, 즉 선언자와 연산자 키워드 또한 같은 범주에 속합니다.

2. 컨테이너 문법

둘째 범주는 사용자 타입을 정의하는 형태입니다. 곱 타입(레코드형) 은 여러 필드를 하나로 묶는 형태이며, 합 타입(태그형) 은 여러 변형 중 하나를 골라 가지는 형태입니다. 비태그 union 은 같은 메모리를 여러 형으로 해석하기 위한 장치이고, 트레잇은 동작의 묶음을 선언하는 수단이며, impl 블록은 트레잇과 메서드의 구체 구현을 담는 자리입니다. 마지막으로 제네릭은 타입을 파라미터로 받는 형태를 가능하게 합니다.

3. 메타 시스템

셋째 범주는 앞의 두 범주에 부착되어 동작을 바인딩하는 속성(attribute) 체계입니다. 이 체계는 언어가 인식하는 정해진 이름 묶음인 표준 속성과, 사용자 정의 속성 및 derive 의 템플릿 시스템으로 구성됩니다.

4. 변수 / 가시성 / 모듈

넷째 범주는 이름과 노출에 관한 규약입니다. 변수 선언 키워드, 참조 수식어, 전역 및 상수 키워드가 여기에 속하며, 가시성 단계와 모듈 및 패키지 단위의 이름 노출 규약 또한 함께 다루어집니다.

5. 연산자 구문

마지막 범주는 a + b, s[1:3], x.f, f(args) 와 같은 표기법의 모양입니다.

다만 이러한 표기법이 어떤 동작을 의미하는지는 언어가 정의하지 않습니다. 표기법은 표준 라이브러리에 등록된 트레잇 메서드로 desugar 되는 방식으로 의미를 얻습니다.

0.4.2. 표준 라이브러리가 정의하는 것

표준 라이브러리는 앞서 언급한 다섯 범주를 제외한 거의 모든 의미를 담당합니다. 구체적으로는 숫자와 문자 타입 및 그 연산이 여기에 속하며, 산술, 비교, 논리, 비트, 인덱싱, 범위 같은 연산자 의미론도 모두 표준 라이브러리의 트레잇 impl 로 정의됩니다. 또한 형 간 변환 규칙 전체를 담는 변환 매트릭스, 리스트와 맵, 셋, 튜플, 문자열 등으로 대표되는 컬렉션이 라이브러리의 영역입니다. 이에 더해 반복자, 스트림, 미래값과 같은 추상, atomic·mutex·channel 로 대표되는 동시성 프리미티브, 태스크와 스레드 및 병렬 실행 API, 입출력·시간·랜덤·네트워크, 그리고 에러 타입 전체 또한 모두 표준 라이브러리가 정의합니다.

언어는 이들 라이브러리 요소의 이름을 알지 못합니다. 컴파일러가 특정 라이브러리 타입을 인식하는 경우는 오직 메타 시스템의 속성 바인딩을 통해서만 발생하며, 그 바인딩 자체도 표준 라이브러리 안에 작성됩니다.

0.4.3. 경계가 만드는 결과

Syntax 는 언어, 동작은 라이브러리

이 분리의 첫 번째 결과는 표기와 의미의 분업입니다.

중요

모든 표기법은 언어가 정의하지만, 값에 가하는 연산의 의미는 표준 라이브러리에 등록된 트레잇 메서드가 결정합니다.

표기언어가 정하는 것라이브러리가 정하는 것
a + b토큰 시퀀스, 우선순위+ 가 어떤 트레잇 메서드인지, 결과 타입
s[1:3]슬라이스 표기 형태인덱싱, 경계 검사, 결과 타입
x.f()메서드 호출 형태메서드 디스패치 규칙
let x = 1선언 형태리터럴 1 의 타입 결정

언어 수준 질문의 범위

이 분리의 두 번째 결과는 질문의 분류 기준입니다. 설계나 구현에 관한 어떤 결정을 마주했을 때, 그것이 언어 수준 질문인지 라이브러리 수준 질문인지를 먼저 구분합니다.

언어 수준에 남는 질문은 다음 영역으로 한정됩니다. 첫째는 컴파일러 의미론으로, 이름 해소, closure capture, 가시성, 에러 진단이 여기에 속합니다. 둘째는 구문 결정이며, 이스케이프, 우선순위, 리터럴 접미사, 슬라이스 표기 모양 등이 그 예시입니다. 셋째는 런타임 호출 규약과 메모리 모델로, 객체 레이아웃과 calling convention 이 포함됩니다. 넷째는 리소스 관리이며, 수명과 예외 전파 메커니즘이 이에 해당합니다. 마지막으로 다섯째는 타입 시스템 규칙으로, 트레잇-as-타입 금지, 점진 타이핑, niche 최적화 등이 여기에 속합니다.

라이브러리 수준으로 위임되는 것

위 목록 외의 거의 모든 값에 대한 연산은 라이브러리의 결정 영역입니다. 따라서 본 사양 문서는 이러한 연산의 시맨틱을 직접 규정하지 않습니다.

대신 사양은 다음 사항들을 명시합니다. 먼저 그 연산이 어떤 트레잇 메서드 호출로 desugar 되는지를 밝히며, 이어서 그 트레잇이 라이브러리의 어느 계층에서 정의되는지에 관한 위치 규약을 정합니다. 마지막으로 정의되지 않은 경우에 발생하는 컴파일 에러의 형태를 함께 규정합니다.

이러한 분리가 곧 rok 의 설계 슬로건인 "작은 언어, 풍부한 라이브러리"를 사양 수준에서 구현하는 방식입니다.

0.4.4. 구현 한도

언어는 중첩, 사슬 길이, 값 크기, 컴파일 타임 평가에 고정 한도를 두지 않습니다. 구현은 자기 한도를 둘 수 있으며, 그것은 언어 요구가 아니라 구현이 정하는 것입니다. rok 의 한도는 다음과 같습니다.

한도rok
parser 중첩 깊이256
연산자 / 후위 연산 사슬 (3.2.6a)4096
값 타입 크기 (2.6.3)펼친 scalar 슬롯 65536 개 또는 4 GiB
const 평가 (5.2.4)4,000,000 단계, 호출 깊이 128

넘으면 컴파일 에러입니다.

GitHub에서 이 페이지 고치기