1P by GN⁺ | ★ favorite | 댓글 1개
  • 한 개발자가 프로덕션에서 Haskell 8년OCaml 8개월을 사용한 경험을 바탕으로, 두 함수형 언어의 실제 개발 감각을 비교함
  • Haskell은 더 간결한 문법과 강력한 타입 기능을 제공하지만, 선택지가 많아 설계와 추상화에 신경을 빼앗기기 쉬움
  • OCaml은 기능 수는 적어도 일급 모듈과 실용적인 가변성, 예측 가능한 코드 스타일 덕분에 구현에 집중하기 쉽다고 평가됨
  • 생태계는 Haskell이 더 크지만 라이브러리 선택이 별도 기술처럼 느껴질 수 있고, OCaml은 작아도 필요한 도구가 생각보다 잘 작동함
  • 두 언어 모두 주류 언어보다 작고 표준 라이브러리는 최소 구성에 가깝지만, 특정 SDK 의존이 크지 않다면 산업용 앱 개발에 충분히 쓸 수 있음

비교의 출발점

  • 기준은 프로덕션에서 Haskell을 8년, OCaml을 8개월 사용한 경험임
  • 비교 축은 문법, 언어 기능, 생태계, 도구, 컴파일러 메시지, 표준 라이브러리임
  • 두 언어 모두 실제 산업적 요구를 지원할 만큼 발전했지만, 현재 선호는 OCaml 쪽에 가까움

문법: Haskell은 더 간결하고, OCaml도 ML 계열 장점이 있음

  • Haskell은 매우 적은 문자로 아이디어를 표현할 수 있어 문법적 우아함이 강하게 느껴짐
  • OCaml도 ML 계열 언어로 훌륭하지만, Haskell 쪽이 더 암묵적(tacit)인 스타일을 제공함
  • 문자열 안의 숫자 합산 예시에서 Haskell은 sum . map read . words로 짧게 표현하고, OCaml은 파이프라인으로 문자열 분리, 변환, 접기 과정을 명시함
  • 이진 트리 타입 정의는 두 언어 모두 대수적 데이터 타입을 자연스럽게 표현함
  • 파싱 예시는 두 언어 모두 패턴 매칭과 옵션 값을 사용하지만, Haskell은 do 표기법과 guard, OCaml은 Option.bind와 명시적 match를 사용함

기능: Haskell은 풍부하고, OCaml은 덜 산만함

  • Haskell은 기능 수가 매우 많아 C++ 정도가 비교 대상으로 느껴질 정도임
  • 많은 기능은 문제를 정교하게 풀 도구가 되지만, 실제 구현 전에 해법 설계 방식 자체를 고민하게 만들 수 있음
  • Haskell에서는 TypeFamilies, DataKinds, GADTs 같은 선택지를 놓고 설계에 빠지기 쉬움
  • 기존 OCaml 프로젝트의 나쁜 상황은 보통 변수명 부족, 문서 부족, 200줄 이상 함수 정도라 감당 가능한 수준으로 봄
  • 반대로 기존 Haskell 프로젝트는 8년 경험으로도 대비하기 어려운 복잡성을 만날 수 있음
  • 이런 차이 때문에 OCaml에서 더 생산적이라고 느낌
  • 두 언어가 공유하는 기능

    • 표현식 중심 문법, 기본 불변성, 고차 함수, 익명 함수, 대수적 데이터 타입, 패턴 매칭을 모두 제공함
    • 매개변수 다형성, 타입 추론, 모나드 문법 설탕, 가비지 컬렉터, 멀티스레딩, GADTs도 공통으로 사용할 수 있음
  • Haskell 쪽에 더 두드러진 기능

    • Haskell은 기본 순수성, 조합 가능한 지연 평가, 타입 클래스, 고차 kind 타입, 선택형 언어 확장을 제공함
    • 강력한 기능을 많이 갖춘 만큼 프로젝트마다 추상화 방식이 크게 달라질 수 있음
  • OCaml 쪽에 더 두드러진 기능

    • OCaml은 일급 모듈(first-class modules), 다형 변형(polymorphic variants), 객체, 클래스와 상속, 사용하기 쉬운 가변성을 제공함
    • 기능의 폭은 Haskell보다 좁지만, 코드베이스를 예측하기 쉽다는 장점으로 이어짐

