20250605 津気屋『トマトつけ麺』

項目 内容 得点 換算点
睡眠時間 6時間22分 75 9.8/13.0
起床 7:36 100 8.0/8.0
散歩 実施・ゴミ拾いあり 100 5.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 ノー 0 0.0/5.0
労働 passion: 85点, discipline: 80点 83 19.9/24.0
ジム 休養日 100 12.0/12.0
勉強会 参加 100 12.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 68 6.1/9.0
総合 1日の総合評価 - 85

あまり気持ちが上がらない。余計な情報を取り入れ、余計なことを考えすぎている。よく知りよく考えることは状況によっては美徳だが、今ではない。今の僕は燃えるTypeScriptおじさんだ。Yaru(Ubuntu)。力がついてきているという実感はあって、何を読んでもあーなるほどねとなる確率が高まっている。

今日も外食の日だったのでつけ麺津気屋でトマトつけ麺なるものを食べてみた。これがかなり良かった。濃厚だし、粉チーズも効いていた。しかし一般的な魚介つけ麺とは味の方向性が全然違うので、海苔とか割りスープとかとは合わなかった。魚介の臭みを強調してしまう感じかな。美味しんぼの牡蠣とワインの回みたいな。味の組み合わせって不思議だよな。どういう研究がされてるんだろう(心理学業界では味覚・嗅覚は刺激のコントロールが極めて難しいのでやっている人がとても少ない)。

ジムは休養日。空いた時間でDota2やったら極めて不愉快な体験をしたので損した。その後は不貞寝して、起きたらもうジムがある日と同じスケジュールに合流してた。悲しいね。でも睡眠はいつだって無駄になるということはない。

寝!

20250604 松屋『旨辛豆腐牛バラ焼定食』 & okimei『シママースバニラ&タルトアイス』

項目 内容 得点 換算点
睡眠時間 6時間23分 75 9.8/13.0
起床 8:46 62 5.0/8.0
散歩 実施・ゴミ拾いなし 100 5.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 ノー 0 0.0/5.0
労働 passion: 80点, discipline: 80点 80 19.2/24.0
ジム 有酸素+筋トレ 100 12.0/12.0
勉強会 参加 100 12.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 71 6.4/9.0
総合 1日の総合評価 - 81

旨辛豆腐牛バラ焼定食、結構うまかったです。意外とすき焼き風の優しい味付け。

そしてシママースバニラ&タルトアイスはかなり良かったです。最近のokimeiシリーズね。ベースがプレーンなだけに変化としてのキャラメルとかが目立ってた。

今日のジム洗い場は水圧が若干高めでした。

いろいろなLLMを使って日本語文章生成能力を比較していたが、この分野ではGeminiが一番強い。GPT-4.5やClaude opus 4のような超高級モデルにも勝っている。箇条書きではない流暢な文章で、文末を適度にちらしたり接続詞を使ったりしてくる。日本語の学習量が多いのかな?

ちょっと睡眠が荒れ気味なのでさっさと寝よう。寝(シンッ!)。

20250603 HWLT

項目 内容 得点 換算点
睡眠時間 6時間38分 85 11.1/13.0
起床 7:37 100 8.0/8.0
散歩 実施・ゴミ拾いなし 100 5.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 ノー 0 0.0/5.0
労働 passion: 70点, discipline: 75点 73 17.5/24.0
ジム 有酸素+筋トレ 100 12.0/12.0
勉強会 参加 100 12.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 80 7.2/9.0
総合 1日の総合評価 - 85

風呂の洗い場って当たりハズレがあるじゃないですか。まあ人によっていろいろな評価基準があると思うんですけど、僕にとってはプッシュ式カランのワンプッシュで出る湯量、厳密に言えばボタンを離してから出続ける時間(Hot Water Lingering Time; HWLT)が長すぎないことが大事。短い分には長押ししていいタイミングで離すことで湯量を任意に調節できるけど、長いとそれ以下にはできないという問題がある。たらいにお湯を入れて髪のシャンプーを流すとき、右手でたらいを持って持ち上げる。そのときに(トレーニング後の腕にも)重すぎずたらいに負荷をかけない範囲内で十分な湯量があるという絶妙な調整が必要とされる。

今日使った洗い場はこれがいい具合だった。でもそもそもカランの配管部分が壊れてて水がブシューって漏れてた。日々の研究によってだいたいオキニの洗い場は決まってるんだけど、今日は冒険してみたんだ(Exploration–exploitation dilemma)。

