web-dev-qa-db-ja.com

Common Lispで数値をインクリメントまたはデクリメントするにはどうすればよいですか?

イディオマティック数値や数値変数をインクリメント/デクリメントする一般的なLISPの方法は何ですか?

27
Jabavu Adams

元の数値(引数)を変更せずに結果を使用するだけの場合は、組み込みの「+」または「-」関数、またはそれらの省略形の「1+」または「1-」を使用します。元の場所(数値を含む)を変更する場合は、組み込みの「incf」または「decf」関数を使用します。

加算演算子の使用:

(setf num 41)
(+ 1 num)   ; returns 42, does not modify num
(+ num 1)   ; returns 42, does not modify num
(- num 1)   ; returns 40, does not modify num
(- 1 num)   ; NOTE: returns -40, since a - b is not the same as  b - a

または、必要に応じて、次の省略形を使用できます。

(1+ num)    ; returns 42, does not modify num.
(1- num)    ; returns 40, does not modify num. 

Common LISP仕様では、上記の2つの形式の意味が同等であると定義されており、実装によってパフォーマンスが同等になることが示唆されていることに注意してください。これは提案ですが、LISPの専門家によると、「自尊心のある」実装ではパフォーマンスに違いは見られないはずです。

Numを更新する場合(1 +その値を取得するだけでなく)、「incf」を使用します。

(setf num 41)
(incf num)  ; returns 42, and num is now 42.

(setf num 41)
(decf num)  ; returns 40, and num is now 40.

(incf 41)   ; FAIL! Can't modify a literal

注意:

Incf/decfを使用して、1単位以上インクリメント(デクリメント)することもできます。

(setf foo 40)
(incf foo 2.5)  ; returns 42.5, and foo is now 42.5

詳細については、Common LISP Hyperspecを参照してください: 1 +incf/decf

37
Jabavu Adams