関数型プログラミング事始め (15) 配列 - Lisp超入門4
関数型プログラミングがはじめての方へ贈る入門の書
前節:変数と名前 次節:繰り返し
参考書:
・五味 弘「はじめてのLisp関数型プログラミング」技術評論社(2016)
・大山口 通夫、五味 弘「プログラミング言語論」コロナ社(2008)
・五味 弘「関数型プログラミングと数学(ITと数学)」技術評論社(2021)
(7) 配列
Lispには配列のデータ構造が用意されています。1次元配列であるベクター(vector)と多次元配列であるアレイ(array)のデータタイプがあります。ちなみにCommon Lispではベクターはアレイの副型となっています。
まずはislispを起動してください。なおISLisp処理系はLisp処理系の導入で紹介していますので参照してください。
> ISLisp Version 0.80 (1999/02/25)
>
ISLisp>
(a) ベクター vector
ベクターは1次元配列で、以下のように使います。
ISLisp>(defglobal v #(0 1 2 3)) ; #(0 1 2 3)のベクターを初期値にする
V
ISLisp>v
#(0 1 2 3)
ISLisp>(aref v 1) ; ベクター v の1番目(0番から始まる)の要素を返す
1
ISLisp>(setf (aref v 1) 10) ; ベクター v の1番目に10を格納する
10
ISLisp>v
#(0 10 2 3) ; 1番目の要素が10になっている
ISLisp>(set-aref 100 v 1) ; セッター関数による値の格納
100
ISLisp>v
#(0 100 2 3)
関数aref(array reference)で要素にアクセスします。用例は(aref ベクター インデックス)です。なおLispのインデックスは0から始まります(0 origin)。
ベクターにデータを格納するときはsetf(set form)を使います。setfは汎用代入ができるもので(setf アクセス形式 値)で使い、ベクターのアクセス形式は(aref ベクター インデックス)になります。ここはCommon Lispと同じです。
なおISLispではセッター関数も定義されており、配列のセッター関数はset-arefがあります。用例は(set-aref 値 ベクター インデックス)です。
(b) アレイ array
Lispでは多次元配列が扱えます。ベクターのベクターで実装されるジャグ配列でなく、各行の長さが同じであり、アクセスがO(1)で可能な多次元配列が使えます。
ISLisp>(defglobal a #2a((0 1 2) (3 4 5) (6 7 8))) ; 2次元配列を初期値にする
A
ISLisp>a
#2A((0 1 2) (3 4 5) (6 7 8))
ISLisp>(aref a 1 2) ; アレイ a の1行2列の値を返す(0 origin)
5
ISLisp>(setf (aref a 1 2) 50) ; アレイ a の1行2列に50を格納する
50
ISLisp>a
#2A((0 1 2) (3 4 50) (6 7 8))
ISLisp>(set-aref 500 a 1 2) ; セッター関数を使って500を格納する
500
ISLisp>a
#2A((0 1 2) (3 4 500) (6 7 8))
多次元配列は次元数Dのときは、#Da((…(0 1 2 …) …) …)のように記載できます。ベクターは1次元配列なので、#(0 1 2 3)は#1a(0 1 2 3)のように記載できます。逆に#(0 1 2 3)は1次元配列の略記と捉えることもできます。
(c) 文字列 string
文字列は要素が文字であるベクターです。このため、アクセスはベクターと同様にできます。なお文字列特有の関数は後日紹介する予定です。
ISLisp>(defglobal s "abc") ; 文字列"abc"を初期値にする
S
ISLisp>s
"abc"
ISLisp>(setf (aref s 1) #\B) ; 文字列"abc"の1番目の文字を#\B(文字B)にする
#\B
ISLisp>s
"aBc"
上記を見てわかるように、Lispの文字列はミュータブル(変更可能)な型です。Javaなどが文字列をイミュータブル(変更不可)にしているのに対し、自由です。すみません、これは完全に言い訳で、関数型プログラミングの風上にも置けない仕様です。
言い訳の2番目として、文字列の値を動的に変更しないようにしましょう。これはC言語などでも同様に言える弁護、いえ、アドバイスです。
(次回予告)Lisp超入門5
次回もOK! ISLisp処理系を使って、Lispの超入門の第5回を紹介する予定です。お楽しみに。
参考:プログラミング言語はどれがお得?(前編)|五味弘 (note.com)
参考:プログラミング言語はどれがお得?(後編)|五味弘 (note.com)