あと今日食べたアイスは『35コーヒー&バニラ 黒糖ソース入り』だけど、コーヒーもバニラも黒糖ソースも全部大したことなくてかなり残念寄りでした。そもそもシャリシャリ系はさ…

20250602 時代

項目 内容 得点 換算点
睡眠時間 6時間40分 87 11.3/13.0
起床 7:34 100 8.0/8.0
散歩 実施・ゴミ拾いあり 100 5.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 実施 100 5.0/5.0
労働 passion: 80点, discipline: 70点 75 18.0/24.0
ジム 休養日 100 12.0/12.0
勉強会 参加 100 12.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 68 6.1/9.0
総合 1日の総合評価 - 89

TSKaigiのパワーが抜けてきている。しかし避けがたいことだ。繰り返すが30代はpassionではない。モチベや気合で何かをするのではなく、当たり前にするのだ。睡眠も浅くて中途覚醒が多いので数字ほど良くない。

このツイートを見てだいぶ悲しい気持ちになっている。そうだよなあ。なんか間違っている方向にみんなで進んでいる気がするんだけど、誰も止められないよなあ。ってね。僕も加担してるし。

時代として総括されてみたいという興味がある。僕らは歴史の授業で100年単位、下手すれば1000年単位で各時代を「こういう時代だった」と総括して学ぶ。各時代を生きた人々にとってみれば冗談じゃないという話だろうが、逆に今僕たちが生きているこの時代もいつかはそうなるのだろう。そういう視点を持ってみると、この毎日も違った見え方がするのかも、という興味がある。まあ書いてて思ったけどこれは使い古された「大きな物語」論ですよね。

会社の同期と、2人で北関東の田舎でボロ一軒家でも買って(築50年3桁万円とかいうすごいやつがそこそこある)犬と車買ってDIYして駄菓子屋でも営みながら暮らすか…なんてバカなことを語り合っていた。一度きりの人生だよ。

20250601 Imperative

今日ものんびり起きてDota2、コードリーディング、天気が回復したので布団カバーの洗濯などをしていた。論理午前中にジムで軽く有酸素し、また近所の新デパートに行ってみたが今日も激混みだったので食事は諦め、6月分の二郎枠を消費してきた。ミニ・ニンニク少なめ・アブラ少なめが丁度いい。

帰宅して、極上の昼寝。普段はロフトベッドで寝ているがたまには布団を床におろしてちゃぶ台にお茶を置いて1時間くらいゴロゴロしていた。これが贅沢というものだ。

今日もGeminiとプログラミングについて対話していた。ある処理のあとに別の処理を行うという命令を、JavaScriptでは

f1();
f2();

と書けるが、これ全然自明じゃないよね、みたいな話をしていた。SQLとか、Haskellの遅延評価とかね。JavaScriptの言語仕様の範囲内でもこれの次にこれを行えという指示は上記以外に

f2(f1());

とか

f1().f2();

とか書き方がある。これがf1, f2が非同期処理になったり失敗しうるようになったりするとそれぞれ進化していくが、やはり基本は一番上の命令形になるだろう。

ところでGeminiとずっと話していると思うのは、会話が単線的なのはポテンシャルを浪費しているのではないかということだ。一般的なAIチャットのUIは人間同士で会話するLINEのように自分の発言と相手の発言が交互に時系列的に並ぶだけのシンプルなものだ。しかし、特にAIが得意とする論理的に込み入った会話では、論点Aから生じた論点B、論点Cに対してそれぞれ別々の会話ブランチを伸ばしていきたいことがある。もちろん私は同時に1つの文章しか入力できないから並列性を上げられるわけではないが、あとから見直して話の筋がわかりやすくなる。コンピュータ上で行う会話なら、そのように進化しても良いはずだ。

冷静にこれSlackのスレッドじゃん。

20250531 チキンケバブ丼

予告通り特に予定がなく、のんびり起きてDota2とかコードリーディングとかしていた。午後はジムで全身鍛えて、その後近所に開店したデパートを視察してきた。よく行くアリオとは雰囲気が違っていて、格式が高い。そして小さい土地に階数を増やして床面積を稼いでいるので良くも悪くも密集度が高く感じた。

さすがに初日は込みすぎて食事はできそうもなかったので松屋で『チキンケバブ丼』を食べた。これはかなり良くて、肉はボリュームがあって香ばしく、ソースもかなり本格派の味だ(僕にはちょっと辛すぎるけど)。肉の量はサービス精神なのかもしれないが、少し野菜に変えてくれてもいいぞ。

