"idea"

2025-01-13

昨日は友達とキリンビール工場に行ってきた。500円のツアーがあってビール作りの概要を教えてもらいつつビールを飲ませてもらえる。だいぶ楽しかった。あの体験は優しさで成立していると思う。

原料となる麦やホップを食べさせてもらえたほか、ビール製造の中間生成物である麦汁の飲み比べをさせてもらえた。何より説明してくれるお姉さんがビール好きで、1つ質問すると厳選した3つを返してくれるのが良かった。一緒に飲んで欲しい。飲ませてもらったビールもめちゃくちゃおいしいし。併設されているレストランに行けていない(リサーチ不足でご飯を食べてから行ってしまった)のと、他にも見学コースがあるみたいなのでまた行きたい。

ホップを使ったリンスを買って使ってみたら、髪からフルーティ系なビールの匂いがして最高。

AIに仕事を奪われることはないだろう。とはいえ単に作業をするだけの労働はAIに奪われる。コードを単に書くのは作業であって、仕様からコードを生み出すだけならAIでやった方が早いし(今の相場なら)安いから。

とはいえそんな単純作業が仕事であることはなくて、将来のこととか仕様の考慮に入っていなかったことをコードを書きながら調整して主体として責任を持って成果を出すことは、社会がまだAIに対して認めていないように感じる。

誰もが優秀な部下を持つようになったが、人々は誰かに責任を持った主張をして欲しくいのだろう。ポジションをとって主張をし、ダメだったときは失落したり挽回することを人格に求めている。信頼をして仕事を任せる相手は人間じゃないと嫌だと社会が思っている。

そういうわけで人間は労働力としての生成AIを手に入れただけであって、人間社会で主体として認められたあらたな人格を手に入れたわけではない(今のところは)。成果を出すためには社会が理解できるポジションを取ることが必要で、そのロールモデルの振る舞いとして社会と交流しないといけない。どんな振る舞いをするのが良いか決めるために生成AIを駆使する仕事の仕方が増えるだろう。ロールモデルには矛盾なくとりうるアトミックな行動があって(思想とか哲学みたいなもの)、それを組み合わせることでその人らしい振る舞いが形成される。思想とか哲学とかに一貫性がないと社会から信頼してもらえない。一方で外部から同じ要求がなん度もくることはないため、それに応じた異なる振る舞いをする必要はある。思想や哲学から外部刺激に対して振る舞うことにはエネルギーとか思考とかが必要で面倒だから生成AIを使うと便利だろう。

これはプログラミングにも応用できる。アプリケーションのコアなロジックのインターフェースは綺麗に設計されてクライアントから受け入れてもらう必要がある。そこがブレると利用するのがそもそも大変だし、見出した価値がすぐに失われてしまうだろう。一方で、それを活用して振る舞いを追加したり修正することは生成AIがこなすだけで十分なのではないだろうか。振る舞いを追加することは、そのアプリケーションのコアな部分のインターフェースと世の中によく知られた技術要素のインターフェースを組み合わせて表現できるだろう。

外部からの要求に応答して振る舞いをしたりインターフェースを利用して新たな機能を提供する際に、コアな思想を見直してアップデートすることもあるだろう。とっているポジションをちょっと変えるということ。使う側からすると理解の仕方をちょっと変えないといけないのでこの変更が気に食わなかったり理解できなかったりすると嫌な感じがする。変化の速度が早すぎて理解が追いつかないとたとえ良い変化であったとしてもアンチになってしまい信頼をなくすことに繋がる。そのため人間に直接理解されるインターフェースは人間に合わせた進化をしないと社会に適合できなず、市民権を失う。

したがって生成AIはインターフェースを提供するソフトウェアエンジニアの職業を奪うことはない。一方でインターフェース設計に関与しない、定義されたインターフェースの中だけで作業をして、他人と相互作用をするインターフェースを定義しないエンジニアリングは生成AIのコストに負けて自動化されるだろう。

次に、他人と相互作用するインターフェースのあり方が変化するかが問題になる。これまで公開されて使われていたようなインターフェースは今後も必要だろうか。インターフェースを解釈するのが生成AIだけになれば、その変化が早くても理解が追いつくためわざわざポジションをとったり人間の理解速度に変化の速度に合わせる必要がなくなる。これは作り上げるものの抽象度の違いに依存するだろう。何かを作り上げたかったらその一段下の抽象度の言葉で構成を説明してほしい。妥当性を検証するために。そこから下は信じることにして(信じられる何らかの根拠を持つことになる、ここも何か困難があるかも、今は著名なOSSだからokとか言って信用することにしている)、欲しいものの一段下のレイヤで自分で納得がいけば良いものであると判断する。

そして、人間の思考とか議論のレイヤは高々10とかにおさまっており、それが生成AIの登場で変わるとも思わない。なのでインターフェースを人間が作ってポジションをとる必要性も今後変わらないと思う。根拠はなくて直感だし、多分僕の願望も入っっている。

良いインターフェースを定めるために、鍛錬を積む必要はあり、それは生成AIによって取って代わられる仕事でなされることが多い。生成AIを使って仕事をやる先端のインターフェース提供者と、そこから学べない後進が場所によっては生成AIがやる仕事をするローカライズされたインターフェースの提供者が並行して存在する世界になるだろう(生成AIに限らずこの状況はあるだろうが)。

2025-01-04

過去に何個か一人でCLIツールを作ったことがある。そのときに雰囲気で乗り越えてしまいストレスの少ない綺麗な書き方を知りたかった概念をあげる。

  • エラーハンドリング
  • 参照周りの型変換
    • 特にパターンマッチやforループ、関数定義で & 記号を書く構文特有の意味があるときがよくわからない
  • ライフタイム
    • 実用的に我々はどんな塩梅で書くのが良いかとか、誰が所有するのが良いかを判断するためのベストプラクティスを持っていない
  • トレイトの勘所
    • ユーザ定義型に機能を実装するときに、どういうインターフェースを持たせるか迷う。どのようなトレイトを実装するかを決められない。クライアントとしての標準を知らないのでサーバとして何を提供するか、常識をもとに判断できない

要件を定めてそれを保証する仕事がソフトウェアエンジニアの仕事になるだろう。それだと単発の仕事か。進み方を把握して、それを促進する作りにする必要はあるはず。

プログラムの開発(状態や環境に反応するソフトウェアの開発)自体は生成AIによって簡単になった。要求や要件を実現することしかまだ生成AIのブラックボックスに入れられていない。要求や要件の整理の道具として生成AIを利用してはいるが、

これからは生成したプログラムに対して保証された機能の制限が大事になってくるだろう。プロダクション環境で動くプログラムを見る人間は減り、その代わりにソフトウェア検証、パーミッションの制限で安全性を保証したり、デモで振る舞いを確認する未来がくるだろう。ソフトウェアを実装するコストが低くなり、つまりソースコードに向き合う機会が減り、コードの振る舞いを静的に理解しなくなっていく。あるいは言語を高級にするだろうか。言語にどんな性質があると幸せ?

生成して良い言語に良い性質を持たせることはありそうなアプローチ。

仕事は確かにたくさん奪われそうだけど、契約をデザインして(うまくそれを表現することを含む!)プログラムを作り上げる営みは楽しいからずっと続けると思う。

2025-01-03

https://dev.nfurudono.com/posts/go-errors-stacktrace に移転しました。

大掃除は年末にしたのだけど、コーヒーグラインダーを掃除し忘れていたのでやった。結構な量の粉が中から出てきて驚いた。豆を砕く場所と粉が出てくる穴の間に傾斜した通路があってそこに溜まっていた。

今日も餃子を作った。昨日たねを作りすぎたので。ちょうど買い足した餃子の皮を消費できた。蒸しと焼きの両方やって昨日と同じ感想だった。たねを作るときに白菜の水分を抜く工程を入れていたが次回は外してみようと思う。

明日は鮭のホイル焼きをしようと思う。衛宮さんちの今日のご飯に感化された。

  • 鮭・玉ねぎ・にんじん・しめじを適切に処理する
    • 鮭には酒と塩を振って5-10min放置してから拭き取る
    • その後酒に塩胡椒を振る
  • 玉ねぎ・にんじんを敷いて、その上にコンソメをかける
  • 全てを載せつつバターも添えてホイルに包む
  • 加熱する
  • パセリか何かをかけるらしい
  • わさびマヨがあっても良いとか

朝は納豆とかかな。卵も食べよう。 朝はサンドウィッチにする。ほうれん草、卵、ベーコンを入れたい。卵しかないので買い出しが必要。パンもない。

2024-12-25

関数の引数はそれぞれ何で、どんな性質を期待するかや、そのほかの事前条件を満たした上でこの関数を呼び出すと、その結果としてどんな返り値が得られてそれ以外にどんな副作用があるかを表明するのが関数の契約。文章を用いるのが簡単だし、伝えやすくするには図を用いても良いし、型とかバリデーションのための式で表現しても良い。何にしても契約を表明すると楽しくプログラミングできる。

この関数の呼び出し側はどんなふうにこの関数を使って処理を実現するだろうかとか、この関数を実装するときはどんなふうに作ろうかと考えるのがまず楽しい。みんなが幸せになれる契約をデザインするのが楽しい。ソフトウェアのテストは契約を守っていることを検証することだと思う。型を用いた表現は契約の表明で、型検査が検証(それも厳密な)である。

このように良い契約をデザインするのがプログラミングでまずやることだと思う。その次に自動で検証するためのコードを書くのがTDDの人だし、関数型の怖い人は型で契約を表現しようとするかもしれない。そのためにすごい表現力を持つ型システムを考えて勉強して使う印象がある。

TDDで最初から完成版のテストを書かないことからわかるように、契約を最初から詳細まで書く必要はない。そんな契約を満たす実装を書けるだろうかと思うこともある。なので最初はふんわり「ユーザの情報を返すAPI」とか決めておいて、IDが欲しいとか、シャーディングしてるから作成日時も欲しい、みたいな事前要件を足したり、ユーザ情報全部返すのはきついし呼び出しがわも幸せじゃないから、名前とメルアドだけ返すことにする、みたいな調整も入るだろう。課金が滞っているユーザに対しては普通の結果は返さない、代わりにエラーを返す、みたいな変更も実装したり呼び出しているうちにしたくなるはず。

結局のところ普通のプログラミングをしようと言っているだけなのだが、僕が強調したいのは契約と実装を分けて考えようということ。契約が先にあってそれに実装を合わせる(合ってない状態はバグってる状態)考え方でいたいし、僕と契約を共有する人には(その共有する契約のレイヤで)いて欲しいと思う。

