Skip to content

필사 모드: 이맥스에서는 모든 것이 서비스로 보인다: "에디터=OS" 밈을 클라이언트-서버 렌즈로 다시 읽기

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

들어가며 — "이맥스는 OS다"라는 오해

Charles Choi(최민수)의 글 "In Emacs, Everything Looks Like a Service"가 최근 Hacker News에서 화제가 됐다. 흥미로운 건 이 글이 "이맥스는 운영체제(OS)다"라는 흔한 찬사에서 출발해 그것을 곧바로 부정한다는 점이다. 저자의 표현은 분명하다. 그 비유는 사실이 아니며, 다만 OS를 떠올리게 하는 것은 이맥스가 커널 위에서 애플리케이션과 유틸리티를 조율(orchestrate)하는 능력이라는 것이다.

그가 대신 제시하는 그림은 더 정확하다. 이맥스는 파일 시스템, 네트워크 같은 OS 서비스에 직접 접근하고 다른 프로그램을 실행할 수 있기 때문에, 그 안에서 클라이언트를 즉흥적으로 만들어 쓰는 일이 일상이 된다. 그래서 사람들이 "이맥스 안에서만 산다(living only in Emacs)"고 말하게 된다는 것이다. 결론은 제목 그대로다. 이맥스 안에서는 모든 것이 서비스처럼 보인다.

여기서 "서비스"는 유행어가 아니라 정확한 기술 용어다. 이 글의 진짜 주장은 이맥스가 데몬을 돌리는 서버라는 게 아니라, 이맥스가 범용 클라이언트라는 것이다. 그 구분이 이 글의 핵심이고, 낡은 "OS 밈"보다 훨씬 쓸모 있는 렌즈다.

클라이언트-서버 렌즈

글의 뼈대는 교과서적인 클라이언트-서버 모델이다. 작업을 자원의 제공자(서비스)와 요청자(클라이언트)로 나누고, 클라이언트가 요청을 보내면 서버가 응답을 돌려준다. 이 거래는 네트워크를 건너갈 수도, 시스템 안에서 국소적으로 일어날 수도 있다. 저자가 강조하는 지점은 바로 이 "국소적으로도"다.

그는 클라이언트가 대체로 세 가지를 책임진다고 정리한다. UI, 서비스와 통신하는 클라이언트 엣지(client edge), 그리고 주고받는 데이터를 담는 로컬 데이터베이스다. 그리고 이맥스에는 이 세 가지 각각을 위한 내장 라이브러리가 이미 있다. UI에는 미니버퍼, 버퍼, 자동완성, tabulated-list-mode, vtable, transient가 있고, 클라이언트 엣지에는 url, TCP/UDP 소켓, SMTP, JSON/XML 직렬화가 있으며, 로컬 데이터에는 연관 리스트, 속성 리스트, 해시 테이블, SQLite가 있다. 이들을 묶는 접착제는 Elisp다 — 런타임에 즉흥적으로 동작을 조립할 수 있는 동적 언어다.

저자의 예시는 wttr.in이라는 콘솔용 날씨 서비스다. 위치를 입력받아 HTTP 요청을 보내고, JSON 응답을 파싱해 결과를 미니버퍼에 띄우는 wttr 명령을 만든다. 핵심은 분량이다. 완성된 wttr.elcloc 기준 67줄이다. 더 흥미로운 건 두 번째 버전이다. 네트워크 요청과 JSON 처리를 파이썬 스크립트 weather에 맡기면, Elisp 쪽은 셸을 호출하는 것이 전부가 된다.

(defun weather (location)
  "Call weather script with LOCATION and show result in minibuffer."
  (interactive "sWhere (default: local): ")

  (let* ((weather-cmd "weather")
         (cmd (if location (format "%s %s" weather-cmd location) weather-cmd))
         (result (shell-command-to-string cmd)))
    (kill-new result)
    (message result)))

저자의 표현대로, 이렇게 하면 셸 명령 자체가 사실상 요청을 보내는 서비스가 된다. 기존 커맨드라인 유틸리티가 무거운 일을 대신 해 준다면, 그 유틸리티를 셸 호출로 접근하는 하나의 "서비스"로 다시 규정할 수 있다는 것이다. 이 한 문장이 글 전체를 지탱한다.

왜 이것이 독특한 계산 모델인가

여기서부터는 내 분석이다. 우리가 평소 쓰는 모델은 "작업마다 앱 하나"다. 웹은 브라우저, 메일은 메일 앱, 셸은 터미널. 각 앱은 자기 세계를 갖고, 그 사이를 오가려면 복사-붙여넣기와 창 전환을 감수한다.

