Common Lisp基礎文法最速マスター - lisp-cookbook-ja/common-lisp GitHub Wiki
かきかけ
なし
一応コンパイル時に文法のチェックがあり、使用の変数なども発見できる
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 (条件)
式)