Scarf가 7년간 프로덕션에서 Haskell을 사용한 뒤, AI 시대의 개발 속도와 도구 체인 마찰을 이유로 신규 제품 개발을 Python으로 옮기게 된 배경과, Haskell 생태계가 직면한 과제를 설명합니다.
Avi Press | 2026년 7월 10일
—
이 글은 쓰기 힘든 글이었습니다. 저는 비판하기보다 만들고 알리는 쪽을 선호하기 때문에, 거의 아예 쓰지 않을 뻔했습니다. 하지만 이 글이 Haskell의 미래에 대한 논의에 건설적으로 보탬이 되기를 바랍니다. 저는 바깥에서 Haskell을 비판하는 입장에서 이 글을 쓰는 것이 아니라는 점을 분명히 하고 싶습니다. 저는 Scarf가 왜 마지못해 Haskell에서 벗어나게 되었는지 솔직하게 말할 만큼 Haskell을 아끼며, 이 피드백을 공동체의 사람들이 진지하게 받아들이게 되기를 바랍니다.
지난 16년 동안 저는 Haskell의 열렬한 팬이었습니다. Haskell은 제 인생에서 단연 가장 중요한 프로그래밍 언어였습니다. 이를 배우면서 저는 훨씬 더 나은 프로그래머가 되었습니다. 저는 이를 옹호해 왔고, 이를 기반으로 돌아가는 회사를 세웠으며, Haskell Foundation과 Haskell.org 위원회의 이사회에서도 활동하고 있습니다.
저는 또한 Haskell이 개선되어야 한다고 생각하는 지점들에 대해서도 꾸준히 공개적으로 이야기해 왔습니다.
Scarf를 시작한 이후, 우리 백엔드는 Haskell로 구축되었습니다. 우리 앱을 구동하는 주요 API는 PostgreSQL 위에서 Servant, Beam 같은 라이브러리를 사용합니다. 또한 우리는 WAI 위에 직접 구축한 고성능 Haskell 서비스인 Scarf Gateway도 만들었습니다. 이 서비스는 대량의 오픈 소스 패키지 트래픽 다운로드 경로에 직접 놓여 있습니다. 이 시스템들은 실제 가동 시간 요구사항과 계약상 보장된 SLA를 가지고 있었고, 우리는 수년간 이를 프로덕션에서 성공적으로 운영해 왔습니다.
우리는 Haskell을 진지한 프로덕션 시험대에 올렸고, 그 약속 중 많은 부분은 실제로 입증되었습니다. 코드는 신뢰할 수 있었습니다. 타입 시스템은 실제 버그를 잡아냈습니다. 이 언어는 우리가 도메인을 어떻게 모델링할지 신중하게 생각하도록 만들었습니다. 고성능 코드를 작성하는 것도 대체로 비교적 수월했습니다.
하지만 비용 역시 현실적이었습니다. 가장 큰 것은 컴파일 시간과 생태계의 마찰이었습니다. 우리는 빌드, 캐시, Nix, 개발자 환경, CI, 그리고 진지한 Haskell 코드베이스 주변에 결국 필요해지는 온갖 장치들을 최적화하는 데 많은 시간을 썼습니다. 오랫동안 그것은 감당 가능한 수준이었습니다. 우리 팀은 언어와 도구를 깊이 이해하고 있었습니다. 어디에 날카로운 모서리가 있는지 알고 있었고, 대부분은 그것과 함께 살아갔습니다.
그러다 AI가 이 균형을 바꾸었습니다.
이제 LLM은 코드를 매우 잘 작성합니다. 물론 완벽하지는 않지만, 소프트웨어 개발의 경제성이 달라질 만큼은 충분히 잘합니다.
역사적으로 저는 오류를 두 곳 중 하나에서 잡는다고 생각해 왔습니다. 컴파일 시점이거나 런타임이었습니다. 이제는 세 번째 장소가 생겼습니다. 바로 코드 생성 시점입니다. 모델은 종종 컴파일러가 코드를 보기 전에 실수를 피할 수 있습니다. 그리고 모델이 더 좋아질수록, 가능한 모든 문제를 컴파일 시점에 잡아내는 것의 상대적 가치도 달라집니다.
그렇다고 타입 안전성이 무가치해졌다는 뜻은 아닙니다. 하지만 이제 타입 검사 비용이 훨씬 더 중요해졌습니다. LLM이 몇 분 만에 동작하는 구현을 만들어 낼 수 있는데, 컴파일 단계는 훨씬 더 오래 걸린다면, 언어와 빌드 시스템은 개발 루프의 병목이 되어 버립니다.
중요한 지표는 이것입니다. 전체 개발 피드백 주기에 얼마나 오래 걸리며, 그 시간 중 얼마를 컴파일러를 기다리는 데 쓰는가? 사람이 한 시간을 들여 코드를 쓴다면 긴 컴파일 주기는 성가시지만 참을 만할 수도 있습니다. 하지만 에이전트가 몇 분 안에 그럴듯한 변경안을 만들고, 그 뒤 콜드 스타트 상태에서 프로젝트가 빌드되기를 15분만 기다려도, 컴파일러는 이제 작은 불편함이 아니라 그 작업 스레드의 지배적인 비용이 됩니다.
이 문제는 여러 코딩 에이전트를 병렬로 쓰기 시작하면 견딜 수 없게 됩니다.
한 번에 하나의 일만 하고 있다면, 콜드 빌드 비용을 한 번 치르고 계속 갈 수도 있습니다. 하지만 점점 저는 그렇게 일하고 싶지 않습니다. 여러 worktree를 띄우고, 서로 다른 작업 흐름을 분기시키고, 에이전트들에게 여러 시도를 맡기고, 결과를 검토한 뒤 쓸 만한 것만 남기고 싶습니다. 그런 세계에서는 콜드 스타트 시간이 매우 중요합니다. 새 worktree마다 긴 Haskell 빌드가 필요하거나, 캐시를 세심하게 설정해야 하거나, 메모리를 엄청 소모한다면, 새로운 작업 스레드마다 세금이 붙는 셈입니다. 다섯 명의 에이전트가 다섯 개의 브랜치를 병렬로 탐색하길 원한다면, 그 세금은 배가됩니다.
Haskell 쪽에서는 캐싱, Nix, 원격 빌더, 그리고 비슷한 도구들에 대한 이야기를 많이 합니다. 그런 도구들은 도움이 됩니다. 우리도 사용했습니다. 하지만 캐시는 결코 완벽하지 않으며, 그것이 충분히 괜찮게 느껴지도록 만드는 데 필요한 노력 자체가 문제의 일부입니다. 실제로 병렬 AI 보조 개발은 값싸고 일회용으로 버릴 수 있는 실행 컨텍스트를 원합니다. 저는 이렇게 말할 수 있길 원합니다. 이걸 분기해 봐, 변경을 시도해 봐, 테스트를 돌려 봐, 무슨 일이 있었는지 보여 줘. 우리의 Haskell 환경은 그런 작업 방식에 비해 충분히 저렴하지 않았습니다.
모든 것이 캐시되어 있고 작은 변경만 한다면, 종종 아주 빠른 컴파일을 얻을 수 있습니다. 때로는 루프가 20초이고, 그건 아주 훌륭하게 느껴집니다. 하지만 그것은 최선의 경우이며, 시스템 전체를 최선의 경우만 기준으로 최적화할 수는 없습니다. 변경이 빌드 계획의 핵심 부분 깊숙이 들어갈수록, 그 이야기는 덜 성립합니다. 에이전트가 많이 개입하는 워크플로에서는 콜드 스타트 경우, 평균적인 경우, 그리고 더 깊은 변경이 있는 경우를 훨씬 더 신경 쓰게 됩니다. 완벽한 캐시 상황이 안정적으로 일어나도록 만드는 데 필요한 엔지니어링 노력 자체가 세금의 일부입니다.
그 점은 점점 더 고통스러워졌습니다.
Scarf에서는 모든 신규 API 작업을 Python으로 시작했습니다. 우리는 Haskell 서버 옆에 Python API 서버를 배포하고, 요청을 알맞은 곳으로 라우팅한 뒤, 기능을 건드릴 때마다 점진적으로 옮기기 시작했습니다. 새 API 라우트는 Python에 들어가고, 기존 Haskell 코드는 계속 돌아가며, 시간이 지나면서 새 서버가 주 경로가 되고 Haskell의 비중은 줄어들게 됩니다.
이 접근 방식 덕분에 극적인 일괄 전환의 위험 없이 이동할 수 있었습니다. 동시에 인증, 데이터베이스 접근, 공유 모델, 배포 이미지, 테스트, 운영용 접착 코드 같은 핵심 요소 일부를 다시 구현해야 했습니다. 과거라면 이런 종류의 준비 작업은 비싸게 느껴졌을 것입니다. 하지만 LLM이 있는 지금은 그렇지 않았습니다. 기존 코드를 새 언어로 포팅하는 일은 오늘날의 모델에게 꽤나 직관적입니다.
개발 주기에서 되찾은 시간, 즉 기다리거나 도구 체인과 씨름하느라 쓰던 시간은 이제 더 많은 기능을 더 포괄적인 테스트와 함께 출시하는 데 재배치되었습니다. AI는 많은 테스트를 작성하는 데 능합니다. 물론 여전히 지켜봐야 합니다. 말도 안 되는 코드와 가짜 테스트를 정말로 써낼 수 있기 때문입니다. 하지만 루프가 충분히 빠르기 때문에, 이 절충은 몇 년 전의 제가 예상했던 것보다 훨씬 잘 작동합니다.
그 결과를 하나의 지표로 잡아내기는 어렵습니다. PR 처리량이 눈에 띄게 늘어난 것은 아니었습니다. 커밋량은 잡음이 많습니다. 코드 줄 수는 나쁜 대리 지표입니다. 배포 횟수 역시 프리뷰, 인프라, 기타 잡음을 포함하므로 흐릿합니다. 하지만 생산성 변화는 이제 우리가 높은 노력 수준으로, 최소한의 감독으로, 심지어 완전히 자동으로까지 무엇을 출시할 수 있는지의 형태에서 분명히 드러납니다. 고객과의 통화 -> 티켓 등록 -> PR 생성 -> PR 검토 및 반복 -> 병합 -> 배포까지, 때로는 제가 고객과의 통화를 끊기도 전에 버그 수정이 실제 서비스에 반영되기도 합니다. 이런 종류의 생산성 향상을 거부하는 것은 이제 선택지가 아닙니다.
지금까지 전환으로 인해 크게 잃은 것은 없습니다. 우리가 포기한 타입 안전성은 아직 어떤 구체적인 방식으로도 두드러지게 문제 되지 않았고, 특히 테스트 커버리지가 어느 때보다 좋아졌다는 점을 고려하면 더욱 그렇습니다. 이제 버그가 실제로 빠져나가더라도, 저는 이전에는 경험해 보지 못한 속도로 핫픽스를 할 수 있습니다. 이제 수정은 말 그대로 Slack 메시지 한 통 거리에 있습니다. 우리 엔지니어링 팀은 생산성 향상과 손에 쥘 수 있는 완전히 새로운 기술 영역에 더 큰 활력을 느끼고 있습니다. 우리는 과거에 비해 개발자 도구 체인에 대해 생각하는 시간을 현저히 덜 쓰고 있습니다.
Haskell은 실제로 위험한 상황에 놓여 있습니다.
AI는 사라지지 않을 것입니다. 이를 잘 활용하는 사람들과 생태계는 그렇지 못한 사람들과 생태계보다 훨씬 더 빠르게 움직이게 될 것입니다. 이제 이것은 더 이상 미묘한 문제가 아니라고 생각합니다. 숙련된 AI 기반 엔지니어는 예전에는 몇 주, 몇 달 걸리던 일을 이제 며칠 만에 해낼 수 있습니다.
또한 제가 어떤 위치에서 이 말을 하는지도 분명히 하고 싶습니다. 저는 Haskell 세계 바깥에서 돌을 던지는 사람이 아닙니다. 저는 HF에서의 역할을 통해 언어 리더십에 직접 관여하고 있습니다. 어느 정도는 도울 수 있는 위치에 있고, 할 수 있는 곳에서는 계속 도울 것입니다. 동시에 제 여유 시간은 Scarf를 운영하는 현실 때문에 매우 제한되어 있습니다. 가만히 서 있기 싫어 애쓰고는 있지만, 이 역학을 제 힘만으로 일방적으로 바꿀 수 있는 능력에는 분명 한계가 있습니다.
Haskell 세계 안에도 경제성의 같은 변화를 보고, Haskell이 이에 적응하기 위해 더 빠르게 움직이길 바라는 사람들이 많이 있습니다. 하지만 전체적으로 보면 Haskell 도구 체인과 생태계의 진전은 제가 생각하는 필요 수준에 미치지 못하고 있습니다.
그런데도 Haskell 공간에서 AI 이야기가 나오면, 대화는 종종 활성화보다 제한에 더 초점이 맞춰져 있는 듯합니다. 사람들이 우려를 갖는 이유는 이해합니다. 규범은 있어야 합니다. 공개도 있어야 합니다. 코드가 AI 보조로 작성되었는지, 어떤 모델이 관여했는지, 어떻게 검토되었는지를 말하도록 요구하는 것은 합리적입니다.
하지만 "LLM을 사용하지 말자", 심지어 "LLM이 포함된 워크플로를 지원하고 싶지 않다"는 진영의 강한 집단이 존재하며, 저는 그것이 역사의 잘못된 편에 서는 일이라고 믿습니다. 제 예측으로는 그것이 언어의 생태계에 좋지 않은 결과를 가져올 것입니다.
AI를 활용하는 Haskell 생태계라면 다른 질문을 던질 것입니다. Haskell을 에이전트가 더 잘 사용할 수 있도록 하려면 어떻게 해야 하는가? 고품질 Haskell 예제를 모델 학습 데이터에 더 많이 넣으려면 어떻게 해야 하는가? 리뷰를 어떻게 확장할 수 있는가? 라이브러리 문서를 단지 아름다운 타입만이 아니라, 복사해서 붙여넣을 수 있는 현실적인 예제로 가득 채우려면 어떻게 해야 하는가? 프로젝트 초기 부트스트랩을 어떻게 빠르게 할 수 있는가? 오류 메시지를 에이전트 친화적으로 만들려면 어떻게 해야 하는가? 콜드 빌드 시간을 어떻게 줄일 수 있는가? 도움을 주려는 모델에게 흔한 산업용 패턴을 어떻게 더 분명하게 보여 줄 수 있는가?
Haskell은 AI를 활용하는 엔지니어와 에이전트에게 의미 있는 언어가 되기에 오히려 매우 유리한 위치에 있어야 합니다. 컴파일러가 에이전트가 빠르게 수렴하도록 돕는다면, 타입 안전성은 LLM이 생성한 코드에 큰 장점이 될 수 있습니다. 하지만 그것은 인간이 손으로 코드를 작성하는 상황에 맞춰 언어를 최적화하는 것과는 다릅니다. 에이전트는 다른 병목을 가집니다. 이들은 코드를 생성하는 데는 싸고, 막혔을 때는 비쌉니다. 이들은 빠른 피드백, 명확한 예제, 낮은 설정 마찰, 그리고 코드를 빠르게 고치도록 도와주는 오류의 혜택을 받습니다.
Haskell이 AI 시대에 훌륭해지고 싶다면, 그 세계를 의도적으로 기준 삼아 최적화해야 합니다.
저는 Haskell이 성장하길 바랍니다. 중요해지길 바랍니다. Haskell이 잘하는 것들, 즉 정확성, 유지보수성, 조합적 설계, 원칙 있는 추상화가 다음 소프트웨어 시대의 일부가 되길 바랍니다.
하지만 이런 것들은 우선순위가 되어야 합니다. 제가 볼 수 있는 범위에서, 그리고 Scarf가 오픈 소스 생태계 추세를 들여다보며 얻는 자체 관점까지 포함해 보면, Haskell의 성장은 다른 곳에서 일어나는 일과 비교할 때 잘해 봐야 미미해 보입니다. 지금 당장 그 밑바탕이 되는 모든 수치를 공유할 수는 없지만, 방향성만 놓고 보면 이야기는 어렵지 않습니다. 많은 개발자 생태계가 AI 시대에 가속하고 있는데, Haskell은 그중 하나처럼 느껴지지 않습니다.
이 정체의 기회비용은 어느 때보다도 커졌습니다.
해답은 우리가 실제로 들어가고 있는 세계에 맞게 Haskell을 가장 좋은 버전의 자신으로 만드는 것입니다. 그것은 AI를 생태계의 일급 사용자로 진지하게 받아들이는 것을 뜻합니다. 타입 시스템 연구보다 빌드 시간, 온보딩, 문서화, 예제, 도구, 에이전트 워크플로, 마케팅을 더 중요하게 여긴다는 뜻입니다. 공동체의 노력을 재배치하고, 심지어 현재의 일부 작업 영역을 포기하는 것까지 뜻합니다. Haskell Foundation이 더 많은 기술 작업에 자금을 대고 조율할 수 있을 만큼 충분한 돈을 모을 방법을 찾는다는 뜻이기도 합니다.
의존 타입 같은 새로운 언어 기능이 흥미롭고 나름의 사용 사례가 있다는 점은 저도 압니다. 하지만 산업 현장의 Haskell 사용자들은 수년간 컴파일 시간과 생태계 마찰에 대해 불평해 왔습니다. AI 시대에 이것들은 단순한 불편을 훨씬 넘어, 언어 생태계와의 근본적인 불일치로 커졌습니다.
Scarf에서 우리는 그 벽에 부딪혔습니다. 우리는 여전히 Haskell을 존중합니다. 여전히 프로덕션에서 Haskell을 운영합니다. 하지만 신규 제품 개발에 대해서는, 소프트웨어를 출하하는 방식과 속도를 바꿔 놓은 최신 AI 도구와 함께 더 빠르게 움직일 수 있게 해 주는 Python 쪽으로 옮겨 갔습니다.
상황이 달랐으면 좋았겠지만, 우리의 조건에서는 이런 이동이 분명하고 논리적인 앞으로의 길이었습니다. Haskell 공동체가 이 순간을 그에 걸맞은 시급함으로 받아들이길 바랍니다.