4月29日、著者が「Why I Still Reach for Scheme and Lisp Instead of Haskell」と題した記事を公開した。この記事では、関数型プログラミング言語としてのHaskellとScheme/Lispの実用性について、実体験を交えた比較について詳しく紹介されている。以下に、その内容を紹介する。
Haskellの美しさとその代償
著者はまず、Haskellを決して否定するものではないと前置きしつつ、3年間にわたってHaskellを習得し、実際のプロジェクトで収益を上げた経験を持つエンジニアの視点から語っている。
Haskellが持つ革新的な機能として、以下の点を高く評価している:
- 最も洗練された複雑な型システム
- 数学的概念をプログラミングに導入する能力
- モナド、ファンクター、代数的データ型などの概念
しかし、その美しさと引き換えに生じる問題点として、「すばやくハッキングして有用なコードを書く」ことに対する抵抗を挙げている。特に関数型プログラミングやモナドに慣れていない開発者にとって、この障壁は大きいという。
プロトタイピングにおける実践的な問題
著者の実体験として、ブックマーク管理ツールのプロトタイプ開発エピソードが紹介されている。データモデルをXMLに変換してファイル出力するという、比較的単純な作業において:
Kotlin/Javaの場合:
- Gradleに依存関係を追加
- JacksonやDOM parserを設定
- 10分後にはデータが操作可能な状態
Haskellの場合:
- 数年の経験を持つ著者でも1時間以上格闘
- 依存関係の問題に続いてMonadic APIに苦戦
- 結果的に諦めてしまう
この例は、Haskellが「事前の大きな設計(big design upfront)」を強要する傾向を示している。
SchemeのREPLによる開発体験の違い
Lisp系言語の最大の武器として、REPL(Read-Eval-Print Loop)による開発体験が詳しく解説されている。
従来の開発サイクル:
編集 → 保存 → コンパイル → 実行
REPLによる開発:
対話的な即座のフィードバック
具体的なメリット:
- インクリメンタル開発: 1つの関数や1行ずつテスト・検証が可能
- 強力なデバッグ:
print文の追加や再起動なしに、実行中のオブジェクトを検査・値を変更・関数を再定義 - 高速プロトタイピング: 新しいライブラリやAPIの実験が瞬時に可能
著者は特にGNU GuileとEmacsの組み合わせを推奨しており、「従来のIDEを遥かに上回る開発体験」と表現している。
DSLの乱立問題
Haskellのもうひとつの問題として、Domain Specific Language(DSL)の乱立を指摘している。
Parsecの成功により、Hackageには数百のDSLが存在する:
- パース用DSL
- XML用DSL
- PDF生成用DSL
問題は、これらがそれぞれ独自の学習コストを要求することだ。XMLパース、JSON変換、PDF出力を組み合わせる場合:
- Java系: 3つのライブラリが一貫したオブジェクト指向的慣例に従う
- Haskell: 3つの異なるDSLの習得が必要(文法の一貫性なし)
Schemeのマクロシステムの威力
対照的に、Schemeはマクロシステムにより言語自体を拡張できる:
(define-syntax define-repo-method
(syntax-rules ()
((_ method-name accessor docstring)
(define* (method-name repo . args)
docstring
(apply (accessor repo) args)))))
Haskellで同等の機能を実現するには、Template Haskellなどの複雑な言語拡張が必要になる:
{-# LANGUAGE TemplateHaskell #-}
import Control.Monad
import Language.Haskell.TH
curryN :: Int -> Q Exp
curryN n = do
f <- newName "f"
xs <- replicateM n (newName "x")
let args = map VarP (f:xs)
ntup = TupE (map (Just . VarE) xs)
return $ LamE args (AppE (VarE f) ntup)
結論:適材適所の言語選択
著者は「Schemeが客観的にHaskellより優れている」と主張するのではなく、個人の開発スタイルとプロジェクト要件による適材適所を強調している。
Haskellは「プログラミング言語のプラトンのイデア」として、ある方向性を示す理想的存在だが、実際の開発においてはやや硬直的すぎると結論づけている。
一方でScheme/Lispは、企業レベルの大規模システムにおいては「バッテリー同梱」のエコシステムが不足している面もあるが、開発者体験と表現力のスイートスポットを提供するとしている。
詳細はWhy I Still Reach for Scheme and Lisp Instead of Haskellを参照していただきたい。