Common Lisp基礎文法最速マスター


かきかけ

基礎

文法チェック

なし

一応コンパイル時に文法のチェックがあり、使用の変数なども発見できる

print式

print式です。

(print "Hello world")
;->
;   "Hello world"
;=> "Hello world"
(format t "Hello world~%")
;-> Hello world
;
;=> NIL

コメント

コメントです。

; コメント

#|

 #| ネストしても大丈夫 |#

|#

変数の宣言

大域変数

; スペシャル変数
(defparameter *foo* "foo")

(defvar *foo* "foo")

;; defvarと defparameterの違い

(progn
  ;; 変数を初期化
  (makunbound '*foo*)

  (defvar *foo* "foo")
  (defvar *foo* "bar")
  *foo*)
;=> "foo"

(progn
  ;; 変数を初期化
  (makunbound '*foo*)

  (defparameter *foo* "foo")
  (defparameter *foo* "bar")
  *foo*)
;=> "bar"

ローカル変数

(let ((foo 3))
  (let ((bar 4))
    (list foo bar)))
;=> (3 4)

スクリプトの実行

コンパイルチェック

(compile-file "foo.lisp")

デバッガの起動

数値

1
1.0d0
1.0e0

四則演算

 四則演算です。

(+ 1 1)
;=> 2

(- 1 1)
;=> 0

(* 1 2)
;=> 2

(/ 1 2)
;=> 1/2

(apply #'+ '(1 1 1 1 1 1 1))
;=> 7

余りと商の求め方です。

floorは商と余りを多値で返します

;; 商
(floor 3 2)
;=> 1
    1

(+ (floor 5 2) 1)
;=> 3

(floor (/ 1 2))
;=> 0
;   1/2

(rem 3 2)
;=> 1

インクリメントとデクリメント

インクリメントとデクリメントです。

;; インクリメント
(incf i)

;; デクリメント
(decf i)

文字列

文字列の表現

文字列はダブルクォートで囲みます。PerlやRubyのようにダブルクォートの中で変数展開することはできません。

"foo"
;=> "foo"

;バックスラッシュや、ダブルクォートを含める際には、バックスラッシュでエスケープされる必要があります。

"\f\o\o"
;=> "foo"

"\\f\\o\\o"
;=> "\\f\\o\\o"

"\"f\"o\"o"
;=> "\"f\"o\"o"

文字列操作

各種文字列操作です。

結合

(concatenate 'string "aaa" "bbb")
;=> "aaabbb"

(format nil "~@{~A~}" "aaa" "bbb")
;=> "aaabbb"

(format nil "~@{~A~^,~}" "aaa" "bbb" "ccc")
;=> "aaa,bbb,ccc"

分割

(ql:quickload :cl-ppcre)

(ppcre:split "," "aaa,bbb,ccc")
;=> ("aaa" "bbb" "ccc")

(labels ((foo (sep str acc)
           (let ((pos (position sep str)))
             (if (null pos)
                 (nreverse (cons str acc))
                 (foo sep
                      (subseq str (1+ pos))
                      (cons (subseq str 0 pos) acc))))))
  (foo #\, "aaa,bbb,ccc" () ))
;=> ("aaa" "bbb" "ccc")

長さ

(length "abcdef")
;=> 6

切り出し

(subseq "abcd" 0 2)
;=> "ab"

検索

文字列から文字を探す

(position #\c "abcd")
;=> 2

文字列から文字列を探す (見つかった場合はその位置、見つからなかった場合はNILが返る)

(search "cd" "abcd")
;=> 2

(search "ce" "abcd")
;=> NIL

(ppcre:scan "cd" "abcd")
;=> 2
;   4
;   #()
;   #()

(ppcre:scan "ce" "abcd")
;=> NIL

リスト

lisp系言語では、配列よりはリストがデータ構造の基本です。
リストは複数の値を格納することができます。変数に代入/束縛できます。

(list 1 2 3 4)
;=> (1 2 3 4)

(let ((foo (list 1 2 3 4)))
  foo)
;=> (1 2 3 4)

(let ((foo (list 1 2 3 4)))
  (setq foo (list 'a 'b 'c 'd)))
;=> (A B C D)

リストの要素の参照と代入

リストの要素を参照と代入です。

要素の参照

(let ((foo (list 1 2 3 4)))
  (elt foo 1))
;=> 2

要素の代入

(let ((foo (list 1 2 3 4)))
  (setf (elt foo 1)
        (* 100 (elt foo 1)))
  foo)
;=> (1 200 3 4)

リスト内の要素数

(length (list 1 2 3 4))
;=> 4

リストの操作

リストを操作する関数です。 先頭の要素を取り出す

(car (list 1 2 3 4))
;=> 1

(first (list 1 2 3 4))
;=> 1

(elt (list 1 2 3 4) 1)
;=> 2

リスト構造は、先頭に要素を追加する方が末尾に要素を追加するより効率が良いので、先頭への追加、先頭からの削除、が基本操作になります

先頭に要素を追加

(cons  0 (list 1 2 3 4))
;=> (0 1 2 3 4)

先頭の要素を取り出す

(let ((foo (list 1 2 3 4)))
  (list (pop foo)
        foo))
;=> (1 (2 3 4))

先頭に要素を追加

(let ((foo (list 1 2 3 4)))
  (push 0 foo)
  foo)
;=> (0 1 2 3 4)

ハッシュの宣言と代入

ハッシュの宣言と代入です。ハッシュは複数の対になる値を代入することのできるデータ型です

(let ((hash (make-hash-table)))
  (setf (gethash 'a hash) 1)
  (setf (gethash 'b hash) 2))

要素数が少ない場合は、キーと値をリストにしたalistも良く利用されます

(let ((alist () ))
  (push '(a . 1) alist)
  (push '(b . 1) alist)
  alist)
;=> ((B . 1) (A . 1))

ハッシュの要素の参照と代入

ハッシュの要素の参照と代入です。

(let ((hash (make-hash-table)))
  (setf (gethash 'a hash) 1)
  (setf (gethash 'b hash) 2)

  (list (gethash 'a hash)
        (gethash 'b hash)))
;=> (1 2)

要素の代入

(let ((hash (make-hash-table)))
  (setf (gethash 'a hash) 1)
  (setf (gethash 'b hash) 2)

  ;; 書き換え
  (setf (gethash 'a hash) 10)
  (setf (gethash 'b hash) 20)

  (list (gethash 'a hash)
        (gethash 'b hash)))
;=> (10 20)
(let ((alist () ))
  (push '(a . 1) alist)
  (push '(b . 1) alist)
  alist)

要素の参照

(let ((alist '((a . 1) (b . 2))))
  (list (cdr (assoc 'a alist))
        (cdr (assoc 'b alist))))
;=> (1 2)

(let ((alist '((a . 1) (b . 2))))
  (setf (cdr (assoc 'a alist)) 10)
  (setf (cdr (assoc 'b alist)) 20)

  (list (cdr (assoc 'a alist))
        (cdr (assoc 'b alist))))
;=> (1 2)

制御文

if式

if式です。

(if (条件)
    式)