생태계: Haskell은 더 크고, OCaml은 필요한 해법이 있음

  • 두 언어 모두 틈새 함수형 프로그래밍 언어라 최신 프레임워크의 일급 지원을 기대하기는 어려움
  • 그래도 일반적인 작업 대부분에는 해법이 있으며, 경우에 따라 커스텀 바인딩을 더 작성해야 함
  • OCaml에서도 다음처럼 실무에 필요한 패키지를 찾을 수 있음
  • Haskell 생태계는 패키지와 바로 쓸 수 있는 해법이 더 많음
  • Stripe API 클라이언트 라이브러리는 Haskell이 13개, OCaml은 1개이며 OCaml 쪽은 마지막 변경이 8년 전이라 사실상 0개에 가깝다고 봄
  • Haskell에서는 해법을 찾은 뒤에도 너무 많은 선택지 중 어떤 라이브러리를 고를지 판단해야 함
  • 라이브러리 선택이 별도의 기술처럼 다뤄질 정도라 라이브러리 평가 방법을 정리한 글도 있음
  • 새 Haskell 라이브러리는 다른 문제를 풀기보다 다른 추상화나 새 기능으로 다르게 작성하고 싶어서 생기는 경우가 많음
  • GitHub API 클라이언트를 만들고 JSON을 많이 파싱하는 일보다, comonads로 logger를 설계하는 일이 더 흥미로울 수 있음

도구: Haskell은 강력하지만 기복이 크고, OCaml은 잘 작동함

  • Haskell 도구는 강력한 장점과 사용성 문제가 공존함
  • Hoogle은 타입 시그니처만으로 전체 생태계를 검색할 수 있는 강력한 도구임
  • 반면 빌드 도구 오류 메시지, 작동 중인 프로젝트에서 빌드 플랜을 찾지 못하는 상황, 패키지 변경 후 IDE 재컴파일, 특정 버전 표준 라이브러리 문서 부재 같은 문제가 있음
  • Haskell 도구 사용 경험은 다른 언어가 이런 도구 없이 어떻게 쓰이는지 놀라는 순간과, Haskell 사용자가 필수 사용성 없이 어떻게 지내는지 놀라는 순간이 함께 있음
  • OCaml은 생태계가 더 작아서 동작하는 것을 발견할 때마다 놀라움이 있음
  • LSP 기반 VSCode OCaml 플러그인은 별도 조정 없이 작동했고 문제가 없었음
  • OCaml 도구 진입 경험이 최고로 편하지는 않아도, 직관적이고 견고하며 대부분의 경우 제대로 작동함
  • 도구 비교

컴파일러 메시지: Haskell은 장황하고, OCaml은 간결함

  • 함수형 언어에서 컴파일러는 코드가 의도한 가정을 왜 만족하지 못하는지 이해하는 핵심 도구임
  • 따라서 오류 메시지는 필요한 정보를 접근하기 쉬운 방식으로 보여줘야 함
  • Haskell 컴파일러 메시지는 맥락 정보가 많고 장황하며, 중복되거나 산만한 정보가 포함되는 경향이 있음
  • OCaml 컴파일러 메시지는 상당히 간결하고, 때로는 너무 간결함
  • 예시 오류 프로그램은 Haskell의 x = 1 + [3, 1, 2]와 OCaml의 let x = 1 + [3; 1; 2]처럼 정수와 리스트를 더하려는 코드임