洗面台の下が水漏れしていたので応急処置(たらいの設置)をして状況を調べて管理会社に連絡した。

Dota2 7.39bでDazzleの不人気の方のfacetであるNothl Boonが微妙に強化された。正直これでもPoison Bloomを選ぶ人が多いだろうからあまり勝率には変化がないだろうけど、Nothl Boonで数戦試してみると案外悪くない。Nothl Boon選択時、Dazzleのスキルを受けた味方は1回ごとにWeaveのスタックが2つ溜まり、1スタックごとにDazzleから受けるヒールが7.5%上昇する。Weaveのスタックは先に乗るので、全てのShadow Waveは回復量が確定で15%増加することになる。それより前に別のShadow WaveかGraveが入っていればスタックは更に溜まっているので、ヒーリングに特化させると相当量のバーストヒールになる。

たとえばDEMOでLv30のTinkerのHPをギリギリまで削ってからLv30Dazzle(ヒール増加タレント+Holy Rocket)でGrave→Wave→Greaves→Holy Rocket(20スタック)とやると430+676+615で1721回復させることができた。

…と思ってたんだけど別にNothl Boonじゃなくても1485回復したわ。意味ねぇ〜。一応バーストヒール入れられるとGrave後に平然と戦闘復帰できる点は強いです。

まあここまでヒーリングに特化してもなあという感じはある。GreavesとHoly Rocketって合わせて7300Gかかってるので、それならGlimmer Cape + セプター買えるじゃん。セプターは敵に囲まれているときヒールが多重で入るようになるので結局回復量を上げる効果もあるし。Greavesのセルフディスペルが重要なゲーム(Silencerとかね)なら意味あるけどねえ。

てかNothl Boonのoverhealって活用してる人いるのかな?無いよりマシだろうけど…結局Poison Touchでレーニング番長やりましょうというヒーローデザインは変わってないので、それなら普通にPoison Bloom選択で良さそう。解散です。解散。

JavaScriptのyield*は移譲先ジェネレーターがreturnした値はyieldしない

本記事は https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/yield*#%E4%BE%8Byield* 式自体の値 に例示されているものを改めて考えつつ説明したものです。

https://github.com/susisu/tskaigi2025 のコードリーディングをしていて、ここがわからなくてしばらく詰まっていた。

it("ジェネレータから yield された Promise が fulfill されたらその位置から再開する", async () => {
  function* myFunc(): Comp<number> {
    const a = yield* waitFor(Promise.resolve(1));
    const b = yield* waitFor(Promise.resolve(2));
    return a + b;
  }
  const promise = run(myFunc());
  await expect(promise).resolves.toEqual(3);
});

JavaScriptには yield* という構文がある。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/yield*

これはジェネレーターの中で使い、別のiterableに制御を移譲するために使う。とてもわかりやすい例があったので引用させてもらう。
https://stackoverflow.com/questions/17491779/delegated-yield-yield-star-yield-in-generator-functions

function* someGenerator() {
    yield 0;
    yield [1, 2, 3];
    yield* [4, 5, 6];
}

for (v of someGenerator()) {
    console.log(v);
}
// 0, [1, 2, 3], 4, 5, 6

yield [1, 2, 3];[1, 2, 3] をそのままyieldする。一方で yield* [4, 5, 6];[4, 5, 6] がiterableなオブジェクトならば、その生成値を1つずつyieldする。移譲すると書いたが、someGeneratorの呼び出し側から見ると、内側の内側にあるiterable([4, 5, 6] のこと)を透過的に扱えるとも言えそうだ。

ところでジェネレーターの中ではyieldの他にreturnも使える。returnに到達すると値を返しつつジェネレーターは終了する。

const gen = function* () {
  yield 1;
  return 2;
}()

console.log(gen.next()); // { done: false, value: 1 }
console.log(gen.next()); // { done: true, value: 2 }
console.log(gen.next()); // { done: true, value: undefined }

では yield* で移譲されたジェネレーターがreturnしたとき何が起きるのか。僕はなんとなくreturnされた値も透過的に外側から触れると思っていたが、触れない。

const g_inner = function* () {
    yield 1;
    return 2;
}();

const g_outer = function* () {
    const a = yield* g_inner;
    yield 3;
    return 4;
}()

console.log(g_outer.next()); // { done: false, value: 1 }
console.log(g_outer.next()); // { done: false, value: 3 }
console.log(g_outer.next()); // { done: true, value: 4 }

なんとなく出てくる値は 1, 2, 3, 4 になりそうな気がしたが(俺だけか?)、正解は1, 3, 4だ。MDNに

