EmacsでLispのプログラミング学習しているおかげで、Emacsの操作も覚えてきているようです。
各ツールも、GUIのメニューからではなく、M-xで直接実行できるようになりました。
特にLispでお世話になっている、M-x ielm は、これが何をするツールなのかは、一生忘れない自信があります。でも、Mキーがどこのキーのことをいってるのかってことに関しては、忘れる自信しかありません。
今回は、seqコマンドのようなことを、Lispでもやってみます。
(いつも、新しく言語を覚えるときは、seqコマンドって必ず作るので)
コマンドラインでseqはこのように、1から指定した数値までの整数の数列を生成してくれますね。
takk@deb9:~/tmp$ seq 10 1 2 3 4 5 6 7 8 9 10 takk@deb9:~/tmp$
カウントダウン、つまり、10から下がっていく方は、すでにやりましたので、簡単ですね。
ELISP> (defun count (n) (if (> n 0) (progn (princ n) (count (- n 1))) )) count ELISP> ELISP> (count 10) 10987654321 nil ELISP>
これをリストにするだけなので、consを使ってリストにします。
ELISP> (defun count (n) (if (> n 0) (cons n (count (- n 1))) )) count ELISP> ELISP> (count 10) (10 9 8 7 6 5 4 3 2 1) ELISP>
しかし、リストが逆になってしまいます。
リストを逆順にする関数、reverseを使うとseqと同じ並びになります。
ELISP> (reverse (count 10)) (1 2 3 4 5 6 7 8 9 10) ELISP>
しかし、reverseを使ってseq関数を作るとなると、関数内にの、別の関数を作らないといけません。 つまり、2つ関数が必要となります。
LISP> (defun seq (n) (reverse (count-down n))) seq ELISP> (defun count-down (n) (if (> n 0) (cons n (count (- n 1))) )) count-down ELISP>
ELISP> (seq 10) (1 2 3 4 5 6 7 8 9 10) ELISP>
まだ、学び直して日が浅いので、Lispプログラミングにおいて、このように関数内に別関数を作ることが、
良いことなのか分かりません。(悪いことなら、別の方法があるはず)
なので、reverseを使わずに、正順の数列を作るため、
関数のパラメータを2つにして完成したことにしました。
ELISP> (defun seq (now max) (if (<= now max) (cons now (seq (+ now 1) max)) )) seq ELISP> ELISP> (seq 1 10) (1 2 3 4 5 6 7 8 9 10) ELISP>
コメント