この記事では、著者は 2 つの主な優れた機能を備えた関数型プログラミングを称賛しました。しかし、彼は (Common) Lisp については言及しませんでした。
Lispのデータはこの「すべてのデータは不変」を満たしていますか?
Common Lisp では、すべてのデータ (プリミティブ変数参照、リスト、配列、ハッシュ テーブルなど) はデフォルトで変更可能であるため、誰かが変数の値、シーケンスの要素、またはフィールドの変更を妨げることはありません。構造。
ただし、プリミティブ データ型ではなくユーザー定義データ、つまり CLOS 構造体とクラスについて話している場合は、それらのスロットを読み取り専用にすることができます。たとえば、構造の場合:
(defstruct person
(name nil :type string :read-only t)
(age nil :type (integer 0 100)))
(let ((john (make-person :name "John" :age 30)))
(princ john)
;; * `age' is mutable:
(incf (person-age john))
(princ john)
;; * `name' is not:
;; (setf (person-name john) "garbage name")
;; ^ you can't do this because the `defstruct' macro just don't emit SETFer
;; for the `name' slot as you made it read-only.
)
クラスは、スロットに対してさらに多くのアクセス制御を提供します (これはconst
、C の修飾子のメカニズムに似ています。違いは、Common Lisp では、コンパイル時の保証ではなく、再起動で処理できる例外であるということです)。読み取りと書き込み、読み取り専用、書き込み専用、またはアクセスなしを与えることができます。
詳細については、次のリンクを参照してください。
Common Lispでは、機能的なスタイルを使用するオプションがあります。setf
、などを避けてくださいsetq
。そうすれば、関数型プログラミング言語を手に入れることができます。つまり、変数値を変更したり、作成後に複合データ構造(cons、vectors、structuresなど)の内容を変更したりしないでください。関数は、状態を変更せずに入力を受け取り、出力を生成します。
したがって、Common Lispは必須の操作を提供しますが、必要がなければそれらを使用する必要はありません。
いいえ。 Common Lisp のデータは不変ではありません。
setf
関数を使用して SBCL で見られるように
* (setf x 0)
0
* x
0
* (setf x 1)
1
* x
1