自由に動くとは、勝手に動かすことではない

John Smith

Hatched by John Smith

Apr 25, 2026

1 min read

58%

0

画面の中で起きていることは、思ったより似ている

私たちはしばしば、プログラミングの自由を「何でもできること」だと勘違いする。CPUで好きにロジックを書けるなら自由、GPUを使えればさらに自由、UIがスクロールに追従すれば体験も自由、そんなふうに考えがちだ。だが実際には、自由なシステムほど、むしろ制約を正しく受け入れている

ここに不思議な共通点がある。GPUはCPUより強力だが、素朴には扱えない。画面のスクロールに追従するAppBarも、見た目は「勝手に動いている」ようでいて、内部ではスクロールという外部の秩序に厳密に従っている。どちらも本質は同じだ。自由に見える振る舞いを、外部のイベントや制約に同期させる技術なのである。

この視点に立つと、GPUプログラミングとスクロール追従UIは、単なる別分野ではない。どちらも「高性能な装置を、人間が理解できる形で制御する」ための設計問題だ。しかもその答えは、命令を増やすことではなく、むしろ抽象化の粒度をそろえることにある。


本当に難しいのは、速く動かすことではなく、意図を壊さずに委譲すること

CPUは汎用的だ。必要なら逐次的に考え、条件分岐し、複雑な状態遷移をそのまま表現できる。だがGPUは違う。GPUは大量の並列処理を得意とする代わりに、細かな逐次制御には向いていない。そこで必要になるのは、処理をGPU向けに翻訳することだ。単に速くするのではなく、何をGPUに任せるべきかを見極める必要がある。

この委譲の難しさは、UIにもそのまま現れる。たとえば WebView のスクロールに追従する AppBar を考えてみよう。ユーザーはただページを上下に動かしているだけなのに、ヘッダーは縮んだり、隠れたり、固定されたりする。ここで重要なのは、AppBar が「自分で動く」ことではない。スクロールという単一の物理法則に従って、振る舞いを変えていることだ。

この構造は非常に似ている。GPU も AppBar も、外部から与えられる流れに乗って自分の状態を変える。入力を受け、状態を更新し、出力を返す。ただし、その入力の性質が違う。GPU は膨大なデータ並列性を受け取る装置であり、AppBar はユーザーの連続的なジェスチャーを受け取る装置だ。どちらにも共通するのは、制御の中心を「こちらが全てを決める」から「相手のリズムに合わせる」へ移すことにある。

優れた設計とは、自由を増やすことではない。制約を正しく受け止められるように、自由の置き場所を変えることだ。

この一文が、GPUとUIをつなぐ鍵になる。GPUに自由を与えるとは、好き勝手に命令を送りつけることではなく、並列性という制約を活かせる形に問題を変換することだ。AppBar に追従性を与えるとは、毎フレーム独立に計算することではなく、スクロールという自然な入力を状態変化の基準にすることだ。どちらも、力任せではなく構造化された従属によって成立している。


Haskellらしさが示すものは、GPUの扱い方だけではない

ここで面白いのは、GPUを扱うときに「Haskellらしいやりかた」が欲しくなる点だ。これは単なる好みではない。低レベルな API を、そのまま低レベルな心構えで使うと、コードはすぐに破綻する。Vulkan のような API は強力だが、同時に、状態管理やリソースの寿命、同期、バッファの整合性を、開発者に鋭く突きつける。

Haskell 的な発想は、ここで別の価値を持つ。副作用を明示し、状態の流れを見える化し、合成可能な単位に分ける。これが GPU のような複雑な装置に向いているのは偶然ではない。GPU の難しさは、演算そのものより、副作用の境界をどこに置くかが難しいことにあるからだ。

この問題は UI の追従実装にも潜んでいる。スクロールに応じて AppBar を動かすとき、本当に難しいのはアニメーションではない。難しいのは、どの状態をフレーム間で保持し、どの状態をスクロール位置から再計算し、どの状態をフレームごとに捨てるかを決めることだ。状態を持ちすぎると破綻する。状態を持たなすぎると、滑らかな追従ができない。

つまり、Haskell らしさと UI の滑らかさは、同じ原理を別角度から表している。どちらも状態を増やすのでなく、状態の責任分界を明確にすることを求める。Vulkan の複雑さを Haskell 的に包むときも、AppBar の追従を Flutter の Sliver として扱うときも、やっているのは「複雑さを消す」ことではない。複雑さの所在をはっきりさせ、触るべき場所だけを小さく保つことだ。

