ast
Table of Contents
Lisp-1/2 の利点と欠点
前回の冒頭で、いきなりLisp-1 Lisp-2 なんてやっちゃったけど、それぞれに利点と 欠点が有るはず。それをチャッピーに聞いてみた。
A: 非常に良い質問です。 「/Lisp-1/」と「/Lisp-2/」の違いは、/関数と変数の名前空間(環境)を分けるかどうか/にあります。 以下で、両者の概要と利点・欠点を整理して説明します。
## 🧠 Lisp-1 と Lisp-2 の基本的な違い
| 特徴 | Lisp-1 | Lisp-2 |
| --------- | --------------------- | ------------------------ |
| 名前空間 | /関数と変数が同じ名前空間/を共有する | /関数と変数が別々の名前空間/を持つ |
| 代表例 | Scheme, Clojure | Common Lisp, Emacs Lisp |
| 関数呼び出しの扱い | 関数も変数の一種(関数値)として扱う | 関数は「関数セル」、変数は「値セル」に格納される |
## 🧩 Lisp-1(例:Scheme)
### 仕組み
関数も「値(オブジェクト)」として変数に代入できる。 したがって、関数呼び出しは単に「関数値を評価して適用」する操作に過ぎない。
(define f +) ; f に加算関数を代入 (f 1 2) ; => 3
f は「関数」という特別な名前空間ではなく、通常の変数として参照されます。
### ✅ 利点
- 言語モデルが単純
- すべての名前は同じ方法で束縛・参照される。
- 評価モデルが一貫しており、「関数」も「データ」も区別がない(関数も第一級オブジェクト)。
- 高階関数が自然
- 関数を変数に代入・渡すのが自然で、関数プログラミングに適している。
(map f lst)のような関数操作が自然に書ける。
- メタプログラミングが単純
- マクロやクロージャなどを扱う際も、名前解決の仕組みがシンプル。
### ❌ 欠点
- 名前の衝突が起きやすい
- 同じ名前を「関数」と「変数」で別々に使うことができない。
- 例:
(define car 10) ; 変数carを定義 (car '(1 2 3)) ; ← 関数carが使えなくなる
これはエラーになる。
- 関数定義の明示性が低い
- =define=で定義したものが「データ」か「関数」か文脈でしか分からない。
## ⚙️ Lisp-2(例:Common Lisp)
### 仕組み
関数と変数の名前は/別々に管理される/。 関数呼び出しでは「関数セル」を参照し、変数参照では「値セル」を参照する。
(setq f #'+) ; 値セルに関数オブジェクトを代入 (defun f (x y) (+ x y)) ; 関数セルに関数を代入 (f 1 2) ; => 関数セルの f が呼ばれる(3) (funcall f 3 4) ; => 値セルの f (#+) を呼び出す(7)
### ✅ 利点
- 名前の衝突が起きない
- 同じ名前を関数と変数で自由に使える。
- 関数定義と変数定義を分けて書けるので、安全で分かりやすい。
- 関数呼び出しが明示的
(funcall var ...)のように、関数オブジェクトを明示的に適用するため、挙動が明確。
- 最適化しやすい
- コンパイラは、通常の関数呼び出し(名前が関数セルに束縛されているもの)を静的に最適化しやすい。
### ❌ 欠点
- 評価モデルが複雑
- 「変数と関数で別々の名前空間がある」ことを常に意識しなければならない。
(f 1 2)と(funcall f 1 2)の違いは混乱を招きやすい。
- 関数を第一級オブジェクトとして扱うときに冗長
- 関数を変数に格納・渡すには
#'やfuncallが必要。
- 関数を変数に格納・渡すには
(mapcar #'f list) ; Common Lisp ;; 対応するSchemeでは (map f list)
## 🧮 まとめ比較
| 観点 | Lisp-1 | Lisp-2 |
| ----------- | ------ | -------- |
| モデルの単純さ | ◎ | △ |
| 名前衝突耐性 | △ | ◎ |
| 高階関数の扱いやすさ | ◎ | ○ |
| コンパイラ最適化 | ○ | ◎ |
| 書きやすさ | ◎(短い) | △(明示的) |
| 初心者への分かりやすさ | ○ | ○(意図が明確) |
## 🧭 総評
- /Lisp-1/(Schemeなど)は「シンプルで一貫性のある関数的世界」向き。 → 教育用・関数型指向・小規模な言語設計に向く。
- /Lisp-2/(Common Lispなど)は「安全で構造的な大規模開発」向き。 → 名前の衝突を避け、コンパイラ最適化を活かした現実的な実用志向。
ast
前回のshellの所で、こんな説明が出てきた。Lispなら、コードの作成の 面倒な部分、解析とか構文木の作成はユーザーの脳に頼っているからなあ。 正直、前の工程は良く知らん。
字句解析 → 構文解析 → 抽象構文木(AST)生成 → 実行(eval / execute)
そこで、予習しときましょ。ぐぐったらpython astってのがデフォで用意 されてたんで、久々にpythonします。
pythonはLisp-1 ?
なんとなく、そう思うんだけど、どうよ。 早速、Lisp-1的かLisp-2的か確認してみます。
>>> def mine(a, b): ... return a + b ... >>> print( mine(3,4) ) 7 >>> mine = "I am var" >>> print( mine ) I am var >>> print( mine(3,4) ) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object is not callable
一瞬、Lisp-2的かと思ったんだけど、違った。
>>> def mine(a,b): ... return a * b ... >>> mine <function mine at 0x73b28157fb00> >>> mine(5, 6) 30
これで明白になりましたね。この特性が有るからMITの授業ではschemeを捨てて pythonに鞍替えしたんだ(激違)。
python ast
抽象構文木 (AST: Abstract Syntax Tree) with Python
関数定義のASTを表示するスクリプト
sakae@lu:tmp$ cat test.py
import ast
src = """
def mine(a,b):
return a + b
"""
node = ast.parse( src )
print( ast.dump(node, indent=4) )
その実行結果
sakae@lu:tmp$ python3 test.py
Module(
body=[
FunctionDef(
name='mine',
args=arguments(
posonlyargs=[],
args=[
arg(arg='a'),
arg(arg='b')],
kwonlyargs=[],
kw_defaults=[],
defaults=[]),
body=[
Return(
value=BinOp(
left=Name(id='a', ctx=Load()),
op=Add(),
right=Name(id='b', ctx=Load())))],
decorator_list=[],
type_params=[])],
type_ignores=[])
関数の引数の形式にも色々有る事を雄弁に語ってくれていますね。その他の事は 専門家じゃないんで良く知らないそ。
そんじゃ、mine = "I am var" にして、評価してみる。
Module(
body=[
Assign(
targets=[
Name(id='mine', ctx=Store())],
value=Constant(value='I am var'))],
type_ignores=[])
何となくJava界隈が大好きなXMLを思い出しちゃったぞ。
ast — Abstract syntax trees 詳細はここ見れ。
rubyは、どうした?
Rubyソースコード完全解説 (RHG) ですよ。
コスモス
道端に自生してるコスモスの種を採取してるオバサンが居た。来年に撒くんですかって 聞いたら、遅い時期に撒くと言ってた。
遅く撒くと、背丈が野生のそれの半分ぐらいになるらしい。強い風でも倒れないので 楽しめるそうだ。そういう知恵は、趣味の園芸には出てこないのかねぇ。
実るほど 頭を垂れる 稲穂かな
背の高い稲は、台風とかで倒れ易い。そこで、背の低い稲穂へと改良が進んでいる そうだ。秋桜みたいに、単純にはいかない訳ね。
README
山口百恵 なんて本を読んだ。彼女が活躍した時代の歌謡曲のヒットチャートが ついていて、昭和時代にドップリでしたよ。おじさんだねぇ。
歌手と女優に大活躍。そして結婚と共に、きっぱりと芸能界から引退。 いさぎよい生き方は、あっぱれと思うぞ。
紅白歌合戦で、PlayBack Part II を歌う事になった。NHKからは、企業の製品名を 止めて、真赤な車にしてくれって指示が飛んだ。でも、百恵ちゃんは、歌手の矜持で 真紅なポルシェって歌った。筋が通ってるねぇ。そんな事、初めて聞くわ。
そして彼女のいなくなった席に座るのは、聖子ちゃんだったりする。一度だけラジオ番組で 近接遭遇したそうな。その他、ピンクレディーが 出てきたりキャンディーズの解散話が出てきたりで、なかなか充実した時間だったわい。