僕はmac osのコードがどうなっているかを気にすることはなくて、普通にパソコンが動けば満足するし、実際動いているので不満はない。キーボード叩いたら文字が出るという契約を守ってくれている。でもosのapiを叩く友達はそもそもドキュメントが公開されてなくて辛い、みたいなことを言っていた。このように、自分が関心のあるレイヤの契約が問題になるのだと思う。

契約はプログラミングの細かいレベルだと変数の名前とか、改行の置き方によって表明されるもので、大きいレベルだとサービスやロールの責務として表現されると思う。サービスのAPIは代表的な契約だと思う。APIという言葉は契約と同じような意味だと思うけど、エンドポイントみたいな意味でも使われているし責務みたいな概念には適用されないと思っていて使わない。

僕たちが欲しいものは何かを表明しよう、というのが契約を表明しようということだと言い換えられる。使う側からしたらその実現方法は関係ないし、提供する側からしたら契約さえ満たせば何をやっても良い。 getterとsetterを提供するからと言ってそういうフィールドをよく知られた方法で提供しないといけないわけではないし、バッファリングとか遅延実行をしても良い。

未定義な状況とか意図しない状況はある。今と昔では状況が変わって、その頃は妥当に思えた契約が時代に合わなくなることもある。契約がないと実装が良くないで話が終わってしまうが、契約があれば仮定が違ったのだと結論づけられる。人の記憶があればその人の心に契約があって仮定が違ったと判断できるだろう。記憶を失ったりその人が失われたりする場合は契約を表明しておくべきだろう。

型はデータ構造やその不変条件を表現したりそれらに名前をつけることで、契約を表現する。そして型を用いて表明された契約は普通型検査によって契約が満たされていることを検証する。正しい場合には正しいと判定するし、正しくない場合には正しくないと判定する。さらに、ある程度ちゃんとした型検査器は、どのように契約が満たされなかったかを説明してくれる。

テストは契約を検証するためのコードで、そのテストが契約のどんな部分を検証するか、テストケースの名前として表明される。その表明を満たすようにテストコードが実装されて、テストランナーに呼ばれる。契約のどんな側面をそれぞれのテストケースで検証するか、検証すると幸せか(誰にとって?)を決めるのはテスト実装者のスキルに依存するだろう。契約の中で脆いところを普通は検証するのだろう。明らかに正しそうなやつは手を抜いてしまえるはず。

バリデーションも契約を表現する手段の一つ。契約を検証処理として実装して表明するのがバリデーション。型と同じようにすべての実行について契約が満たされるかを検証する。一方でテストと同じように実際に動くものに対して検証を行う。

実際に動かして試すのは何だろう。契約とはあまり関係なさそう。実装したやつがどんな感じになってるか微妙なので試して動作を観察するのがとりあえず動かしてみる目的。これは脇道だったな。ただし、あまりによくわからなくなっているときは分割統治をするときだと思う。自分の手の中にある対象をコンポーネントに分割して、それぞれに対して契約をデザインする。その契約を満たすように実装しつつ、その契約を期待して組み合わせて元々の目的を達成すれば良い。わからない部分が新しい契約の内側にはいれば小さくなった簡単な契約を満たすことに問題は帰着できたし、それらの契約を組み合わせることに課題があるなら詳細を忘れて便利な道具を手に入れられたのだからやはり問題は簡単になっているはず。うまく契約を設計することが難しいなら、それは楽しいから問題ない。ずっと取り組んでいればいい。

何にしても契約を表明することが何より先にくる。これだけでプログラミングが楽しくなる。その後に型、テスト、バリデーションを書いたり実装をしたりする。

そういう考え方が how to design programsにデザインレシピとして書いてあるのでよかったら読んでみてください。

プログラミング言語はこの辺りが優秀で、型システムの研究とかで契約を表明して保証する方法を検討しているし実際に生かされている。なので言語に守られているうちは割と安心できる。あとは怠慢にならなければいいだけ。

プログラミング言語に閉じられなくなるとき、例えばWeb APIを提供するときは急に難易度が上がる。Web APIでも契約を表明して検証するためにスキーマ駆動開発がある。契約を書き下すことを支援するのはもちろん、型とかバリデーションで表明することも支援する。テストツールの支援もある。

僕たちが求めているのは以下である。

  • 契約を表明すること
  • 契約を洗練すること
  • 契約を犯せないようにすること
  • 契約を犯しかけたらなるはやで誰かに教えてほしい
  • これらを簡単に実現できること

最初のやつは設計しようぜ!という話。次が設計技法とか良い設計みたいな話。三つ目は型とかバリデーション、テストの話。次もそう。最後のやつはそれら全てを支援するエンジニアリングの話。

契約の話をしたのでパラダイムの話をしたい。オブジェクト指向と普通のやつの話。どっちでもいいけど、契約を表明しやすいパラダイムが良いと思う。

オブジェクト指向な考え方だと、内部状態を持つオブジェクトがメソッドを受信してその結果内部状態を変えたり返信したりする。そういうふうに契約を表明して守っていくならオブジェクト指向を使えばいい。

関数型みたいな普通のやつは、仮定が与えられた状況で関数を呼ぶと結果を出す。そういう契約の書き方をするなら関数型みたいに書けばいい。

どちらも相互に変換可能だから力まず表現しやすい言葉遣いを使えば良いだろうと思う。

割と思いの丈をダンプした。これは就職したからできたことのように思う。学生の頃に培った理想が現実世界では必ずしも簡単に実現しないことを体験できた。自明だと思っていた領域の非自明な部分に気がついて思うところが出てきた。

プログラミングの楽しいところは、ロールを分けてうまく契約群を設計することにあると思う。フレームワークを作るのはそういう契約の集まりを定義することだから楽しい。一方でフレームワークを使うと契約を設計する機会を奪われる分楽しくないかもしれない。

その分他のレイヤに注力すればいいのだろうが。

自分が自由に設計したいレイヤで他人に契約を決められるとストレスだろう。本当につまらない。反対に自分が関心なくて誰かにうまくやって欲しいときには良い契約を強い人に決めて欲しいと思う。そういうレイヤを担当するフレームワークを使って欲しいし、技術を選定したい。

アーキテクチャ設計についても言及できそう。アーキテクチャは中長期的には変遷するものだが、短期的には変わらない。アーキテクチャに乗っかってここのコンポーネントを作り込む。ここのコンポーネントをストレスなく作り込みやすくするアーキテクチャが良いアーキテクチャなのだろう。

2024-12-13

  • kamakura.goの感想とかを書く

2024-12-12

We recommend that all third-party code generators be written as plugins, as this allows all generators to provide a consistent interface and share a single parser implementation.

https://protobuf.dev/reference/other/#plugins

はえ〜って感じ。Goのライブラリはだいぶ使い勝手良かったのでまあ確かにと思ってる。

2024-12-05

viperってinit使わないといけないのかな。 viperに依存性を注入するような使い方をしたい。Facadeを受け取ってCLIを返すようなCLIジェネレータを定義しようとしていて、CLIジェネレータを実装するためにviperの諸々をinitとかで終えようと思うと困る。実行時にfacadeを入れたいので。

2024-11-28

Reactのカスタムフックの心をわかっていなかったけど、クロージャに変数をキャプチャさせて、状態をもつクロージャ(の組)を返す関数がカスタムフックぽい。組と言ったのは、getterとsetterが別々に提供されることがあるから。例えば const [v, setV] = useState()v がgetterで setV がsetterと思える。

カスタムフックの呼び出しもとの再レンダリングのたびに返却する関数の実態が同じにするかしないかは、useCallback を用いて制御できる。例えば useStateuseCallback してると思える。

このようなプログラミングテクニックを用いると、振る舞いを実現するクロージャだけが定義されていて、それが裏で扱う状態遷移がフック定義の中で隠蔽されるのが嬉しい。

カスタムフックのモチベーションは単に状態を関数型っぽいやり方で扱いたいだけなのだと理解した。

OCamlでのmutable counterの実装例を見つけた。鉄板の例だと思う。僕はこれをイメージして状態を保つクロージャと呼んでいた。

2024-11-27

Branded typeはTSでnominal typingっぽいことをするためのプログラミングテクニックの一つ。Branded Typesを導入してみる / TypeScript一人カレンダー が詳しい。

僕はこんな感じに実装に入れてみた。https://github.com/naoyafurudono/naoyafurudono.github.io/commit/778270955b4c4e7672f50600fb28dff6c12b9fa0

全てがstringになりがちで不安になるけど、これなら安心安全。型の名前を信用できるようになって、名前をつける意欲も湧く。嬉しい。

makeって、ある種CLIのDSLみたいなものだが、helpを自動生成してはくれない。いい感じにやるための工夫を見つけたのでシェアする。

以下はconnectrpcのサンプル実装リポジトリにあったmakefileの一部

.PHONY: help
help: ## Describe useful make targets
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-30s %s\n", $$1, $$2}'


.PHONY: all
all: ## Build, test, and lint (default)
	$(MAKE) test
	$(MAKE) lint


.PHONY: clean
clean: ## Delete intermediate build artifacts
	@# -X only removes untracked files, -d recurses into directories, -f actually removes files/dirs
	git clean -Xdf
...

make help とすると、呼び出せるmakeのtarget一覧とその説明を出力してくれる。便利。コメントのフォーマットを定めておいて、helpを呼ぶときにはawkとかでmakefile自身を処理することでヘルプを出している。

2024-11-26

https://architecture-con.findy-tools.io/ これに来ている。

登壇資料のまとめがあるとのこと

これはあくまで僕のメモであって、発表とか僕がお話しした人がこのまま主張したわけではないです。変なところがあれば僕のせいだし、良い主張があれば彼らのおかげです。繰り返しですが僕のメモなので第三者が読んで何かに活かしたり議論の種にすることは、しない想定です。僕が便利なのでインターネットにおいておくだけ。

  • トレードオフ分析をすることが仕事
    • 最強ソリューションを出すことではない
  • トレードオフは絶対にある、ないと思ったらまだ見つかってないだけ
  • https://speakerdeck.com/findyinc/modern-trade-off-analysis?slide=15
    • デザインは挙動に関する議論であるがアーキテクチャは能力に関するものであるから、徐々に変えるのではなく最初からスパッとやらないといけない
  • フィードバックが早いのは良い。軌道修正はできる
  • ex マイクロサービスの粒度
    • 単一の責任だけでは曖昧で無理
    • 分ける要因と統合する要因を考えるべきだと主張
    • ハードパーツの本に書いてあったやつだな
  • 名前つけるのが難しいから、名前がつく粒度まで分解しちゃう、みたいな話が出てびっくりしてる。理にかなっている気もするがパッと受け入れられてない
    • メッセージングの件
  • ベストプラクティスは、状況に対して何をやれば良い、という提案。ベストなので判断の余地はない
  • 組織の目的は考える必要がある
    • 絶対壊れちゃいけない v.s. 要望からリリースまでの時間の短さ
  • 設計を繰り返すために定性分析して、結果的に定量分析しよう
  • 過去のベスプラが今野アンチパターンになるのはエコシステムがコンスタントに変わるから
  • それに追従するためにも分析を続けるのがよかろうということかな

