概要
- Lisp は歴史あるプログラミング言語で、独自の特徴を持つ
- Racketは Lisp系言語 の現代的進化形で教育や研究に活用
- コードとデータが同じ構造( ホモアイコニシティ)
- 関数型・再帰・高階関数・マクロなど 強力な抽象化
- DrRacketを使い 実際に手を動かして学ぶ体験 ができる
Lisp入門:歴史と特徴
- Lisp は1958年、MITの John McCarthy によって発明
- 現存する高級言語で Fortran に次いで2番目に古い
- ガーベジコレクション、 第一級関数、 REPL、 条件式の値返却 など多くの現代的概念を最初に導入
- コード=データ( ホモアイコニシティ)という思想
- 1970~80年代はAI研究の中心言語、 Lispマシン も登場
- AI冬の到来で主流から外れるも、強い影響力を持ち続ける
LispからScheme、Racketへ
-
1975年、 Gerald Sussman と Guy Steele が Scheme を開発
- ミニマルで数学的な美しさ
- 教育分野で広く採用(代表的な書籍: SICP)
-
1995年、 PLT Scheme (現 Racket)誕生
- 教育と言語研究向けに設計
- 2010年に Racket へ改名
- Language-oriented programming :独自言語を簡単に作成可能
年表 • 1958: Lisp誕生 • 1975: Scheme誕生 • 1984: Common Lisp標準化 • 1995: PLT Scheme誕生 • 2007: Clojure誕生 • 2010: Racketへ改名
現在のLisp活用例
- Clojure :銀行や航空、スタートアップで本番運用
- Common Lisp :専門システムや科学計算分野
- Emacs Lisp :多くのユーザーが日常的に利用(エディタEmacs)
- Guile/Guix :SchemeベースのLinuxディストリビューション
- Racket :年次カンファレンス、研究・教育・芸術分野で活用
- 新しいLisp系 :Fennel(Lua向け)、Janet、Hy(Python上)など
Racketのインストールと基本操作
- https://racket-lang.org からインストーラーをダウンロード
- DrRacket (統合開発環境)を起動
- 上部:プログラム定義エリア
- 下部: REPL (対話型実行環境)
- 最初の1行に
#lang racketを記述 - ターミナル派は
racketコマンドでREPL起動、racoでパッケージ管理 - 基本式例
> (+ 1 2) ; => 3 > (* 3 (+ 2 2)) ; => 12 > (string-append "hello " "world") ; => "hello world" - すべての構文は
(演算子 引数1 引数2 ...)の形
定義・関数・コメント
- 定数定義:
(define pi-approx 3.14159) - 関数定義:
(define (circle-area r) (* pi-approx r r)) - コメントは
;から行末まで - 無名関数:
(lambda (x) (* x x)) - 直接適用例:
((lambda (x) (* x x)) 5) ; => 25
リスト処理:Lispの心臓部
- リスト生成:
(list 1 2 3)、'(1 2 3)(クォートで評価抑制) - 先頭要素取得:
(first '(1 2 3)) ; => 1 - 残り取得:
(rest '(1 2 3)) ; => '(2 3) - 追加:
(cons 0 '(1 2 3)) ; => '(0 1 2 3) - 長さ:
(length '(a b c)) ; => 3 - クォート
'は「評価せずデータとして扱う」印
高階関数による抽象化
- 関数を引数に取る例
- 変換:
(map (lambda (x) (* x x)) '(1 2 3 4 5)) ; => '(1 4 9 16 25) - 選択:
(filter even? '(1 2 3 4 5 6)) ; => '(2 4 6) - 畳み込み:
(foldl + 0 '(1 2 3 4 5)) ; => 15
- 変換:
- ループ不要、3つで多くのリスト処理を網羅
再帰的思考
- 「N回繰り返す」より「基本ケースと再帰的進行」
- 階乗関数例
(define (factorial n) (if (= n 0) 1 (* n (factorial (- n 1))))) (factorial 5) ; => 120
グラフィック描画例
- Racketには 2htdp/image などのグラフィックライブラリが付属
- シェルピンスキーの三角形描画例
#lang racket (require 2htdp/image) (define (sierpinski level) (if (= level 0) (triangle 8 "solid" "purple") (let ([t (sierpinski (- level 1))]) (above t (beside t t))))) (sierpinski 6)
コードがデータ:ホモアイコニシティとマクロ
- クォート
'で「コードをデータ」に変換'( + 1 2 )はリストとして扱われる(eval '(+ 1 2)) ; => 3でデータをコードとして実行
- マクロ :実行前にコードを生成・拡張できる
- C言語のテキストマクロと異なり「構造化された式」を操作
- 例:while構文を自作
(define-syntax-rule (while condition body ...) (let loop () (when condition body ... (loop)))) (define counter 0) (while (< counter 5) (displayln counter) (set! counter (+ counter 1))) - 構文拡張 で言語自体を拡張可能
さらに学ぶために
- How to Design Programs :Racket設計思想の基礎書(無料公開)
- The Racket Guide :公式ドキュメント
- Beautiful Racket :独自言語構築の入門書
- SICP :Schemeによるプログラミングの古典的名著
Lisp/Racket は「抽象化」「拡張性」「思考法」において他の言語と一線を画す プログラム=データ構造 という発想が、柔軟な言語設計と創造性を支える