Rustでのエラーハンドリング

34日連続で雨だったそうで、そりゃー今年は涼しかったわけですね。その分千葉のあたりは大変なことになっておりますが。 Rustで真面目にWeb APIを作っていると、とても悩ましいのがエラーハンドリングだと思います。ちょっとやってみた内容を紹介します。 Result or panic これについては、Javaとか他の言語のノリでpanicすると大変なことになるので、まず 原則panic禁止 くらいでいいかと思います。CLIならpanicしたほうがいいケースも多いと思いますが、Web APIでやったら多分ぶっ殺されます。 panic自体はhandlerがあったりはしますが、それに頼ったところでrewindとかそういったものもないので、SpringBootとかの黒魔術に慣れた人は、わりと気をつける必要があります(自分)。 anyhow/eyreで潰す or 潰さない エラーハンドリングを語るときに外せない eyreまたは anyhow がまず出てくると思います。これは Box<dyn std::error::Error + Sync + Send + 'static> あたりを都度定義する・・・というところに対するカウンターだと理解してます。 これが効果を発揮するのは、 とりあえずResultにするけど、エラー定義がめんどくせぇ ってときだと思います。基本的に eyre! などで潰すことで、なんでも放り込めるエラーを作れます。これはプロトタイピングとか、 APIのトップレベル みたいな、もうハンドリングする必要がないところでは役立ちます。 が、これはTraitでは使えません。というか使うと困るのは多分自分です :angel: pub trait Hoge { // うーん、失敗するんだろうけどどう失敗するかわかんないな。とりあえず潰しとこう fn foobar() -> eyre::Result<Huga>; } fn main() { let foo = Foo::new(); foo.foobar().map_err(|e| { match e { // さて・・・?あれ、区別できないぞ } }) } traitはinterfaceというか操作の契約=contractを表すので、エラーになるのであれば、きちんと定義しておくのがベターであるとは思います。今のところはこのように整理しました。 Trait境界ではeyre/anyhowを 使わない eyre/anyhowはmainとかでは使ってよし どうせpanicするレベルなので DDDとかでドメイン層がある場合は・・・後述 みんなの味方、thiserror thiserror は、おそらくエラーを定義する際にはほぼ必携のcrateです。手で書くとひっじょーにめんどくさいError traitの実装を肩代わりしてくれるのとともに、color_eyreを利用したときに役立つsource chainのハンドリングもしてくれます。 ...

October 3, 2026 · derui

Flutterを触り始めてみた

今年の夏は、記憶の感じではこの10年くらいで一番涼しい夏だったんではないでしょうか。35℃行く日が少ないだけで涼しいってのもどうなんだ?と冷静に思いますけども。 今まで触ってこなかったものの一つにAndroidというかスマホアプリがあるのですが、ちょうど節目を迎えたことと、ちょうどいい題材を見つけたのでチャレンジしてみることにしました。 最初から最難関、Nixでの環境構築 せっかくなのでFlutter × dartでやっていきます。 さて、何はともあれ開発環境・・・なんですが、いかんせん私の環境はNixOSです。いろいろ有志の方が研究しているものの、どうも直近のAndroid SDKは、 SDKのdirectoryを弄り倒す という、nix側からすると狂気の行為をするようです。 https://github.com/NixOS/nixpkgs/issues/355045#issuecomment-2466910779 local.propertiesだといったぞ?とか https://github.com/tadfisher/android-nixpkgs/issues/91 そもそもandroid-studioが使えないぞ・・・とか。nix storeは完全immutableが基本なので、そこに書き込もうとするのはすでにどうしようもありません。事前に全部定義したらいい、ってのがnix wayではあるんですが、SDKとimageとemulatorを・・・とか全部事前に用意するのはなかなかというかだいぶ辛いです。 ちなみに私は、local.propertiesまでは行ったんですが、Gradleのエラーで 読み込み専用のところに書き込めない ってエラーをみて、諸々諦めました :angel: Android Studioを使わない、とかならいいんでしょうが、Gradleで出るのはもはや如何ともしがたいと判断しました。となるとどうなるんですか・・・?なんですが、Android SDKは基本的にhome directoryの下に増えますので、純粋Nixな人は許せないかもしれません。私はhome directoryの下については流石に実利を取ってるので、これで進めることにしました。なおこのエラーはFlutterを利用するgradleの設定というかプラグインがこういう仕様になっているようです。ただ、 flutter コマンドからなら普通にできたので、これは気にしないようにしたほうがFlutterではよさそうです。 なお、この場合Android SDKについてはandroid-studioから入れるか、sdkmanager / android CLI から入れるか、とする必要があります。私はandroid-studioから入れました。 emulatorの起動 本家NixのWikiにもこう書かれております。 View the Android wiki page for more info, but you can set up emulators in Android Studio, run them from there, then target the emulator in VSCode when running your flutter code. Otherwise, you can Nixify or even manually add your emulators as stated in the Android wiki page ...