感想: トレードオフとビジネス要求、をみて決めるのだなという気持ちと、無限に時間がかかるのでタイムボックスを決めてガッと決めることなのだろうと思った。それを何回も適宜行うイメージ。

saas: 業務のベスプラを提供するモデルテナント: 契約の提供を受ける単位のことコントロールプレーンとアプリケーションプレーンなるほど。コントロールプレーンはなるだけ作りたくないテナント、本当に必要なのか?は気になる。ここで主張されるテナントには何が含まれるのだったか。テナントの本存在するのか。

  • クライアントでブラウザを使わない、リアルタイムサーバがあるのがwebアプリとの違いっぽい
  • 専用ゲームサーバ: DGS, dedicated game serer
  • DBがやばかったのはspannerを使うことでなんとかなった

  • モブプロ

  • BDD

  • イベントソーシング

  • どんなコンポーネントがあって、どう連携するかを決める

  • vuca, ooda
  • 観察とか行動とかは具体的に何をするんだろう
  • マイケルポーター 競争優位
  • ask the speaker
    • 競合優位性でググろう、本を読もう
    • エンジニアがやっていくとスムーズそう
    • 増田さんの会社がワークショップを開催したり、本を出したりするかも

なんで全く新しく作らなかったのだろう

  • バンブーで1日かけて設計したとのことだが、どうやって決めた?意思決定プロセスが気になる。強い人?
    • 強い人が決めると決めてる。領域ごとに担当者がいる。これはknowledgeworkの意思決定プロセス(口頭でシュッと聞いただけなので、書いた内容は正確ではなさそう)
    • もちろんレビュー依頼などはする
    • それだと独裁になるのがいや。なのでこの会議で決めるとしている
    • そこまでに議題は共有されている。異論があれば準備しておく
    • 異論が出なければ決まる

scim: azureとかでユーザ作ったらsaasでもユーザ作るみたいなやつ

バッチとバックエンドはapi呼び出しで繋がってたのかな

IRでのシナリオ気になる。エンドポイントだけでなくシナリオを作ってるのかな

取り巻く環境の中で継続的な改善可能性をもつシステムを作る環境に合わせる話は大事変化を発見したときにちゃんとついていく。変化を捉えることは必要そう

  • 実現したいことをトッププライオリティにおく、ビジネスissueとしても重視する。それを実現する手段には拘らない。でもその分野についてのビギナーには手段が中心に見える。その目的が見えない。なんでその手段を取るかを理解するのは難しい
  • こうしたら良くなるの提案を頑張って説明する。自分の主張も大体間違ってると思ってドキュメントを事実ベースで論理的に書くと成功確率上がる。言語化して検証する。

  • いろんなところがconnect使ってる。layerx、knowledgework、flattが確か使っているとのことだった。
  • アーキテクチャの話を聞きにきたはずが意思決定の進め方とか社内での役割について質問していたし勉強になることが多かった。あとは共感できないか、もう知っていることが多かった

オフレコのつもりで話していた方もいるだろうからここには詳細書かない方が良さそうかな。知らない業種の話を聞けたり、一方的に存じ上げていた方のお悩みをお聞きしたのが印象的。また増田さんや他の登壇者の方に質問したり、そこから発展したお話し伺えて楽しかった。ドメインエキスパートどこにいるんだよ、いなくない…?みたいな話を質問した。他にも色々お話し聞けた。

増田さん、川中さんのお話が響いたし、発表後に質問に伺って教えていただいた知見が良かった。熱い気持ちになっている。そのほかのセッションではFlattセキュリティの内容が面白かった。ASM、そんなステップが中にあることを今まで全くイメージできてなくて、概要を知れたことが嬉しかった。 Webアプリケーションの構造を始めて学んだときみたいな気持ち。登壇者がラムダノートのWebブラウザセキュリティの本の著者だと聞いてなるほどな気持ち。

増田さんからはドメインモデリングと事業を進める話を学んだ。訳書である「ドメイン駆動設計をはじめよう」を読んで、今回の発表内容の結構な部分を腹落ちさせていたのだが、増田さんがどこをどういう形で支持しているかを知れたのが収穫。また、僕が抱えていた悩みとして「ドメインモデリングしたいが、ソフトウェアだけじゃなくてドメイン自体の設計も僕たちが結局やる必要がある。ではドメインをどう作っていくのが良いだろう」というのがあった。それを増田さんにぶつけてそれが真っ当な悩みっぽいと共感していただけた(と僕は思っている)ことと、それへの対処(競争優位を重視して作るとか、エンジニアから歩み寄ってディレクタとかと会話するとか)を引き出せたことが収穫。あと懇親会で色々お話し聞けて楽しかった。ここのお話しから収穫あったのはそうだけど、人柄を知れたのがでかい。

川中さんからはプロダクト開発における意思決定の進め方を学んだ。初期には対象範囲(バックエンドとかフロントエンドとか)を決めて強い人が決める、それに対して責任を持つ、範囲の境界の契約(APIスキーマとか)はちゃんと決めて厳格に運用する。まあ確かにシュシュっと決まりそうだし、なんとかする未来を描きやすそう。

その他の意思決定の仕方として、やはり強い人が提案をして決めにかかるやり方もあるそうだが、それだと独裁になっちゃうので最終決定を会議でするようにしてるとのこと。決める内容はあらかじめ共有しておいて、反論があれば会議までには用意する必要がある。会議で異論がなければ決まる。もちろんレビューを依頼することはある。

2024-11-25

  • それぞれの記事に「次の記事」と「前の記事」へのリンクをつける
    • 記事のレンダリングとは別にページの属性として前後の記事のURLかパスを持たせるように、テンプレートみたいにすると良い。計算フェーズを分ける

2024-11-20

  • proto2cliを実装する
    • やった
    • 名前を決める:connectはブラウザやgRPCと互換性のあるAPIを提供するのに必要なボイラープレートが必要なのを軽減してくれるやつ。
      • これはそれらにCLIをインターフェースとして加える。つまりローカルから、サーバを立てる事なく実行できるようにする。そういう立ち位置がいい。単にインターフェースを一個加えるだけ。実装はできるだけシェアしたい。
      • まずはconnectを採用するアプリケーションを一個用意して、それにCLIを入れる。ここで上手い入れ方を探る
      • 次にその入れる作業を自動化する。そのためのCLIがproto2cli
    • サブコマンドでサービス、位置引数でメソッド、フラグ引数(-d)でリクエストメッセージを受け取る。
      • サブコマンドと位置引数は最初は特に区別しなくていいか。 cmd <service> <method> -d <request message json> の形式で呼び出すだけ。
      • CLIへの入力はそのままサービス名、メソッド名、リクエストメッセージがそれぞれbyte列かstringのどちらかで得られる。それらをなんとかするのは一旦別のコンポーネントの役割にしよう
      • ここまでは普通にflagsパッケージとかを使うだけでいける
    • 次にリクエストメッセージのデコードを自動化する。
      • func unmarshalRPC(service, method, req string) (MessageInterface, error)
        • 対応する型のunmarshellerへのディスパッチとその呼び出しが責務
      • dispatchUnMarshelelr(service, method string) (func(byte[], MessageInterface) error, error)
        • ディスパッチだけでも良さそう
    • 次に、サービスの呼び出しを行う
      • connect サーバをclient経由で呼び出す
      • 単にサービスを呼び出す
        • インターセプタを通過できない、特にproto validateを通せない
      • インターセプタとサービスを合成する
        • できればhttpサーバの仕組みに乗っかりたい
        • でも無理がありそう、intercepter (unaryfunc) を受け入れてデコレートする感じにしそう

以下のようなprotoスキーマを定義する。

syntax = "proto3";

package nfurudono.sample.v1;

service SampleService {
  rpc Say(SayRequest) returns (SayResponse) {}
}

// SayRequest is a single-sentence request.
message SayRequest {
  string sentence = 1;
}

// SayResponse is a single-sentence response.
message SayResponse {
  string sentence = 1;
  bool dry_run = 2;
}

こんな定義があるときに

$ ./sample say --sentence "hello world" --dryrun
sentence: "I will say: hello world"

みたいなやりとりを定義するためのCLIテンプレート生成ツールを作る。あくまでテンプレートなので、生成ツールではインターフェースとかグルーコードだけ提供して、ユーザは以下のようなコードを書くことになる。

  • connectとかでサービスとサーバの起動を定義してmainからいい感じに呼ぶようにすると、gRPCサーバがたつのに対して、
  • CLIテンプレート作成ツールでサービスとCLIコマンドの呼び出しを定義してmainからいい感じに呼ぶようにすると、CLIから実行できる

package service

import (
	"fmt"
	
  sample "github.com/nfurudono/gen/go/sample"
)

type SampleImpl struct {}
// sample.SampleServiceはprotocとかが生成するようなinterface。gRPCとかconnectとかで使われているようなやつ。
var _ sample.SampleService = &NewSampleImpl()

func NewSampleImpl() { return SampleImple{} }

func (* SampleImpl) Say(ctx *context.Context, req *connect.Request[samplev1.SayRequest]) (*connect.Response[samplev1.Response], error) {
	s := req.GetSentence()
	d := req.GetDryRun()
	if d {
		return fmt.Sprintf("I will say: %s", s), nil
	}
	return fmt.Sprintf("%s!!", s), nil
}

package main

import (
	slog
	
	tool "github.com/naoyafurudono/good-tool"
	"github.com/naoyafurudono/sample-cli/service"
)

