たくさん寝太郎の寝床

料理とITと皿回しが好きなオタクのブログ

Lispの話(変数・関数定義)

こんばんは、たくさん寝太郎です。

最近Lispの勉強を再開しました。
このブログで本で学んだ内容をアウトプットする練習をしようと思います。

プログラミング初心者なので間違いや冗長なコードになることも多いと思いますが、指摘等あればコメントお願いします。

 

ちなみに読んでいる本はLand of Lisp,使用しているコンパイラCLISPです。

Land of Lisp

Land of Lisp

global変数の定義
(defparameter *foo* 1)

defparameterは元の値の上書きが可能です。

(defvar *foo* 2)

対して、defvarは上書き出来ません。

local変数の定義
(let ((a 1)
      (b 2))
  (+ a b))
3

第一引数で変数定義、第二引数に本体を書きます。
letの返り値は最後の式の評価値です。

global関数の定義
(defun 関数名(arguments) 処理)

上のように記述します。

例としてHello,world!を出力する関数を定義すると以下のようになります。

(defun hello_world() (format t "Hello,world!"))

(hello_world)を実行すると以下のようになります。

Hello,world!
NIL

REPLではコードを走らせる度に入力した式の値が表示されます。
formatは第一引数がtのときnilを返すので、上のようにformatによる文字列の出力の次にnilが表示されます。(ちょっと分かりにくい)

例えばprognは引数を左から評価していき最後に評価した引数の返り値を返すので、実行結果は以下のようになります。

(progn (print (* 1 2)) (print (+ 1 2)))
2
3
3

1行目は(* 1 2)の実行結果、2行目は(+ 1 2)の実行結果で3行目はprognの返り値です。

local関数の定義
(flet ((関数名 (arguments)
                      処理))
        本体)

例としてlocal関数f(x)とg(x)を定義して合成関数g(f(x))を考えてみます。

(flet ((f (x)
            (+ x 1))
        (g (x)
            (* x 2)))
        (g (f 2)))

 f(x)=x+1, g(x)=2x, g(f(x))=2x+2
実行すると6を出力します。

再帰的な定義をしたいときはlabelsを用います。

(labels ((f (n)
	   (if (= n 1) 1 (* n (f (1- n))))))
  (f 3))

 f(n)=n!
実行すると6を出力します。


今日はここまでです。次回はリストの話をしようと思います。