コンテンツにスキップ

Common Lisp

出典: フリー教科書『ウィキブックス(Wikibooks)』

Common Lisp ハンドブック

[編集]

Common Lisp は、多様なプログラミングスタイルをサポートする汎用プログラミング言語であり、主にAI研究や複雑なシステムの開発に用いられます。本ハンドブックでは、Common Lispの基本的な文法から応用的なトピックまでを体系的に解説します。

目次

[編集]
  1. Common Lisp概要
  2. 環境のセットアップ
  3. 基本文法
  4. データ構造
  5. 関数とマクロ
  6. オブジェクト指向プログラミング
  7. エラー処理とデバッグ
  8. 並列処理
  9. 外部ライブラリの利用
  10. 応用例

Common Lisp概要

[編集]

Common Lispは、1984年に標準化されたLispファミリーの一言語であり、高度な抽象化能力と動的な性質を持つ強力な言語です。以下の特徴を備えています。

  • マルチパラダイムのサポート(手続き型、関数型、オブジェクト指向)
  • 動的型付けと強力なREPL(Read-Eval-Print Loop)
  • マクロシステムによる言語拡張
  • 高い移植性と標準ライブラリ

環境のセットアップ

[編集]

Common Lispを使い始めるには、適切な実装とツールをインストールする必要があります。

推奨実装

[編集]

以下の実装が広く利用されています。

エディタと開発環境

[編集]

基本文法

[編集]

式と評価

[編集]

Common Lispでは、すべてのコードは式(S式)として記述されます。式はリストで構成され、関数呼び出しやデータ表現に使用されます。

;; 足し算の例
(+ 1 2 3) ;=> 6

;; ネストした式
(* (+ 2 3) 4) ;=> 20

変数定義

[編集]

変数はdefvarまたはsetqを使って定義します。

;; グローバル変数の定義
(defvar *x* 10)

;; 変数の再代入
(setq *x* 20)

データ構造

[編集]

Common Lispには、多様なデータ構造が用意されています。

リスト

[編集]

リストはLispの基本的なデータ構造です。

;; リストの作成
(setq my-list '(1 2 3 4))

;; 要素の追加
(push 0 my-list) ;=> (0 1 2 3 4)

;; 要素の削除
(pop my-list) ;=> 0

配列

[編集]

配列(ベクトル)は、固定長のデータ構造です。

;; 配列の作成
(setq my-array #(1 2 3 4))

;; 要素へのアクセス
(aref my-array 2) ;=> 3

;; 要素の更新
(setf (aref my-array 2) 42)

関数とマクロ

[編集]

関数定義

[編集]

defunを使って関数を定義します。

(defun add (a b)
  (+ a b))

;; 関数の呼び出し
(add 2 3) ;=> 5

マクロ定義

[編集]

マクロは、コードを生成するための仕組みです。

(defmacro when (condition &body body)
  `(if ,condition (progn ,@body)))

;; マクロの使用
(when t
  (print "Hello, world!"))

オブジェクト指向プログラミング

[編集]

Common Lispは、CLOS(Common Lisp Object System)を通じて強力なオブジェクト指向プログラミングをサポートします。

;; クラスの定義
(defclass person ()
  ((name :initarg :name :accessor person-name)
   (age :initarg :age :accessor person-age)))

;; オブジェクトの生成
(setq john (make-instance 'person :name "John" :age 30))

;; アクセサの使用
(person-name john) ;=> "John"
(setf (person-age john) 31)

エラー処理とデバッグ

[編集]

エラー処理にはhandler-caserestart-caseを使用します。

(handler-case
    (/ 1 0)
  (division-by-zero ()
    (print "Division by zero occurred.")))

並列処理

[編集]

並列処理は、実装に依存しますが、Bordeaux Threadsなどのライブラリを利用すると簡単に実現できます。

外部ライブラリの利用

[編集]

Quicklispを使って外部ライブラリを簡単にインストール・利用できます。

;; Quicklispのロード
(ql:quickload "alexandria")

;; ライブラリの利用
(alexandria:flatten '((1 2) (3 4))) ;=> (1 2 3 4)

応用例

[編集]

簡易Webサーバー

[編集]

以下は簡単なHTTPサーバーの例です。

(ql:quickload "hunchentoot")

(defparameter *my-server* (make-instance 'hunchentoot:easy-acceptor :port 8080))

(hunchentoot:start *my-server*)

(format t "Server running on http://localhost:8080")

GUIアプリケーション

[編集]

CLXMcCLIMを利用して、GUIアプリケーションを作成できます。

Common Lispと他のLISP方言との差異

[編集]

Common Lispは、SchemeやEmacs Lispなどの他のLISP方言と比較して、いくつかの重要な特徴を持っています。

1. 標準化と移植性

[編集]

Common LispはANSIによって標準化されています。これにより、異なる実装間でのコードの移植性が高いという利点があります。他の方言は、標準が明確でない場合が多く、互換性が課題となることがあります。

2. データ型の豊富さ

[編集]

Common Lispは、数値型、文字列、シーケンス、ハッシュテーブルなど、非常に多様なデータ型を備えています。これに対し、Schemeなどの方言では、データ型が最小限に抑えられている場合があります。

3. マクロシステム

[編集]

Common Lispのマクロシステムは強力で、コード変換を自由に行うことができます。他の方言、特にSchemeでは、マクロがより単純化された形式で提供されています。

4. オブジェクト指向プログラミング

[編集]

Common LispはCLOS (Common Lisp Object System) を備えており、強力なオブジェクト指向プログラミングの機能を提供します。他の方言では、オブジェクト指向機能が欠如しているか、限定的な実装に留まることがあります。

5. 実行環境の違い

[編集]

Emacs Lispは主にEmacsのカスタマイズや拡張のために設計されていますが、Common Lispはより汎用的で、スタンドアロンアプリケーションや高度なアルゴリズム開発に適しています。

関連リンク

[編集]