func main() {
	s := service.NewSampleImpl()
	// NewCLI()の結果(CLI)はサービスを登録される。
	// サービスを保持するCLIはサービスが契約するrpc(名前、入力、出力)を知っている。
	// これらはprotoの仕組みで生成される。protovalidateなどのプラグインもそのレイヤで対応できるはず。
	cli := tool.NewCLI().AddService(s)  // このあたりのインターフェースはもうちょい考えても良いかも?
	// Runがコマンドライン引数を読んで以下を半ドアリングする
	//   - 呼び出すrpcの判定(ルーティング)、サブコマンドの名前が対応する
	//   - rpcに渡す入力messageのデコード、サブコマンドへのフラグ引数が対応する
	//   - rpcの出力メッセージやエラー内容の出力、コマンドの標準出力、標準エラー出力、コマンドのステータスコードの出しわけが対応する
	if err := cli.Run(); err != nil {
		slog.Fatalf("unexpected input: %w", err)  // 予期しないサブコマンドが来たらエラーを返すのもまた一興かな。
	}
}

便利じゃない?

2024-11-13

fzfで表示される選択肢と選択した結果得られる値を分けられるようにしたいので作った。 yamlでkey-valueペアのリストを保持しておいて、そのキーの選択をfzfで行い、得られる値はvalueである、みたいな感じ。

#!/bin/bash

# ヘルプメッセージ
function print_help {
    echo "Usage: $0 <yaml_file>"
    echo
    echo "This script allows you to select a key from a YAML file using fzf, and outputs the corresponding value."
    echo
    echo "Options:"
    echo "  -h    Show this help message and exit"
    echo
    echo "Sample YAML format:"
    echo "  key1: value1"
    echo "  key2: value2"
    echo "  key3: value3"
}

# -hオプションのチェック
if [ "$1" == "-h" ]; then
    print_help
    exit 0
fi

# 引数チェック
if [ -z "$1" ]; then
    echo "Error: No YAML file specified." >&2
    print_help
    exit 1
fi

# 引数からYAMLファイルのパスを取得
YAML_FILE="$1"

# YAMLファイルの存在チェック
if [ ! -f "$YAML_FILE" ]; then
    echo "Error: File '$YAML_FILE' not found." >&2
    exit 1
fi

# キーをfzfで選択
selected_key=$(yq e 'keys | .[]' "$YAML_FILE" | fzf)

# キーが選択されていない場合
if [ -z "$selected_key" ]; then
    echo "No key selected." >&2
    exit 1
fi

# 選択されたキーに対応する値を取得
selected_value=$(yq e ".${selected_key}" "$YAML_FILE")

# 値を標準出力に表示
echo "$selected_value"
exit 0

上のコマンドを fzf-keyvalue-select という名前でパスを通しておく。その上で以下のような関数を登録しておくと便利。

function notion
    set url (fzf-keyvalue-select ~/.local/fish/notion.yaml)
    and open $url
end

2024-10-16

  • トピックをセクションのタイトル (hN要素) で宣言して、それを集約したページを勝手に生成するようにしたい。
    • about:<TOPIC_NAME> <TEXT> という名前のタイトルをヘッダにつけたら、/topic/<TOPIC_NAME> というページを生成して、  そこに <TEXT> - <DATE> みたいな名前のセクションを埋め込みたい。元記事へのパーマリンクも添えておくと良さそう。
    • 読書記録に使えそう
    • その他にも普通のブログではタグを記事につけるようなノリで使うのも可能。記事の単位だとタグによる分類は不便に思うのだけど、セクションくらいの粒度ならつけるときも読む時もちょうど良いだろうと思う

エンジニアリングの中ではプログラミングは割と得意なのかもしれないとここ1ヶ月くらいでなんとなく思うようになった。こういうプログラムの構成の方が良くない?みたいなことを理由込みでそれなりに説明・提案できることが周囲より多そうな気がしてきたので。

失敗できないように作るとか(設計、型の宣言)、失敗には早く気がつけるようにするとか(リント、コントラクト、バリデーション)、プログラムのあるべき振る舞いをテストするとかは似たような話に思う。先に挙げたものほどフィードバックが早くて良い。リントとかテストはそのプログラムそのものの性質ではなくて外からどうこうする点が特殊。テストではこういうふうに使うと確かにこんな感じに振る舞う、みたいな確認をする。リントではこういう感じの使い方をするとやばいからやめておいて欲しい、と怒る(この観点では型と一緒)。リンターのライフサイクルは対象のソフトウェアと一緒とは限らないのが辛いところなのかな。型システムは言語の一部だし、設計はプログラムの一部。でもリンターは一部とは限らない。一部になっている奴はだいぶ使い勝手が良いが、そうでないやつはいろんな人が勝手気ままに思想を入れるし、それらの互換性は比較的真面目には考えられないだろうから品質が悪くなりそう。

そういうわけでリンター難しそう。

2024-10-10

  • protobufとかsqlcでファイル生成をするツールを使ってチーム開発をしているとすごくコンフリクトして辛い。生成するファイルを分割して、例えばrpcとかmessage単位にファイル(パッケージではない!)を分ければgitのコンフリクトは避けられる。パッケージも一緒なので振る舞いには影響しない。

2024-10-06

LLMはコンパイラとかみたいに説明とか分析を出力してくれるものではあるけど、 LLMはコンパイラよりも人間に近いものだと思っている。コンパイラみたいな決定的な出力をするツールに対して良い入力を与えてその出力をそのまま共有することには価値がたくさんあるけれど、 LLMから得られた出力をそのまま「LLMに聞いたらこう返してくれました!」っていうのは(少なくとも現代使えるLLMのレベルでは)意味が薄いと感じる。

人間に対して質問して、その回答をそのまま人に共有することにも、場合によって価値がたくさんあったり薄かったり感じることがそれぞれある。質問を回答してくれる人間に対して信頼というか専門家としての信頼というかがあったら、そのまま回答を知りたいと思うが、その辺のただの人とか単に知識がたくさんあるだけな人だと、 (アンケート回答のデータとかなら別だけど)意見や情報としては価値を見出しにくい。そんな感じに、ぼくはLLMを専門家だとはまだ思えていない。単に知識がたくさんあってそれっぽい文章を生成するだけの(論理的思考の欠けた)出力をするやつだと思う。

とはいえ知識や経験がたくさんあれば結構な量の論理的思考は不要だろうことは段々わかってきた。なんのために考え事が必要なんだろうね。そして論理的思考とは何なのだろう。

今週は疲れた。先週の金曜から毎日飲み会だとか人と会ったりだとかのイベントがあった。それぞれは楽しいのだけど全てに参加していると大変。昨日はずっと寝ていたし、今日は家事をしていた。本を読む気力もない。体としては寝ても良さそうなのだが頭は何かをしたがっているので文章を書いている。本を読みたい気持ちもあるが、落ち着いて考え事をしたい気持ちもある。今その本を本当に読みたいのだったか、とか。

わかったつもり 読解力がつかない本当の原因 (光文社新書) に本屋で出会って読んでいるのだが良い。わかるとか理解する、みたいなことは一体何なのかは高校生の頃からのぼくのテーマの一つなのだが、それを一段深めてくれている。

ぼくの中での「理解する」とは、説明をつけることとか腹落ちしていることであった。論理とかは客観的なアレとして社会的に認められていたり、自然科学は実際問題役に立っているので市民権を得ているが、そんなことは「理解している」とは関係ないと思っている。理解しているか否かは主観的な問題で、腹に落ちた感じがするなら自分はそれを理解していると思うし、自分が同意できる説明を他者がするなら他者はそれを理解しているように感じる。そういうものだと思っていたし、今も思っている。

この本の説明ではぼくの解釈と矛盾しない中で理解の程度を論じているように思う。文脈とそれに対する解釈を持っている人間は、文脈を新たに獲得し明らかにすることで対象の解釈をより鮮明にする、みたいな主張だと今のぼくは大体思っているはず。鮮明にするというか、よりわかるというか。

これまでのぼくの理解への価値観には抽象度の違いがなかった。抽象解釈をするときにどれだけfineに解釈するかの違いが認識する文脈の違いに依存することをこの本に解らさられた。

この前ご近所さんとお話した影響で今日は八百屋に行ってきた。はじめて行くタイプの八百屋で、なんとカゴとレジは存在しなくて、床に陳列されている野菜を見ながら店員さんに口頭で欲しい野菜をクエリするタイプの買い方だった。ちなみに野菜の品質はそんなに良くなかったので次は他のところかなと思っている。安くはあった。

結局人は自分と近しい考えを読んでそれを楽しいと思うのだな、みたいなことを恩師が言っていたのを思い出した。ぼくもそう思う。そういう答え合わせみたいな読書は楽しい。

読書に限らずおしゃべりとかでもなんやかんや同調とか、似たような哲学のもとでの「議論」みたいなことをするときが楽しそう。「あいつはやばいから!」と嬉しそうに友達を紹介する人は、大体その友達と大差ないとかだとか。議論をするときに背景に共通点を見出して群れるのもそういうことだと思う。良し悪しは知らない。

named-letです。

2024-09-18

日記からtodo一覧を抽出して専用ページにtodoアイテムとその文脈を列挙する機能を実装した。この手の機能はtodoに限らず文章で考えや記録をつける人を幸せにするだろう。

例えば、読書メモをする場合、ぼくはそれを日記に書きたい。でもある本についての読書メモはまとめてみたい気持ちもある。そんなときに、その本に関する記述をまとめてみる機能があると幸せなはずだ。あくまでメモなので、その内容はその日の自分に依存する主張を持つ。なので、日記としての文脈は必要なはず。日記はぼくの考えたこととか記録を時系列でまとめたものであって、ぼくにまつわるいろんなものは時系列に沿って進んでいく。考えて、書くのも時間的な変化とともに進めていくものだし。なので書き出すフォーマットは日記が良い。楽だし、情報が失われにくそうなので。

その反面、読み方によっては他のアスペクトで抽出したりまとめたいこともある。それは日記を切りはりしたものとしてある程度表現できるはず。普通にぼくたちがあるアスペクトでまとまった記述をするときには、時間をかけて一つの側面から解釈しやすいようにする。文書を作成するときは反復して改善するものだし、推敲をするものでもある。では推敲をしない文書作成は、あるテーマについて日記を切り貼りしたものなのではないだろうか。

その切りはりをやるツールとしてtodo一覧の抽出みたいな機能を使えると思う。

セクションの単位でアスペクトを宣言できると良いだろうと思っている。あるいはAIでアスペクトを後付けしてもいいかもしれない。でも、どちらかというと、ぼくは普段の日記を書くときに後から見返す解釈を意識してかけたら楽しいだろうと思う。なのでアスペクトは明示的に日記を書く人が付けられるといいと思う。ふとアスペクトを思いついて、これまでの自分はどう思ってたんだっけと気になることもある。そのときには確かにAIに全部みていい感じにタグ付けしてほしい。

あと、今はunifiedを使って実装しているけど、pandocに移行しても楽しそう。型が辛いと思っているので。pandocはhaskell製なので型が弱くて文句を言いたくなることはないはず。

