계약 기능을 두고는 P2900 찬성, 계약은 원하지만 P2900은 반대, 계약 자체에 반대, 어느 쪽이든 관심 없음으로 나뉨. 압도적으로 큰 집단은 마지막임. 나도 계약 자체에 반대했지만 Rust에서 Verus를 쓰면서 입장이 바뀜. 계약은 원하되 P2900 같은 형태는 원하지 않음. 시스템 프로그래밍에서 Rust와 C++는 복잡한 장단점이 있지만, Rust에 Verus를 더하면 C++를 고려할 이유가 없을 정도로 우위가 명확해짐. P2900으로 C++는 이 영역을 영구히 포기한 셈임.
C++의 구조적 문제는 상당수 기능에 대해 대다수가 무관심하다는 데 있음. 좋은 기능은 필요성에 폭넓은 합의가 있고 소수 전문가가 설계함. 원자적 연산이 좋은 예임. 나를 포함한 WG21의 최소 90%는 원자적 메모리 모델을 설계할 역량이 없으리라 추측하지만, 순수 C++로 뮤텍스를 구현할 수 있어야 한다는 데는 모두 동의했음. 람다는 기존 함수 호출 연산자 오버로딩을 문법적으로 간결하게 만드는 기능이어서, 필요성과 구현 변환을 대부분 이해할 수 있었음.
반면 소수만 중요하게 여기고 나머지는 관심 없는 기능도 많이 들어옴. 이런 기능은 표준 라이브러리보다 Boost 같은 외부 라이브러리에 있어야 함. 표준 라이브러리는 CPU·운영체제 기능을 이식 가능하게 사용하는 추상화, 대부분의 프로그램이 내부적으로 필요로 하는 기능, 여러 라이브러리의 인터페이스 호환성에 필요한 공통 타입에 집중해야 함. 현재 기능과 제안 중 상당수는 어디에도 해당하지 않음.
언어 자체에는 추상 기계의 저수준 의미론을 구현하는 데 필요한 기능과, 흔한 구현 패턴을 간결하게 표현하는 문법이 필요함. 전자는 표준 라이브러리와 외부의 실제 요구에서 출발해야 하며, C++11의 우측값 참조가 좋은 예임. 비슷한 이유로 빌림 의미론, 관점 적응(viewpoint adaptation), 제약된 람다에서의 비지역 반환도 추가할 만함. 후자는 대규모 실사용에서 반복되는 패턴을 바탕으로 해야 함. 람다는 새 추상 기계 의미론 없이도 C++98의 클래스·생성자·필드·operator()로 변환할 수 있지만, 그 번거로운 코드를 줄여 줌.
P2900은 두 종류를 모두 추가함. ODR 위반이면서 위반으로 취급되지 않는 상황이나 함수 전후의 코드 실행 등 새 의미론을 도입하지만, 계약을 분석 가능한 대상으로 제한하지는 않음. 계약에 사용할 언어 부분집합을 정의하는 일은 명시적으로 범위에서 제외돼, 결국 계약은 조건부로 실행되는 코드에 그침. pre, post, contract_assert 문법도 모든 계약에 표현식이 있다는 특정 사용 형태에 맞춰져 있음. 리플렉션과 비슷한 인터페이스로 API 형태에 계약을 적용하거나 매개변수별로 기술하는 접근 대신 이 설계를 택할 만한 C++의 대규모 실사용 근거는 없음. 다른 언어에서 널리 쓰인 계약 설계는 전혀 다르지만 그것도 제안 범위에서 제외됨. C++에는 애초에 이런 제안을 평가할 일관된 설계 철학이 없음.
국가 표준 기구의 역할도 구분해야 함. 나는 BSI의 JTC1/SC22/WG21 대표단 소속이지만, BSI는 이들이 개인 자격으로 활동한다고 봄. WG21에서 나 자신과 경우에 따라 고용주를 대표해 논의하고 국제표준 초안(DIS)을 만들면, SC22의 국가별 대표가 투표해 국제표준(IS)으로 승인함. SC22 대표는 WG21 소속이 아닐 수도 있고, 모든 프로그래밍 언어와 관련 분야에서 BSI를 대표하므로 역할도 다름.
보통 SC22 대표는 작업반을 신뢰해 합의안을 그대로 받아들이지만, 이번에는 처음으로 여러 사람이 자국과 다른 나라의 대표에게 DIS 반대표를 요청함. 다른 나라 대표에게 접촉하는 것은 규칙 위반일 가능성도 있음. P2900에 기술·문화·절차상의 반대 이유가 많고 포함돼서는 안 된다고 보지만, 이런 로비도 달갑지 않음. P2900은 잘못된 문제에 대한 잘못된 해법이며 여기까지 와서는 안 됐음.
비밀유지 약정 때문에 더 말할 수 없는 부분도 있음. WG21에 심각한 구조·절차 문제가 있고 P2900이 C++26에 들어가서는 안 된다는 데 동의함. C++29에서도 비슷한 것을 넣기보다, 계약을 도입한다면 1986년이 아니라 적어도 2006년 수준의 기술을 토대로 해야 함. 찬성 측의 설명에는 솔직하지 않거나 오해를 유도하거나 명백히 거짓인 부분이 있지만, 특히 목소리 큰 반대자 두 명도 마찬가지임. 국가 표준 기구 로비만으로 DIS 부결을 설명할 수는 없으며, 로비 자체도 근본 원인이 아니라 증상에 가까움.
이 분야에서는 Kani와 Creusot만 알고 있었는데 Verus의 매크로 기반 확장이 흥미로움. 제약을 검사한 뒤 유효한 Rust 코드를 생성하므로, 우회적이지만 기술적으로는 실제로 유효한 Rust 파일만 유지할 수 있음.
IDE나 비슷한 방식의 다른 언어 확장과 충돌할 수 있어 장기적으로 최선은 아닐 수 있음. 그래도 미완성 기능을 언어에 넣고 영구히 떠안는 것보다는 훨씬 나음. 이 방식이면 자유롭게 실험하며 실사용 경험을 쌓을 수 있음.
Objective-C를 쓰던 분으로 기억하는데, 언제 어떤 계기로 Rust를 쓰기 시작했는지 궁금함.
계약 기능 논의를 대부분 안다고 생각했는데 예상보다 훨씬 자세한 글임. 2018년 무렵의 계약 제안도 논의되다가 제외됐으니 이번에도 다시 돌아올 수 있지 않을까? 아니면 그때보다 절차가 나빠진 걸까? C++17 이후 표준화된 기능의 품질을 보면 그래도 놀랍지는 않을 듯함.
Safe C++ 를 무산시키는 과정이 너무 험악해서 Sean이 이 주제를 다시 다루지 않기로 했는데, 이제 계약 기능까지 논란에 휘말림.
계약 제안이 다시 추진될 것으로 기대하지 않음. 이미 한 번 표준에서 빠졌고 또 빠질 가능성이 크며, 핵심 관계자들이 그렇게 공격적으로 대한 제안을 누가 맡고 싶겠는가? 몇 달마다 이런 큰 소동이 반복되면 표준화에 기여할 사람을 구하기가 더 어려워짐.