September 23, 2026 · derui

Emacsでのcursor移動をisearchに1本化しようとしている

気づいたら新入社員がはいって来てました。なんか去年も同じこと書いた気がしますが、気のせいでしょう。 まだまだEmacsを現役で利用していますが、カーソルの移動に対するアプローチを変えつつあります。 もともとの課題感 私はEmacs上では multistate という、modal editingの仕組みだけを提供しているpackageを利用して、modal editingそのものは すべて 自前で定義しています。evilとかmeowとかも使ってたので、そういったもののエッセンスも入ってます。 ちなみにevilを利用しなくなったのは単純で、Qwertyを利用しなくなったのでマッスルメモリーが使えなくなった、というのが最大です。ただ、なんだかんだEmacs上でのエミュレートではあるのと、個人的にはtext objectよりもpuni/treesitterベースでの選択ができればそれでよかったです。 そんな中で、ずっと悩ましかったのがカーソル移動です。上下左右についてはそりゃー定義していますが、 10行下にあるfoo に行きたい、となった場合に、大抵10回キーを押してます。word単位の移動とかならまだいいんですが。一応avyとかも入れていたんですが、よくある文字だと候補が多すぎて・・・っていうのにもなります。 avyを激推しする記事 2021年の記事にはなりますが、すっごい長文の記事があります。めちゃくちゃ長いのですが、Emacsを利用している場合は読んでおくといいと思います。 https://karthinks.com/software/avy-can-do-anything/ この記事の要旨としては、 カーソルの移動というものは換言すると3stepの話でしかない 同じ筆者が書いた、Emacsのウィンドウ管理に対する記事でも、同じような話があります avyがすでにそれを提供している isearchかavyで十分だ というところです。間違ってたらごめんなさい。この記事を何回か読んで、なんとなーく把握できました。 移動の優先度を見直す 私がやるカーソル移動(検索含む)は以下です。上から順に頻度が高いです。 hjkl likeな文字単位移動 word単位移動 consult-xxx consult-lineが最も頻度が高いです isearch 色々見直した感じ、以下のようになるようにしてます。 hjkl likeな文字移動 isearch + avy consult-xxx mode-specificな移動 orgだったらheading単位とか insert modeのままで・・・というのであれば他の選択肢もあると思いますが、いかんせんQwertyじゃないのでキー配置が色々ございまして、移動はnormal mode、と割り切っている次第です。 さて、isearchなんかいらなくて、全部consult-lineでいいじゃん?という方もいるでしょう。そこは自由なので「そうですね」となるのですが。それだと面白くないので、理由を書いてみようかと思います。 isearch vs consult-line Emacsの検索というとisearchがまずデフォルトであるのですが、大抵は consult-line などの利用を勧めているケースが見られます。これがなんでかなーというところを考えると、 スペース区切りだったりで検索できる(ように見える) 結果の一覧が見える のが大きいのだと思います。これについては全く違和感がないのですが、ことカーソル移動を主眼に置くと、以下の点でoverpowerです。 本質は filtining なので、検索はしていない 今見えてる場所を一覧しても何も嬉しくない 逆にminibuffer/bufferへの視線移動を伴う 同一行に複数の結果がある場合に対応できない 特に最後は、consultの本来的な目的を考えると、サポートは難しいというかしないと思います。が、移動となると頻繁にありえます。isearchならなんの問題もなくできますよね?という。 isearchのカスタマイズ 激推しされるavyには、 avy-isearch というもうそのまんまな機能があります。対象のfilterをisearchでやり、selectをavyでやる、という形で1本化することができます。お、これで解決では? キー数が増えてる、非効率だ!ってのはあると思いますが、単一操作であらゆるケースに対応できるので、記憶容量はむしろ減ると思います。avy/isearchの使い分けを・・・って考える時間のほうがもったいないんじゃ?と参照元も書いてた気がします。 さて、そんなisearchですが、欠点もあります。それは 検索方向を最初に決めないといけない ということです。 isearch-forward と isearch-backward ですね。isearchをカーソル移動として利用しようとしたとき、これが困ることが多いです。 ...

