3/9
持病のPC弄り病の発作が出てしまい、秋葉原にすっ飛んで行ってケース・電源・CPUクーラーを買ってしまった。7月の大規模アップグレードのときに電源は変えなかったのだが、電源の劣化を示唆するような症状は見られないと言えども(いや、実は出ているかもしれない…?)、購入から8年間酷使している電源はそろそろ不安だ。そして現在使用しているのがATXの省スペース横置きという変態型であるが故に電源の交換やHDDの追加作業が非常にめんどいという事情がある。このケースの厳しい寸法制限のせいでCPUクーラーは小さくて低性能なものを使わざるを得ず、またエアフローも貧弱であるために追加のファンがうるさい。
このケースを買った当時は学生で部屋が狭く、空間の活用も下手だった。今は違い、いかにもPCを置けそうな遊んでるスペースがデスク下にある。それならクソデカケースを買えばいろいろな問題が一挙に解決するではないか(なにか1つの新手によって全ての問題を一挙に解決できそうになると細かいことを考えるのがめんどくなるやつ)。
最近のケースは3.5インチベイが少ないのがトレンドとのことだが、僕は最低4は欲しく(現状も3使ってるし)、Define R5にした。10年以上前から使われている定番商品らしい。電源とクーラーはあまり詳しくなく、750WGOLDのATX3系であるMSI MAG A750GL PCIE5、そして国産であり低価格帯でAK400と双璧をなす定番・虎徹Mark3にした。
夕食は秋葉原の日乃屋カレーにした。日乃屋カレーってこんな味だったかな…?と思った(プラスの意味なのかマイナスの意味なのかは お察しください )。雨でとても寒い日だったのにメイドカフェ?の呼び込みはみんな足を見せる服装で大変だなあ。
ケースが届く月曜日が、Xデーだ。
3/10
普通の
↑これだけ入力した後温めたお茶を取りに行ったら何を書こうとしていたのか忘れた。何が普通だよ(さっき考えていたことを思い出そうとしても思い出せないこと、あるよね…あるよね?)。
家事
明日のPC換装・配置換え作業を控えて今日は念入りに掃除をした。昔は長机1つをPCデスクにしていたのだが、今は友人から貰ったクソデカ机(なんと天板120cm x 70cm)の左側にもう1枚机を連結してクソデカスギ机として運用している。クソデカ机の下にはキャビネットと僕の太ももが入っているが、追加机の下は何も活用されない空間になっていた(実際のところ故障して直線が引けない液タブが放置されている)。
なぜ液タブが放置されていたのか。それは捨てるのが難しそうだったからだ。一般に家電は捨てるのが難しいし、液タブは粗大ゴミとして捨てようにも分類が不明で問い合わせが必要そうだったので面倒そうで放置していた。今回改めて調べてみると近所のジョーシンで550円払って回収してもらえた。半導体はリサイクルされて回り回って今度はLLMのパーツにでもなるんだろうか。
その流れでベルトや食品を買って帰宅。冷凍餃子ってレンジじゃなくてフライパンで解凍するんですね。知らなかった。
RimWorld
RimWorldは人生の多くの洞察を与えてくれるが、一般規則と個別事例の関係もそうだ。後半のpawnが増えてきたコロニーは一人ひとりの行動をチェックして最適化していくのは困難だ。それはチェックが手間というのもあるし、一人ずつ最適化しても全体最適にならないからだ。そこでなるべく少ない数の一般的な規則を発布し、各pawnが自律的に行動することで全体が円滑に回ることを期待する。たとえば衣服に関して言えば
- pawnのデフォルト着脱ルール(気温に合わせた服を着る)
- pawnに「HP50%の服は着てはいけない」
- 溶鉱炉「HP50%以下の服が存在する限りそれを燃やす」
- ミシンに「衣服の在庫が1になるように製作する」
という4つのルールを設定することでpawnが衣服に関して困ることがなくなる。これが一般規則による問題の解決だ。
しかし現実は複雑だ。pawnが着るべき服は各pawnの性質によって大きく異なる。食人嗜好者なら人皮製の服、ヌーディストなら衣服なしにしたいし、戦闘時に前衛か後衛かによって防具も変わってくる。ミシンで製作できない拾い物の高性能衣服があるならそれを誰が着るかという設定も必要だ。
つまり、一般規則と個別事例の両方を意識しないと物事はうまく回らない。誰かが割を食うという可能性もあるし、システム全体が破綻するという可能性もある。思えば刑法が裁判官に対して量刑の範囲を指定し、裁判官が個別事例に応じて量刑を決定するというのはこれに通じるところがあるだろう。
Rust
このようなコードをコンパイルしようとすると
fn f() -> Vec<i32> {
vec![1,2,3,4,5]
}
fn main() {
let v1 = f().iter();
println!("{:?}", v1);
let v2 = f().into_iter();
println!("{:?}", v2);
}
v1のほうだけ失敗する。
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:6:14
|
6 | let v1 = f().iter();
| ^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
7 | println!("{:?}", v1);
| -- borrow later used here
|
help: consider consuming the `Vec<i32>` when turning it into an `Iterator`
|
6 | let v1 = f().into_iter();
| ~~~~~~~~~
help: consider using a `let` binding to create a longer lived value
|
6 ~ let binding = f();
7 ~ let v1 = binding.iter();
|
そもそも解説ページに全部書いてあるのだが、メソッドチェーンの形が解説のコード例につながるということがしばらくわからなかった(それが自明に思える人は以下読む必要ない)。
https://doc.rust-lang.org/error_codes/E0716.html
v1がやろうとしていることは、メソッドチェーンを分解するとつまりはこういうことであり
let v1 =
{
let tmp = f();
tmp.iter()
};
println!("{:?}", v1);
v1はtmpをborrowしているが、当のtmpはprintln!が実行されるころには存在していない。そもそもprintln!の場所でv1はもう使えないということだ。言われてみればRustの目玉機能である所有権の基礎of基礎なのだが、テキストで読んだ形と少しでも変わるともうわからなくなってしまっていた。やはり実践は重要だ。