EmacsでLispの覚え直し(その6)

Emacsを覚えたいからLispも覚える。Lispを覚えたいからEmacsを覚える。
どちらが最初か分からなくなるときがあります。
GNU is NOT Unixみたいです。もしかしてEmacsを学ぶとGNUの精神がわかるのでは? なんて気がしてきました。

さて、今回もLispやります。

if関数は、必ずthen側とelse側がないとならないと思ってました。

ELISP> (if (> 5 3) (princ "A") (princ "B"))
A
"A"
ELISP> (if (> 5 8) (princ "A") (princ "B"))
B
"B"
ELISP> 

しかし、else側はなくても動くようです。

ELISP> (if (> 5 8) (princ "A"))
A
"A"
ELISP> (if (> 5 8) (princ "A"))
nil
ELISP> 

条件式はlistを使うと、
空でない場合に、真となり、

ELISP> (list 10 20)
(10 20)

ELISP> 

リストが空の場合に、偽となります。

ELISP> (list)
nil
ELISP> 

条件式にリストを使ってカウントダウンするプログラムを組んでみます。

ELISP> (defun count (n)
(if n
  (progn (princ (car n))
         (count (cdr n))) ))
count
ELISP> 

実行。

ELISP> (count (list 10 20 30))
102030
nil
ELISP> 

ん〜。elseがないと、最後にnilが出てしまいますね。
まだうまく使いこなせませんので、あきらめ。

次は、リストのsumを求めてみます。もともとsum関数があるか確認。
関数が存在するか、本来の調べ方は分からないので、使って確認します。

ELISP> (sum)
*** Eval error ***  Symbol's function definition is void: sum
ELISP> 

ないようですので、sumを自作します。

ELISP> (defun sum (n)
(if n
  (+ (car n) (sum (cdr n)))
  0
))
sum
ELISP>

今度はelseに意味のある0を書くことができました。
使ってみます。

ELISP> (sum (list 1 2 3 4 5 6 7 8 9 10))
55 (#o67, #x37, ?7)
ELISP> 

感動。