April 22, 2026 · derui

project管理をできるだけシンプルに行うpackageを作った話

気づけば卒業式シーズン。いかがお過ごしでしょうか。というかこっちの卒業式って3月の半ばなんですかね?(わかってない) 最近Emacs弄りの熱がまた上がってきたところですが、生成AIにコンセプトを伝えて作らせたものを紹介します。 できたもの https://github.com/derui/projab Project.el + Tab-bar というところで projab としました。一応ググってもそれっぽいのは出てこなかったので大丈夫だとは思います。 余談ですが、生成AIが提案した名前に workroom (後で出てきます)ってのがありましたが、もう全く同じ名前のpackageがありました。事前調査は重要ですね。 Project management系統なので、基本的に画面とかはありませんが、自分が欲しい以下の機能を兼ね備えたpackageがなかったので作成しました。 標準パッケージにだけ依存する Emacsの標準パッケージはすでにかなり充実していますので 特に、visualにかかわらない部分については、大半が汎用性のある形でできてます Bufferのリストだけ保存される 意外と Window layoutも 復元しようとするケースがあるのですが、これは究極に複雑な系統になるのと、だいたいその辺キー一発なので切りたかったんです 自動レストア機能 + Projectを開いたときだけ 復元 大抵、projectを含めて全体を復元・・・ってやるのですが、それをやられると、長時間使ってると、次回起動時にとっても時間がかかるようになります 実際、Nixをdirenvで有効にしているprojectがあったりすると、開くだけでLSPの起動やらなんやら含め、長時間待たされます 私のsetupは、起動速度に重点を置いているので、ちょっと許容できなくなってきたという背景もあります そんなことで、以下のことができるように、というコンセプトで作ってます。 project.el / tab-bar / desktop.el を利用する project外のファイルも復元のリストに入れられる 復元単位はproject = tab Window/frameの復元は不要 とりあえず使える・・・って状態になるまで1,2時間くらいでした。ほぼほぼ利用する関数は自分でも把握していたので、reviewも早いですね。 自分が把握している範囲が広いほど、生成させるときも速い です。 他のpackageを利用しなかった理由 このsession管理というのは、Emacsの歴史上何度となく大きなトピックになってきた(と勝手に思ってます)ものであり、多数のpackageが存在しています。 Tabspaces もともと利用していたもの。project.el + tab-barというのはほぼほぼ同一 ただし、 自動restoreは全体の復元が強制される ことと、Windowやtemporary bufferまで保存しようとすることで、復元するときに結構厄介な状態になったり、ということがあったのが、今回作った主な動機です emacs-workroom ほぼほぼ同じ動機。 project.el + desktop.el ただ、tab-barのintegrationを作者がする気がない様子 perspective-el この分野の有名どころ より複雑な管理(merge/split)を可能としてます。elscreenとか書いてあるくらいなので、非常に歴史があるpackageでもあります これも昔使ってました つまり、個人的には 帯に短し襷に流し を地で行っている状態だった・・・というのが、ド新規でわざわざ作ろうと思った動機です。以前であれば、こうなると妥協して・・・ってのがありましたが、今はこれくらい(400〜500行程度)のElispであれば数分で作成できてしまうため、アイディアなりコンセプトの具現化は非常にやりやすいと思います。 やらないこと、を決める このpackageでは、最初から以下はやらん、と決めていました。多分作らせようと思えばできるのですが、そもそもやる理由がないのと、コンセプトからブレるためです。 ...

