docs를 고친 그림

Mandelbrot 렌더러가 docs가 약속한 세금을 재러 들어갔다: float의 infix 연산자는 없다, 그래서 모든 식은 prefix 호출의 산이 된다, 고. docs는 언어에 유리한 쪽으로 틀려 있었다 —— float infix 산술은 3 backend에서 얼마 전부터 동작하고 있었고, docs에 충실한 독자는 한 줄당 아홉 개의 쓸데없는 prefix 호출을 그냥 쓰고 있었다. 낡은 한 문장 둘레에 진짜 gap이 셋 숨었고, 저편 끝에서 나온 그림은 옳았고, 날 픽셀이든 ASCII든 바이트 단위로 동일했다.

merefloatsdocumentationbackendslanguage-design

이 Part의 대부분은 언어가 겉보기보다 좁았던 것에 대한 것이다. 이 이야기는 언어가 겉보기보다 넓었던 회 —— 문서가 실재하는 것보다 가난한 언어를 기술하고 있었고, 제한을 재려고 쓰인 probe가, 제한은 조용히 해제되어 있었다고 찾은 회다.

없는 세금을 잰다

계획은 Mandelbrot 렌더러, 바로 float 산술이 바닥까지 이어지기에 골랐다. 레퍼런스가 기술하는 세금을 정량화하기 위해서다: float는 「prefix 함수형만, infix 없음」—— 모든 a*b + c는 중첩된 prefix 호출로 써야 하고, 탈출 시간 식은 부풀어 오른다. 렌더러의 바로 첫 줄이 음의 float 리터럴을 원해서 type error를 얻었고, 그것은 뒷받침으로 느껴졌다. 그러다 무관한 무언가를 확인하다가, 1.5 + 2.03.5를 반환했다. float의 infix +는 동작했다. -, *, /, 그리고 모든 비교도 —— interpreter에서, C에서, wasm에서. overload는 어딘가에서 더해졌고, 레퍼런스는 한 번도 갱신되지 않았다. 아직 prefix-only의 세계를 약속하고, 그것을 믿은 독자는 세 줄의 식에 이유도 없이 아홉 개의 쓸데없는 prefix 호출을 쓴다. 이것은 앞 Part의 「이미 있었다」 이야기의 거울상이다: 저쪽에서는 probe가 세우려던 기능이 이미 있다고 찾았다. 여기서는 probe가 docs가 부정한 기능이 이미 있다고 찾았다. 문서는 양방향으로 어긋날 수 있다. 그리고 어느 쪽으로 어긋났는지는, 언어를 돌려 보는 것만이 알려준다.

진짜 gap 셋과, 정직한 주름

낡은 한 문장은 진짜 gap을 셋 숨기고 있었고, 전부 고쳤다. 단항 마이너스는 아직 정수 전용이라 —— -2.5는 정말로 type error였고, 음의 float 리터럴은 이름 붙은 부정 함수를 요했다 —— 그래서 이항 연산자와 같이 수치 overload가 되었다, 4 backend 전부에서. LLVM backend는, 밝혀진 바로는, float infix 산술에 대해 부동소수점 피연산자에 정수 덧셈 명령을 emit하고 있었다 —— 컴파일러가 즉시 거부하는 invalid IR이고, float 비교에는 정수 비교를 —— 그래서 적절한 부동소수점 덧셈 일가와 ordered 부동소수점 비교를 얻었다. 그리고 앞 이야기의 바이너리 이야기의 쓰기 절반이 빠져 있었다: 바이트 vector reader는 있었지만 writer가 없어서, 렌더러는 짝이 되는 write_file_bytes를 얻었고, 이미지 형식의 ASCII 도피 대신 날 픽셀 형을 emit할 수 있게 되었다 —— 날 형은 약 3분의 1 크기다. 렌더러는 400×300 집합을 날 infix 수식으로 그리고, 그 날 픽셀 출력은 ASCII 판의 픽셀과 바이트 단위로 동일하다. 한 정직한 주름이 남아, 정정된 docs에 적혀 있다: overload는 피연산자가 구체적으로 float일 때만 float로 해결하므로, 주석 없는 함수 파라미터는 아직 정수로 default하고, float 중심의 코드는 파라미터에 주석한다. 정정은 레퍼런스와 표준 라이브러리 노트 양쪽에 들어갔다. 교훈은 Part 전체와 짝을 이룬다: 4 backend는 서로 어긋날 수 있고, docs는 넷 전부와 한 번에 어긋날 수 있다. Part 마지막 이야기는, 이 probe들 중 둘이 우회해야 했던 papercut을 고치고 —— 그리고 그날의 장부를 닫는다.

← Back to Mere: 언어를 만들다