ディスカッション (11件)
Statecharts(ステートチャート)は、階層構造を持つステートマシン(有限オートマトン)の一種です。従来の複雑な条件分岐の山を整理し、UIの状態管理を予測可能かつ堅牢にするための非常に強力な手法です。単なるステートマシンを超え、入れ子構造や並行状態を表現できるため、複雑なフロントエンドアプリケーションの設計において、バグを未然に防ぐ「正解」といえるアーキテクチャパターンです。
昔からステートマシンが好きで、もっと普及してほしいと願っている。AIが生成したコードは人間が書いたコードほど理解しづらいから、状態を視覚的に把握する重要性はますます高まっている。フロントエンドフレームワークでは、依然としてストアベースのリアクティビティが好まれているみたいだ。みんなそれがデフォルトだから変える理由がない、それにXStateのようなライブラリは文法を覚えるのが難しくて記述も冗長になりがち、という意見は理解できる。でもAIがあればその問題はほぼ解消されるし、何か自分が見落としているもっと深い理由があるのか、それとも単にステートチャートがまだピークに達していないだけなのか気になるところだ。
2時間経ってもまだコメントゼロかよ!?一時期、ステートチャートはフロントエンドやUIのエコシステムで少しだけ注目を集めていた気がする。UIインタラクションにステートマシン(特に、ステートマシンを組み合わせたステートチャート)を活用すると、複雑なフローの推論が圧倒的に楽になるのに!悲しいことに、理由は不明だけど結局流行らなかったみたいだ。もしステートチャートを初めて知ったなら、Ian Horrocksの『Constructing the user interface with statecharts』(1999年)を強くおすすめする。古いけど、ステートチャートをどう実践的に適用し活用するかを知るには最高の入門書だよ。
ステートチャートがまだ注目されているのを見られて嬉しい!私はステートマシンやステートチャートを構築・実行・可視化するJS/TSライブラリ「XState」の開発者だよ。もう10年以上取り組んでいるけれど、一番学んだのは、ステートチャートは単なるドキュメントではなく「実行可能な振る舞い」として扱うときにこそ最も価値があるということ。だからといって、何でもかんでもステートチャートでモデル化すればいいわけじゃない。「次はどうなる?」という問いの答えが、現在の状態とイベントの両方に依存するような振る舞いがあるときに特に役立つ。ステートチャートは「この状態でこのイベントが起きたとき、次の状態は何で、どんなエフェクトを実行すべきか?」という問いに対するオラクル(預言者)として機能するんだ。近々、人間工学的な改善や型安全性、コンポーザビリティを重視し、新しいビジュアライザーも搭載したXStateの次期メジャーバージョンのアルファ版をリリースする予定。オープンソースの基本ビジュアライザーもあるよ(https://sketch.stately.ai )。フォーマルな仕様面ではW3CのSCXMLや、David Harelの原論文も一読の価値あり。
タイトルには「階層的(hierarchical)」とあるのに、本文にはその記述がないね。階層構造がないと、ステートチャートはすぐに手に負えないほど巨大化しちゃうから、そこは必須だと思う。
ステートチャートをTemporalやDBOS、Restateといった「Durable Execution(永続的実行)」エンジンと組み合わせることは可能なんだろうか。仕事ではオンボーディングや決済ワークフローの管理にCloudflare Workflowsを使っている。フローチャート図が生成されるからワークフローの動きを素早く把握するのに役立っているんだけど、これって結局ステートチャートが目指しているものと同じな気がする。
ちょっと追記させて。ETL向けのステートチャート(https://www.etlcpp.com/state_chart.html )やQuantum Leaps(https://www.state-machine.com )もいいよね。自分は主に安全性重視のシステムで使っているけど、複雑さやタイミング、振る舞いを効果的に検証できる能力が求められる現場では特に重要だよ。意思決定とアクションを分離できるのは本当に助かる。「この状態でこのイベントが起きたら何をするか」という意思決定を切り出すのは、一般的なプログラムの構造とはちょっと違うけれど、分離がしやすくなるし、異なる条件下での振る舞いを推論しやすくなるのは間違いない。
まあ、これは自動車業界ではかなり前から使われている手法だよ。Matlab/Simulinkを見てみて。アルゴリズムをステートマシンとして描いて、そこからコードを生成できる。最近、CSSトランジションを伴う複雑なReactコンポーネントの状態管理にステートマシンを実装してみたけど、そこまで難しいものじゃない。ただ、みんながこれにあまり慣れていないだけなんだと思う。
入門書でよく飛ばされる点がある。履歴疑似状態(H, H*)を使うと、外部からはステートチャートが形式的に非決定的になることだ。「現在の状態は入力の純粋関数である」というのがセールスポイントなのに、履歴はそれを破壊する。H経由で親に再入すると、前回アクティブだった子状態に戻るから、同じ外側の状態から同じイベントが来ても、内部の異なる2つの状態に到達しうる。この潜在的な「前回アクティブだった子状態」というのは、図には描かれない隠れた「状態」そのものなんだ。Harelの原論文では認められているし、SCXMLもXStateも実装しているけど、誰もこれについてあまり話さない。再入時にサブツリーの状態を保持するためにディープヒストリー(H*)を使っているなら、それは状態の管理をチャートエンジンに押し付けているということ。それはそれでいいけど、図だけでは全貌を把握できなくなるし、履歴遷移も他の状態と同じようにテストが必要になるね。
金融ネットワークプロジェクト(https://github.com/xlnfinance/xln )をやっていたとき、現実のネットワークを決定論的にエミュレートする方法が必要だという問題にぶつかった。そこで、あらゆるブロックチェーンは単なる「レプリケートされたステートマシン」だと気づいたんだ。だから、各ユーザーノードを「Runtime -> Entity -> Account」という3階層のステートマシンにカプセル化してみた。外側のマシンが内側を完全に制御する形だね。異なるコンセンサスモードを持つ「ブロックチェーンの中のブロックチェーン」みたいなもの。そのあと「階層型ステートマシン」で検索してステートチャートを見つけた。この2つのアイデアはかなり似ていると思う。非決定性という最悪のバグに対処するために、もっと多くのソフトウェアでステートマシンの階層構造を使うべきだと個人的には思うよ。
ステートチャートの階層機能は素晴らしいね。いくつか質問がある。1. ロボット開発でC/C++を使っているんだけど、検索で出てくるようなトランスパイラを使うべき?それとも別の選択肢がある? 2. Tinyfsm(https://digint.ch/tinyfsm/ )を見つけたんだけど、これについて何か意見はあるかな?