March 15, 2026 · derui

tabspaceをtab-barなしで利用するようにしてみた

まだEmacs使ってるの?って空気を感じる中、変わらず触っています。最近ちょっと一念発起して、header lineをカスタマイズしてみたので、ちょっと紹介します。 問題意識 Emacsのsession managementについては、色々試した結果、紆余曲折ありつつもtabspaceを利用しています。このpackageは、名前の通りEmacs標準のtab-barをprojectの単位として利用することで、spaceの切り替えを明示的にすることができるようになっています。 そんなtab-barですが、デフォルトだとこんな感じの表示です。 簡素ですがまー用は足ります。なんですが、最近の流行りに合わせてbreadcrumbを利用してheader lineも利用していると、以下のような課題が出てきます。 そもそもの領域が削れてしまう header-line + tab-bar + mode-line + echo area、という固定領域が発生してしまいます 切り替えたときに、別のprojectが見えてる意味が薄い そもそもなのですが、一回切り替えると、大体はそのprojectに関連したものに統一されるわけで・・・ 常に見えてる必要もないね? tabspaceのecho areaに表示するoptionも試してみたが、これはこれでなかなか厳しい 多分相当にいじれば問題はなさそうなんですが、上記にあるとおり、 そもそも常時見えている必要とは 🤔 と。 実際はもうちょっとカスタマイズしていたので、さらに高さがありました。 ヘッダーラインとモードライン さて、ヘッダーラインとモードラインですが、それぞれ色々と用途はあります。ただ、現状はヘッダーラインがほぼほぼbreadcrumbの領域しかないことと、大体projectの内容も含まれていることから、ヘッダーラインを追加することにします。 (defun my/header-line-project-name () "Get the current project name (tab name) for header line" (alist-get 'name (tab-bar--current-tab))) (defvar my/header-line-separator nil "Cached separator string for header line, rebuilt on theme changes") (defun my/header-line-update-separator (&rest _) "Rebuild the cached separator string" (setq my/header-line-separator (concat (propertize "|" 'face 'shadow) " "))) (add-hook 'enable-theme-functions #'my/header-line-update-separator) (defvar-local my/header-line-element-project-name '(:eval (concat "[" (my/header-line-project-name) "] " (or my/header-line-separator (my/header-line-update-separator) my/header-line-separator))) "An elenemt of header line to display project name") ;; set local variable for header line (put 'my/header-line-element-project-name 'risky-local-variable t) (defun my/setup-header-line () "Setup `header-line-format' for my purpose" (setq-default header-line-format '("%e" my/header-line-element-project-name (:eval (breadcrumb--header-line))))) (with-low-priority-startup (my/setup-header-line)) こんな感じの設定になりました。ミソとしては breadcrumb--header-line です。これはbreadcrumbの内部処理なのですが、breadcrumbが提供するheader lineがちょうどいい感じなので、これを利用しています。また、注意としては breadcrumb-modeを有効化してはならない ってのがあります。これはbreadcrumb-modeは有効化した瞬間にheader lineを強制的に変更してしまうため、こっちが想定した形にならなくなります。 ...

February 15, 2026 · derui

自分用のEmacs packageをLLMで作る

あれ、1月ってありましたっけ?という勢いで1月が終わりました。あれを何月くらいにやろうかな、とか考えてるとすぐに終わっちゃいますね。 今回はちょっと最小限で欲しいEmacs lispのpackageを作って・・・というか作らせてみました。 できたもの とりあえず画像を見るのが一番早いので貼っときます。 こんな感じに、 置換対象のものだけを、置換後とside by sideで見える ってものです。とってもシンプルで単機能です。 モチベーション できたものは、概ね行数としても150行とかなのです。もともとは単純に 置換前後をみたい というものなのですが、これが地味に対応するものがない・・・というところなので、探してました。 より高機能なものとして visual-replace やanzu.elなどがあるのですが、こちらは 検索処理そのものを置換している という課題があります。なんだかんだ、interactiveな検索・置換というのは恐ろしく複雑な行為なので、自作はしたくない・・・。また、標準へのalignが最近のトレンドと考えると、既存の継続的にメンテナンスが行われているlibraryを利用しない、というのもなかなかもったいないことだなーと。 発見と作成 ふとした発見は、 replace-update-post-hook というhookを見つけたことです。これは置換を行う直前くらいで呼び出されるhookで、今回やりたいやつにぴったりでした。 ちょうどよかったので、完全にLLMでやっていい規模だったので、全面的に生成させてます。 全体のデフォルト構成はCopilot Agentに初期生成 実際の実装はClaude Codeでplanさせてから実装 テストの生成/documentもClaude Code 動作確認は自分 という感じで、大体はClaude Codeに生成させたものになります。やっぱり一発では無理で、存在しないlexical変数を使おうとしたり、エラーハンドリングが足りずに C-g でキャンセル・・・とか気の利いた感じにはやはりなりませんでした。 とはいえ、overlayの作成やdefvarの作成といった、Emacs Lispお決まりの管理などを含めると、実際のロジックはほんの2,30行程度、というのが実態でした。やはり色々言われている、 大体定型的な処理になるもの とかは、生成させるのに向いていますね。 Emacs Lispとの向き合い方 Emacs Lispは、Emacsを触るうえで絶対に避けられないものですし、色々な概念が絡み合って、大変に複雑です。しかし、シンプルなpackageを作るとかは、今だと1時間とかあったら、 ボイラープレート的にやるもの を含め、だいぶ楽に作れます。 作れるからといって何でも作る と、それはそれでメンテナンスが不可能になっていくのですが、Unix wayのように、単機能のものをいじったり作ったりする分には、問題はそこまで露出しないかな〜、とも思っています。 Emacsを触ってみるいいチャンスとして、一個気に食わない部分をpackageにしてみる、とかいかがでしょう?

February 5, 2026 · derui

RustでOperator Overloadを利用したDSLを作ってみる

気が付いたら2025年が終わってました。今年の抱負とか考える前に仕事が始まったので、今年もいきあたりばったりに行きていければと思います。 最近Rustで細々と格闘しているんですが、ちょっとやってみたいことがあってやってみたらできたので、小ネタとして残しておこうかと思います。 やりたいこと 諸事情で、代数式をstructとして管理することをしています。毎度ですが、なんでそういうことをしようとしているのか?は聞いてはなりません。 // こんなtraitを定義しておく trait Equation { // envは変数のhashmap fn evaluate(&self, env: &HashMap<String, f32>) -> f32; } こんなtraitを実装したものを考えたいです。なお実装は自明なので省きます。で、これを普通に実装すると、ちょっと複雑になっただけで大変なことになります。 // 3.2 + 3.4 let e = ArithmeticEquation::new(Add, ConstantEquation::new(3.2), ConstantEquation::new(3.4)) // 掛け算とかがnestすると大変なことになる これをなんとかある程度楽にしたい、というのがモチベーションです。 方法の検討 Rustだと、大きく3通りのやり方があると思います。 procedural macroを実装する lexer/parserを利用してparseを実装する operator overloadとstructを駆使して頑張る macroとoperator overloadはcompile時に、lexer/parserは動的になる感じです。最終的にはlexer/parserが必要になりそうなんですが、一旦は静的にできれば(テストを書いたりするときに)便利です。となると、macroかoperator overloadが選択肢になる感じですね。 lexer/parser自体を生成するmacroとかはあるようですが、そもそもparseするという行為自体が、compileした後の話になるので。 Operator overloadを検討してみる RustのOperator overloadは大変に強力である意味シンプルなのですが、 Scopingが困難 です。 KotlinとかのOperator overloadでは、interfaceの実装元とかで切り分けられたり、scoped functionを利用することで、DSL/operator overloadの利用範囲をscopingすることがるできます。 object Ops { operator fun invoke(f: Ops.() -> Unit) { f() } infix fun String.test(rhs: String): boolean {...} } // こんな感じで使える Ops { "hoge" test "foo" } // 外だと明示的なimportが必要。 翻ってRustのOperator overloadは、標準にある Add や Sub といったTraitを型に対して実装する・・・という形です。 ...

January 12, 2026 · derui

bevyでgltfを読み込むときに.metaファイルが要求されて困るとき

たまには超小ネタです。 Bevy触ってます ちょいちょい中断しつつですが、bevyというゲームエンジンを触っています。なんというか現代的なゲームエンジンを触るのは実は初めてなんですが、Direct3Dで・・・みたいな時代とは隔世の感がありますね。そもそも古すぎか。 やりたいことのためにWASMで動作するように作っているのですが、 glTF ファイルを読み込ませようとしたら、 .gltf.meta という謎のファイルが要求されてエラーになって困ったことになりました。ちなみにglTFファイルとは、WebGLの標準フォーマットとのことです。 https://knowledge.shade3d.jp/knowledgebase/gltf%E3%81%A8%E3%81%AF 解決 https://github.com/bevyengine/bevy/issues/10157 困ったときは公式のissue、ということで探したらありました。どうもbevy_assetsの機能で、metadataを確認することでより適した処理にできる、とかそういうもののようです。ちなみに生成するためには 一回起動したらいいよ 、とのことですが、WASMの場合そもそも書き込むっつってもどこに?となってしまいます。 app.add_plugins(( DefaultPlugins .set(AssetPlugin { // これを追加する meta_check: AssetMetaCheck::Never, ..default() }), )) issueにあったやり方とは違いますが、meta_checkを無効化するとOKです。私がやりたい範囲ではglTFはほぼ使わないので、これで特に問題なさそうでした。

October 13, 2025 · derui

最近のAIを使ったProgrammingについて

すっかり初夏の感じになってきました。半年すぎるのが早すぎます。 すっかり間が空いてしまいましたが、今回は最近のお仕事で使ってるものとかを簡単に書いてみようかと思います。 ...

June 22, 2025 · derui

Monadic ParserでSchemeのリストをパースする

去年のGWに何をやっていたか全く記憶が無いんですが、今年も特に何もないGWになりそうですね。なんだかなぁ、という気分しかありませんが。 そんな状態ですが、最近チマチマと作っているOCamlでのScheme処理系で、Monadic Parserを作ってみたので、その紹介をちょっとできれば。 <!–more–> Monadic parserとは まずMonadic parserとは何か、ですが、あんまり明確な定義は無いというか、名は体を表すというか、そのまんまというか。モナドを利用したparserです。HaskellのParsecが有名ですね。 基本的には、 関数で構成されている モナド則により合成可能である という感じかなー、と。理論的な背景はあんまり理解しきれていないので、あくまで私の理解ではありますが。 OCamlのapplicable let Haskellだと、Monadの記述にとても役立つ、 do記法 というのがあります。OCamlには長らくそういうのがなく、PPXとかで各ライブラリごとに拡張を書いていたり、ppx_letのように汎用的な拡張を利用したり・・・というのが必要でした。 が、OCamlの4.08?くらいで導入された Applicable let というのを利用すると、do記法と同じような記述を、OCamlらしく記述することができます。 module Nanika_monad = ... let ( let* ) v f = Nanika_monad.bind f v let () = let* v = Nanika_monad.return v in ... applicable letと言っても、なんてことのない関数定義です。 let* とかだけではなく、 let+ みたいなものも定義できます(定義の中身は、定義の実装者次第です)。letが定義できるということで、同時に and* のような関数も定義することができます。 これですが、 >>= での結合をほぼそのまま変換することができ、逐次処理のように見せることができます。記号で繋げまくっていくのも楽しいですが、後から見たときに処理が明瞭になるので、最近はMonadとかを利用するときはこれを使ってます。 Applicative ParserではなくMonadic Parserになる理由 Monadic Parserとはよく呼ばれるけど、 Applicative Parser というのが無い理由ですが、これはシンプルで、 Applicableだとパースできないものが沢山ある から、という理由のようです。 具体的な例は、もっとよく説明しているサイトを参考にするのがよいと思います。私の浅い理解だと、 Applicableだと、繰り返しやバックトラックといった挙動を定義することができない 前の値を利用する、というようなことができない ため、そもそもパーサーという目的には機能が足りないのでApplicative Parserというものは事実上作成されない、ということのようです。よりシンプルなパースができればいいのであれば、Applicative Parserとかも作れると思います。 ...

April 25, 2021 · derui