이맥스가 제시하는 모델은 정반대다. 오래 떠 있는 하나의 Lisp 환경 안에서, 각 능력은 어떤 서비스에 대한 얇은 클라이언트로 구현된다. 날씨든, 메일이든, 깃이든, 데이터베이스든 전부 같은 버퍼·같은 키맵·같은 Elisp 위에서 돈다. 저자가 말한 "이맥스 안에서만 산다"는 표현이 성립하는 이유가 이것이다. 앱을 오가는 대신, 서비스에 요청을 보내는 클라이언트를 그때그때 만들어 붙인다.

정확히 짚자면, 이 글의 주장은 버퍼나 프로세스가 곧 서비스라는 게 아니다. 서비스는 바깥에 있다 — 네트워크 API이거나, 셸 뒤의 CLI 도구다. 이맥스가 하는 일은 그 서비스들에 대한 클라이언트가 되는 것이다. 그래서 이 렌즈는 "이맥스는 OS다"라는 밈보다 정확하다. 이맥스는 커널을 대체하지 않는다. 커널 위의 자원들에 말을 거는 보편적 창구가 될 뿐이다.

매력과 비용

매력은 분명하고 과장이 아니다. 날씨 클라이언트 하나가 67줄이고, CLI를 감싸는 버전은 9줄이다. 유닉스에 존재하는 수많은 커맨드라인 도구가 곧바로 호출 가능한 서비스가 된다. 통일성도 크다. 한 번 익힌 편집·검색·키맵이 모든 "클라이언트"에 그대로 적용된다. 조합 가능성과 즉흥성 — 이것이 이 모델이 파는 진짜 가치다.

비용도 정직하게 봐야 한다. 첫째, 저자의 코드가 스스로 드러내는 대가가 있다. fetch-json-as-hash-tableurl-retrieve-synchronously를 쓴다 — 동기 호출이다. Elisp는 사실상 단일 스레드이므로 요청이 도는 동안 편집기 전체가 멈출 수 있다. 둘째, 추상은 높지만 배관은 내가 쥔다. HTTP 헤더를 지나 url-http-end-of-headers로 포인트를 옮기고, 메모리 누수를 막으려 네트워크 버퍼를 직접 kill-buffer해야 한다. 셋째, 더 근본적으로 이렇게 만든 클라이언트는 대개 전용 앱이 이미 더 잘 하는 일의 얇은 재구현이다. 완성도를 내주고 통합과 조합을 얻는 거래다.

그래서 "이맥스는 훌륭한 OS인데 쓸 만한 에디터가 없을 뿐"이라는 오래된 농담이 남긴 긴장은 여전히 유효하다. 다만 이 글은 그 농담을 비껴간다. 이맥스를 OS라고 부르는 대신 범용 클라이언트라고 부르면, "무엇이든 할 수 있다"는 매력과 "무엇 하나도 최고는 아니다"라는 비용이 동시에 설명된다. 이 모델은 이미 이맥스 안에 사는 사람에게 강력하다. 그렇지 않은 사람에게는, 얇은 클라이언트를 직접 조립하는 즐거움이 곧 비용이기도 하다.

마무리

이 글의 진짜 기여는 새 기능이 아니라 정확한 프레이밍이다. "이맥스는 OS다"라는 느슨한 밈을 "이맥스 안에서는 모든 것이 서비스로 보인다"는 검증 가능한 주장으로 바꿔 놓는다. 그리고 그 주장은 코드로 뒷받침된다 — 67줄짜리 날씨 클라이언트, 9줄짜리 셸 래퍼.

내가 덧붙이고 싶은 건 균형이다. 이 렌즈는 매력을 설명하는 만큼 비용도 설명한다. 동기 호출의 멈춤, 직접 쥐어야 하는 배관, 전용 앱 대비 낮은 완성도. 저자의 마지막 문장대로, 이 능력은 그 기회를 알아보는 사용자에게 강력하다. 나는 거기에 한 줄을 더한다 — 그 기회를 택하는 순간, 완성도와 조합 가능성 사이의 오래된 거래를 함께 택하는 것이다.

참고 자료

현재 단락 (1/26)

Charles Choi(최민수)의 글 "In Emacs, Everything Looks Like a Service"가 최근 Hacker News에서 화제가 됐다. 흥미로운 건 이 ...

작성 글자: 0원문 글자: 3,109작성 단락: 0/26