yield* は式であり、文ではありません。そのため、値に評価されます。

とサラリと書かれている通り、g_innerのreturnで返される値はg_outerのaに束縛される。それだけで、g_outerの呼び出し側には返されない。

ここで逆に考えてみる。移譲先のreturnで停止すると仮定すると、どのような問題が起きるだろうか?

まず、yieldの機能として、呼び出し側からnextに引数を与えることで、値を受け渡すことができる。

const gen = (function* () {
  const a = yield 1;
  const b = yield 2;
  return a + b;
})();

console.log(gen.next());     // { value: 1, done: false }
console.log(gen.next(10)); // { value: 2, done: false }
console.log(gen.next(20)); // { value, 30, done: true}

初回呼び出し後にyield 1;で停止しているジェネレーターに対して10を与えて再開させ、次にyield 2;で停止しているジェネレーターに20を与えて再開させている。3回目のnext呼び出しの後はreturn a+bに到達して30を返して終了する。

これは yield* で移譲された内側のジェネレーターにも機能するのだが、returnで停止すると仮定してシミュレーションしてみる。

const g_inner = function* () {
    const a = yield 1; // aに10が入る
    return 2; // ここで停止すると仮定
}();

const g_outer = function* () {
    const x = yield* g_inner;
    yield 3;
    return 4;
}()

console.log(g_outer.next());     // { done: false, value: 1 }
console.log(g_outer.next(10)); // { done: false, value: 2 } が返ると仮定する
console.log(g_outer.next(20)); // { done: false, value: 3 } このnextに渡した20はどこへ…?
console.log(g_outer.next());     // { done: true, value: 4 }

return 2で停止すると仮定すると、そのときnextに渡された値はどこに行くのだろう?xにはg_innerから返された値が入ることになっているので行き場がない。捨てるしかない。そうなると、g_outerを利用する側は中でg_innerに処理を移譲しているなんて本来知る必要がないのに、それを知らないと何回目かのnextに渡した値が勝手に捨てられてしまうことになる。インターフェースとしての安定性が失われている。

そういう意味で、returnでは停止しないのは筋が通っている。割と非直感的だと思ったんだけど、MDNだとサラッと1行説明されて例が1つあるだけで終わるので難しかった。普段からジェネレーターを使ってる人(いますか?)には自明な動作なのかもしれない。

一般のジェネレーターにおいてreturnは停止して値を返すという点でyieldと同じように見えるが、その見方は間違っているのだろう。yieldが明確に停止を意図した機能である一方で、returnは終了だから結果的に停止に見えてしまっているだけで、その本質はただ値とともに処理を返すことだけだ。yield* のようにその後も外側のジェネレーターに制御を戻して続行できるのであれば停止しないように見えるのは必然なのだろう。

20250530 褒められ欲

項目 内容 得点 換算点
睡眠時間 6時間26分 77 10.0/13.0
起床 7:19 100 8.0/8.0
散歩 実施・ゴミ拾いなし 100 5.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 ノー 0 0.0/5.0
労働 passion: 80点, discipline: 75点 78 18.7/24.0
ジム 休養日 100 12.0/12.0
勉強会 参加 100 12.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 60 5.4/9.0
総合 1日の総合評価 - 83

今週はTSKaigiのモチベバフと睡眠好調が相まってかなりモーレツ気味(当社比)で働いていたけど、金曜日はさすがに疲労を感じる。意外と体は習慣通りに動きそうなんだけど、精神力が上がりきらない。

https://github.com/susisu/tskaigi2025

これがめっちゃ難しくてClaudeに解説させながら読んでる。AI教師、対応範囲が(人間よりは)広いし能力は間違いないし時間も場所も感情も気にする必要ないし優しいのでかなりすごい。AIに褒められて褒められ欲(結構ある)の充足を感じるけどこれでいいのかなあと疑問。でも確実に僕の役に立っているしなんなら僕を賢くしている。

明日は久々の完全オフ。ジム以外特にすることなさそうなのでのんびり布団でも干すかな。うまいものも食いたい。食いに行きたい。休養だけでなくリフレッシュの気持ちになっているのもモーレツの反動かもしれない。

20250529 『モナ王』/sort-package-json3.2.0でソートアルゴリズムが変わったっぽい

