どうも、マイクです。おはようございます。
九月二十九日、火曜日の朝七時を回りました。ここからの時間は「zenncast」、きょうもZennで話題になっているトレンド記事を、ゆるっと楽しくご紹介していきます。
きょうは全部で、五本の記事をピックアップしてきました。技術寄りなんですけど、どれも実務とか日々の開発に直結する内容なので、「へえ〜」っていう発見があると思いますよ。
それじゃあ、さっそくきょう紹介する内容、いってみましょう。まず一つ目。
最近かなり話題になっている、VS Code 用の拡張機能「Claude Code」。
これの「更新頻度がめちゃくちゃ高い問題」を、ちゃんとデータから分析して、その対処法までまとめてくれている記事です。
ポイントはですね、Claude Code が「だいたい一日一本ペース」でアップデートされているんですけど、そのすべてが **安定版チャンネルとして**リリースされている、というところなんですね。
つまりユーザー側から見ると、「試験的バージョン」とか「先行リリース」じゃなくて、いつも「安定版です!」って顔をして、最新で変化の激しい版がどんどん乗ってくる構造になっていると。
で、他の人気拡張機能だとどうしているかというと、更新自体は多くても、pre-release、いわゆる試験的版の方に流しておいて、普通のユーザーに届く stable、安定版の更新はかなり抑えめにする、っていう運用がけっこう多いんですよね。
なので Claude Code の運用は、そこから見るとかなり攻めた設計になっている、と。
一方で、同じ Claude でも、Anthropic が出している CLI 版、コマンドラインツールの方は「latest」と「stable」の二系統が用意されていて、ユーザーが「すぐ試してみる」か「一週間ぐらい寝かせた落ち着いた版を使うか」、ここを選べるようになっています。
なのに VS Code 拡張機能側には、同じようなリリースチャンネルの仕組みが無い。ここがいまの問題点だろう、と記事では指摘しています。
じゃあユーザーとしては、どう対策すればいいのか。
記事で提案されているのは、VS Code 側の設定で、まず `extensions.autoUpdateDelay`、拡張機能の自動更新までの待ち時間ですね。これを二十四時間から七十二時間くらいにして、更新が降ってくる頻度を落とす、というやり方。
あるいは、特定の拡張機能だけ、自動更新のチェックを外してしまう。もっと割り切るなら、拡張機能全体の更新チェック自体を止めてしまう、という選択肢も紹介されています。
筆者としては、「更新が多いこと自体」は、バグ修正が早いとか、新機能がどんどん出てくる、そういうポジティブな面もあるから、一概に悪いとは言えない。
ただし、CLI には「落ち着いた stable を使う」という選択肢があるのに、VS Code 拡張機能には同じ選択肢が用意されていない。そこがいまいちバランス悪いよね、という話なんですね。
将来的にもし、VS Code 拡張にも「stable」と「latest」といったリリースチャンネルが用意されれば、わざわざ VS Code の設定を工夫したり、毎日のように再起動を迫られて「またか〜」ってなるストレスも減るはずだ、と。
そうなれば、頻繁なアップデートの恩恵は受けつつも、安心して落ち着いて使えるようになるよね、という希望も込めて締めくくられています。開発スピードとユーザー体験のバランス、むずかしいところですよね。
。。。。
二つ目は、Cシャープの `CancellationToken` をテーマにした記事です。
キャンセル処理って、非同期プログラミングやってると必ず出てくるんですが、ここで一回「キャンセル要求」「待機の終了」「処理や後始末の完了」って、実はそれぞれ別物なんだよ、って整理してくれている内容になっています。
登場人物としては `CancellationTokenSource` と `CancellationToken` の二つですね。
`CancellationTokenSource` がキャンセルを「発行する側」、キャンセルボタンみたいな役割で、一方で `CancellationToken` は「キャンセル要求が出たかどうか」を周りのコードに伝えるだけの存在です。
重要なのは、**どこで実際に処理を止めるかは、Token を受け取った側のコード次第ですよ**、ってところ。トークンそのものが、強制的に処理を止めてくれるわけじゃないんですね。
記事では、`WaitAsync` や `Register` といった API の内部で何が起きているかにも軽く触れています。
たとえば、ある待機処理をキャンセルしたとしても、「待つのをやめる」だけで、もともとの Task はそのまま進んでいく可能性がある。ここを勘違いしがちなんですが、「待っている側」と「仕事本体」は必ずしも同じじゃない、という視点をくれる記事になっています。
それから、`CancellationToken` は値型で、キャンセルの「権限」は持っていない、という設計もポイントです。`Cancel` できるのはあくまで `CancellationTokenSource` だけ。
これによって、キャンセルを発行できる範囲をきちんと制限して、「どこが止めていいのか」を明確にしているわけですね。
面白いのは、ここから他の言語との比較に話が広がっていくところです。
Python の `asyncio.wait_for`、Go の `Context`、それから Rust と Tokio の `timeout`、こういった機能と見比べて、
・タイムアウトやキャンセルが、「仕事本体」にまで影響するのか
・「仕事は続けたいけど、待つのだけやめたい」っていうとき、どういう書き方になるのか
このあたりを例に出しながら整理しています。
そのうえで、Cシャープと .NET のやり方は、「協調的キャンセル」と呼ばれるスタイルになっていて、フレームワーク側が無理やり止めるんじゃなくて、アプリケーション側がトークンを見ながら「そろそろやめるね」と協力してくれる前提で設計されている、と。
この設計思想が、他言語のタイムアウト機構とどう違っているか、というのが浮かび上がってくる記事になっています。非同期まわりがモヤっとしている人には、かなり腑に落ちる内容だと思います。
。。。。
三つ目は、いろんなプログラミング言語を横断しながら、「型がどこまで振る舞いを持つべきか?」っていう、ちょっと哲学寄りの設計の話を掘り下げている記事です。
対象になっているのは、C や Cプラスプラス、Cシャープ、Java、Go、Rust、TypeScript などなど。幅広いですね。
Rust や Go みたいな、「型」と「振る舞い」を分離しておいて、コンパイル時に単相化する仕組みと、Cシャープのように「型そのものがメソッドを持つ」オブジェクト指向寄りの仕組み。
この記事では、見た目や用語は違っても、「実際にやっていることとしてはかなり似ているんだよ」という説明をしています。
つまり、違いは「どういう抽象の見せ方を選んでいるか」とか、「どんな言葉で呼んでいるか」に近くて、本質的にはそこまで別世界の話じゃない、と。
そのうえで、最近のトレンドとして、AI が生成するコードとか、Rust/Go 的な「関数をどんどんつないでいく」スタイルに引っ張られると、
**なんでもかんでも「ただの関数呼び出しの連続」に押しつぶされてしまって、型という抽象概念の設計や、責務の分担が軽く見られがちだよね**、という問題提起をしています。
DDD、ドメイン駆動設計とか、SOLID原則みたいな有名なキーワードがありますけど、ああいったものだけだと、「型レベルでどんな責務を持たせるのか」という、もう一段細かい戦術的な設計指針が足りないんじゃないか、と。
その結果として、せっかく列挙型で意味を表現していたのに、すぐに bool やただの素の型に潰してしまったりして、抽象を壊したコードになりがちだ、という嘆きも書かれています。
筆者が大事だと言っているのは、最終的にマシンが見るのは「関数の連鎖」かもしれないけど、人間がレビューして、意味を読み取る側からすると、「きちんと意味を持った抽象」があることがすごく重要だ、という点です。
つまり、ある型に紐づいた振る舞いや責務がちゃんと整理されていると、「このコードは何を表しているのか」が保たれる。ここをおろそかにして、「とりあえず動けばいいや」になってしまうと、長い目で見てツラいコードベースになるよね、と。
なので、**実装が形式的に正しいかどうかよりも、まずはセマンティクス、コードが表す意味を守る設計が優先されるべきだ**、と締めくくっています。
AI コード補完全盛のいまだからこそ、あえて「型の意味」をちゃんと考えようよ、というメッセージでもありますね。
。。。。
四つ目は、ちょっと趣きが変わって、Microsoft 365 界隈の Tips 記事です。
テーマは「Work IQ」というサービス。聞き慣れない方もいるかもしれませんが、これは Teams や Outlook など、Microsoft 365 上にたまっている自分のメール、会議、チャットの履歴を読み取って、
**「あなた、これフォローし忘れてますよ」とか「このタスク、まだ完了してないですよ」って教えてくれる、個人向けの業務記録エンジン**みたいな位置づけの機能なんですね。
もともとは Microsoft Copilot の裏側で、ひっそり自動的に使われている存在なんですけど、実は API 経由で明示的に呼び出すこともできます。
この記事では、その API をどうやって叩くか、という実務寄りの話がまとまっています。
Work IQ は、AツーA、MCP、それから通常の REST API としても提供されていて、たとえば Cシャープのコンソールアプリなんかから `https://workiq.svc.cloud.microsoft/mcp` にアクセスして、
`tools/list`、`ask`、`fetch` といったメソッドを JSON-RPC 形式で呼び出すことで、自分の「直近七日分の作業ログ」から、未完了のタスク一覧を取ってくる、みたいな処理が実現できるようになっています。
実際の企業環境だと、けっこうな確率で「Azure 用のテナント」と「Microsoft 365 用のテナント」が分かれているんですよね。
この記事では、その前提に立って、「M三六五側の Entra ID」、旧 Azure AD ですね、そこで Service Principal、つまりアプリの代表ユーザーを作って、その情報を他のクラウドやオンプレミス側に持ち込む構成を想定しています。
そうすることで、外側のシステムからでも Work IQ を呼び出せる、という設計です。
使い始める前の大きなポイントが、課金まわりの設定です。
Microsoft 365 Admin Center の「Copilot > Cost management」というところで、usage-based billing、使った分だけ課金するモードを有効化して、M三六五テナント配下の Azure サブスクリプションをひも付けておく必要があります。
これをやっていないと、`caller tenant billing policy not configured for WorkIQ` というエラーが出てしまって、`ask` や `fetch` だけが失敗する、という罠があるんですね。ここは事前準備が大事です。
Entra ID 側での手順も具体的に書かれていて、まずは Work IQ 本体の Service Principal を、`az ad sp create --id fdcc1f02-fc51-4226-8753-f668596af7f7` という形で作成します。
そのうえで、自分のアプリ用の、シングルテナントな App Registration を用意して、リダイレクト URI に `http://localhost` を設定。
さらに Work IQ API の delegated permission、`WorkIQAgent.Ask` を追加して、管理者承認を与えておくことで、ユーザーがサインインしてトークンを取得しつつ、Work IQ を安全に呼び出せるようになります。
要するに、「自分のメール・会議・チャットを、API 経由でちゃんと振り返る仕組みを整えると、かなり賢いタスク管理ができるよ」という話なんですが、その裏にあるテナント構成と課金設定、権限まわりの現実を、きちんと踏まえた解説になっています。実運用でハマりそうなポイントが一通り押さえられている印象ですね。
。。。。
そして、きょうのラスト、五つ目の記事です。
テーマは Go 一点二八で予定されている、`string(int)` の仕様変更について。オピニオンも交えながら、この変更がどういう意味を持つのか解説している記事です。
いまの Go だと、`string(六十五)`みたいに整数から直接文字列に変換しようとすると、「六十五」という文字列になるわけじゃなくて、その整数を Unicode のコードポイントとして解釈して、「A」が出てきたりするんですね。
この挙動が、**直感に反しているうえに、一貫性もあまり無いのでは**、という問題意識があります。
とくに厄介なのが、サロゲート領域の値を扱うときで、同じ値でも書き方によって、コンパイルが通るかどうか、あるいは実行結果がどうなるかが変わってしまう、というケースがあると。
こういうところが、初心者だけじゃなくて経験者でも誤解やバグのもとになりがちだ、という指摘です。
そこで出てきた新しい Proposal、仕様変更の案では、「整数から文字列への変換」をかなり絞り込もう、という動きになっています。
具体的には、`rune` と `byte`、それからその基底型が `rune` や `byte` になっている型、そして `'A'` みたいな rune リテラル。このあたりからの変換だけを許可する方向です。
逆に言うと、ただの `int` のリテラルとか、`int` 型の変数から、いきなり `string(...)` で文字列にするのはエラーになる、というルールに変わります。
じゃあ、「数値の六十五を、そのまま“六十五”という文字列にしたいときはどうするの?」という話なんですが、そこはもうはっきり割り切って、`strconv.Itoa` や `strconv.FormatInt` といった、専用の変換関数を使いましょう、という方針です。
これによって、「コードポイントとして扱いたいのか」「数値として文字列化したいのか」が、コード上も明確に分かれるようになります。
もちろん、互換性の問題も出てきますよね。そこで Go チームとしては、モジュールごとの `go.mod` に書いてある `go` バージョンを見て、挙動を切り替える、という案を取っています。
つまり、古いバージョンをターゲットにしているモジュールでは、従来通りの動きが維持されるようにして、既存コードがいきなり全部ビルドエラーになる、みたいなショックを和らげているわけですね。
筆者としては、この変更によって、「これってどういうつもりのコードなんだろう?」という誤解を減らせるし、変なバグも防ぎやすくなるので、
**Go のコードがより読みやすくて安全な方向に進む変更だ**、と、わりとポジティブに評価しています。
型変換のルールをちょっと厳しめにすることで、「意味のはっきりしたコードを書いていこう」というメッセージにもなっているのかな、という印象ですね。
。。。。
ということで、きょうの「zenncast」は、全部で五本の記事をご紹介してきました。
ざっとおさらいすると、
まずは VS Code の「Claude Code」が、ほぼ毎日安定版として更新されていて、ユーザーが常に最新の版を踏まされている現状と、その対処法の話。
つぎに、Cシャープの `CancellationToken` を入り口に、「キャンセル要求」「待機の終了」「処理の完了」をきちんと分けて考える、協調的キャンセルの設計思想の話。
三つ目は、複数言語をまたぎながら、「型にどこまで振る舞いと責務を持たせるか」、セマンティクスを守る設計の大切さを語った記事。
四つ目は、Work IQ を API 経由で呼び出して、メールや会議から自動的に未完了タスクを拾い上げる、そのためのテナント構成や課金設定、権限の実務的な Tips。
そして最後は、Go 一点二八での `string(int)` 仕様変更をめぐって、「直感に反した変換をやめて、明示的な変換に寄せていこう」という話でした。
それぞれ、もっと細かい手順やコード例、背景の議論なんかは、ショーノートに元の記事への情報をまとめておきますので、気になったトピックがあれば、ぜひそちらもチェックしてみてください。
「zenncast」では、番組の感想や、「こんなテーマを扱ってほしい」みたいなリクエストも、いつでもお待ちしています。
普段どんなふうに記事を活用しているか、こんなところが助かった、ここはよく分からなかった、などなど、率直な声を送ってもらえると、今後の構成の参考になります。
それでは、きょうはこのへんでお別れです。
お相手はマイクでした。また次回の「zenncast」でお会いしましょう。
きょうも良い一日をお過ごしください。