2024-09-16

  • 掃除
    • ルンバを起動したのでok
  • 外出
    • 電車乗るくらいの外出をする。秋物出たかな。あるいは外で使うと幸せになれるグッツを買うか。
    • ランニングパンツと靴下を買う。帰省でランニングのズボンを置いてきたのと、靴下が大体ボロボロになってきたので。
    • 靴下は買った。ランニングパンツはまあいっかと思って買わず。そのほかに秋に向けて服を見たけどピンと来なかったので特に買わずだった。
  • 本読む。k8sのあれ。あとは認証の技術気になるので学ぶ。認可も気になる。
  • todoをリストアップする拡張の実装
  • todoの拡張、出先でチェック入れたくなりそうなので、githubでの編集へのリンクをつけたい
    • やっぱりいいや。出先ではのんびりしよう。todoのことなんて忘れればいい。

https://diary.nfurudono.com/todos/に実装した。これでもう過去のtodoを忘れない。収集とレンダリングの両方が必要でだるかった。特にレンダリングはunifiedのアーキテクチャを理解してなくて手間取った。今の実装がunifiedのアーキテクチャに沿っているか自信がない。

本棚を作って設置したところ、そろそろキャパシティが限界だと気がついた。本棚を増やすためには引越しが必要。そろそろ減らしてもいい本も増えてきたので、 2年周期の引越しで問題ないとは思うが。今で3/4年か…、今年のうちに西側の探索をしたいな。今度友達とどこに行くか決めてないので、そっちの方に雑に行ってみて案内してもらおう。向こうが詳しいかは知らないけど。

寝たり本を読んだり景色をみたり、考え事をしたりする環境として電車で過ごすのが好き。年末は北国に電車に乗りに行きたいな。高校生の頃に一週間電車に乗りっぱなしの旅行をしたけど、あんな感じのことをまたやりたい。それでいうとシベリア鉄道は憧れる。

景色が変わるのがいいし、椅子しかないのも良い。なので新幹線みたいな机があるのはそれほど好きじゃない。横に細いサイドテーブルみたいなのはok。ものを置けるけどそこで何かやる感じではないのがいい。集中できるし、パッと休憩しようと思ったら外を見ればいい。なので電車に乗るのは日中がいい。夜は外が見えないので興醒めする。

家にいても景色が変わらなくてつまらない。外に出るのも良いが、それだと本読んだりできない。電車の中は家と同様に自分が暇なのに快適で、移動しているのがいい。

金曜日の昼過ぎに三連休だということを知った。なんと来週も三連休だということだった。この三連休は本棚を作り、あとは家でまったりした。こういうのもあり。

2024-08-15

日記をnextjsでビルドして、cloudflare pagesにデプロイするようにした。cnameの設定が効くようになれば、https://diary.nfurudono.comから見えるようになるはず。

cloudflareのアカウントを初めて作って設定したが、体験よかった。デプロイとか周りの開発のためにCLIツールやそれのgithub actionsバインディングが提供されていて、サクッとデプロイできた。記念すべき初デプロイの成功をメモしておくhttps://github.com/naoyafurudono/naoyafurudono.github.io/actions/runs/10399555684/job/28798614059

Hugoの設定をたくさん書いていても楽しくないのでNext.jsでなんでもやってみよう、というモチベーション。unifiedがいい感じで楽しいので動くところまで持って来れた。

ソースコードはhttps://github.com/naoyafurudono/naoyafurudono.github.io/tree/main/tools/ttにある。

2024-08-03

ソフトウェアを設計するときにはどこを変えやすくしたいか(どんな変更をしやすくしたいか)を把握したい。 Expression probremは必ずしも解決しなくてよいと思っていて、変更に必要な気合がどれくらいかを把握したうえでそれを許容できるかが論点だと思う。

もちろん使う気合が小さいのに越したことはないのだが、コード読み書きするのはみんな好きだろうし、嫌いなひとは割とAIに任せられる世の中なのだから、小手先のテクニックでなんでもできる設計とかにしておくうまみはあまりないと思う。

会社ではmacbook proを使っていて、家ではmacbook airを使っている。使っているソフトウェアとか設定は大体同じにできていて便利ではあるのだけど、今日は手ぐせで会社でよく触っているリポジトリにcdしようとして失敗するのを何回もやってしまった。 lsのノリでそのディレクトリにcdすることに辛さを感じる。

  • 飲み会の場所を抑える
    • ビールをたくさん飲めるところでそう遠くないところがいい
  • 健康料理
    • 野菜を食べたいです
  • 外出
    • 15:30を回ったが、まだ外に出ていない。お日様が欲しい
  • 洗濯
    • あとは干すだけ
  • 運動
  • ルータを吊るす
    • そういえば家の壁に釘打っても怒られなさそうな板が壁に付いているので、そこにルータをなんとかつけたい

今日は小学校4年生の頃に転校してきた友達の誕生日。ブルーアイズホワイトドラゴンをくれた、寡黙なやつだった。元気だといいな。

2024-05-12

社内外のrubyistの人たちとたくさん喋れた。明日ruby.wasmの話を聞けるのが楽しみ。質問するぞ!!1

2024-05-12

チャットを読み書きするのが大変なのではなく、それらを始めるのが大変という話。ラインが嫌いとかでは全然ないし、会話が嫌いなわけでもない。

僕はラインを手紙くらいの速度でしか見たくないと思うような付き合い方をしてしまっている。議論とかすり合わせをガッとする文脈になれば集中して通知を気にするようにはなれるのだけど、そうではなくて雑談とか、会話ではなく外部の処理に時間のかかるイベントの後処理とかをする文脈だとなかなか通知を見れないというか、そこに意識と返信の気合を割けない。

そもそもラインとか会話に限らず、返信とかリアクションを外部からの割り込み契機で行うのに辛さを感じる気がしている。例えば宿題出されてそれをやるのがしんどいのと同じイメージ。自分からこの辺の分野・技術を学んでみようと思ってやるのは何も辛くないし、むしろ他の辛さを乗り越えてでもやろうと思うが、それが外部から要求されると辛くなる。

おそらく原因は人から指図されることではなく、自分がそれをやる体制に入っていない状態で、やる義務を感じてもやる気にならないことにあると思う。宿題はやり始めて意義を感じたり調子が出たりすることでやるのが辛くなくなる。それが2,3週間かかるものであったとしても、体制に入れると辛くなくなる。

ラインの件も同じだと思っていて、普段僕は会話や事務処理をするモードではない。そのタイミングで人からその依頼が飛んでくると、会話に返事する義務を感じはするものの、処理するやる気は出てこない。

雑談はしてると楽しいし、事務処理も乗ってくると楽しいものではあるのだが、それらを始めるのに時間がかかるし、大変なのだ。これは子供の頃から変わらない(なんなら全人類そういうものなのではないだろうか)ので受け入れて自分の問題として迂回するなり利用するなりしていこう。

ちなみに仕事でSlack使うのは全然苦ではない。仕事するためにSlackでコミュニケーション取るのは有効だと思っているし、始業はすでに始めるインセンティブを持てているので苦なくSlackコミュニケーションは取れる。プログラミング集中してるときとかは通知に気がついてもちょっと返信したくないときがあるにはあるが、それくらい。基本的に仕事するときにはリアクションを優先するモードになっているのだと思う。コードレビューと同じ意識を持っていて、普段のあれとは異なる。そして、仕事する時間は決めていて休日にSlackの通知は切っているがそれが他の人に対しても共通の認識になっているのは良い。

ラインでも時間決めてプロフィールに書くとかするか?(あまり書きたくないけど)。休日の作業しない時間とかになりそうではある。ちなみに今がほとんどそんな感じの運用になっている。

感謝を伝えるのが苦手で、ご飯奢ってもらったりプレゼントをもらったときとかどういう顔をすれば良いかわからなくなる。

ラインでそれをやらないといけない状況ではなかなかヤバい。気がつくとなぜだかわからないが(ライン見ないからなのだが)伝えたい感謝が2,3個溜まり、ついでに謝りたいことも少しできてたりする。早めに、こまめに連絡するのが良いのだろうな。

感謝を伝えるのは単に技術の問題な気がするのでさっさと習得しよう。特に複数溜まった感謝の意を伝える能力が欲しい。

会話やチャットに文脈があるように、僕が日々過ごすことにも文脈というかモードというかがあるみたいだ。仕事、雑務、おしゃべり、勉強、家事、読書(小説)、読書(技術書)、外出、網羅的でも排他的でもないが、それぞれに飽きて数ヶ月やらなくなることはないが、数週間くらいならおろそかになるものが出てくる。

排他的ではない例として、仕事な雰囲気になっているときに雑務、おしゃべり、プログラミングは全然する。ただし、雑務やおしゃべりはプログラミングに集中しているときはできないし器用に行き来も無理。

このセクションは、だからどうというわけではないのだけど走っているときにそんなことを思ったのでメモ。

2024-03-20

Webアプリケーションのテストをどう実施したものかと最近考えることが多い。 Webアプリは雰囲気で変更したいはずで(ソフトウェアって大体そう?)、またテストは長持ちしてほしいと思う。

テストではなんらかの仮定のもとで実装がある条件を満たすことを検証する。その仮定を上手に置くことがテスト戦略を決める人の腕の見せどころだろう。

例えば関数の単体テストをする場合は、そこに渡す実引数を仮定して、その関数の出力が意図した通りになることを検証するし、モックを使うならそのモック対象の振る舞いを仮定することになる。 e2eではユーザの操作を仮定するのだろう。

いろんな仮定の置き方とその結果実現できる検証内容がある気がしていて、安定した仮定(覆るとテストを直さないといけない)を選びつつ、そこがクリアできれば安心と思える検証内容を取ることがテスト戦略の設計で目指すことなのだと朝の東横線で思ったのだった。

で、そういうお得さを出せるように実装するのも大事なんだろうなと思っています。

2024-02-26

人間失格の主人公はそんな失格っていうほどやばい人には思えないというのはあるあるだと思っていて、そういう感想を抱いたことで自分を許せるようになったと思う。そういう人も結構いるんだろうと思う。

太宰修がまともじゃない人間について描写したおかげで、それを読んだぼくみたいな他人がもっと救いのある解釈を手に入れられたのだ。当の太宰修は自殺してしまった(理由をぼくは知らないけど)が、彼の残した解釈のおかげでぼくはそれなりに幸せに生きているのでなかなか感謝している。昔は太宰修は愚かだと思ったけど、たたきを作った人は偉いし、その恩恵を自分は受けているのだった。