표준 라이브러리: 둘 다 최소 구성이고, 문서 품질은 Haskell이 돋보임

  • 표준 라이브러리는 언어의 첫 프로그램과 이후 사용 경험을 형성함
  • 좋은 표준 라이브러리는 프로그래밍 언어 성공의 기반이고, 부족한 표준 라이브러리는 대체 표준 라이브러리 논쟁을 계속 만들 수 있음
  • 바람직한 표준 라이브러리는 batteries-included 방식에 가까워야 한다고 봄
  • 원하는 구성에는 Option 유사 타입, UTF-8 문자열, Map과 HashMap, JSON과 XML 파서, 비동기 프리미티브 등이 포함됨
  • 빌드 도구와 의존성 추적 구현을 배우지 않으려면 표준 라이브러리에 더 많은 기능이 필요함
  • Build Systems a la Carte는 의존성 추적기와 빌드 도구 영역을 분석한 자료임
  • Haskell과 OCaml 모두 표준 라이브러리는 비교적 최소 구성임
    • Haskell에는 Map과 HashMap이 포함되지 않음
    • OCaml에는 non-empty lists와 Bitraversable이 없음
  • Haskell 표준 라이브러리는 base이고, OCaml은 OCaml standard library를 사용함
  • Haskell 문서 품질은 숙련 개발자도 놀랄 정도로 좋은 경우가 있음
  • Haskell 문서에는 소스 코드로 이동하는 기능 같은 장점도 있으며, OCaml에도 그런 기능이 준비 중이라는 말을 들었다고 함
  • 문서 예시

    • Haskell List 문서 예시
    • OCaml List 문서 예시
    • 결과가 명백한 함수라도 예제 중심 문서는 API를 어떻게 활용할지 즉시 감을 줌

결론: 둘 다 산업용으로 쓸 수 있지만 현재 선호는 OCaml

  • 두 언어 모두 실제 산업적 요구를 지원할 만큼 많이 발전함
  • 주류 언어와 비교하면 여전히 작은 언어에 속함
  • 특정 SDK 존재에 치명적으로 의존하지 않는다면, 두 언어 중 어느 쪽을 골라도 다음 앱을 즐겁게 개발할 수 있음
  • 현재는 OCaml이 실제로 무언가를 만드는 일에 더 집중하기 쉽다고 평가됨

댓글과 토론

