[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bep] learning lisp
- To: bep@argv.org
- Subject: Re: [bep] learning lisp
- From: TAKAHASHI Naoto <ntakahas@m17n.org>
- Date: Thu, 31 May 2001 10:49:29 +0900 (JST)
- Delivered-To: mailing list bep@argv.org
- Mailing-List: contact bep-help@argv.org; run by ezmlm
- User-Agent: SEMI/1.14.3 (Ushinoya) FLIM/1.14.2 (Yagi-Nishiguchi) APEL/10.2 Emacs/21.0.104 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI)
n高橋です。まとめてリプライします。
長くてややこしいので、後でゆっくりどうぞ。
Reiko TAKAHASHI (高橋玲子)writes:
> 「リスト」というのは何ですか?
Koichi INOUE writes:
> atomが()の中につながったもの・・・?
> '(setq x 10)
> は三つのatomからなるlist?
対応する括弧でくくられたものは全部リストです。中身は atom に限りません。
(a (b c) (d e (f g) h) i) もリストです。
(defun (x y) (+ (* x x) y)) もリストです。
() もリストです。空リスト(くうりすと)と言います。「からりすと」と読む
人もいます。英語だと empty list です。Emacs Lisp を含め一般の Lisp で
は () と nil は同じものです。
守岡さんのメールに出てきた cons の話もしたいのですが、混乱させてしまい
そうなので後に回します。
Reiko TAKAHASHI (高橋玲子)writes:
> } (progn (setq x 1)
> } (setq y 2)
> } (setq z 3))
> }
> } とすると、(setq x 1) と (setq y 2) はそれぞれ1と2という値を返しますが、
> } これらの値は誰に利用されることもなく消えて行きます。最後の (setq z 3)
> } が返す3という値は progn に引き継がれ、(progn ...) 全体の値となります。
> そして、xに1、yに2、zに3が束縛された、という結果(副作用)はしっかり残
> るんですね。
はい、しっかり残ります。
> # (progn ...)の意味は、例の『やさしいEmacs-Lisp講座』の本で拾い読み
> # しながら調べてみました。複数のS式を一つにまとめる関数(?)なんですね。
そのとおりです。progn はちょっと特別なので、厳密には「関数」ではなくて
"special form" と呼ばれていますけど。日本語で何と言うかは忘れました。
「スペシャル・フォーム」かな。(笑)
> べつに「評価結果」が使われなくても、プログラムとして、「副作用」が利用
> できたり、なにか他の役割(?)を果たしていればいいんだということ……ですよね
> ?
そのとおりです。前にも書きましたが、goto-char なんていうのはカーソルを
動かすという副作用を目的として使われることがほとんどで、返される値は大
抵捨てられてしまいます。
> 「変数」と「文字列」の違いは、どのように判断されますか?
> 1文字なのが変数で、2文字以上が文字列……でしょうか?
Koichi INOUE writes:
> 変数には数値、文字、文字列、'yなどの別のシンボルを入れることができます。
> 数値は1, 3.14など
> 文字は ?a ?bなどとあらわされます。
> 文字列は"a", "abc", "3.14", "GNU Emacs"などの「文字の列」
> 変数にはほかの値を束縛(bind)することができますが、数値や文字列は定数と言
> われるものでそれになにかをbindすることはできません。
もっと簡単に言うと、ダブルクオートでかこまれたのが文字列で、むき出しな
のが変数です。文字数は関数ありません。
Reiko TAKAHASHI (高橋玲子)writes:
> } setq はちょっと特別で、第1引数を評価しません。setq とほとんど同じこと
> } をする関数に set というのもあり、こっちは第1引数も評価します。評価結果
> } を→で書くことにすると、
> }
> } (setq x 'y) → y
> } (set x 10) → 10
> } x → y
> } y → 10
> }
> } となります。ちなみに 'y は (quote y) の略記法で、quote というのは与え
> } られた引数そのものを評価せずに返す関数です。もし一番上で (setq x y) と
> } すると、y を評した結果を x に束縛することになってしまいます。
> これ、とても難しかったのですが、以下のように考えてみました……。
> (setq x 'y) → y
> 変数xそのものに、yという変数と同じ意味を持たせる。
> なので、全体の評価結果はy(という変数)。
う〜ん、ちょっと違います。シンボルxの値としてシンボルyを束縛するという
ことです。結果として、シンボルxを評価するとシンボルyが得られることにな
ります。シンボルには数値や文字列だけでなく、シンボルを束縛することもで
きます。
もしxとyが同じ意味だとしたら、xを評価した結果も10にならなくてはいけま
せん。
Koichi INOUE writes:
> これの意味を理解するのが難しかったのですが、そういうことみたいですね。
井上さん自身が上の方で、「変数には…別のシンボルを入れることができます」
と書いているように、変数xにシンボルyを入れているわけです。
# ちなみに別のシンボルだけでなく、自分自身を入れることもできます。
# (setq x 'x)
# x → x
# x → x
# …
# きりがない。これはこれは使うことがあります。
Reiko TAKAHASHI (高橋玲子)writes:
> (set x 10) → 10
> xを評価した結果(y)に10を束縛する。
> 束縛された値が10なので、このS式全体の評価結果は10。
そのとおりです。
> x → y
> 1行目でxをyと見なして(?)いるので、xの評価結果はy。
見なすのではなくて、xを評価した結果が別のシンボルyになっているのです。
> y → 10
> 2行目で、yと見なされた(評価された)xに10を束縛しているので、yの評価結
> 果は10。
2行目というのは (set x 10) ですね。
関数 set は、第1引数を評価した結果として得られるシンボルに、
第2引数を評価して得られるS式を束縛します。
第1引数はxで、これを評価するとシンボルyになります。
また第2引数は10で、これを評価した結果は10そのものです。
ですからシンボルyに10を束縛することになります。
別の例ですが、たとえば
(setq x 5)
(set x 10)
は2行目でエラーになります。なぜなら第1引数xを評価した結果はシンボルで
はなくて数値だからです。数値に数値を束縛することはできません。
> なぜ、(let (a) (setq a 20))の最初のaが括弧でくくられているのでしょう?
> # (let ...)も例の本で調べてみたのですが、こちらは、拾い読みでは全然
> # わかりませんでした。括弧の中だけで有効なsetq関数みたいなもの、と
> # 考えていいでしょうか?
その考え方で大体合ってます。より詳しくは、井上さんの説明
Koichi INOUE writes:
> (let 一時的な束縛指定 やりたいこと
> という決まりになっていて、
> 一時的な束縛指定は
> (a) → aという変数をletの中だけで周りに影響を与えずに(ローカルに)宣言する。
> ((a 10) (b 20)) →letの中だけでaを10に、、bを20に束縛する。
> ((a (point))) →letの中だけでaを(point)の結果、つまり現在のカーソル位置
> に束縛する。
> みたいに使います。
のとおりです。
Reiko TAKAHASHI (高橋玲子)writes:
> } ここで問題です。2行目の a は let の内側だけで有効なのに、なぜ2行目全体
> } を評価した結果が 20 になるのでしょうか。
> ……2行目の中でいちばん右の関数に当たる
> (setq a 20)
> から返される値が20なので、(let ...)は、その値を、全体の評価結果としてその
> まま返しているのかな……と思ったのですが……???
すごい。それが正解です。
Mitsugu SAKAMOTO writes:
> これに便乗してなのですが、関数と変数って読んでいてどう区別しますか?
プログラムとして用いられているリストの中ならば、最初の要素が関数でそれ
以外が変数です。使われ方によって同一のシンボルが変数にも関数にもなりま
す。例を出しましょう。
(defun (x) (* x 2))
(setq x 3)
とすると、
x → 3
(x 1) → 2
(x 2) → 4
(x 3) → 6
(x x) → 6
となります。最後の (x x) はわかりますか?
最後に用語ですが、「束縛する」は英語で to bind です。当然ながら「束縛
された」は be bound です。「評価する」は to evaluate です。eval という
関数もあります。日本語の「威張る」に引っかけて
(ここで詳細読みをオン)
「エバる」
(詳細読みオフ)
ということもよくあります。以前話題になった某アニメとは関係ありません。
--
TAKAHASHI Naoto
ntakahas@...
http://www.m17n.org/ntakahas/