Split View: 조회 비용이 읽을 수 있는 것을 정합니다 — 2천 년 된 텍스트에서 코드 탐색까지
조회 비용이 읽을 수 있는 것을 정합니다 — 2천 년 된 텍스트에서 코드 탐색까지
- 사전을 200번 찾아야 하는 텍스트는 읽을 수 없습니다
- Ancient Library가 하는 일
- 어디서 온 것들인지가 절반입니다
- 형태 분석을 자동화한 선택과 그 대가
- 조회 비용이 0이 되면 바뀌는 것
- 우리가 이미 아는 같은 이야기
- 그래서 생기는 새로운 실패 방식
- 이번 주에 해 볼 것
- 정리와 출처
사전을 200번 찾아야 하는 텍스트는 읽을 수 없습니다
고전어를 배워 본 사람은 이 감각을 압니다. 문법은 대략 알고 어휘도 어느 정도 쌓였는데, 원전 한 쪽을 읽는 데 두 시간이 걸립니다. 이유는 어렵기 때문이 아니라 끊기기 때문입니다.
한 단어가 막힙니다. 굴절된 형태라 사전에 그대로 나오지 않으니 먼저 원형을 짐작해야 합니다. 짐작이 맞으면 사전을 펴고, 항목이 길면 그 안에서 이 문맥에 맞는 뜻을 고릅니다. 여기까지 30초 걸렸다고 합시다. 그리고 문장으로 돌아오면 앞 절반을 잊어버렸습니다. 다시 읽습니다.
한 쪽에 이런 일이 200번 있으면 총합은 시간의 문제가 아니게 됩니다. 작업 기억이 매번 초기화되기 때문에 문장이 문장으로 조립되지 않습니다. 그러면 그 텍스트는 어려운 텍스트가 아니라 읽을 수 없는 텍스트가 됩니다.
Ancient Library가 하는 일
Ancient Library는 이 문제 하나를 없애는 사이트입니다. 그리스어와 라틴어 원전을 모아 두고, 텍스트 안의 아무 단어나 누르면 그 자리에서 원형과 형태 분석과 사전 항목 전체를 보여 줍니다.
규모는 사이트에 그대로 표시되어 있습니다. 저작 1,060편이고 그중 라틴어가 293편, 그리스어가 767편이며 저자는 140명입니다. 장르별로 라틴어 14개, 그리스어 16개 분류로 정리되어 있습니다.
사전은 고전학에서 표준으로 쓰이는 두 가지입니다. 라틴어는 Lewis and Short의 1879년 라틴어 사전, 그리스어는 Liddell-Scott-Jones의 1940년 9판 그리스어-영어 사전입니다. 사이트는 스스로를 Worth Media의 공익 사업이라고 밝히고 있습니다.
어디서 온 것들인지가 절반입니다
이 사이트를 볼 때 놓치기 쉬운 부분이 출처입니다. 텍스트는 터프츠 대학의 Perseus Digital Library에서 왔고 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0으로 제공됩니다. 두 사전도 Perseus가 디지털화한 것입니다.
즉 이 사이트가 새로 만든 것은 텍스트도 사전도 아닙니다. 수십 년에 걸쳐 공개된 자원들을 한 화면에서 한 번의 클릭으로 연결한 것입니다.
이 구조가 시사하는 바가 있습니다. 조회 비용을 없애는 도구는 대개 새 데이터를 만들지 않습니다. 이미 있는 데이터 사이의 거리를 줄입니다. 그리고 그 거리가 비용의 거의 전부입니다. 사전은 100년 전에도 있었고 텍스트는 2천 년 전부터 있었습니다. 없었던 것은 둘 사이를 잇는 0.2초짜리 경로였습니다.
형태 분석을 자동화한 선택과 그 대가
원형과 형태 분석은 사람이 손으로 붙일 수 있는 양이 아닙니다. 이 사이트는 그 작업을 고전어로 학습된 언어 모델에 맡겼다고 밝힙니다. 고전 그리스어에는 odyCy를, 라틴어에는 LatinCy를 썼다고 적혀 있습니다.
그리고 사이트는 이 선택의 대가를 스스로 명시합니다. 자동 분석은 완벽하지 않으며 드문 형태는 원형이나 분석이 잘못 붙을 수 있다는 것입니다.
저는 이 한 문장이 이 사이트에서 가장 중요한 부분이라고 생각합니다. 자동 분석의 실패는 조용하기 때문입니다. 틀린 분석은 물음표를 띄우지 않고 그럴듯한 격과 수를 보여 줍니다. 초보자는 그것이 틀렸다는 것을 알아챌 수 없고, 알아챌 수 있는 사람은 애초에 도구가 덜 필요합니다. 도구의 이득이 가장 큰 사용자가 그 도구의 오류에 가장 취약하다는 구조입니다. 이 사실을 사이트가 먼저 적어 둔 것과 적지 않은 것은 사용자에게 완전히 다른 상황입니다.
조회 비용이 0이 되면 바뀌는 것
비용이 줄어드는 것과 0이 되는 것은 다릅니다. 여기서 바뀌는 것은 속도가 아니라 가능한 작업의 종류입니다.
사전을 30초에 찾을 때 우리는 정말 막힌 단어만 찾습니다. 애매하지만 대충 넘어갈 수 있는 단어는 넘어갑니다. 그런데 조회가 0.2초가 되면 애매한 것도 확인하게 되고, 확인하다 보면 자기가 어디를 잘못 알고 있었는지 알게 됩니다. 즉 비용이 사라지면 읽는 방식 자체가 바뀝니다.
두 번째 변화는 흐름입니다. 앞에서 본 것처럼 진짜 손실은 30초가 아니라 그 30초 동안 잃어버린 문장의 앞부분이었습니다. 같은 화면 안에서 답이 나오면 흐름이 끊기지 않고, 그러면 긴 문장이 긴 문장으로 남습니다.
세 번째는 조금 덜 분명한데 실무에서는 가장 큽니다. 조회가 싸지면 확인하지 않고 넘어가는 습관이 줄어듭니다. 비싼 조회를 앞에 두고 우리가 실제로 하는 일은 확인이 아니라 추측이고, 추측은 대체로 맞기 때문에 틀렸다는 사실을 알 기회가 없습니다. 그렇게 굳어진 오해는 몇 달 뒤에 전혀 다른 자리에서 드러납니다. 비용을 없애는 도구가 주는 이득의 상당 부분이 여기, 즉 틀린 채로 굳는 것을 막아 주는 데 있습니다.
우리가 이미 아는 같은 이야기
이 구조가 익숙하다면 정확합니다. 코드에서 이미 같은 일을 겪었기 때문입니다.
식별자에서 정의로 이동하는 기능이 없던 시절의 코드 읽기를 생각해 보면 됩니다. 함수 이름을 보고 그것이 어디 있는지 찾으려면 파일 트리를 뒤지거나 전체 검색을 걸어야 했습니다. 그러면 지금 읽던 자리를 잃습니다. 그래서 우리는 정말 막힌 것만 찾아보고 나머지는 이름으로 짐작했습니다.
정의로 이동이 즉시 동작하게 되자 코드를 읽는 방식이 바뀌었습니다. 낯선 코드베이스를 위에서 아래로 훑는 대신, 하나를 잡고 계속 파고들어 갈 수 있게 됐습니다. 처음 보는 저장소에서 하루 만에 어느 정도 지도를 그릴 수 있게 된 것은 우리가 똑똑해져서가 아니라 조회가 공짜가 되었기 때문입니다.
그래서 생기는 새로운 실패 방식
같은 이득에는 같은 대가가 따라옵니다. 코드 탐색 도구도 조용히 틀립니다.
동적 언어에서 정의로 이동은 후보가 여럿일 때 하나를 고릅니다. 그 선택이 틀려도 편집기는 물음표를 띄우지 않고 어떤 파일을 열어 줍니다. 열린 파일이 그럴듯해 보이면 우리는 그것을 정답으로 받아들이고 그 위에서 판단을 쌓습니다. 인터페이스와 구현이 여럿인 경우, 몽키 패치가 있는 경우, 생성된 코드가 섞인 경우에 특히 자주 어긋납니다.
여기서 실무적인 결론이 하나 나옵니다. 자동 분석에 기대는 도구는 자기가 틀릴 수 있다는 사실을 사용자에게 보여 줘야 합니다. Ancient Library가 한계를 문서에 적어 둔 것처럼, 편집기의 탐색 기능도 후보가 여럿이었다는 사실을 감추지 말아야 합니다. 하나를 골라 조용히 열어 주는 것이 편하긴 하지만, 편한 만큼 틀렸을 때 발견이 늦습니다.
이번 주에 해 볼 것
이 관점을 우리 팀에 옮긴다면, 물어야 할 질문은 어떤 도구를 쓰느냐가 아니라 우리 코드베이스에서 아직 비싼 조회가 무엇인가입니다. 대개 다음 넷 중 하나입니다.
- 이 설정 값이 실제로 어디서 읽히는지. 문자열 키로 접근하면 정의로 이동이 통하지 않습니다.
- 이 API 응답 필드가 어느 코드에서 만들어지는지. 서비스 경계를 넘으면 탐색이 끊깁니다.
- 이 에러 메시지가 어디서 나오는지. 문자열이 조립되어 있으면 검색으로 찾히지 않습니다.
- 이 테이블 컬럼을 누가 쓰는지. ORM이 이름을 변환하면 연결이 보이지 않습니다.
네 가지의 공통점은 자동 탐색이 끊기는 자리라는 점입니다. 한 주 동안 팀원들이 어떤 것을 찾느라 슬랙에 물어봤는지 세어 보면 목록이 나옵니다. 그중 상위 두 개에 대해서만 검색 가능한 형태를 만들면, 그러니까 문자열 키를 상수로 바꾸거나 조립된 메시지를 한 자리에 모으면, 그 한 번의 변경이 앞으로 수백 번의 조회를 없앱니다.
정리와 출처
도구가 하는 일은 없던 지식을 만드는 것이 아닙니다. 이미 있는 것 사이의 거리를 줄이는 것입니다. 그런데 그 거리가 줄면 우리가 할 수 있는 일의 종류가 바뀌고, 그래서 도구는 종종 능력의 문제처럼 보입니다.
- Ancient Library — 저작 편수와 언어별 분포, 클릭 시 제공되는 정보, 두 사전의 판본
- Ancient Library 소개 페이지 — 텍스트가 Perseus Digital Library에서 왔다는 점, 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0 조건, odyCy와 LatinCy를 형태 분석에 사용했다는 점, 자동 분석이 완벽하지 않다는 명시적 한계
- 본문 후반의 코드 탐색 이야기는 위 자료가 다루는 내용이 아니라 제가 같은 논리를 개발 작업에 옮긴 것입니다.
Lookup Cost Decides What You Can Read — From Two-Thousand-Year-Old Texts to Code Navigation
- A text that needs two hundred dictionary lookups cannot be read
- What Ancient Library does
- Where the pieces came from is half of it
- The choice to automate morphological parsing, and its price
- What changes when lookup cost reaches zero
- The same story we already know
- The new failure mode that comes with it
- Something to try this week
- Summary and sources
A text that needs two hundred dictionary lookups cannot be read
Anyone who has studied a classical language knows this feeling. You roughly know the grammar and you have accumulated a fair amount of vocabulary, and yet one page of the original takes two hours. The reason is not that it is difficult. It is that you keep getting interrupted.
One word stops you. It is inflected, so it does not appear in the dictionary in that form, and you first have to guess the lemma. If the guess is right you open the dictionary, and if the entry is long you pick out of it the sense that fits this context. Say that took thirty seconds. Then you come back to the sentence and you have forgotten its first half. You read it again.
When that happens two hundred times on one page, the sum stops being a matter of time. Because working memory is reset every single time, sentences do not assemble into sentences. At that point the text is not a difficult text; it is a text that cannot be read.
What Ancient Library does
Ancient Library is a site that removes exactly this one problem. It gathers Greek and Latin originals, and when you click any word inside the text, it shows you the lemma, the morphological parsing, and the whole dictionary entry right there.
The scale is stated on the site itself. There are 1,060 works, of which 293 are Latin and 767 are Greek, by 140 authors. They are organized into 14 Latin and 16 Greek genre categories.
The dictionaries are the two standards of classical scholarship. For Latin it is the 1879 Latin dictionary of Lewis and Short; for Greek it is the 1940 ninth edition of the Liddell-Scott-Jones Greek-English lexicon. The site describes itself as a public-benefit project of Worth Media.
Where the pieces came from is half of it
The part easiest to miss when looking at this site is provenance. The texts came from the Perseus Digital Library at Tufts University and are provided under Creative Commons Attribution-ShareAlike 4.0. Both dictionaries were digitized by Perseus as well.
That is to say, what this site newly made is neither the texts nor the dictionaries. It connected resources that had been public for decades into one screen, one click away.
There is something this structure implies. Tools that remove lookup cost usually do not create new data. They shorten the distance between data that already exists. And that distance is nearly the entire cost. The dictionaries existed a hundred years ago and the texts have existed for two thousand years. What did not exist was the 0.2-second path between the two.
The choice to automate morphological parsing, and its price
Lemmas and morphological parsing are not a quantity of work a person can attach by hand. The site states that it handed that work to language models trained on the classical languages. It is written that odyCy was used for Ancient Greek and LatinCy for Latin.
And the site itself spells out the price of that choice: automatic parsing is not perfect, and rare forms may get the wrong lemma or the wrong analysis attached.
I think that one sentence is the most important part of this site, because failures of automatic parsing are silent. A wrong analysis does not raise a question mark; it shows a plausible case and number. A beginner cannot notice that it is wrong, and the person who could notice needed the tool less to begin with. The structure is that the user who gains most from the tool is the most vulnerable to its errors. Whether the site writes this down up front or does not leaves the user in a completely different situation.
What changes when lookup cost reaches zero
Cost going down and cost going to zero are different things. What changes here is not speed but the kind of work that is possible.
When a dictionary lookup takes thirty seconds, we look up only the words that truly block us. Words that are ambiguous but can be waved past get waved past. But when a lookup takes 0.2 seconds we check the ambiguous ones too, and while checking we find out where we had been wrong. That is, when the cost disappears, the way of reading itself changes.
The second change is flow. As we saw above, the real loss was not the thirty seconds but the first half of the sentence lost during those thirty seconds. When the answer appears inside the same screen the flow is not broken, and then a long sentence stays a long sentence.
The third is a little less obvious and is the biggest one in practice. When lookups get cheap, the habit of moving on without checking shrinks. Faced with an expensive lookup, what we actually do is not verify but guess, and because guesses are mostly right there is no occasion to learn that we were wrong. A misunderstanding hardened that way surfaces months later in a completely different place. A good share of the benefit a cost-removing tool gives lies right here, in preventing a wrong belief from setting.
The same story we already know
If this structure feels familiar, that is correct. We have already been through the same thing in code.
Think back to reading code in the days before jumping from an identifier to its definition. To see a function name and find where it lived, you had to dig through the file tree or run a full-text search. Doing that lost the place you had been reading. So we looked up only what truly blocked us and guessed the rest from names.
Once go-to-definition worked instantly, the way we read code changed. Instead of skimming an unfamiliar codebase from top to bottom, we could grab one thing and keep drilling into it. That we can now sketch a rough map of a repository we have never seen before in a single day is not because we got smarter. It is because lookups became free.
The new failure mode that comes with it
The same benefit brings the same price. Code navigation tools also fail quietly.
In dynamic languages, go-to-definition picks one candidate when there are several. Even when that pick is wrong, the editor does not raise a question mark; it opens some file. If the opened file looks plausible we accept it as the answer and stack judgments on top of it. It goes wrong especially often when there are several interfaces and implementations, when monkey patching is involved, or when generated code is mixed in.
One practical conclusion comes out of this. A tool that leans on automatic analysis has to show the user that it can be wrong. Just as Ancient Library wrote its limits into its documentation, an editor navigation feature should not hide the fact that there were several candidates. Picking one and quietly opening it is comfortable, but the comfort is paid for by finding out late when it was wrong.
Something to try this week
If you move this perspective onto your team, the question to ask is not which tool to use but what is still an expensive lookup in our codebase. Usually it is one of the following four.
- Where this config value actually gets read. If it is accessed by a string key, go-to-definition does not reach it.
- Which code produces this API response field. Navigation breaks at a service boundary.
- Where this error message comes from. If the string is assembled, search does not find it.
- Who uses this table column. If the ORM transforms names, the link is invisible.
What the four have in common is that they are the spots where automatic navigation breaks. Count what your teammates asked about in Slack over one week and the list appears. Make searchable forms for just the top two of them — turn string keys into constants, gather assembled messages into one place — and that single change removes hundreds of lookups from here on.
Summary and sources
What a tool does is not to create knowledge that did not exist. It is to shorten the distance between things that already do. But when that distance shrinks, the kind of work we can do changes, and so a tool often looks like a question of ability.
- Ancient Library — the number of works and their distribution by language, the information provided on a click, the editions of the two dictionaries
- Ancient Library about page — that the texts came from the Perseus Digital Library, the Creative Commons Attribution-ShareAlike 4.0 terms, that odyCy and LatinCy were used for morphological parsing, and the explicit limit that automatic parsing is not perfect
- The code navigation discussion in the second half is not something those sources cover; it is my own transfer of the same logic to development work.