久しぶりにUbuntuでブログを書いのだけど、入力がキビキビしていて気持ちがいい。最近は会社や私物のmacを使っていた。何が違うんだろう。

2024-02-12

管理画面の設計について考えてみる。 Webアプリケーションでもろもろを設定する際のUI設計を考えている。

設定の初期化時や更新時でフローが異なるはずだ。

初期化のタイミングでは、氏名やメールアドレスの設定・認証や、オプショナルな事項(決済情報とか追加の契約事項とか)の設定が挟まり、最後に確認してよければコミット、ダメなら修正する。

更新では最初の設定で気に食わなかったところを修正したり、追加の設定項目をいじったりするだろう。

それぞれのタイミングで何を設定させるかや、どれだけサクサク入力できるかによってユーザの体験が左右されそう。例えば初期では認証情報だけをコミットして、その他の情報は更新で登録する手もあれば、ファストバスを登録時に持ってきてしまって、8割のユーザが最短で使用を開始できるようにするパターンもあるだろう。

ユーザが行うそれぞれのフローはアプリケーションというかシステムにどのような影響を与えるだろうか。というよりも、ユーザがそれぞれのフローの結果及ぼせる作用をどのようにデザインすると良いだろうか。

この作用をデザインするにあたって、アプリケーションで表現するモデルがどんなであるかを明らかにしておくと良いはずで、そのモデルに対する作用の一つの実現方法としてユーザが操作するフローがある、と思えそう。

ユーザによる操作じゃない作用としては、決済が行われたとか権限が時間経過で失効したみたいな作用がありそう。

データにもいろいろありそう。モデルを表現するためのデータと、作用を実現するために一時的に保持するデータは異なる。

例えばユーザが登録されているか登録されていないかしかないモデルでは、メール認証中にはユーザが登録されていないけど、メール認証のためのトークンとかはサーバにデータとして持っていないといけない。

もちろん、そういう一時的な状態もモデルに含めるてもあるはず。RDBで実装する場合delete操作が激しくなりそうだけど。セッションキーもそうかな。セッションキーはモデルを表すデータに持つことは少なさそう。モデルの表現には含まれないログイン状態として扱われるイメージがある。揮発性のあるデータストアで保持しそう。

全部モデル化してしまうのが教科書的なんだろうな。汚いとわかるならあえて汚いことをやる必要はないだろう。

モデルではないけど、DBMSの都合について説明する記事があったので貼っとくセッションの保存などにRDBMSよりもRedisやmemcachedのような、NoSQLが向いているのは何故ですか?他にNoSQLの用途として向いている(いない)処理にはどのようなものがありますか? (Quora)

TTLが欲しいよね、という感じか。確かにそもそもセッションキーにはTTLが欲しい気がするし、モデルを考える上でTTLはあまり意識したくない気もする(頭弾けそう)。

反面、TTLもうまく表現したら面白そうな気もするし、割と欠かせないんじゃないかという気もする。そのときに普段のモデルを表現するのに使うDBとTTLを複雑さを吸い取らせるために導入したDBが異なると不必要な複雑さが生じたりするかもなと思った。

今日たくさん寝て軽くランニングしたらなかなか幸せな時間を過ごせた。ただいまはそのクオリティが持続していない。夕食の目処が立っていないこととか部屋がちょっと寒いこと、姿勢が微妙なことが原因だろう。軽く座って作業する空間はやはり欲しい。机にがっつり向かうか後傾でノートパソコンを叩くか、床で作業するかの三択でQOLっぽい作業時間を過ごす空間がない。コメダで作業する姿勢を家でも取れるようにしたいイメージ。やはりベンチソファだと思うんだよな。僕のユースケースだとソファだけでなく机も欲しいことに気がついたのが今週末の成果。

あとは壁が寂しいことにも気がついた。なんか怖くないすっきりとした絵とか飾ればいいんだろうな。めんどいので誰かに決めてほしい。ああいうのってどこで売ってるんでしょうね。

2023-11-07

ドキュメントを読むときに参考文献が適切に使われていないと辛い。ドキュメントには2種類あると思っている。

  1. 水先案内
  2. 主張をするドキュメント

主張をするタイプのドキュメントで参照先を読まないと主張を理解できない場合は辛い、というのが今回の主張。

水先案内のドキュメントとしては、wikipediaの水先案内ページやgoogle検索の結果ページが該当する。水先案内のドキュメント自体は主張をしておらず、その水先案内ページに辿り着いた読者が適切なドキュメントにたどり着くためのサポートをする役割を持つ。

主張をするドキュメントとしては、この記事やAPIの仕様を説明するページなどが該当する。参考文献とか例を上げる目的で引用とか他のドキュメントへの参照を持つことはあるけれでも、そのドキュメントを全く読まないでも主張を理解できることが期待される。もしも読まないと理解できないのであれば、その文章は主張をできていないんじゃないかと思う。サーベイ論文は主張をするドキュメントだと思う。参照を探す目的で使うこともできるけど、対象をサーベイしてこういう歴史があるとか界隈はこういう感じになっているよねといった主張をすることが目的なはずなので。論文のアーカイブページは水先案内。

ドキュメントはそれ自体で完結していて欲しいので、参照先に主張の内容が書かれているはドキュメントとして不十分で読むのが辛い。内容ではなく根拠を委譲するのは良いし、よくある引用のスタイルだと思う。

2023-09-13

今家のトイレで気がついてんですが、冷蔵庫と自分の体にはどんな落書きしても人に迷惑かけないので落書きし放題です!! 何書こうかな…。

人生楽しくなってきた。今度人生つらそうな人を見たらこれを教えてあげつつ、鏡のある場所を教えつつ、マッキーをプレゼントしよう。

ちょっと前に買ったbowmoreが美味しい。味の表現はさておき美味しいからそれでいいんです。テイスティンググラスでストレートで飲んでいます。 aged 12 yearsと書いてあります。

350ml瓶を買ったんですが、このサイズの便が一番かっこいいです。他のサイズでかっこいいのはフロムザバレルくらい?

350のbowmoreはリュックの横に挿してもいいかなというくらいかっこいい。

会社ではあだ名で呼ぶ文化がある。それはなかなか楽しくて好きなんだけど、人生のほとんどを苗字呼びの文化で過ごしてきて、会社の飲み会で苗字よびをしてもらって、「ああ、こんな感じだったな」と昔の感覚を思い出した。新しく上の人から苗字呼びされる経験は僕にとって深いところに刻まれた体験なのかもしれない。

ホッピー師匠とも知り合えたことだし、今日の飲み会は僕にとっていいものだった。明日は走って帰るか。判断は夜にするとして、ランニングシューズを履いて、ジャージを持って出勤する。

まふまふの夢花火を久しぶりに聴いている。中学生に頃に友達にまふまふのCDを貸してもらって夢花火をしり、高校までめざましは夢花火だった。懐かしい思い出。

去年の暮れに会社の同僚がまふまふファンだと聞きちょっとテンションが上がったことを思い出した。今はまふまふの他にもdazbeeやado、co shu nieとかのアーティストが好き。オタクって感じがする。

オタクっぽくない歌手っているかと思うと、どのアーティストもそのアーティストが好きというと途端にオタクぽくなる気がするので気にすることではなさそう。 AKBもSMAPもheysayjumpも何もかも、アーティストが好きって言ったらおタックぽい気がする。

オタクっぽさを排除して「この曲が好き」みたいなことを表明しようと思うと、自身の音楽性に芯があるか流行りに乗っていくミーハーみたいになりそう。

そろそろ世間体について考えるのに疲れてきた。このくらいにしよう。僕がコモンセンスとして取れている自信を持っているのは、新劇場版のエヴァの最後のやつで「よかったねぇ」と思えたことです。ATフィールドは全ての人の間にあると思っているタイプの人間です。よろしくお願いします。

オフィスカジュアルっていうのやめません? 曖昧で、インターフェースで要求しているような感じがしつつ、実装する側にはその要件が伝わらない。コミュニケーションのための符号としてあまり良く機能していないように見える。

  • ジャケット
  • シャツ
  • パンツ

以上の四つについての要求を書いて欲しい気持ちが芽生えた。これらが指定されない限りは、どれだけフォーマルに寄っても、喪服まで行かない限りは文句言えないと思うし、喪服まで行かなくても服を着てくる側に対して不親切だろう。

ブログを分割したい

このブログは日記も開発っぽいことも両方書いてある。これらを別のサイトに分けようと考えている。

  • 開発の記事が日記に埋もれるのが嫌だから
  • 今の環境だと開発の記事を書きにくい・表現しにくいから
    • コードや数式を書きにくい・表示が微妙など
    • madoko使いたい

そのための準備としてnetlifyを試しに使ってみた。このブログのリポジトリを登録したら、特に細かい設定をしないでもシュッとデプロイできてしまった。すごい。DNSとかSSLとかの設定を試していく。

ところでデプロイの設定は何もわからないのでチュートリアルが必要。madoko使うなら設定ちゃんとしないとだろうし。

タスク分解と見積もり

見積もりとかについて真面目に考えてみる。

仕事をするときに、頑張ります!と意気込んで、目標を分解しひとつひとつこなしていくことはある程度できるし、途中で分解したタスクが違った方を向いていることに気がついて、自分がやることを軌道修正することもできる。

全部ではないけれど、ある程度のことは十分に時間があれば達成できるんじゃないかと思う。特に目標を具体的に描けていればできることは多い(できないことをなかなか目標として想像できないとか、そもそもできないことがある、みたいな話はそれはそうだけど一旦置いておく)。

仕事とかチームで動くときとかでは、歩みを揃えられることが大事なわけで、自分の好みで十分な時間を消費して良いわけではない。仕事では、目標に、達成する事項だけでなく期限がついてくる。目標を達成できそうかを判断するには、期限と見積もりを照らし合わせれば良い。

目標は期限と達成する事項のペアだと思うことにして、達成する事項のことはタスクと呼ぶことにしよう。つまり、目標はタスクと期限のペア。今まではタスクを分解して一個ずつクリアしていけば良かったが、仕事では目標を分割して、タスクをクリアする中で期限も一緒に守らないといけない。次元が増えるのだから難しくなるのは当たり前だ。

タスクの分解は、タスクをよく観察して論理的に推論すれば割と上手くいく。それに対して期限を含めてうまく目標を細分化するには、つまり見積もりをするには、自分の能力や環境要因、タスクの達成の確実性などを含めて考慮しないと考え切ることはできない。

見積もりは曖昧さを伴ったものになるはず。そこが難しいのかな。また、タスクを分解して軌道修正をするとタスクはそれで洗練される一方で、期限の方は純粋に遅れが生じるのも難しい。時間は巻き戻らないのだ。

