categoryLISP覚書

任意個の仮引数:&rest指定

trackback0  comment0
プログラミング覚書 017

任意個の仮引数:&rest指定
----------------------------------------------------------------------

(defun func2 (&rest x-lst)
x-lst) ;FUNC2
(func2 1 2 3 4 5) ;(1 2 3 4 5)

----------------------------------------------------------------------
  実引数をリストで受け取る
categoryLISP覚書

&optional指定

trackback0  comment0
LISPに戻ります。
プログラミング覚書 016

省略可能な引数:&optional指定
----------------------------------------------------------------------

(defun func1 (&optional (x 1) y)
(list x y))
;使用例
(func1 10 33) ;(10 33)
(func1) ;(1 NIL)

----------------------------------------------------------------------
  仮引数 x,y は省略可能
  省略時の x,y のデフォルト値はそれぞれ、1,nil
categoryLISP覚書

スタック

trackback0  comment0
プログラミング覚書 015

スタック
----------------------------------------------------------------------

(setf '(a (d f) g)) ;(A (D F) G)
(pop x) ;A
x ;((D F) G)
(push 'a x) ;(A (D F) G)

----------------------------------------------------------------------
categoryLISP覚書

ソート sort

trackback0  comment0
プログラミング覚書 014

ソート sort
----------------------------------------------------------------------

(sort '(3 1 5 7) #'<) ;(1 3 5 7)

----------------------------------------------------------------------
categoryLISP覚書

リストの要素の変更

trackback0  comment0
プログラミング覚書 013

リストの要素の変更
----------------------------------------------------------------------

(setf x '(1 2 3 4 r)) ;(1 2 3 4 r)
(setf (car x) 'ee) ;EE
x ;(EE 2 3 4 R)

----------------------------------------------------------------------
  setfは第2引数で指定した値で、第1引数から計算したメモリの場所を更新する
   第1引数に(car x)のようなS表現を指定できる
   このような参照を「一般化されたメモリ参照」と呼ぶ
categoryLISP覚書

cons:リスト生成用関数(コンス

trackback0  comment0
プログラミング覚書 012

cons:リスト生成用関数(コンス)
----------------------------------------------------------------------

(cons 'a '(a b c)) ;(A A B C)

----------------------------------------------------------------------
 第1引数の値を第2引数で指定したリストの先頭要素にしたリストを返す
  第2引数はリストでなければならない。
  第1引数はアトムでもリストでもよい
categoryLISP覚書

マクロの例

trackback0  comment0
プログラミング覚書 011

マクロの例:引数をnilに設定するマクロ
----------------------------------------------------------------------

(defmacro nil! (x))
(list 'setf x nil))

----------------------------------------------------------------------
 引数を1つとる新しいオペレータ、nil!が定義される
 (nil! a)という形で呼び出すと、
コンパイルないし評価の前に(setf a nil)と変換される
----------------------------------------------------------------------

;使用例
(nil! x) ;NIL
x ;NIL

----------------------------------------------------------------------
(nil! x)とタイプするのは、マクロを展開した形の
(setf x nil)とタイプするのと全く等価である
categoryLISP覚書

バッククォート

trackback0  comment0
プログラミング覚書 010

バッククォート
  : ,(コンマ)および ,@(コンマ・アットマーク)を使って、評価を部分的に実行できる
----------------------------------------------------------------------

(setf a 1 b 2)
`(a is ,a and b is ,b) ;(A IS 1 AND B IS 2)

----------------------------------------------------------------------
  バッククォートとコンマを一緒に使うことでリストのテンプレートが作れる
categoryLISP覚書

マッピング関数

trackback0  comment0
プログラミング覚書 009

マッピング関数
  :リストの要素に対して連続的に関数を適用するための関数
----------------------------------------------------------------------

(mapcar #'(lambda (x) (+ x 10))
'(1 2 3)) ;(11 12 13)

(mapcar #'list
'(a b c)
'(1 2 3 4)) ;((A 1) (B 2) (C 3))

(maplist #'(lambda (x) x)
'(a b c)) ;((A B C) (B C) (C))

----------------------------------------------------------------------
mapcar 引数:関数と1つ以上のリスト
    関数をリスト中の要素に対して順次適用した結果を返す
      (いずれかのリストが空になれば終了する)
maplist  関数はリストのcdr部(末尾部;テイル)を順次とりながら適用される
categoryLISP覚書

反復 do

trackback0  comment0
プログラミング覚書 008

反復
----------------------------------------------------------------------

(defun show-squares (start end)
(do ((i start (+ i 1)))
((> i end) 'done)
(format t "~A ~A~%" i (* i i))))
;使用例
(show-squares 2 5)
;2 4
;3 9
;4 16
;5 25
;DONE

----------------------------------------------------------------------
doマクロ   
  第1引数 反復オペレーター (変数 初期値 更新方法)
  第2引数 
    第1式 反復を終了するテスト
    最終式 doマクロの値
  第3引数以降 順番に評価されるループの本体
         反復毎に変数が更新される
categoryLISP覚書

入出力

trackback0  comment1
プログラミング覚書 007

入出力
----------------------------------------------------------------------

(defun askem (string)
(format t "~A" string)
(read))

(askem "How old are you? ") ;How old are you? 53
;53

----------------------------------------------------------------------
format:出力関数   read:入力関数
categoryLISP覚書

繰り返し loop

trackback0  comment0
プログラミング覚書 006

繰り返し
(loop 式1 式2 .... 式n)
----------------------------------------------------------------------

(setq x 1)
(setq sum 0)
(loop (and (> x 100) (return sum))
(setq sum (+ sum x))
(setq x (1+ x))) ;5050

----------------------------------------------------------------------
loopはreturnで値を返してループを抜ける。
categoryLISP覚書

繰り返し while

trackback0  comment1
プログラミング覚書 005

繰り返し
(while 条件式 式 .... 式)
----------------------------------------------------------------------

(setq x 1)
(setq sum 0)
(while (<= x 100) (setq sum (+ sum x))
(setq x (1+ x))) ;NIL
x ;101
sum ;5050

----------------------------------------------------------------------
条件式が真である間、式を順に繰り返す。
categoryLISP覚書

if文

trackback0  comment0
プログラミング覚書 004

if文
----------------------------------------------------------------------

(setq a 6)
(if (< a 5) (+ a 4) (- a 4)) ; 2

----------------------------------------------------------------------
categoryLISP覚書

lambda関数

trackback0  comment1
プログラミング覚書 003

lambda関数
----------------------------------------------------------------------

(mapcar #'(lambda (x) (* x x)) '(1 2 3 4 5))
     ;(1 4 9 16 25)

----------------------------------------------------------------------
名前を付けない(付ける必要のない関数)
categoryLISP覚書

letの使い方(局所変数)

trackback0  comment1
プログラミング覚書 002

letの使い方(局所変数)
----------------------------------------------------------------------

(defun 4jou (x)
(let ((y (* x x)))
(* y y)))
使用例
(4jou 3)

----------------------------------------------------------------------
yに(* x x)を格納する(関数内でのみ有効)。
categoryLISP覚書

LISPの再帰関数の例

trackback0  comment0
プログラミング覚書 001
LISPの再帰関数の例
----------------------------------------------------------------------

;x の n 乗
(defun beki (x n)
(cond ((zerop n) 1)
(t (* x (beki x (1- n))))))
使用例
(beki 2 3)

----------------------------------------------------------------------

読み下し

関数bekiを(x n)を引数にして定義する
  場合分け
    nが0ならば(0になれば)、1を関数値として返す
    それ以外(nが0でなければ)、
      nから1を減じてbekiを再帰的に呼び出し、
      戻り値にxを掛けたものを関数値として返す
      
nは再帰の呼び出し毎に1減ぜられ、n回の呼び出しで0となり、
再帰の戻り毎に(n回)、xが掛けられることになる。

ループを使った別解を以下に示す。(読み下しは省略)

----------------------------------------------------------------------

;別解
(defun beki1 (x n)
(prog (ans)
(setq ans 1)
loop
(cond ((zerop n) (return ans)))
(setq ans (* ans x))
(setq n (1- n))
(go loop)))

----------------------------------------------------------------------
New «‡Top‡» Old