[過去ログ] Lisp Scheme Part40 [転載禁止]©2ch.net (1002レス)
上下前次1-新
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
966(8): デフォルトの名無しさん [sage] 2018/07/11(水) 13:07:02 ID:7FwajRbN(1/7) AAS
教えてください。初心者です。
(defun test ()
(let ((result '(0 0 0 0 0 0 0)))
(format t "~{ ~a ~}" result)
(incf (nth 4 result) 7)
(incf (nth 6 result) 6)
result))
この関数なんですが、実行するたびに結果が変わるのです。
HOGE 28 > (test)
0 0 0 0 0 0 0
(0 0 0 0 7 0 6)
HOGE 29 > (test)
0 0 0 0 7 0 6
(0 0 0 0 14 0 12)
(let ((result (make-list 7 :initial-element 0)))...
にすれば意図したとおりに動作するのは分かっているのですが、
何で元の関数定義でだめなのかが分からないのです。
ちなみに、Lispworks 7.0 Windows 32bitです。
他の処理系でも同じような動作になるのでしょうか。
967(1): 966 [sage] 2018/07/11(水) 13:41:02 ID:7FwajRbN(2/7) AAS
何でこうなるかは、何となくわからなくはないのですが(1回目の実行と2回目の実行で同じリストをletで束縛してるってことですよね?)、
letってそういう動作するのを想定して使わなきゃいけないものなのか、ってのがわかってないのです。
僕の理解では元の関数定義でいけそうな気がするのです。
968: 966 [sage] 2018/07/11(水) 15:14:10 ID:7FwajRbN(3/7) AAS
(defparameter *FOO* '(bar bar bar))
(defun hoge-is-foo (&optional (piyo nil))
(let ((hoge '(fuga fuga fuga)))
(if piyo (setf *foo* hoge))
(format t "HOGE: ~{ ~a ~}~%" hoge)
(format t "*FOO*: ~{ ~a ~}~%" *foo*)
(if (eq hoge *foo*)
(format t "HOGE IS FOO!~%")
(format t "HOGE IS NOT FOO!~%"))))
PIYO 82 > (hoge-is-foo)
HOGE: FUGA FUGA FUGA
*FOO*: BAR BAR BAR
HOGE IS NOT FOO!
NIL
PIYO 83 > (hoge-is-foo t)
HOGE: FUGA FUGA FUGA
*FOO*: FUGA FUGA FUGA
HOGE IS FOO!
NIL
PIYO 84 > (setf (car *foo*) 'baz)
BAZ
PIYO 85 > (hoge-is-foo)
HOGE: BAZ FUGA FUGA
*FOO*: BAZ FUGA FUGA
HOGE IS FOO!
NIL
こーゆーもんなん?
971(1): 966 [sage] 2018/07/11(水) 17:18:46 ID:7FwajRbN(4/7) AAS
>>970
966です。
僕が知りたかったのは>>969の内容です。どうもありがとうございました。
未定義動作なのですね。基本的にこのような破壊的代入は避けるってことですかね。
しかし、これが未定義だと、確率は低いでしょうけど、いつかどこかで事故が起こったりするんじゃないのかな。知らんけど。
974: 966 [sage] 2018/07/11(水) 20:23:44 ID:7FwajRbN(5/7) AAS
>>972
破壊的な変更には注意が必要なこと自体は、入門書などを読んで知っていたのですが、
今回の例では関数を呼び出す度に別のリストをletが束縛するだろうjkと勝手に思っていました。
勉強になりました。ありがとうございます。
976: 966 [sage] 2018/07/11(水) 20:46:42 ID:7FwajRbN(6/7) AAS
>>975
でないっす。
977(2): 966 [sage] 2018/07/11(水) 21:11:34 ID:7FwajRbN(7/7) AAS
自分の環境でSBCLでやってみたら↓みたいになった。
個人的にはLispworksの挙動より意味不明かも。
(hoge-is-foo)はLispworksと同じ結果。
* (test)
0 0 0 0 0 0 0
(0 0 0 0 7 0 6)
* (test)
0 0 0 0 7 0 6
(0 0 0 0 7 0 6)
* (test)
0 0 0 0 7 0 6
(0 0 0 0 7 0 6)
上下前次1-新書関写板覧索設栞歴
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.033s