見積もりを安定させるには、このように生じる遅れの量を最小化すれば良い。そのためには目標の分解を小さくして、細かい粒度で軌道修正すれば安定するはず。あまり細かく分解しないでガッと取り組みうまくいけば最速だし、細かく分解して検討を繰り返して良さそう良さそうと確認をたくさんするのは時間がかかる。それでも確認することを込みで見積もることはできるので、安定性の面ではやはり有利に働くだろう。この辺りは最急降下法とかで、一回のイテレーションでどのくらい進むのが良いか、みたいな話と似ている。

なんにせよ、今の僕は安定した見積もりをできていないので学習の意味を込めて、細かすぎるくらいのタスクの分解をするのが良いのだろうなと思った。

自分の性格と合うだろうか。

先ほどの段落で、一発でガッと仕事して上手くいけばそれが最速、みたいなことを言った。これが実際にありうるのは個人で仕事をしているときであって、チームで仕事をするときには普通以心伝心というわけにはいかず、解釈違いやすり合わせ、議論に会話が必要だろうし、それができるのがチームの強みのはず。

これをこまめに行うことは、多くのチームにとって課題だろうし、僕がチームに参加するときに度々足りていないなと思うところでもある。

タスクの分解を細かくすることでコミュニケーションの機会を増やせるだろうから、チームでの仕事には細かいタスク分解がプラスに働きやすそう。

dotfilesのセットアップスクリプトを書いた

dotfilesをGitHubで管理しているのだが、今までは設定ファイルの管理だけで、インストールは手動で行なっていた。設定ファイルを使いまわせるだけでだいぶ便利なんだけど、コンテナ環境の中で作業したくなると、手動インストールに耐えられなくなる。そこで重い腰を上げてセットアップを自動化した。

git のインストールと以下の実行でok。 nvimとかfishとかcargoとかが入る。

git clone https://github.com/naoyafurudono/dotfiles.git
bash dotfiles/setup.sh

test

arm環境かつubuntuだけでしか動かしていないが、dockerコンテナでセットアップスクリプトを動かして、正常に終了するかを確認するテストを書いた。

この手のセットアップスクリプトのテストって、世の中ではどのようにテストしているんだろう。以下の難しさがテストを大変にしている気がする。

  • 環境依存な部分をうまく吸収する必要があること
  • インストール失敗の判定が難しいこと

2023-07-01

envsubstを使うと標準入力の環境変数の参照っぽいところに環境変数の値を埋め込んだテキストを吐ける。 readmeにコマンドのヘルプメッセージを載せたいときに便利。例: https://github.com/naoyafurudono/tools/tree/main/cl

gitで管理しているファイルのパスが得られる。 git grepみたいに管理対象だけに興味があるときに便利そう。 fzfとの相性が良さげ。

2023-05-04

  • 昨日スクワットしてからランニングしたら、今日トレランに行った翌日みたいな感覚になっている。手軽に足の疲労感を感じられておとく。
  • この間オンライン飲み会をしたときに秋吉台ロゲに参加することを決めてしまった。 5/21に5時間走る予定。競技エリアが「秋吉台山焼きの実施範囲」とされていて絶対楽しい。 5時間走って新幹線に飛び乗り、翌日仕事できる体力をつけないといけない。まずはたくさん走ることに慣れよう。5/6の午前中にたくさん走ることにする。ロゲイン的な走り方をしたい。平野ではないけど山でもないところをのっぺり走り続けるようなスタイルをイメージ。

2023-04-28

今日は意味論の直感が少し生えたので機嫌がいい。寝て起きたらもう少しまじめに考えよう。

完全に忘れていた。一回捨てた継続渡しスタイルで考えるのがやはり良いだろうという直感のもとでの考えだった。細かいことは忘れてしまったが、少し考えれば再現できる程度だったと思う。継続フレームを生むときと、式を評価するタイミングを明示的にわけるとか、反対にそういうくくりで共通化することでこれまで見えていなかったアスペクトが表面化していい感じになりそう、みたいな直感だった気がする。

2023-04-27

人と語るわけでもなければ、熱狂的に推すわけでもないのに、僕はなにのためにアニメを見たり、小説を読んだり、音楽を聞いたりするのだろうか。アニメはほぼ毎日みるし、小説は人並み以上に読むと思う。漫画もそれなりに読むし、音楽もなんやかんや毎日聞いている。これまでそういう作品の良さをまともに語ったことはないし、積極的に人と共有したりもしない。物語のキャラクターを推したいと思ったこともない。アーティストを好きになることはあっても、エッセイを読みたいとはあまり思わなくて、あくまでその人の作品が好きだからアーティストを好きになっているように思う。

アニメや漫画は単に面白いからだろうか。少なくとも日常的に触れる作品はそういう毛色が強い気がする。たとえば、鬼滅の刃やかぐや様のアニメはおもしろいから見ている。その一方で、ゾクゾクする経験があって、それが好きだという側面もある。たとえば91daysは面白かったがそれ以上にゾクゾクしたから記憶に残っている気がする。 Fate heaven’s feelやヴァイオレット・エヴェーガーデンも僕にとってゾクゾク系。

音楽はゾクゾクするのを求める気持ちがより強い。Co shu nie には特にゾクゾクを求めている。その他アニソンやボカロ、ピアノ、その他jpopも、そのときの気分にあったゾクゾクを求めて聞いている気がする。横道だけど、900STを買ってから飛躍的に音楽を聞くのが楽しくなった。幸いなことにヘッドホンはまだこれしか買っていない。初手でいいものを買う戦略が功を奏した。昨日くらいから電車通勤で音楽を聞くことに良さを見出してしまい、ワイヤレスでノイキャンのついたいいヘッドホンが欲しくなってしまった。

話を戻そう。ふんわり楽しい時間を求めるのと、ゾクゾクするのを求めるのの、2つの欲求があってそれらを満たすためにアニメとか音楽とかを浴びているようだ。それらの限らず、僕の幸せはそのどちらかにあるような気がする。ゾクゾクするほうが刺激的で楽しいので、今後はそっち方面の体験を増やすために意思決定を進めようと思う。

散歩をしてきて、本当に音楽とかに限らない話だと思った。プログラミング言語や数学のことを考えたり、プログラミングをしたり、オリエンテーリングをするときに、僕が一番好きな瞬間でモチベーションになっている体験はやはりゾクゾクしたときのことだと思う。今挙げた分野でのゾクゾクは、ハイになって、理解のぎりぎりのところで間に合ってというか、手が届いて自分のものにできた感覚だ。それに対して音楽とかアニメとかでのゾクゾクは、与えられた気持ち良さですごく心地良い体験だったり、強く共感したり、よくそこまでいった!すごい!みたいな感動から来る気がする。どちらのゾクゾクも僕を幸せにしてくれるけど、なんとなくプログラミング言語と戯れているときみたいなゾクゾクのほうが欲しい気がする。

2023-04-03

オリエンテーリングの人たちと飲み会をした。社会人としての心構え()を教えて頂いた。今日の入社式から頑張って行こうと思う。

こういう書き方をするとふざけているようにしか見えないだろうけど、内心ではそれなりに不安に思っているし、しっかりとしたフィードバックも受け取れたと思う。

今日、明日で良い出会いをできるといいな。

2023-03-19