項目 内容 得点 換算点
睡眠時間 7時間19分 100 13.0/13.0
起床 8:08 93 7.4/8.0
散歩 実施・ゴミ拾いあり 100 5.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 実施 100 5.0/5.0
労働 passion: 85点, discipline: 75点 80 19.2/24.0
ジム 有酸素 100 12.0/12.0
勉強会 参加 100 12.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 80 7.2/9.0
総合 1日の総合評価 - 93

今日の仕事は並列度が高くてあまり集中できなかったな。

『モナ王』

『モナ王』を食べた。『チョコモナカジャンボ』の隣に並んでいたらまず選ばない商品だが、だからこそ食べておくかということで食べた。結論から言うと特に選ぶ理由はない。チョコの風味が要らない、パリパリが要らない、そんなムーディーな気分の日ならいいかもしれない。

sort-package-json3.2.0でソートアルゴリズムが変わったっぽい

sort-package-jsonというライブラリがある。その名の通りpackage.jsonをソートすることで秩序をもたらすツールである。最近npmのソートアルゴリズムに合わせるということで変更が入ったのだが

https://github.com/keithamus/sort-package-json/pull/358

これがyarnのソートアルゴリズムとは違っており、しかも間の悪いことにyarnは yarn install を実行するたびにpackage.jsonをソートし直すので、sort-package-jsonとの共存が実質的に不可能である(開発中に yarn install をするたびに意味のない差分が発生し、commitするときにlint-stagedで消える)。じゃあsort-package-jsonの代わりに yarn install を使えばいいのでは?とも思うが、コマンドの意味・副作用からしてかなり正しくない度が高い解決だ。苦しい。

https://github.com/keithamus/sort-package-json/issues/363

ソートアルゴリズムの違いというのはどうやらこういう違いのようだ。

https://github.com/keithamus/sort-package-json/issues/355#issuecomment-2848325132

// yarn
> ["a", "b", "A", "B"].sort()
[ 'A', 'B', 'a', 'b' ]
// npm, sort-package-json
> ["a", "b", "A", "B"].sort((a,b) => a.localeCompare(b, "en"))
[ 'a', 'A', 'b', 'B' ]

実はnpmではパッケージ名に大文字を使ってはいけない。昔は使えたのかも知れないが、今は大文字名でinstallしようとすると404で弾かれる。だからこの問題は内製パッケージを使っていたりエイリアスを付けていたりしないと表面化しにくい(一応 -_ とかでも差が出てしまうらしい?)。

まあそこまで重大な違いではないように思えるが、sort-package-jsonは結構な人気があるパッケージなので、そこそこ困っている人がいるかもしれない。

20250528 一生は長いが一日は短い

項目 内容 得点 換算点
睡眠時間 6時間53分 95 12.3/13.0
起床 7:37 100 8.0/8.0
散歩 実施・ゴミ拾いなし 100 5.0/5.0
朝食の栄養カバレッジ 3色カバー 100 5.0/5.0
体操 実施 100 5.0/5.0
労働 passion: 90点, discipline: 85点 88 21.1/24.0
ジム 有酸素+筋トレ 100 12.0/12.0
勉強会 参加 100 12.0/12.0
個人開発 実施 100 7.0/7.0
あすけん - 65 5.8/9.0
総合 1日の総合評価 - 93

今日もかなり良い。やはり睡眠が基本だ。朝は散歩しながらプログラミングのフローについて考えていた。TypeScriptを第一言語とする僕にとっては、関数の連続は

const a = f1();
const b = f2(a);
const c = f3(b);

のように書かれた方がわかりやすい。

const c = f3(f2(f1()));

は厳しい。上から下に流れること、得た値を束縛すること。この2点がだいぶ馴染みがある感に寄与している。手続き的と宣言的と言ってもいいのかもしれない。あるいはメソッドを生やしてやって

const c = f1().then(f2).then(f3);

という考え方もあるかもしれない。同じプログラムの流れであっても、それがどこに表現あるいは隠蔽されているのかというのがいろいろ違うよねという話。そして流れの理解が重要なプログラムを書くときに、流れを隠蔽するような記法を使って良いのか?

これがまあ f3(a, b) になったりPromiseになったりResultになったりするとどんどんゴチャってきて、その場合どれがベストなのか…!という話になる。言語がデザインする書き方もあるし、個人・チームの慣れ・志向もある。

人生が長いか短いかはまだわからない(どちらかと言えば長い寄りの感覚でいる)が、一日は間違いなく短いということを最近感じる。ちゃんと寝て、起きて働いてやるべきことやって、その上で遊びの時間も取るというのは、かなりのテクと意思が必要だ。31歳なのでね。幸いやりたいことが減ってくれて、集中できる。