なぜ Lisp なのか: プログラム可能なプログラミング言語の力
なぜ Lisp なのか: プログラム可能なプログラミング言語の力
Lisp はプログラマが問題に合わせて言語を成長させるパラダイムを可能にする
Lisp はほとんどの一般的なプログラミング言語とは根本的に異なり、開発者が解決しようとする問題に合わせて言語自体を適応させることができます。あらかじめ決められた構文の制約に問題を合わせるのではなく、Lisp はプログラマが新しい構造や抽象化を作り出し、実際のプログラムを書く前に言語を問題に向かって「成長」させるワークフローを提供します。
マクロによる言語拡張性
Lisp は「プログラム可能なプログラミング言語」としばしば呼ばれますが、これは言語内部で拡張できることに起因します。主に macro 演算子を通じて実現され、C、Rust、Swift などの言語にあるマクロとは大きく異なります。
マクロと関数の違い
関数は実行前に引数を評価しますが、Lisp のマクロは引数を純粋なデータとして扱います。これにより、マクロは言語の一部となる全く新しい構文構造を作り出すことができます。
例えば、Common Lisp には組み込みの while ループがありません。プログラマはマクロを使って次のように実装できます。
(defmacro while (condition &body body)
`(loop while ,condition do
(progn ,@body)))
マクロは condition や body をすぐに評価しないため、コードを loop 構造に変換し、コンパイラがそれを実行します。もしこれを関数として実装した場合、引数は即座に評価されてしまい、式そのものではなく式の結果が渡されるため、実行時エラーにつながります。
ホモアイコニシティ: コードはデータ
Lisp の力は ホモアイコニシティ(同形性)に由来します。これはコードもデータも同じ構造、すなわちリスト(シンボリック式または s‑expression)で表現される性質です。
- アトム: データの基本単位(数値、文字列、シンボル)。
- リスト: アトムや他のリストの集合。
Lisp ではリストは評価されるコードとしても、操作されるデータとしても扱えます。クオート演算子(')はインタプリタにリストをデータとして扱うよう指示します。この微妙な違いにより、Lisp プログラムは自分自身のソースコードを操作でき、「プログラムを書くプログラム」を作り出すことが可能になります。
REPL 主導の開発とライブシステム
Lisp は静的なファイルの集合をコンパイルして実行するのではなく、ライブシステムとして動作します。このワークフローの中心は Read‑Eval‑Print Loop(REPL) です。
進化的ワークフロー
従来の開発サイクルは「書く‑コンパイル‑実行‑デバッグ」です。Lisp ではプロセスが常に動作しており、開発者はコードを直接ライブプロセスに評価し、関数やマクロをその場で再定義します。これを REPL 主導の開発 と呼びます。
このアプローチは「ホットリローディング」をネイティブ機能として提供します。Lisp プロセスは数週間も稼働し続けられるため、プログラムは段階的に進化します。環境内で再定義されたシンボルはすぐに実行中のシステムに反映され、頻繁な再起動や複雑なインジェクションツールは不要です。
DSL で拡張可能なソフトウェアを作る
言語拡張性とライブ環境の組み合わせにより、 ドメイン固有言語(DSL) を簡単に作成できます。ドメイン固有の操作をカプセル化したマクロを書くことで、特定タスク向けのミニ言語を構築します。
DSL の実用例
- Web 開発: マクロでサーバ側 HTML を生成でき、開発者は Lisp のフルパワー(ループや変数)を使ってビューを書けます。別途 Jinja や Liquid といったテンプレート言語は不要です。
- 数式描画: DSL を作って曲線や点を定義し、複雑な描画ロジックをシンプルで表現力の高いインターフェースの背後に隠すことができます。
- 業界の事例: AutoCAD は AutoLISP を自動化に利用し、Emacs は独自の Lisp 方言で実装されているため、PDF リーダー、ウェブブラウザ、メールクライアントへと拡張可能です。
コミュニティの視点と批判
Lisp はそのエレガンスとパワーで称賛される一方、実用性や現代のエコシステムに関しては大きな批判も受けています。
Lisp に対する批判
- 可読性と構文: 括弧が多用されることや、一部の方言で従来の名前空間が欠如していることが、参入障壁や時代遅れの設計と見なされることがあります。
- DSL の保守性: 批評家は、商業環境で DSL がアンチパターンになる可能性を指摘します。十分に文書化されていないカスタム言語は、新しい保守担当者にとって理解が困難になることがあります。
- ツールとエコシステム: REPL は多くのモダン言語でも一般的ですが、Lisp の特有の利点は、モダンな並行性のサポートが不足していることや、実装が分散していることによって相殺されがちです。
プログラミングの「ダークサイド」
ある見方では、プログラミングは「光の側」(静的型付けや制約でミスを防ぐ)と「闇の側」(マクロや自己修正コードでプログラマに最大の自由度を与える)という緊張関係にあります。Lisp はプログラマに言語そのものへの絶対的な権限を委ねる、究極の「闇の側」言語と見なされています。
要約: Lisp はホモアイコニシティ、マクロ、REPL 主導の開発というユニークな機能を通じて、プログラマが問題領域に合わせて言語自体を進化させることを可能にします。