最近AIが流行っていて、精度がすごいと話題で、生活が多かれ少なかれ変わっていくのだろうなという感じがする。ああいう機械学習ベースのAIは学習で直感を鍛えて、それに基づく出力をするものだと僕は解釈している。人間が頭を使うときには直感を論理とか議論で検証して、主張の穴を見つけて改善するサイクルを回すはずだ。今の機械学習っぽいAIは直感で得た主張を論理で解釈しないだろう(NECがそういうことを考えていそう。それができればAIはもっとつよくなるはずだし、そういうAIを見てみたい。

実現するためにはAIの入出力に使う「言語」に解釈を入れることと、それをもとにして論証を行うことが必要だろう。今のAIは抽象構文木を操作の対象にしていて、それを意味を解釈するようにしたらいいんじゃないかという想像だ。

今ある論理が世の中の事象を扱うのに十分かはわからないし、多分結構不足しているはずだ。機械学習AIのための論理体系の研究とかあったら楽しいだろう。NIIとかでやってないだろうか?

おととい届いたBig Peatがとてもおいしい。明日の研究室飲み会にもっていこう。ちょうど二年くらい前に部活の先輩に勧めていただいたのだが、懐具合の問題で飲めずにいた。少し無理してでも飲んでおいたほうが良かったかと思うくらいには好き。ストレートで飲んでもおいしいし、ハイボールにしてもおいしい。天才か? ぼくはスコッチウイスキー?が好きなのかもしれない。

学部2年のころ、確率論基礎の試験の前日にウイスキーを飲む会に誘っていただいたとき、ラフロイグ・ロアを味見させていただいて半分感動したのを覚えている。あのころは二十歳になりたてでお酒のおいしさは今よりも分かっていなかったのだが、それでもいいかんじなことは分かった。それからラフロイグ・ロアには縁がなかったのだが今気になっている。数量限定なようで、毎年11月ころに発売されそうな雰囲気がある。今もアマゾンで売ってるが、転売価格に見えるので時期がくるまで我慢しよう。

ちなみにBig Peatと一緒に勧めていただいたジョニーウォーカーのグリーンラベルはすでに飲んでいて、 やはり好きな感じだった。

使い勝手の良いデスクトップ向けウィンドウマネージャが欲しい

使い勝手のよいウィンドウマネージャがWindowsとかMacに搭載されることはないだろう。使うアプリケーションやブラウザ、入力デバイスやその使い方によって使い勝手が大きく変わるだろうから。 OSが決め打ちで提供できるものでは無いんじゃないかと思う。なので自分でまじめに使い勝手の良いものを考える必要がある。

先日オリエンテーリングのインカレの配信のお手伝いをしたのだが、そこで使っていたスイッチャがなかなかデスクトップでのウィンドウマネージャの機能として魅力的に感じた。

スイッチャにはいろんなウィンドウ(カメラからの入力や、図、合成用のテロップなど)が接続されていて、すべてが画面の下部に控えめに表示される。それらを見ながらスイッチャのオペレータが放送するためのウィンドウを選択、合成する。放送されるウィンドウは画面上部に大きく表示される。放送されるウィンドウの右に同じサイズでプレビューウィンドウも表示される。これらの違いは放送されるか否かだけで、合成のテストとかに使える。

これを実現するためには操作用のデバイス(このデバイスをスイッチャというようだ)と、大きなモニタが必要だ。

デスクトップのウィンドウマネージャでもスイッチャのように

  • すべてのウィンドウを表示しておいて
  • 本番+alphaくらいのウィンドウをメインエリアに表示する

と便利な気がする。単純にはいかないだろうけど、いい線行きそうだ。

懸念事項は以下の通り:

  • ウィンドウの個数が多くなりそう
  • ウィンドウサイズが固定ではない(アスペクト比)
  • ウィンドウの動的な生成とその配置方法が非自明

エフェクトハンドラの良さと実用性について

エフェクトハンドラで継続や代数的エフェクトを扱う必要性は一ミリもなくて、実用的にそれらが欲しくなることはないか、あるいは限られていてそこまで一般的な機能を提供する必要はないんじゃないかと感じている。

このあたりを議論するために

  1. エフェクトハンドラの嬉しさ
  2. 意味論の歴史的経緯
  3. 改善ポイント

を考える。

なお、この記事はとくに裏付けもなく書いている。気が向いたら裏付けをしようと思っているが、この記事の目的は僕の考えの整理であって、世に主張をしたいわけではない。

記事の内容は不正確なことを留意されたい。

エフェクトハンドラが実際的 (practical) なプログラミング言語でエンドユーザに使わせたくなるのは

  • エフェクトシステムと相性のよい意味論
  • 動的束縛

を提供したいからではないだろうか。エフェクトハンドラを言語に入れれば、それで表現できる操作は自動的にエフェクトシステムで追跡できるし、ハンドラを用いることでエフェクトをローカルに使えるのは特筆するべきだろう。汎用性とlocal reasoningのしやすさはエフェクトハンドラのもつ良い性質だと思う。

エフェクトハンドラで実現できる動的束縛はとても使い勝手が良い上に、エフェクトシステムで追跡することで使い勝手が上がりそうだ。動的束縛のためだけのエフェクトシステムではなく、もう少し凝ったことができるエフェクトシステムがつくとなお幸せだろうから、エフェクトハンドラみたいな抽象度の比較的高いフレームワークで実現するのは幸せなんじゃないかと感じる。

エフェクトハンドラと呼ばずに “algebraic effects” とか “algebraic effects and handlers” とか呼ぶ流派、時代がある。歴史的には

  • algebraic effects
  • algebraic effects and handlers
  • effect handlers

みたいな流れで登場したはずだ。最初はハンドラはなくて、モナドとかの話をするような人たちが副作用にモナドではない別の表現を与えようとしたんだったか。ここでいうモナドはモナド則とかを真面目に考えるような数学のモナド。代数的エフェクトもその流れの中に(このころは)あったはず。そもそも代数的エフェクトの代数とは、操作が(0だか1こ以上)あって、それらに等式制約を課す。それを満たすようなモデルを持つのが代数 (algebra) である、みたいな世界だっと思う。群とか環は代数だけど、体は代数じゃないみたいな話を聞いたことがある。そういうのりの代数として、エフェクトを表現したらモナドの合成みたいなことを考えるときに幸せだ、という主張がことの発端だった気がする。

ここまでは数学とかモデル理論?とかの話によっていて、あまりプログラミング言語っぽい雰囲気がしない。ハンドラとか継続が入ってきた経緯はしらないが、多分、プログラミング言語に代数的エフェクトを入れるにあたって、モナドのbindやreturnみたいなものを定義するように、エフェクトに意味を与える仕組みとしてハンドラが考えられたんじゃないかと思う。このあたりは論文をまじめに読めば分かるはず。これが確か2014年くらいのこと。

2000年くらいだったかから考えられていたエフェクトシステムとの相性に目をつけたからか知らないが、「代数的エフェクトとハンドラ」を取り入れた言語が2014年ころに登場し始める。2017年くらいにでてくる印象がある。 EffやKokaはこのへんな気がする。このあたりで、エフェクトが代数的であることはとくに気にされなくなっていき、エフェクトシステムと例外ハンドラがうまいこと組み合わさる限定継続演算子くらいの気持ちで代数的エフェクトとそのハンドラが捉えられて、やがて代数的ではないことが気になる人々がエフェクトハンドラと呼ぶようになったのではないかと思っている。

限定継続は本当に必要だろうか。もっとやさしい概念を提供するのにとどめるのはいかがだろうか。ワンショット継続とかに限定する言語もあるが、それは正しい方向性だろうか。

僕たちがほしかったものは、local reasoningしやすいエフェクトシステムとそれで健全に管理できる意味論なんじゃないかと思う。エフェクトハンドラはその条件を満たすけど、もっと使い心地のよい意味論があるはずだと思う。

最後の文をメモしたくてこの記事を書いた。それ以外は文脈である。

軽いドキュメントを印刷するためのツールが欲しい

さくっと書いた文書を印刷したいことがある。ビジネスライクな手紙とか、その日のTODOリストなんかがそうだ。 LaTeXやMadokoを使うのは大げさな感じがして、諦めて手書きするか、Google Docsで済ませることが多い。とはいえ手紙の書き方を毎回調べたり、フォーマットを調整したり、PCで打ち込んだデータを手書きするのはつらい。

テンプレートと変数の宣言、UIの調整と文書のまともな処理をして印刷(A4)できるものが欲しい。A4のPDFに変換できればよい。それぞれの文書のソースはマークダウンのちょっとした拡張くらいの文法で書きたい。エディタで編集したいのでGoogle Docsとかはなしで。テンプレートの作成方法はテキストにこだわらない。いじりやすいと嬉しい。

問題が以下のように分割できるはず。

  • テンプレート作成
  • ソースの文法
    • Markdown拡張
  • テンプレートへのソースの埋め込み
  • PDFへの変換

HTML/CSSやlatexを勉強してMadokoでくっつければなんとかできる気はするが、大変そうだしあまり楽しくない。文書作成ツールを自作するか?とりあえず、HTML/CSSで手紙を表現できるようになるところから始めるのが良さそうか。自作マークダウン拡張(というより処理系)はまれに欲しくなるのでやっても良いだろう。Hugoもそんなに快適じゃないし、Madokoはいじりにくいので。

  • 自分でコードをいじりやすいこと
  • メタな文書処理がしやすいこと
    • 識別子や文書の変数への束縛、正規表現やCFGベースのテキスト置換など
    • この辺はMadokoが強い
  • そういえばMadokoはPDFの生成でHTMLを使わずにlatexを使っていたな…

ここまで来て、Paper CSSという良さげなリポジトリを見つけた。 Qitaでこのライブラリを使って帳票を作る例が解説されている

まだそれぞれをあまり読んでいないのであとで確認する。このあたりの技術に合うように出力することにして、それを生成するマークダウンエンジンを用意すればok?

やはりしんどい気がする。GUIでなんとかする方法を探すのが楽だろうか。あらためて考えよう。

Google Docs APIを利用するのはどうだろうか。 APIはあまりリッチではなくて、create, update, pullができるのみ。文書構造の編集はJSONをごりごりいじることで実現する。JSONスキーマが定義されているので、これを見ながら必要な変換を定義すればよい。

テンプレートをGoogle DocsのGUIで作成して、それをAPIでpullした上で、コンテンツを注入したドキュメントをcreateすれば、やりたかったことを実現できそうだ。テンプレートの置き換え箇所の指定方法はどうするのが良いだろうか。

(開始記号)名前(引数リスト)(終了記号)を文書に埋め込む。これがひとかたまりの文書オブジェクトとして認識されることが必要。また、これにスタイリングを適用した場合、埋め込み後もそのスタイリングが保たれるようにする。引数に他の名前が出現しうることに注意する

テンプレに埋め込むテキストを定義する側では、埋め込み内容の定義リストを作成する:

def name(args: list[str]) -> str:
  return f"""\
ここに置換後の文字列を書く。
ここにも埋め込みの出現を許す。
"""

埋め込み処理では、JSON形式のテンプレのすべてのテキストについてマクロ展開をすればよい。

リブロワークスからCSSで組版するノウハウをまとめた本が5/12に出るらしい。途中までをオフィシャルが公開している。 Vivliostyleというソフトを使って、MarkdownとCSSで書籍を作るらしい。その手のソフトは他にもあるようで、比較サイトを先の書籍で紹介されていた。

こう思うとmadokoはだいぶ良いものだなと感じる。適用範囲を限定した置換とlatexはなかなか強い。 latexとcssを完全に理解すればmadokoが最高かもしれない。

HugoでタグをつけるためのTips

車輪の再発明ではあるだろうけどメモしておく。archetypes/hugo newで生成する.mdファイルのテンプレを置くことができる。そこにありうるすべてのタグを書いておけば、記事を書くときに関係ないタグを消すことで、関連するタグを忘れずにつけることができる。

僕は以下のようにフロントマターを設定している。

---
title: "TODO"
date: {{ .Date }}
author: "Naoya Furudono"
draft: true
tags: [
    "daily"
    ,"PL"
    ,"tech"
    ,"ubuntu"
    ,"alexa"
    ,"book"
    ,"idea"
    ,"python"
    ,"tool"
]
---

Local File Transfer

近距離でのファイル交換はあまり洗練されていない印象がある。 Apple製品間ではAirdropが使えるし、Windowsにも似たような機能があったはずだ。でも汎用的に(たとえばOSを気にせずに)使える機能は見かけない。そういうときにはGoogle DriveやDropBoxみたいなクラウドサービスを使うか、USBメモリを使うのが一般的だろう。 Slackとかメールに頼ることもある。

インターネットに頼るのは不便だし、USBメモリが刺さらないデバイスも多い。 Blootoothを基本の通信方式として、それが使えない場合にインターネットを経由するのはいかがだろうか。

通信技術は既存手法を組み合わせるだけで良いだろう。難しいことはないだろう。一方でアプリケーションのUIには工夫が必要なのではないだろうか。

  • どこにファイルを保存するか
  • OS間でのファイルの互換性
  • 送信先の選択
  • 受信の制御

これらの選択に一般的な回答は存在するだろうか? 他のアプリに組み込む形がよいかもしれない。例えばローカルの会議で各自が自身のPCで文書や画像、図面などを編集するアプリがあったとして、参加者間でのデータ共有のために今考えているものを使う。このときUIはアプリの特性から決まるだろう。

この例に対して、スマホやPCのファイルシステムは一般的すぎて設定を決め打ちできないのではないだろうか。そうすると、ファイル共有の実行時にユーザが設定をあたえることになる。大変不便だろう。

設定ファイルの編集やディスパッチの機能をつければ楽になるか? ルールエンジンとかは大げさだろうか。