ここで重要な洞察がある。高度なシステムにおいては、自由度はしばしば「全部を直接いじれること」ではない。むしろ、高次の意図だけを記述し、低次の実現は仕組みに任せられることが自由なのである。

たとえば、GPU に対しては「この大量のデータをこう処理せよ」と言いたいのであって、「このワープをこうスケジュールし、このメモリをこう同期せよ」と毎回言いたいわけではない。AppBar に対しても、「スクロールに応じて隠れたり戻ったりしてほしい」と言いたいのであって、「何ピクセル動いたら何ミリ秒で何 % アニメーションするか」を毎回手書きしたいわけではない。

真に洗練された抽象化は、低レベルの現実を消し去らない。その代わり、人間が考えるべき単位を上に持ち上げる


追従する UI は、実は GPU 的な問題でもある

ここで少し視点をずらしてみよう。スクロール追従の AppBar は、単なる UI の美学ではない。あれは実質的に、連続入力に対するリアルタイムな状態機械だ。スクロール位置というストリームを受け取り、ヘッダーの表示状態を更新し続ける。これは、ある意味で小さな並列システムと言ってよい。

なぜなら、ユーザーの操作は止まらないからだ。入力が来るたびに全体を再構築していたら、体験はぎこちなくなる。だからシステムは、入力の変化だけを拾い、見た目の変化だけを最小限に再計算する。GPU が得意とするのもまさにこれだ。大きな全体を毎回人間の手で組み直すのではなく、変化した部分だけを高速に処理する

この共通点は、UI と GPU を「速いもの」として見るのではなく、「ストリームを扱うもの」として見ると見えてくる。GPU の入力は頂点、ピクセル、行列、テクスチャといった大量データであり、UI の入力はスクロール、タップ、ドラッグといった連続イベントだ。両者に必要なのは、イベントをそのまま処理することではなく、イベントから安定した状態を抽出することだ。

ここに一つの実践的なフレームワークがある。

  1. 入力を流れとして捉える 何が高速に変化し、何が遅くしか変わらないのかを分ける。
  2. 状態を最小化する 毎回持ち歩くべき情報だけを残し、再計算できるものは捨てる。
  3. 境界を明示する GPU なら同期点、UI ならスクロール状態の受け渡しを曖昧にしない。
  4. 高次の意図に寄せる 「どう動くか」ではなく「どう見え、どう感じるか」を先に定義する。

このフレームワークは、Vulkan のような低レベル API にも、Flutter の Sliver 系の抽象化にも有効だ。なぜなら、両者は違うようでいて、結局は同じ問いに答えているからだ。変化の激しい世界で、どこまでを自動化し、どこからを人間の責任にするか


Key Takeaways

  • 自由とは、全部を直接制御することではない。 制約を味方にし、意図だけを表現できることが本当の自由。
  • GPU も追従 UI も、外部の流れに同期する設計問題として見ると、共通原理が見える。
  • 複雑さは消せないが、置き場所は変えられる。 状態、副作用、同期の責任分界を明確にする。
  • 高性能化の本質は、速くすることより、変化した部分だけを扱うこと。 ストリーム思考が重要。
  • 抽象化の良し悪しは、低レベルを隠すかではなく、人間の思考単位を引き上げるかで決まる。

まとめ: 自由に動かすとは、制約に美しく従わせること

GPU を自由に動かしたい、スクロールに追従する UI を作りたい。その欲望の根っこは同じだ。人間は、複雑で速い現実を、手で全部追いかけるのではなく、意味のある単位で扱いたいのである。だからこそ、優れた設計は「制約をなくす」方向には進まない。むしろ、制約を前提にして、その上でもっとも自然に振る舞う形を探す。

本当に強いシステムは、何でもできるシステムではない。何ができないかを理解したうえで、できることを驚くほど滑らかに見せるシステムだ。GPU も、追従する AppBar も、その美しさは同じ場所から来ている。自由とは、制約から逃げることではなく、制約に最もよく適応したときに生まれる感覚なのだ。

Sources

← Back to Library

Hatch New Ideas with Glasp AI 🐣

Glasp AI allows you to hatch new ideas based on your curated content. Let's curate and create with Glasp AI :)

Start Hatching 🐣