완고한 개발자의 언어 서버 도전기

A curmudgeon tries a language server

완고한 개발자의 언어 서버 도전기

이 글은 Haskell 개발자가 언어 서버(LSP)와 ghcid, foreign-store를 결합해 Lisp 스타일의 대화형 개발 워크플로를 구현하려는 시도를 다룹니다. 저자는 기존의 편집-컴파일-실행 사이클을 벗어나, 코드를 저장할 때마다 자동으로 재컴파일하고 테스트를 실행하며 애플리케이션 상태를 유지하는 방법을 소개합니다. Emacs에서 Eglot과 Haskell Language Server를 설정하는 과정의 세부 단계와 겪은 어려움도 공유합니다.

우리는 결국 편집기에서 코드를 작성하고, LSP 서버가 코드에 대한 정보를 제공하는 프로세스를 갖게 됩니다. REPL에서 실험하는 대신, 실험을 단위 테스트로 작성합니다. 변경 사항을 저장하면 ghcid가 코드를 다시 로드하고, 테스트를 실행하고, 중요한 상태를 잃지 않고 애플리케이션을 재시작합니다. 우리는 편집기를 떠나지 않습니다.
  1. dieggsy

    Common Lisp 개발자로서, 서문에서 Lisp에 대해 한 말은 대체로(?) 사실인 것 같습니다.

    제 경험상 우리는 실제로 '코드를 컴파일하고 실행'한다고 말할 수 있지만, 설명된 워크플로우 덕분에 증분 방식으로, 그리고 컨텍스트 전환을 덜 하면서 그렇게 할 수 있습니다. 하지만 실제로는 별도의 컴파일 및 실행 단계가 있는 경우가 꽤 많습니다. 단지 전체 프로그램 수준에서 그런 것은 아닐 뿐입니다(예: 함수 하나를 컴파일하고 그 함수나 호출 함수를 실행하는 것).

    또한 실제 실행 중에 코드를 재정의하는 것이 강점으로 자주 소개되지만, 실제로는 그렇게 흔하지 않다고 생각합니다. 물론 가끔 사용되기는 하지만, 많은 프로그램이 애초에 그런 패러다임에 잘 맞지 않습니다. 예를 들어 일부 게임이나 오래 실행되는 서버에서는 잘 작동할 수 있습니다.

    소스 코드 없이 이미지에서 작업하는 것은 정말 끔찍한 아이디어처럼 보입니다. 사소한 일회성 실험에서는 할 수 있겠지만, 일반적으로는 코드를 일찍 작성하고 정리하는 것이 이점이 있습니다. 설명된 대로 이미지에서 소스 코드를 추출하는 특히 쉽거나 깔끔한 방법을 저는 알지 못합니다. 가능할 수도 있지만, 제가 생각할 수 있는 모든 방법은 오히려 고통스럽거나 지저분해 보입니다. 제 경험일 수도 있고, 상용 Lisp의 멋진 기능을 놓치고 있을 수도 있습니다.

  2. cassepipe

    정확히 같은 것은 아니지만 C/C++ 프로그래머에게 언급할 가치가 있습니다: gdb는 실제로 C와 C++를 위한 일종의 '저렴한' 라이브 환경으로 기능할 수 있습니다.

    중단점에서 멈추면 C/C++ 표현식을 평가하고, 상태를 수정하고, 함수를 호출하고, compile code 명령을 사용하면 GDB가 실행 중인 프로세스의 컨텍스트에서 새 C/C++ 코드를 컴파일하고 실행할 수 있습니다:

    (gdb) set variable state->counter = 42

    (gdb) call recompute_state(state)

    (gdb) compile code

    > printf("counter = %d\n", state->counter);

    > do_something(state);

    > end

    이는 놀랍도록 훌륭한 '실행 중인 C 프로그램에 연결된 REPL' 경험을 제공합니다. 힙을 건드리고, 변수를 변경하고, 기존 코드를 호출하고, 프로세스를 재시작하지 않고 새 코드 조각을 주입할 수 있습니다.

    제가 기억하는 한 가지 사용 사례는 다양한 트리 구조를 구현하고 트리를 .dot 형식으로 출력하는 print_dot 함수를 추가한 것이었습니다. gdb 내에서 그 함수를 호출할 때마다 xdot 창이 업데이트된 트리 그래프로 다시 그려졌습니다.

    주입된 코드가 영구적으로 유지되는 Lisp 이미지와 완전히 같지는 않지만 여전히 유용하다는 것을 알고 있습니다.

    추신: 처음으로 gdb의 tui를 사용해 보는데 프로그램에 여전히 print 문이 많다면, printf 출력 후 Ctrl+L 또는 refresh 명령으로 화면을 정리할 수 있습니다.

  3. PaulHoule

    세상에, 그 이미지 기반 프로그래밍 방식은 끔찍한 혼란을 만들기 때문에 주류가 된 적이 없습니다.

    Python으로 작업하는 데이터 과학자들이 답을 노트북에 구워서 다른 사람들에게 보여주고 싶어 하지만, 버전 관리에서 코드와 데이터를 분리하고 기술을 활용하려면 매번 위에서 아래로 실행할 수 있는 스크립트가 필요하다는 것을 깨닫지 못하는 그 노트북 악몽을 보세요.

  4. ux266478

    솔직히 말해서, GHC가 만들어내는 구조적 파괴의 양을 고려할 때 이미지 기반 개발은 정말 나쁜 생각인 것 같습니다. Haskell은 시스템 관점에서 이해하기 매우 이상하고 직관적이지 않은 언어입니다. 거의 직접 보거나 상호작용할 수 없는 언어를 위한 매크로를 작성하는 것으로 제한된 것과 같기 때문입니다. 소스 코드에서 컴파일러가 내뱉는 것으로의 변환은 사용자 정의 재작성 규칙 같은 것을 도입하기 전에도 매우 비국소적이고 예측 불가능할 수 있습니다.

    제 생각에 Haskell로 작업하는 현명한 방법은 반복의 정반대입니다. 종이에 설계하고, 다듬고, 대수적 규칙을 찾고, 더 다듬은 다음, 정확히 무엇을 하고 있는지 알게 되면 코드 작성을 시작하는 것입니다. '그냥 코드 작성을 시작하라'는 유혹에 굴복하는 것이 불투명한 타입 스파게티로 끝나는 길이라고 생각합니다. 그건 제 개인적인 느낌일 뿐입니다.

  5. airza

    이 게시물에서 Haskell과 Lisp에 대한 흥미로운 사실을 많이 배웠습니다. 그 사실들은 둘 중 하나를 사용하여 소프트웨어를 개발하려는 생각에 도망치고 싶게 만듭니다. Haskell로 보낸 시간은 저를 더 나은 프로그래머로 만들었고, LLM이 일부 문서를 더 이해하기 쉽게 만들었을 것이라고 확신하지만...

이 날의 다른 글

2026-08-26