Hacker News 의견들
  • 몇 번 접해보며 가장 거슬렸던 건 글에서 빠진 도구 체계의 복잡함과 유동성
    특정한 좁은 범위의 GHC 버전에서만 컴파일되는 코드를 자주 만났고, 너무 오래되거나 너무 새 버전이면 그냥 안 됨
    Haskell 문법이 가장 우아하다는 평가에도 동의하지 않음. ML 계열 문법 전반을 별로 좋아하지 않고, 그중에서도 Haskell이 가장 취향에 안 맞았음
    “가능한 적은 글자로 생각을 표현하는 즐거움”에도 동의하지 않음. 그게 좋았다면 APL 계열이나 Factor를 썼을 것 같음

    • 동의함. 함수형 언어 경험은 많지 않지만 OCaml 예제는 비교적 쉽게 흐름을 잡을 수 있는 반면, Haskell 예제는 Forth 비슷하게 느껴짐
      필요하면 머리로 파싱할 수는 있겠지만, 그런 난해한 한 줄짜리 코드는 유용한 프로그램이라기보다 퍼즐처럼 보임
    • Haskell을 몇 년 썼지만 들여쓰기 규칙은 끝내 이해하지 못했음
      Haskell 쪽 사람들은 그게 헷갈릴 수 있다는 사실 자체를 의아해하는 것 같았음
      그리고 do 표기법도 있음. 세 사람이 “람다에서 단순히 기계적으로 변환되는 것”이라고 했지만, 막상 어떻게냐고 물으면 설명하지 못했음
    • 오히려 Haskell 문법을 정말 좋아함. 보기에는 단연 가장 마음에 드는 언어임
    • ML 문법은 보통 가장 깔끔한 문법으로 여겨지는데 싫어한다니 흥미로움. 보통 어떤 문법 계열을 좋아하는지 궁금함
      그리고 Haskell은 사실 ML 문법이라고 보기도 애매함. ML 계열은 좋아하지만 Haskell 문법은 꽤 못생겼다고 느낌
    • Haskell 문법의 문제는 ML 계열이라는 점보다는, 커링 때문에 복잡한 타입 별칭이 끔찍해질 수 있다는 데 있음
      함수 시그니처로 만든 타입 별칭이 있고, 그 안에 또 함수 시그니처 별칭이 들어가며, 이런 식으로 20층쯤 쌓인 탑을 상상해보면 됨
      이 쓰레기 탑의 서로 다른 층에 있는 타입을 동시에 다루면 금방 결합성 지옥에 빠지고, 작업해야 하는 타입 시그니처는 전혀 도움이 안 됨
      커링이라는 개념 자체의 결함과 Haskell 타입 시스템의 복잡성이 함께 만든 결과임
  • 대략 6개월마다 불나방처럼 Haskell에 끌림. 끌리는 이유는 익숙해지면 개념을 아주 간결하게 표현할 수 있기 때문이고, 예시의 포인트프리 스타일도 그런 매력이 있음
    모나드는 이해하고 다룰 수 있음. 하지만 Monad Transformer와 여러 패키지 선택지까지 가면 흥분이 두통으로 바뀜
    기본 자료구조에 containers 패키지가 필요하다는 점도 아쉬움. Python처럼 배터리 포함이 아니고, 이 때문에 사소하지 않은 프로그램에도 stack이나 cabal 같은 패키지 관리자를 써야 해서 한 줄짜리 ghci 명령보다 덜 편함
    그래도 Haskell을 배운 건 다른 언어로 프로그램을 생각하고 구성하는 방식에 매우 긍정적인 영향을 줬음. “함수형 코어, 명령형 껍데기” 같은 식임
    Haskell로 어느 정도 진지한 프로그램을 만들 일은 없을 것 같지만, 요즘은 명령줄에서 jq를 쓰며 매일 함수형 감각을 채우고 있음

    • 10년도 더 전에 회사 환경에서 Microsoft를 쓰던 시절, F# 을 발견하고 좋아하게 됐음
      매우 간결하고 알고리즘을 자연스럽게 표현할 수 있었으며, 계층형 클라이언트-서버 WCF 기반 VS.NET 솔루션군에서는 얻기 어려운 “함수형 코어, 명령형 껍데기” 기능을 줬기 때문임. 여기에는 Juval Lowy의 뛰어난 IDesign 접근법도 크게 기여했음
      아쉽게도 F#은 VS.NET 공간에서 완전히 2등 시민이라, 촘촘한 C# 클래스를 F#으로 먼저 만든 뒤 C#으로 옮기는 용도로만 유용했음. 기본 DB 접근 클래스도 F#으로 개발한 뒤 C#으로 번역했고, 핵심은 설계 시점에 교체 가능한 DB2/SqlServer 접근을 담당하는 동형 클래스 쌍이었음
      이제는 운영체제로 Microsoft를 쓰지 않겠다는 이유도 있지만, F#도 Don Syme가 만든 최소한의 OCaml 기반 v2에서 자동 마법이 많아진 v3+ 쪽으로 이동한 듯해서 별로 끌리지 않음
      결국 우리가 의존하는 도구 설계자들이 계속 스스로를 뛰어넘으려 할 때, 단순하면서도 효과적인 상태를 유지하기는 어려움. 개발자의 요구가 커지며 설계 도구도 확장되는 자연스러운 분기처럼 보임. 좋은 점은 도구가 우리의 필요나 욕구를 넘어서 진화하거나 아예 맞지 않더라도, 관점 자체는 한 단계 올라간다는 것임
    • 배터리는 포함되어 있음. containers는 모든 GHC 배포판에 함께 제공되고, 노출시키기 위해 stack이나 cabal을 쓸 필요도 없음
      % ghci
      GHCi, version 9.4.8: https://www.haskell.org/ghc/ :? for help
      ghci> import Data.Map
      ghci> singleton 5 "Hello"
      fromList [(5,"Hello")]
      직접 같은 방식으로 해보고, 안 되면 알려주면 문제 해결을 도와볼 수 있음
    • Python에서도 아주 기본적인 도구를 쓰려면 패키지 관리자를 쓰거나, 맞지 않는 의존성 조합의 해결책을 찾아야 하는 느낌임
      이 문제가 나한테만 있는 건지 궁금함
  • 조직에서 Haskell을 계속 쓰기 좋게 유지하려면, 사용하는 언어 확장을 보수적으로 제한하는 것이 꽤 중요함
    TypeFamiliesDataKinds를 쓰느냐고 하면 쓰긴 하지만, 아주 드묾
    https://www.simplehaskell.org/는 꽤 합리적인 가이드라인임. 다만 우리는 그보다 더 보수적인 접근을 택함

    • Perl과 비슷해 보임. 어떤 일을 하는 방법이 20가지쯤 있고, 그중 15가지는 더 이상 권장되지 않거나 커뮤니티에서 피하라고 하는 식임
    • 요즘은 GHC2024 같은 언어 에디션이 있어서 안정적인 언어 확장 여러 개를 묶어 줌
      유지보수 관점에서는 켜도 확실히 안전함
      문서 링크: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/cont...
    • 덜 화려한 기능이나 언어 확장으로 문제를 푸는 방법을 권장하는 사람들이 있어서 좋음
      특히 상업적 맥락에서는 Haskell 코더가 모두 프로그래밍 언어/컴파일러 덕후는 아니라는 점을 생각해야 함
  • 비슷하게 1년 Haskell, 2년 OCaml로 전환해봤고, 내 경험과 꽤 맞음
    추가로는 컴파일러 속도는 OCaml의 명확한 승리임
    OCaml의 모듈 시스템은 더 명시적이라 항상 Map.find처럼 한정해서 씀. 반면 Haskell의 타입 클래스 시스템은 더 편해서 인스턴스를 타입으로 찾고 명시적 주석이 필요 없음. 예를 들어 fmap fmap fmap에서 두 번째 fmap은 Reader의 fmap이어야 함
    기존 OCaml 프로젝트에서 이전 개발자가 변수명을 나쁘게 짓고 문서를 거의 안 쓰고 200줄 넘는 함수를 만들어놨다면, 그래도 특별한 일은 아니고 감당할 수 있음. 다만 흔하지는 않아도 펑터가 많은 코드베이스는 머리를 아프게 함. 반대로 패키지 사이에서 타입 클래스 인스턴스를 통일하는 일도 재미없음
    OCaml은 부작용 있는 코드와 순수 코드를 섞기 쉬워서 라이브러리와 코드베이스에서도 그렇게 쓰게 됨. 그래서 더 빠를 수 있지만 더 많이 터질 수도 있음

    • OCaml의 문제는 런타임이 제공하는 것이 너무 적어서 애매한 위치에 있다는 점임
      선점형 스케줄링을 갖춘 경량 스레드, 트랜잭션 메모리 등을 원하는 대부분의 Haskell 사용 사례와 비교하기 어렵고, 기본적으로 두 언어의 런타임은 같은 일을 하도록 갖춰져 있지 않음
      그래서 OCaml은 대신 Odin, Zig, Rust 같은 더 얇은 런타임의 컴파일 언어들과 경쟁하게 됨
      동작을 직접 제어하는 측면에서는 OCaml이 Odin과 Zig에 꽤 크게 밀림. 성능을 잘 내려면 들여야 하는 노력도 마찬가지임. OCaml 팬들이 뭐라 해도 마법 가루가 아니며, 원하는 할당 패턴을 표현하는 데 OCaml에서는 여전히 간접성이 있음. Odin/Zig라면 그런 간접성이 없어서 그런 상황에는 OCaml이 덜 적합함
      OCaml의 마지막 장점은 언어 단순성인데, Odin과 비교할 만큼 작거나 단순하지는 않음. Zig도 최선을 다해 복잡해지려 해도 OCaml보다 더 단순하고 날씬한 언어임. 또 Zig는 comptime 키워드만으로 펑터를 표현할 수 있는 특이점이 있음. 매개변수화된 함수를 담은 구조체를 컴파일 시점에 반환하는 식이라, 그 점에서는 OCaml보다 거의 더 나은 OCaml처럼 보임
      위를 보면 어떤 작업이든 OCaml보다 분명히 더 나은 언어가 늘 있는 것 같음. 가장 중요한 축에서 더 나은 무언가가 있을 가능성이 높고, “OCaml다움” 자체가 축이 아닌 이상 이기기 어려움
      다만 BuckleScript로 OCaml을 작성해 JS로 컴파일하고, OCaml을 JS 대안처럼 쓰는 건 좋았음
  • Stripe API 쪽 OCaml SDK는 1개뿐이고, 마지막 변경이 8년 전이라 사실상 0에 가까움
    한동안 OCaml을 개인 프로젝트 중심으로 쓰고, 회사의 작은 유틸리티에도 조금 썼음. 그중 하나가 Datadog과 연동하는 일이었는데, 예상대로 OCaml SDK는 없었음
    결론적으로 경험은 좋았음. 제공된 명세를 보고 OCaml 도구로 구현하는 것도 빨랐고, 속도 제한 처리에 도달했을 때도 약 20분 만에 코드를 리팩터링했더니 마법처럼 변한 느낌이었음
    그래서 라이브러리 가용성을 절대적인 논거로 삼지는 않게 됨. 모든 외부 라이브러리는 부채이고, 언어가 편한 도구와 도우미를 제공한다면, 높은 수준의 잡다한 만능 라이브러리보다 사용에 충분한 추상화 수준의 자체 코드가 더 나을 수 있음
    외부 연동이 아주 많다면 그런 생태계를 갖춘 Go 같은 것을 쓰겠지만, API 구현자라면 OCaml을 더 선호함

    • 그게 Lisp의 저주 아닌가 싶음
      직접 만들어 쓰기가 너무 쉽다 보니 합의된 서드파티 라이브러리가 없고, 그런 라이브러리가 없으니 채택도 적어지는 구조임
  • Haskell 표준 라이브러리는 더 작은 부분들로 분리됐음. Map도 원래 표준 라이브러리의 일부였음
    현재도 Map을 포함한 containers 패키지는 GHC 컴파일러와 함께 미리 설치되므로 표준 라이브러리의 일부로 봐야 함
    GHC 3.02 문서를 보면 https://downloads.haskell.org/~ghc/3.02/docs/users_guide/use... FiniteMap 타입이 제공됐다는 점이 명확히 나옴

    • “분할 정복”에는 어느 정도 공감하지만, 내게는 libc, libm, libffi 정도가 아주 좋은 분리로 보임
      libgnuc는 장난치는 것 같고, libobjc는 놀림당하는 느낌이 들기 시작했으며, stdlib을 알게 됐을 때는 걱정을 멈추기로 했음
      예전에는 라이브러리 체인의 순환 의존성을 가장 빨리 해결하는 방법이 -Lthing을 여러 번 순서대로 추가하는 것이었음. 그러면 뒤의 라이브러리가 앞의 이름 목록과 그 오른쪽에 있는 의존성까지 로드됐다고 확신할 수 있었음
      함수형 프로그래밍에서 map/reduce처럼 근본적인 것을 가져다가 “부속 라이브러리에 둬도 된다”고 하는 건 분할 정복을 너무 멀리 밀어붙인 것처럼 느껴짐
  • 제목이 오해를 부름. 이 글은 실제로 어느 언어의 프로덕션 환경에 대한 글도 아닌 것 같음
    다른 사람들이 말했듯 프로덕션에 대한 글이라면 빌드를 깨뜨린 도구/의존성 업데이트가 있었는지, 라이브러리나 런타임 때문에 실제 운영에서 눈에 띄는 버그를 겪었는지, 런타임이 높은 부하를 얼마나 효율적으로 처리하는지, 예를 들어 GC는 어떤지 등을 다뤘어야 함
    이 글은 문법 차이에 더 가까움. 그마저도 두 언어가 팀과 장기 프로젝트에 얼마나 잘 맞는지 궁금함. 두 경우 모두 여러 사람이 코드베이스의 여러 부분을 작업하게 됨. 사람들이 직접 작성하지 않은 코드를 읽고 수정할 수 있는지, 예를 들어 버그 수정 때는 어떤지 궁금함
    새 하위 컴포넌트를 넣을 때 타입 시스템이 리팩터링으로 인한 오류를 얼마나 잘 막았는지도 알고 싶음. Haskell이 OCaml에서 실제로 발생한 여러 실용적 문제를 막아줬는지, 아니면 실제로는 겪은 버그 유형에서 차이가 없었는지도 흥미로울 것임
    이 블로그 글은 장기 사용에서만 나오는 깊은 경험과 함정보다는, 신규 사용자를 위한 리뷰에 나오는 기본 언어 기능 비교처럼 느껴짐

  • 전문가는 아니지만 몇 년 동안 돈을 받고 OCaml과 Haskell을 썼음
    장단점은 있지만 결론은 Haskell은 멋진 기능이 많지만 너무 복잡하다는 것임. OCaml에서는 같은 안전성 이점을 얻으면서 더 빠르게 반복할 수 있음
    초보자에게는 학습 곡선도 덜 가파르고, 모듈 시스템 덕분에 대규모 프로그래밍에도 더 적합하다고 봄
    OCaml이 지금보다 더 인기 없다는 게 꽤 아쉬움

    • OCaml은 Rust처럼 보이게 외관 개선이 필요하다고 봄
  • Haskell에는 다른 언어에서 찾지 못한 흐릿하지만 특별한 성질이 하나 있음. PL 공간에서 OCaml에 가까운 F#조차도 해당되지 않음
    Haskell은 내가 표현하고 싶은 것을 방해하지 않음. 많은 언어에서는 쓰고 싶은 코드의 아이디어가 있어도, 언어의 어떤 특이점 때문에 이상해 보이지 않게 다른 방식으로 표현해야 함. Haskell은 그런 식으로 서툴게 느껴지는 일이 거의 없음
    객관적으로 참은 아니라는 건 알고 있음. Haskell도 리소스 할당 동작 같은 이유로 의도와 다르게 코드를 써야 하는 경우가 많음. 그런데 이상하게 그런 제약은 덜 아프게 느껴짐. 왜 그런지는 모르겠음

    • 내게는 그 이유가 비엄격성
  • 일급 효과와 타입 시스템이 강제하는 순수성은 프로그래머로서의 삶을 훨씬 낫게 만들어줬음
    추론해야 하는 상태 공간의 크기를 극적으로 줄여주고, 모든 맥락이 함수 정의에 선언되므로 어떤 함수가 무엇을 하는지 파악하기가 아주 쉬워짐
    언어 확장에 대한 지적에는 동의하고, 연산자가 잔뜩 들어간 포인트프리 코드에도 꽤 많이 욕해봤음
    그래도 누군가 더 나은 것을 만들기 전까지는, 어쩌면 그게 Lean 4일 수도 있지만, Haskell이 여전히 어떤 프로덕션 준비 언어보다 더 큰 즐거움을 줌