| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 
 | \section{列、行列とテーブル}
\markright{\arabic{section}. 列、行列とテーブル}
\subsection{一般列}
ベクトル(1次元行列)とリストは、一般の列である。
文字列(string)は、文字(character)のベクトルなので、列である。
{\bf map, concatenate}や{\bf coerce}における結果の型を明記するためには、
クラスオブジェクトがsymbolにバインドされていないので、引用符なしで
{\tt cons, string, integer-vector, float-vector}などのクラス名symbolを使う。
\begin{refdesc}
\funcdesc{elt}{sequence pos}{
{\bf elt}は、{\em sequence}の中の{\em pos}番目の位置の値を得たり、({\bf setf}と
ともに)置いたりする最も一般的な関数である。
{\em sequence}は、リストまたは任意のオブジェクト、{\tt bit, char, integer, float}の
ベクトルである。
{\bf elt}は、多次元の行列に適用できない。}
\funcdesc{length}{sequence}{
{\em sequence}の長さを返す。
ベクトルにおいて、{\bf length}は一定の時間で終了する。
しかし、リスト型においては、長さに比例した時間がかかる。
{\bf length}が、もし環状リストに適用されたとき、決して終了しない。
代わりに{\bf list-length}を使用すること。
もし、{\em sequence}がfill-pointerを持つ行列ならば、
{\bf length}は行列全体のサイズを返すのではなくfill-pointerを返す。
このような行列のサイズを知りたい場合には、{\bf array-total-size}を
使用すること。}
\funcdesc{subseq}{sequence start \&optional end}{
{\em sequence}の{\em start}番目から({\em end}$-$1)番目までをそっくりコピーした
列を作る。
{\em end}は、デフォルト値として{\em sequence}の長さをとる。}
\funcdesc{copy-seq}{sequence}{
{\em sequence}のコピーした列を作る。
このコピーでは、{\em sequence}のトップレベルの参照のみがコピーされる。
入れこリストのコピーには{\bf copy-tree}を使い、
再帰参照を持つような列のコピーには
{\bf copy-object}を使うこと。}
\funcdesc{reverse}{sequence}{
{\em sequence}の順番を逆にし、{\em sequence}と同じ型の新しい列を
返す。}
\funcdesc{nreverse}{sequence}{
{\bf nreverse}は、{\bf reverse}の破壊(destructive)バージョンである。
{\bf reverse}はメモリを確保するが、{\bf nreverse}はしない。}
\funcdesc{concatenate}{result-type \&rest sequences}{
全ての{\em sequence}を連結させる。
それぞれの{\em sequence}は、なにかの列型である。
{\bf append}と違って、最後の一つまで含めた全ての列がコピーされる。
{\em result-type}は、{\tt cons,string,vector,float-vector}などの
クラスである。}
\funcdesc{coerce}{sequence result-type}{
{\em sequence}の型を変更する。
例えば、{\tt (coerce '(a b c) vector) = \#(a b c)}や
{\tt (coerce "ABC" cons) = (a b c)}である。
{\em result-type}型の新しい列が作られ、
{\em sequence}のそれぞれの要素はその列にコピーされる。
{\em result-type}は、{\tt vector, integer-vector, float-vector, bit-vector, string, cons}
またはそれらの1つを継承したユーザー定義クラス
のうちの1つである。
{\bf coerce}は、{\em sequence}の型が{\em result-type}と同一である場合、コピーをする。}
\funcdesc{map}{result-type function seq \&rest more-seqs}{
{\em function}は、{\em seq}と{\em more-seqs}のそれぞれのN番目($N=0,1,\cdots$)の要素
からなるリストに
対して適用され、その結果は{\em result-type}の型の列に蓄積される。例えば、{\tt (map float-vector \#'(lambda (x) (* x x)) (float-vector 1 2 3))}のように書く。}
\funcdesc{fill}{sequence item \&key (start 0) (end (length sequence))}{
{\em sequence}の{\em start}番目から({\em end}$-$1)番目まで、{\em item}で満たす。}
\funcdesc{replace}{dest source \&key start1 end1 start2 end2}{
{\em dest}列の中の{\em start1}から{\em end1}までの要素が、
{\em source}列の中の{\em start2}から{\em end2}までの要素に置き換えられる。
{\em start1}と{\em start2}のデフォルト値はゼロで、
{\em end1}と{\em end2}のデフォルト値はそれぞれの列の長さである。
もし片方の列がもう一方よりも長いならば、
endは短い列の長さに一致するように縮められる。}
\funcdesc{sort}{sequence compare \&optional key}{
{\em sequence}は、Unixのquick-sortサブルーチンを使って破壊的に(destructively)
にソートされる。
{\em key}は、キーワードパラメータでなく、比較用のパラメータである。
同じ要素を持った列のソートをするときは十分気をつけること。
例えば、{\tt (sort '(1 1) \#'>)}は失敗する。なぜなら、1と1の比較は
どちらからでも失敗するからである。
この問題を避けるために、比較として{\tt \#'$>=$}か{\tt \#'$<=$}のような関数を用いる。}
\funcdesc{merge}{result-type seq1 seq2 pred \&key (key \#'identity)}{
2つの列{\em seq1}と{\em seq2}は、{\em result-type}型の1つの列に
合併され、それらの要素は{\em pred}に記述された比較を満足する。}
\funcdesc{merge-list}{list1 list2 pred key}{
2つのリストを合併させる。{\bf merge}と違って、一般列は引数として
許可されないが、{\bf merge-list}は{\bf merge}より実行が速い}
\end{refdesc}
次の関数は、1つの基本関数と-ifや-if-notを後に付けた変形関数から成る。
基本形は、少なくともitemとsequenceの引数を持つ。
sequenceの中のそれぞれの要素とitemを比較し、
何かの処理をする。
例えば、インデックスを探したり、
現れる回数を数えたり、itemを削除したりなど。
変形関数は、predicateとsequenceの引数を持つ。
sequenceのそれぞれの要素にpredicateを適用し、
もしpredicateがnon-NILを返したとき(-if version)、
またはNILを返したとき(-if-not version)に何かをする。
\begin{refdesc}
\funcdesc{position}{item seq \&key start end test test-not key (count 1)}{
{\em seq}の中から{\em item}と同一な要素を探し、
その要素の中で{\em :count}番目に現れた要素の
インデックスを返す。
その探索は、{\em :start}番目の要素から始め、それ以前の要素は無視する。
デフォルトの探索は、{\tt eql}で実行されるが、
{\em test}か{\em test-not}パラメータで変更できる。}
\fundesc{position-if}{predicate seq \&key start end key}
\fundesc{position-if-not}{predicate seq \&key start end key}
\funcdesc{find}{item seq \&key start end test test-not key (count 1)}{
{\em seq}の中の{\em start}番目の要素から
{\em :end}番目の要素までの間で要素を探し、
その探された要素の内、{\em :count}番目の要素を返す。
その要素は、{\em :test}か{\em :test-not}に{\tt \#'eql}
以外のものが記述されていないなら、{\em item}と同じものである。}
\funcdesc{find-if}{predicate seq \&key start end key (count 1)}{
{\em seq}の要素の中で{\em predicate}がnon-NILを返す要素の内、
{\em :count}番目の要素を返す。}
\fundesc{find-if-not}{predicate seq \&key start end key}
\funcdesc{count}{item seq \&key start end test test-not key}{
{\em seq}の中の{\em :start}番目から{\em :end}番目までの要素に{\em item}が
何回現れるか数える。}
\funcdesc{count-if}{predicate seq \&key start end key}{
{\em predicate}がnon-NILを返す{\em seq}内の要素数を数える。}
\fundesc{count-if-not}{predicate seq \&key start end key}
\funcdesc{remove}{item seq \&key start end test test-not key count}{
{\em seq}の中の{\em :start}番目から{\em :end}番目までの要素のなかで、
{\em item}と同一の要素を探し、{\em :count}
(デフォルト値は∞)番目までの要素を削除した新しい列を作る。
もし、{\em item}が一回のみ現れることが確定しているなら、
無意味な探索を避けるために、{\em :count=1}を指定すること。}
\fundesc{remove-if}{predicate seq \&key start end key count}
\fundesc{remove-if-not}{predicate seq \&key start end key count}
\funcdesc{remove-duplicates}{seq \&key start end key test test-not count}{
{\em seq}の中から複数存在するitemを探し、その中の1つだけを残した新しい列を作る。}
\funcdesc{delete}{item seq \&key start end test test-not key count}{
{\em delete}は、{\em seq}自体を修正し、新しい列を作らないことを除いては、
{\bf remove}同じである。
もし、{\em item}が一回のみ現れることが確定しているなら、
無意味な探索を避けるために、{\em :count=1}を指定すること。}
\fundesc{delete-if}{predicate seq \&key start end key count}
\funcdesc{delete-if-not}{predicate seq \&key start end key count}{
{\bf remove}や{\bf delete}の{\em :count}デフォルト値は、1,000,000である。
もし列が長く、削除したい要素が一回しか現れないときは、
{\em :count}を1と記述すべきである。}
\funcdesc{substitute}{newitem olditem seq \&key start end test test-not key count}{
{\em seq}の中で{\em :count}番目に現れた{\em olditem}を{\em newitem}に置き換えた
新しい列を返す。
デフォルトでは、全ての{\em olditem}を置き換える。}
\begin{verbatim}
(substitute #\Space #\_ "Euslisp_euslisp") ;; => "Euslisp euslisp"
\end{verbatim}
\fundesc{substitute-if}{newitem predicate seq \&key start end key count}
\fundesc{substitute-if-not}{newitem predicate seq \&key start end key count}
\funcdesc{nsubstitute}{newitem olditem seq \&key start end test test-not key count}{
{\em seq}の中で{\em count}番目に現れた{\em olditem}を{\em newitem}に置き換え、
元の列{\em seq}に返す。デフォルトでは、全ての{\em olditem}を置き換える。}
\fundesc{nsubstitute-if}{newitem predicate seq \&key start end key count}
\fundesc{nsubstitute-if-not}{newitem predicate seq \&key start end key count}
\end{refdesc}
\newpage
\subsection{リスト}
\begin{refdesc}
\funcdesc{listp}{object}{
オブジェクトがconsのインスタンスかもしくはNILならば、Tを返す。}
\funcdesc{consp}{object}{
{\tt (not (atom object))}と同一である。{\tt (consp '())}はNILである。}
\funcdesc{car}{list}{
{\em list}の最初の要素を返す。NILの{\bf car}はNILである。
atomの{\bf car}はエラーとなる。{\tt (car '(1 2 3)) = 1}}
\funcdesc{cdr}{list}{
{\em list}の最初の要素を削除した残りのリストを返す。NILの{\bf cdr}はNILである。
atomの{\bf cdr}はエラーとなる。{\tt (cdr '(1 2 3)) = (2 3)}}
\funcdesc{cadr}{list}{
{\tt (cadr list) = (car (cdr list))}}
\funcdesc{cddr}{list}{
{\tt (cddr list) = (cdr (cdr list))}}
\funcdesc{cdar}{list}{
{\tt (cdar list) = (cdr (car list))}}
\funcdesc{caar}{list}{
{\tt (caar list) = (car (car list))}}
\funcdesc{caddr}{list}{
{\tt (caddr list) = (car (cdr (cdr list)))}}
\funcdesc{caadr}{list}{
{\tt (caadr list) = (car (car (cdr list)))}}
\funcdesc{cadar}{list}{
{\tt (cadar list) = (car (cdr (car list)))}}
\funcdesc{caaar}{list}{
{\tt (caaar list) = (car (car (car list)))}}
\funcdesc{cdadr}{list}{
{\tt (cdadr list) = (cdr (car (cdr list)))}}
\funcdesc{cdaar}{list}{
{\tt (cdaar list) = (cdr (car (car list)))}}
\funcdesc{cdddr}{list}{
{\tt (cdddr list) = (cdr (cdr (cdr list)))}}
\funcdesc{cddar}{list}{
{\tt (cddar list) = (cdr (cdr (car list)))}}
\funcdesc{first}{list}{
{\em list}の最初の要素を取り出す。
{\bf second, third, fourth, fifth, sixth, seventh, eighth}もまた定義されている。{\tt (first list) = (car list)}}
%\funcdesc{second}{list}{{\tt (second list) = (cadr list)}}
%\funcdesc{third}{list}{{\tt (third list) = (caddr list)}}
%\funcdesc{fourth}{list}{{\tt (fourth list) = (car (cdddr list))}}
%\funcdesc{fifth}{list}{{\tt (fifth list) = (cadr (cdddr list))}}
\funcdesc{nth}{count list}{
{\em list}内の{\em count}番目の要素を返す。
{\tt (nth 1 list)}は、{\tt (second list)}あるいは{\tt (elt list 1)}と等価である。}
\funcdesc{nthcdr}{count list}{
{\em list}に{\bf cdr}を{\em count}回適用した後のリストを返す。}
\funcdesc{last}{list}{
{\em list}の最後の要素でなく、最後のconsを返す。}
\funcdesc{butlast}{list \&optional (n 1)}{
{\em list}の最後から{\em n}個の要素を削除したリストを返す。}
\funcdesc{cons}{car cdr}{
{\tt car}が{\em car}で{\tt cdr}が{\em cdr}であるような新しいconsを作る。}
\funcdesc{list}{\&rest elements}{
makes a list of {\em elements}.}
\funcdesc{list*}{\&rest elements}{
{\em element}を要素とするリストを作る。しかし、最後の要素は{\bf cons}されるため、
atomであってはならない。
例えば、{\tt (list* 1 2 3 '(4 5)) = (1 2 3 4 5)}である。}
\funcdesc{list-length}{list}{
{\em list}の長さを返す。{\em list}は、環状リストでも良い。}
\funcdesc{make-list}{size \&key initial-element}{
{\em size}長さで要素が全て{\em :initial-element}のリストを作る。}
\funcdesc{rplaca}{cons a}{
{\em cons}の{\bf car}を{\em a}に置き換える。
{\bf setf}と{\bf car}の使用を推薦する。
{\tt (rplaca cons a) = (setf (car cons) a)}}
\funcdesc{rplacd}{cons d}{
{\em cons}の{\bf cdr}を{\em d}に置き換える。
{\bf setf}と{\bf cdr}の使用を推薦する。
{\tt (rplacd cons d) = (setf (cdr cons) d)}}
\funcdesc{memq}{item list}{
{\bf member}に似ている。しかしテストはいつも{\tt eq}で行う。}
\funcdesc{member}{item list \&key key (test \#'eq) test-not}{
{\em list}の中から条件にあった要素を探す。
{\em list}の中から{\em item}を探索し、{\em :test}の条件にあったものがなければNILを返す。
見つかったならば、それ以降をリストとして返す。この探索は、最上位のリストに対して
行なわれる。{\em :test}のデフォルトは{\tt \#'eq}である。
{\tt (member 'a '(g (a y) b a d g e a y))=(a d g e a y)}}
\fundesc{assq}{item alist}
\funcdesc{assoc}{item alist \&key key (test \#'eq) test-not}{
{\em alist}の要素の{\bf car}が{\em :test}の条件にあった最初のものを返す。
合わなければ、NILを返す。
{\em :test}のデフォルトは{\tt \#'eq}である。
{\tt (assoc '2 '((1 d t y)(2 g h t)(3 e x g))=(2 g h t)}}
\funcdesc{rassoc}{item alist}{
{\bf cdr}が{\em item}に等しい{\em alist}のなかの最初の組を返す。}
\funcdesc{pairlis}{l1 l2 \&optional alist}{
{\em l1}と{\em l2}の中の一致する要素を対にしたリストを作る。
もし{\em alist}が与えられたとき、
{\em l1}と{\em l2}から作られた対リストの最後に連結させる。}
\funcdesc{acons}{key val alist}{
{\em alist}に{\em key val}の組を付け加える。
{\tt (cons (cons key val) alist)}と同等である。}
\funcdesc{append}{\&rest list}{
新しいリストを形成するために{\em list}を連結させる。
最後のリストを除いて、{\em list}のなかの全ての要素はコピーされる。}
\funcdesc{nconc}{\&rest list}{
それぞれの{\em list}の最後の{\bf cdr}を置き換える事によって、{\em list}を
破壊的に(destructively)連結する。}
\funcdesc{subst}{new old tree}{
{\em tree}の中のすべての{\em old}を{\em new}に置き換える。}
\funcdesc{flatten}{complex-list}{
atomやいろんな深さのリストを含んだ{\em complex-list}を、
1つの線形リストに変換する。そのリストは、
{\em complex-list}の中のトップレベルに全ての要素を置く。
{\tt (flatten '(a (b (c d) e))) = (a b c d e)}}
\macrodesc{push}{item place}{
{\em place}にバインドされたスタック(リスト)に{\em item}を置く。}
\macrodesc{pop}{stack}{
{\em stack}から最初の要素を削除し、それを返す。
もし{\em stack}が空(NIL)ならば、NILを返す。}
\macrodesc{pushnew}{item place \&key test test-not key}{
もし{\em item}が{\em place}のメンバーでないなら、
{\em place}リストに{\em item}を置く。
{\em :test}, {\em :test-not}と{\em :key}引数は、
{\bf member}関数に送られる。}
\funcdesc{adjoin}{item list}{
もし{\em item}が{\em list}に含まれてないなら、{\em list}の最初に付け加える。}
\funcdesc{union}{list1 list2 \&key (test \#'eq) test-not (key \#'identity)}{
2つのリストの和集合を返す。}
\funcdesc{subsetp}{list1 list2 \&key (test \#'eq) test-not (key \#'identity)}{
{\em list1}が{\em list2}の部分集合であること、すなわち、
{\em list1}のそれぞれの要素が{\em list2}のメンバーであることをテストする。}
\funcdesc{intersection}{list1 list2 \&key (test \#'eq) test-not (key \#'identity)}{
2つのリスト{\em list1}と{\em list2}の積集合を返す。}
\funcdesc{set-difference}{list1 list2 \&key (test \#'eq) test-not (key \#'identity)}{
{\em list1}にのみ含まれていて
{\em list2}に含まれていない要素からなるリストを返す。}
\funcdesc{set-exclusive-or}{list1 list2 \&key (test \#'eq) test-not (key \#'identity)}{
{\em list1}および{\em list2}にのみ現れる要素からなるリストを返す。}
\funcdesc{list-insert}{item pos list}{
{\em list}の{\em pos}番目の要素として{\em item}を挿入する
(元のリストを変化させる)。
もし{\em pos}が{\em list}の長さより大きいなら、{\em item}は最後に
{\bf nconc}される。
{\tt (list-insert 'x 2 '(a b c d)) = (a b x c d)}}
\funcdesc{copy-tree}{tree}{
入れこリストである{\em tree}のコピーを返す。
しかし、環状参照はできない。環状リストは、
{\bf copy-object}でコピーできる。
実際に、{\bf copy-tree}は{\tt (subst t t tree)}と簡単に記述される。}
\funcdesc{mapc}{func arg-list \&rest more-arg-lists}{
{\em arg-list}や{\em more-arg-lists}それぞれのN番目($N=0,1,\cdots$)の要素からなるリストに
{\em func}を適用する。
適用結果は無視され、{\em arg-list}が返される。}
\funcdesc{mapcar}{func \&rest arg-list}{
{\em arg-list}のそれぞれの要素に{\em func}を{\bf map}し、
その全ての結果のリストを作る。例えば、{\tt (mapcar \#'(lambda (x) (* x x)) '(1 2 3))}のように書く。
{\bf mapcar}を使う前に、{\bf dolist}を試すこと。}
\funcdesc{mapcan}{func arg-list \&rest more-arg-lists}{
{\em arg-list}のそれぞれの要素に{\em func}を{\bf map}し、
{\bf nconc}を用いてその全ての結果のリストを作る。
{\bf nconc}はNILに対して何もしないため、
{\bf mapcan}は、{\em arg-list}の要素にフィルタをかける(選択する)
のに合っている。}
\end{refdesc}
\newpage
\subsection{ベクトルと行列}
7次元以内の行列が許可されている。
1次元の行列は、ベクトルと呼ばれる。
ベクトルとリストは、列としてグループ化される。
もし、行列の要素がいろんな型であったとき、その行列は一般化されていると言う。
もし、行列がfill-pointerを持ってなく、他の行列で置き換えられなく、
拡張不可能であるなら、その行列は簡略化されたと言う。
全ての行列要素は、{\bf aref}により取り出すことができ、{\bf aref}を用いて{\bf setf}
により設定することができる。
しかし、一次元ベクトルのために簡単で高速なアクセス関数がある。
{\bf svref}は一次元一般ベクトル、{\bf char}と{\bf schar}は
一次元文字ベクトル(文字列)、{\bf bit}と{\bf sbit}は
一次元ビットベクトルのための高速関数である。
これらの関数はコンパイルされたとき、
アクセスはin-lineを拡張し、型チェックと境界チェックなしに実行される。
ベクトルもまたオブジェクトであるため、
別のベクトルクラスを派生させることができる。
5種類の内部ベクトルクラスがある。
{\tt vector, string, float-vector, integer-vector}と{\tt bit-vector}である。
ベクトルの作成を容易にするために、make-array関数がある。
要素の型は、{\tt :integer, :bit, :character, :float, :foreign}
かあるいはユーザーが定義したベクトルクラスの内の一つでなければならない。
{\em :initial-element}と{\em :initial-contents}のキーワード引数は、
行列の初期値を設定するために役に立つ。
\begin{refdesc}
\constdesc{array-rank-limit}{
7。行列の最大次元を示す。}
\constdesc{array-dimension-limit}{
\#x1fffffff。各次元の最大要素数を示す。
論理的な数であって、システムの物理メモリあるいは仮想メモリの大きさによって
制限される。}
\funcdesc{vectorp}{object}{
行列は1次元であってもベクトルではない。
{\em object}が{\tt vector, integer-vector, float-vector, string, bit-vector}
あるいはユーザーで定義したベクトルならTを返す。}
\funcdesc{vector}{\&rest elements}{
{\em elements}からなる一次元ベクトルを作る。}
\longdescription{関数}{make-array}{dims \&key \= (element-type vector) \\
\> initial-contents \\
\> initial-element \\
\> fill-pointer  \\
\> displaced-to \\
\> displaced-index-offset 0) \\
\> adjustable}{
ベクトルか行列を作る。
{\em dims}は、整数かリストである。
もし{\em dims}が整数なら、一次元ベクトルが作られる。}
\funcdesc{svref}{vector pos}{
{\em vector}の{\em pos}番目の要素を返す。
{\em vector}は、一次元一般ベクトルでなければならない。}
\funcdesc{aref}{vector \&rest indices}{
{\em vector}の{\em indices}によってインデックスされる要素を返す。
{\em indices}は、整数であり、{\em vector}の次元の数だけ指定する。
{\bf aref}は、非効率的である。なぜなら、{\em vector}の型に従うように
変更する必要があるためである。コンパイルコードの速度を改善する
ため、できるだけ型の宣言を与えるべきである。}
\funcdesc{vector-push}{val array}{
{\em array}のfill-pointer番目のスロットに{\em val}を保管する。
{\em array}は、fill-pointerを持っていなければならない。
{\em val}が保管された後、
fill-pointerは、次の位置にポイントを1つ進められる。
もし、行列の境界よりも大きくなったとき、エラーが報告される。}
\funcdesc{vector-push-extend}{val array}{
{\em array}のfill-pointerが最後に到達したとき、自動的に{\em array}のサイズが
拡張されることを除いては、{\bf vector-push}と同じである。}
\funcdesc{arrayp}{obj}{
もし{\em obj}が行列またはベクトルのインスタンスであるならTを返す。}
\funcdesc{array-total-size}{array}{
{\em array}の要素数の合計を返す。}
\funcdesc{fill-pointer}{array}{
{\em array}のfill-pointerを返す。
fill-pointerを持っていなければNILを返す。}
\funcdesc{array-rank}{array}{
{\em array}の次元数を返す。}
\funcdesc{array-dimensions}{array}{
{\em array}の各次元の要素数をリストで返す。}
\funcdesc{array-dimension}{array axis}{
{\bf array-dimension}は、{\em array}の{\em axis}
番目の次元を返す。{\em axis}はゼロから始まる。}
\funcdesc{bit}{bitvec index}{
{\em bitvec}の{\em index}番目の要素を返す。
ビットベクトルの要素を変更するには、{\bf setf}と{\bf bit}を使用すること。}
\fundesc{bit-and}{bits1 bits2 \&optional result}
\fundesc{bit-ior}{bits1 bits2 \&optional result}
\fundesc{bit-xor}{bits1 bits2 \&optional result}
\fundesc{bit-eqv}{bits1 bits2 \&optional result}
\fundesc{bit-nand}{bits1 bits2 \&optional result}
\fundesc{bit-nor}{bits1 bits2 \&optional result}
\funcdesc{bit-not}{bits1 \&optional result}{
同じ長さの{\em bits1}と{\em bits2}というビットベクトルにおいて、
それらのand, inclusive-or,
exclusive-or, 等価, not-and, not-orとnotがそれぞれ返される。}
\end{refdesc}
\newpage
\subsection{文字と文字列}
EusLispには、文字型がない。
文字は、{\tt integer}によって表現されている。
ファイル名を現わす文字列を扱うためには、
\ref{Pathnames}節に書かれている{\bf pathname}を使うこと。
\begin{refdesc}
\funcdesc{digit-char-p}{ch}{
もし{\em ch}が{\tt \#$\backslash$0}〜{\tt \#$\backslash$9}ならTを返す。}
\funcdesc{alpha-char-p}{ch}{
もし{\em ch}が{\tt \#$\backslash$A}〜{\tt \#$\backslash$Z}または
{\tt \#$\backslash$a}〜{\tt \#$\backslash$z}なら、Tを返す。}
\funcdesc{upper-case-p}{ch}{
もし{\em ch}が{\tt \#$\backslash$A}〜{\tt \#$\backslash$Z}なら、Tを返す。}
\funcdesc{lower-case-p}{ch}{
もし{\em ch}が{\tt \#$\backslash$a}〜{\tt \#$\backslash$z}なら、Tを返す。}
\funcdesc{alphanumericp}{ch}{
もし{\em ch}が{\tt \#$\backslash$0}〜{\tt \#$\backslash$9}、
{\tt \#$\backslash$A}〜{\tt \#$\backslash$Z}または
{\tt \#$\backslash$a}〜{\tt \#$\backslash$z}なら、Tを返す。}
\funcdesc{char-upcase}{ch}{
{\em ch}を大文字に変換する。}
\funcdesc{char-downcase}{ch}{
{\em ch}を小文字に変換する。}
\funcdesc{char}{string index}{
{\em string}の{\em index}番目の文字を返す。}
\funcdesc{schar}{string index}{
{\em string}から文字を抜き出す。
{\em string}の型が明確に解っていて、型チェックを要しないときのみ、{\bf schar}
を使うこと。}
\funcdesc{stringp}{object}{
{\em object}がバイト(256より小さい正の整数)のベクトルなら、Tを返す。}
\funcdesc{string-upcase}{str \&key start end}{
{\em str}を大文字の文字列に変換して、新しい文字列を返す。}
\funcdesc{string-downcase}{str \&key start end}{
{\em str}を小文字の文字列に変換して、新しい文字列を返す。}
\funcdesc{nstring-upcase}{str}{
{\em str}を大文字の文字列に変換し、元に置き換える。}
\funcdesc{nstring-downcase}{str \&key start end}{
{\em str}を小文字の文字列に変換し、元に置き換える。}
\funcdesc{string=}{str1 str2 \&key start1 end1 start2 end2}{
もし{\em str1}が{\em str2}と等しいとき、Tを返す。
{\bf string=}は、大文字・小文字を判別する。}
\funcdesc{string-equal}{str1 str2 \&key start1 end1 start2 end2}{
{\em str1}と{\em str2}の等価性をテストする。
{\bf string-equal}は、大文字・小文字を判別しない。}
\funcdesc{string}{object}{
{\em object}の文字列表現を得る。
もし{\em object}が文字列なら、{\em object}が返される。
もし{\em object}がsymbolなら、その{\tt pname}がコピーされ、返される。
{\tt (equal (string 'a) (symbol-pname 'a))==T}であるが、
{\tt (eq (string 'a) (symbol-pname 'a))==NIL}である。
もし{\em object}が数値なら、それを文字列にしたものが返される
(これはCommon Lispと非互換である)。
もっと複雑なオブジェクトから文字列表現を得るためには、
最初の引数をNILにした{\bf format}関数を用いること。}
\fundesc{string$<$}{str1 str2}
\fundesc{string$<=$}{str1 str2}
\fundesc{string$>$}{str1 str2}
\fundesc{string$>=$}{str1 str2}
\fundesc{string-left-trim}{bag str}
\funcdesc{string-right-trim}{bag str}{
{\em str}は、左(右)から探索され、もし{\em bag}リスト内の文字を含んでいるなら、
その要素を削除する。
一旦{\em bag}に含まれない文字が見つかると、その後の探索は中止され、
{\em str}の残りが返される。}
\funcdesc{string-trim}{bag str}{
{\em bag}は、文字コードの列である。
両端に{\em bag}に書かれた文字を含まない{\em str}のコピーが作られ、返される。}
\funcdesc{substringp}{sub string}{
{\em sub}文字列が{\em string}に部分文字列として含まれるなら、Tを返す。
大文字・小文字を判別しない。}
\end{refdesc}
\subsubsection{日本語の扱い方}
{\bf euslisp}で日本語を扱いたい時、文字コードは{\bf UTF-8}である必要がある。
例えば{\bf concatenate}を用いると、リストの中の日本語を連結することが出来る。
{\bf ROS}のトピックとして一つずつ取ってきた日本語を、連結することで一つの{\bf string}型の言葉に変換したい時などに便利である。
(concatenate string "け" "ん" "し" "ろ" "う") 
→ "けんしろう"
最初から全ての文字がリストに入っていて、文字を連結したい時はこのようにすればよい。
(reduce {\#}'(lambda (val1 val2) (concatenate string val1 val2)) (list "我" "輩" "は" "ピ" "ー" "ア" "ー" "ル" "ツ" "ー" "で" "あ" "る"))
→ "我輩はピーアールツーである"
{\bf coerce}を用いて、次のように書くことも出来る。
(coerce (append (coerce "私はナオより" cons) (coerce "背が高い" cons)) string)
→ "私はナオより背が高い"
\subsection{Foreign String}
{\bf foreign-string}は、EusLispのヒープ外にあるバイトベクトルの1種である。
普通の文字列は、長さとバイトの列を持ったオブジェクトであるが、
foreign-stringは、長さと文字列本体のアドレスを持っている。
foreign-stringは文字列であるが、
いくつかの文字列および列に対する関数は適用できない。
{\bf length}、{\bf aref}、{\bf replace}、{\bf subseq}と{\bf copy-seq}だけが
foreign-stringを認識し、 
その他の関数の適用はクラッシュの原因となる恐れがある。
foreign-stringは、/dev/a??d??(??は32あるいは16)の特殊ファイルで与えられる
I/O空間を参照することがある。
そのデバイスがバイトアクセスにのみ応答するI/O空間の一つに
割り当てられた場合、
{\bf replace}は、いつもバイト毎に要素をコピーする。
メモリのlarge chunkを連続的にアクセスしたとき、比較的に遅く動作する。。
\begin{refdesc}
\funcdesc{make-foreign-string}{address length}{
{\em address}の位置から{\em length}バイトの
{\bf foreign-string}のインスタンスを作る。
例えば、{\tt (make-foreign-string (unix:malloc 32) 32)}は、
EusLispのヒープ外に位置する32バイトメモリを参照部分として作る。}
\end{refdesc}
\newpage
\subsection{ハッシュテーブル}
hash-tableは、キーで連想される値を探すためのクラスである({\bf assoc}でもできる)。
比較的大きな問題において、hash-tableはassocより良い性能を出す。
キーと値の組数が増加しても探索に要する時間は、一定のままである。
簡単に言うと、hash-tableは100以上の要素から探す場合に用い、
それより小さい場合はassocを用いるべきである。
hash-tableは、テーブルの要素数がrehash-sizeを越えたなら、自動的に拡張される。
デフォルトとして、テーブルの半分が満たされたとき拡張が起こるようになっている。
{\bf sxhash}関数は、オブジェクトのメモリアドレスと無関係なハッシュ値を
返し、オブジェクトが等しい(equal)ときのハッシュ値はいつも同じである。
それで、hash-tableはデフォルトのハッシュ関数に{\bf sxhash}を使用している
ので、再ロード可能である。
{\bf sxhash}がロバストで安全な間は、
列やtreeの中のすべての要素を探索するため、比較的に遅い。
高速なハッシュのためには、アプリケーションにより他の特定のハッシュ関数を
選んだ方がよい。
ハッシュ関数を変えるためには、hash-tableに{\tt :hash-function}メッセージを
送信すれば良い。
簡単な場合、ハッシュ関数を{\tt \#'sxhash}から
{\tt \#'sys:address}に変更すればよい。
EusLisp内のオブジェクトのアドレスは
決して変更されないため、{\tt \#'sys:address}を設定することができる。
\begin{refdesc}
\funcdesc{sxhash}{obj}{
{\em obj}のハッシュ値を計算する。
{\bf equal}な2つのオブジェクトでは、同じハッシュ値を生じること
が保証されている。
symbolなら、そのpnameに対するハッシュ値を返す。
numberなら、その{\tt integer}表現を返す。
listなら、その要素全てのハッシュ値の合計が返される。
stringなら、それぞれの文字コードの合計をシフトしたものが返される。
その他どんなオブジェクトでも、{\bf sxhash}はそれぞれのスロットのハッシュ値を
再帰的呼出しで計算し、それらの合計を返す。}
\funcdesc{make-hash-table}{\&key (size 30) (test \#'eq) (rehash-size 2.0)}{
hash-tableを作り、返す。}
\funcdesc{gethash}{key htab}{
{\em htab}の中から{\em key}と一致する値を得る。
{\bf gethash}は、{\bf setf}を組み合せることにより{\em key}に値を設定する
ことにも使用される。
hash-tableに新しい値が登録され、そのテーブルの埋まったスロットの数が
1/rehash-sizeを越えたとき、hash-tableは自動的に2倍の大きさに拡張される。}
\funcdesc{remhash}{key htab}{
{\em htab}の中から{\em key}で指定されたハッシュ登録を削除する。}
\funcdesc{maphash}{function htab}{
{\em htab}の要素全てを{\em function}で{\bf map}する。}
\funcdesc{hash-table-p}{x}{
もし{\em x}がhash-tableクラスのインスタンスなら、Tを返す。}
\classdesc{hash-table}{object}{(key value count \\
\> hash-function test-function \\
\> rehash-size empty deleted)}{
hash-tableを定義する。
{\em key}と{\em value}は大きさが等しい一次元ベクトルである。
{\em count}は、{\em key}や{\em value}が埋まっている数である。
{\em hash-function}のデフォルトは{\bf sxhash}である。
{\em test-function}のデフォルトは{\bf eq}である。
{\em empty}と{\em deleted}は、{\em key}ベクトルのなかで空または削除された
数を示すsymbol(パッケージに収容されていない)である。}
\methoddesc{:hash-function}{newhash}{
このhash-tableのハッシュ関数を{\em newhash}に変更する。
{\em newhash}は、1つの引数を持ち、{\tt integer}を返す関数でなければならない。
{\em newhash}の1つの候補として{\bf sys:address}がある。}
\end{refdesc}
\newpage
\subsection{キュー}
\begin{refdesc}
queue はFIFO(first-in first-out)形式で要素の追加や検索を可能にするデー
タ構造である。
carがqueueの実体であり、このqueueのインスタンスをqとすると,その配列
は(print (car q))で表示できる。cdrに最も最近に追加された要素が確保される。
\classdesc{queue}{cons}{(car cdr)}{
FIFO queueを定義する。}
\methoddesc{:init}{}{
queueを初期化する。}
\methoddesc{:enqueue}{val}{
このqueueにxを最新の要素として追加する。}
\methoddesc{:dequeue}{\&optional (error-p nil)}{
このqueueの最も過去に追加された要素を返し、
queueから削除する。queueが空の場合,error-pが
NILでない場合はエラーを表示し、それ以外の場合はNILを返す。}
\methoddesc{:empty?}{}{
このqueueが空の場合、Tを返す。}
\methoddesc{:length}{}{
このqueueの長さを返す。}
\methoddesc{:trim}{s}{
このqueueの要素のうち古いものを破棄し、queueの長さをsとする。}
\methoddesc{:search}{item \&optional (test \#'equal)}{
このqueueにitemが存在するか調べる。もし無ければNILを返す。}
\methoddesc{:delete}{item \&optional (test \#'equal) (count 1)}{
このqueueからitemと同一の要素を探し、:count番目までの要素を削除する。}
\methoddesc{:first}{}{
このqueueの先頭の要素(最も過去に追加された要素)を返す。}
\methoddesc{:last}{}{
このqueueの最後の要素(最も最近に追加された要素)を返す。}
\end{refdesc}
\newpage
 |