---------------------- 表1 ---------------------- C-j 直前の式を評価.結果はバッファに出力されます C-x C-e 直前の式を評価.結果はミニバッファに出力されます C-u C-x C-e 直前の式を評価.結果はバッファに出力されます(同一行) M-C-i シンボルの補完 ---------------------- リスト1 ---------------------- "foo" ;ctrl-jをタイプ "foo" ;評価結果が表示されます 42 ;ctrl-jをタイプ 42 ;評価結果が表示されます ---------------------- リスト2 ---------------------- (type-of 42) ;=> integer (type-of 3.14) ;=> float (type-of "foo") ;=> string (type-of '(1 2)) ;=> cons (type-of '[1 2]) ;=> vector (type-of 'foo) ;=> symbol (type-of ?a) ;=> integer (Javaの'a'相当.内部的には数値) (type-of ?\010) ;=> integer (8進数の数値) ---------------------- リスト3 ---------------------- integer symbol string cons float subr vector bool_vector char_table hash_table compiled_function marker overlay buffer process window frame window_configuration ---------------------- リスト4 ---------------------- ;; This code defines a ring data structure. A ring is a ;; (hd-index length . vector) (defun ring-p (x) "Returns t if X is a ring; nil otherwise." (and (consp x) (integerp (car x)) (consp (cdr x)) (integerp (car (cdr x))) (vectorp (cdr (cdr x))))) (defun make-ring (size) "Make a ring that can contain SIZE elements." (cons 0 (cons 0 (make-vector size nil)))) (defun ring-length (ring) "Returns the number of elements in the RING." (car (cdr ring))) ---------------------- リスト5 ---------------------- (setq foo "FOO") foo ;=>"FOO" (setq foo 42) foo ;=>42 ---------------------- リスト6 ---------------------- class Lisp_Symbol { String name; //シンボル名 Object value; //値セル Object function; //関数セル List plist; //属性リスト 略 public Lisp_Symbol(String name) { //疑似コンストラクタ this.name = name; } } ---------------------- 図1 ---------------------- obarray (ハッシュテーブル) +-- key:"foo" V +--+-+--------------- | |*| +--+-+--------------- | +--> value: +Lisp_Symbol+ |name:"foo" | |value:-----+---> String "FOO" |function:空+ +-----------+ ---------------------- リスト7 ---------------------- (setq foo "FOO") ;=> "FOO" foo ;=> "FOO" (type-of foo) ;=> string (fooの評価結果の型) (type-of 'foo) ;=> symbol (foo自身の評価結果の型) (setq bar foo) ;=> "FOO" bar ;=> "FOO" (barの値セルはfooの評価結果を参照) (setq bar 'foo) ;=> foo bar ;=> foo (barの値セルはシンボルfoo自身を参照) (type-of 'bar) ;=> symbol (type-of bar) ;=> symbol (barの評価結果の型) (setq foo 'bar) ;シンボルもオブジェクト (type-of (eval bar)) ;=> string (set 'foo "foo") ;setqを使わない書き方(1) (set (quote foo) "foo") ;setqを使わない書き方(2) ;backquoteの例 (setq bar `,foo) ;,のついたオブジェクトは評価.そうでないオブジェクトは未評価 bar ;=> "FOO" (setq bar `foo) bar ;=> foo ---------------------- リスト8 ---------------------- (symbolp 'foo) ;シンボルか否かの判定.tが真.nilが偽. (symbol-name 'foo) ;=> "foo" (symbol-value 'foo) ;=> "FOO" (boundp 'foo) ; 値セルに値があればt,なければnil (fboundp 'foo) ; 関数セルに関数があればt,なければnil (symbol-function 'foo) ;まだ設定していないので,今はエラー ---------------------- リスト9 ---------------------- (symbolp t) ;=> t (symbol-value t) ;=> t t ;=>t tを評価すると結果はt (symbolp nil) ;=> t (symbol-value nil) ;=> nil nil ;=>nil nilを評価すると結果はnil (type-of ()) ;=> symbol (type-of '()) ;=> symbol (eq nil ()) ;=>t 内部的にはnilと空リストは等価 ---------------------- リスト10 ---------------------- struct Lisp_Cons { Lisp_Object car; Lisp_Object cdr; }; ---------------------- リスト11 ---------------------- (type-of '("FOO" . "BAR")) ;=> cons (setq foo '("FOO" . "BAR")) foo ;=> ("FOO" . "BAR") (type-of foo) ;=> cons (setq foo (cons "FOO" "BAR")) ; 上のsetqと同じ意味 foo ;=> ("FOO" . "BAR") ; シンボルfooが参照するコンスセルの内部状態 struct Lisp_Cons { Lisp_Object car; => "FOO"文字列オブジェクトを指します Lisp_Object cdr; => "BAR"文字列オブジェクトを指します }; ---------------------- リスト12 ---------------------- (car '("FOO" . "BAR")) ;=> "FOO" (cdr '("FOO" . "BAR")) ;=> "BAR" (car foo) ;=> "FOO" (cdr foo) ;=> "BAR" (setcar foo "FOO2") foo ;=> ("FOO2" . "BAR") (setcdr foo "BAR2") foo ;=> ("FOO2" . "BAR2") ---------------------- リスト13 ---------------------- (cons "FOO" '("BAR" . "BAZ")) ;=> ("FOO" "BAR" . "BAZ") '("FOO" . ("BAR" . "BAZ")) ;=> ("FOO" "BAR" . "BAZ") (このふたつは表記の違いです) (cons "FOO" '("BAR" . nil)) ;=> ("FOO" "BAR") '("FOO" . ("BAR" . nil)) ;=> ("FOO" "BAR") ---------------------- 図2 ---------------------- +---+---+ +---+---+ +---+---+ |car+cdr|-->|car+cdr|-->|car+cdr|-->nil +---+---+ +---+---+ +---+---+ | | | +->"FOO" +->"BAR" +->"BAZ" ---------------------- リスト14 ---------------------- ; リストの生成例 '("FOO" . ("BAR" . ("BAZ" . nil))) ;=> ("FOO" "BAR" "BAZ") (setq lst (cons "FOO" (cons "BAR" (cons "BAZ" nil)))) lst ;=> ("FOO" "BAR" "BAZ") ; リストのcarとcdr (car '("FOO" "BAR" "BAZ")) ;=> "FOO" (cdr '("FOO" "BAR" "BAZ")) ;=> ("BAR" "BAZ") (cdr (cdr '("FOO" "BAR" "BAZ"))) ;=> ("BAZ") cdr (cdr (cdr '("FOO" "BAR" "BAZ")))) ;=> nil ---------------------- リスト15 ---------------------- (setq lst (cons "VALUE" lst)) ; リストlstに要素をprepend (list "FOO" "BAR" "BAZ") ; 引数を要素に持つリストを生成 ;=> ("FOO" "BAR" "BAZ") (append '("FOO" "BAR") '("BAZ")) ; 連接したリストを生成 ;=> ("FOO" "BAR" "BAZ") (car (nthcdr 1 '("FOO" "BAR" "BAZ"))) ; N番目の要素の取得(0ベース) => "BAR" (nth 1 '("FOO" "BAR" "BAZ")) ; N番目の要素の取得(0ベース) => "BAR" ; イテレーションの例 (リストの要素の合計値を求める例) (setq lst '(1 2 3 4 5 6 7 8 9 10)) (let ((sum 0) (alst lst)) (while alst (setq sum (+ sum (car alst))) (setq alst (cdr alst))) sum) (let ((sum 0)) (mapcar '(lambda (n) (setq sum (+ sum n))) lst) sum) (let ((sum 0)) (dolist (n lst) (setq sum (+ n sum))) sum) (defun get-sum (lst) (cond ((null lst) 0) (t (+ (car lst) (get-sum (cdr lst)))))) (get-sum lst) (apply '+ '(1 2 3 4 5 6 7 8 9 10)) ---------------------- リスト16 ---------------------- (defun my-plus1 (n) (+ n 1)) (my-plus1 10) ;=> 11 (defun my-plus (m n) (+ m n) (my-plus 2 5) ;=> 7 ---------------------- リスト17 ---------------------- (symbolp 'my-plus) ;=> t (symbol-function 'my-plus) ;=> (lambda (n m) (+ n m)) ; defunと同じことをfsetで書いた例 ; シンボルmy-funcの関数セルがlambdaシンボルで始まるリストを参照します (fset 'my-func '(lambda (n m) (+ n m))) (my-func 4 2) ;=> 6 (fboundp 'my-func) ;=> t (リスト8参照) ; car,defun,setqなども,関数セルが関数を参照するシンボルです (type-of 'car) ;=> symbol (symbol-function 'car) ;=> # (symbol-function 'setq) ;=> # ---------------------- リスト18 ---------------------- (defun functionp (object) "Non-nil if OBJECT is a type of object that can be called as a function." (or (subrp object) (byte-code-function-p object) (eq (car-safe object) 'lambda) (and (symbolp object) (fboundp object)))) ---------------------- リスト19 ---------------------- (my-plus 1 3) ; リストの先頭がシンボルであれば関数セルが参照する関数を呼び出します ;=> 4 ((lambda (m n) (+ m n)) 1 3) ;シンボルlambdaで始まるリストも「関数」です ;=> 4 ; funcall関数は引数の1番目を関数として呼びます. (funcall 'my-plus 1 3) ;=> 4 (funcall '(lambda (m n) (+ m n)) 1 3) ;=> 4 ; 値セルにlambdaを参照させて,関数呼び出しすることも可能です (setq foo '(lambda (m n) (+ m n))) (funcall foo 2 5) ;=> 7 ---------------------- リスト20 ---------------------- ; (let (ローカルシンボル定義...) 式...) ; ローカルシンボル定義は,シンボル単体,もしくは(シンボル 値)のリストのいずれかです (let (foo) t) ; ローカルシンボルfoo.値セルはnilに初期化 (let ((foo "FOO")) t) ; ローカルシンボルfoo.値セルは"FOO"に初期化 (let (foo (bar "BAR")) t) ;ローカルシンボルfooとbar (let ((foo "FOO") (bar "BAR")) t) ;ローカルシンボルfooとbar ; グローバルシンボルも,letを使うと一時的に値を変更できます. ; 例えば,以下のように書くと,実行部の中だけ,検索がcase sensitiveになります (let ((case-fold-search nil)) (実行部)) ---------------------- リスト21 ---------------------- ; dynamic scope (let ((foo "FOO")) (defun my-show-foo () foo)) (let ((foo "BAR")) (my-show-foo)) ;=> "BAR" ; lexical scope (require 'cl) ; CommonLisp package (lexical-let ((foo "FOO")) (defun my-show-foo () foo)) (let ((foo "BAR")) (my-show-foo)) ;=>"FOO" ---------------------- リスト22 ---------------------- ; (if 条件式 THEN式 ELSE式...) (if (= (length lst) 0) (message "zero size") (message "not zero size")) ; THEN式に複数の式を書きたい場合はprognを使います (if (/= (length lst) 0) (progn (message "/= means not equal") (message "not zero size")) (message "= means equal") (message "zero size")) ; (while 条件式 式...) (let ((n 0) (sum 0)) (while (< n 10) ; 0から9までの和 (setq sum (+ sum n)) (setq n (+ n 1))) sum) ; Javaのswitch-case相当 ; (cond (条件式 式...) (条件式 式...) (条件式 式...) ...) (let ((len (length lst))) (cond ((= len 0) (message "list size is zero")) ((= len 1) (message "list size is one")) ((= len 2) (message "list size is two")) (t (message "list size is over three")))) ; 条件式tはJavaのswitch-caseのdefault相当