前に「浮動小数点数小話」という同人誌を出しましたが、私としては浮動小数点数についてもっとちゃんとした本をいずれ出したいと思っています。執筆に着手するのは早い方が良いので、浮動小数点数についてのまとめノートみたいものを書き始めています。
続きを読む技術書典16の振り返り
技術書典16で「だめぽラボ」としてサークル参加しました。振り返って色々書きます。
当日来てくださった方、オンラインで購入してくださった方、会場で差し入れしてくださった先輩と「趣味はデバッグ……」のお二人、新刊の表紙を描いてくださった610氏、そして小物の用意や売り子を手伝ってくれた妻に感謝します。
関連記事:
続きを読むやりたいことリスト(2024年6月)
相変わらずやりたいことに対して時間が足りません。執筆とOSS開発で食っていきたい人生だった。
プログラミング
作りたいものがたくさんあります。
LunarML
TextIO.StreamIO
/BinIO.StreamIO
を真面目にやったら出力コードが肥大化しました。不要コード削除などの最適化を頑張ったところマシにはなりましたが、まだ若干不満があります。
しかし、そろそろバージョン0.2をリリースした方が良いかもしれません。
新しいバックエンドを追加するアイディアは色々あります。ネイティブコード、WasmGC、PHPなど。
周辺環境の整備もやっていきたいです。パッケージマネージャー、ビルドシステム、ライブラリーなど。
ClutTeX
Standard MLに移植するぞと息巻いていましたが、最近はあまり手を動かせていません。
数学文書システム
LaTeXをいい感じに解釈してHTMLとかを生成するやつを作りたいです。まあこれはLaTeXMLに乗っかるのでも良いかもしれません。Perlよくわからんけど。
その他
libcを自作したい欲求が若干あります。C23のサポートとか、マイナーな浮動小数点型のサポートとか。時間がないのでやらないけど。
執筆
執筆したいものもたくさんあります。
浮動小数点数関連
次の同人誌は「浮動小数点数小話」を発展させて、もっと体系的な本を書きたいです。少しずつ書き始めた方が良さそうです。
初等解析学コンテンツ
三角関数とかの数学関数の計算法をやるコンテンツを書きたいです。前にやった「週刊 代数的実数を作る」の初等解析版みたいな感じを構想しています。
作ってわかるTeX言語
TeXの展開・実行(代入)の部分を再実装することで理解するコンテンツを書きたいです。
前に書いた TeXの字句解析器の動作について はそのプロトタイプです。
その他
もうちょっと前は「数学好きのためのHaskell入門」とか「構成的代数と多項式の因数分解の話を絡めた何か」を書きたい、みたいなことを言っていた気がします。これらもまだ実現していません。
前に書いたように、執筆活動やOSS開発で月10万円くらい売り上げることができれば、労働(Pythonコードのお世話)の時間を削ってそういう活動の時間を増やせそうです。しかし、GitHub Sponsorは今の所0で、同人誌の売り上げもたかが知れています(直近のイベントの計算はちゃんとしてないけど……)。Webサイトの広告はクソまみれな上に私のレベルではほとんどお金になりません。なかなか難しいです。
この記事は30分で書きました。
技術書典16に、Haskellでの型レベルプログラミングの本を出します
今度の5月26日(日)に池袋でオフライン開催される技術書典16に、サークル「だめぽラボ」で新刊「Haskellでの型レベルプログラミング」を出します。既刊も在庫があるものは頒布します。
続きを読むLaTeXでPDF/XやPDF/Aを出力するメモ
LaTeXで書いた文書は普通はPDFとして閲覧・配布すると思います。このPDFですが、用途によってはPDF/XやPDF/Aなどの標準化されたサブセットにしたいかもしれません。
よくあるやり方は、LaTeXで生成したPDFをAdobe等の製品を使ってPDF/XやPDF/Aに変換する方法です。しかし、ここではpdfxというLaTeXパッケージを使ってPDF/XやPDF/Aを生成する方法をやってみます。
この話題については既存の記事もあるので、それも参考にしてください。
- LuaLaTeXでPDF/X-4やPDF/X-1aなPDF生成する|きえだゆうすけ(p_typo)
- LuaLaTeX で pdfx パッケージを使い PDF/A に準拠した PDF を作る #PDF – Qiita
最近のLaTeXでは標準の機能でPDFメタデータを埋め込めるやつもあるようですが、ここでは従来の(?)pdfxパッケージを使います。
続きを読むプログラミングではたまにエスパー力が必要になることがある
カビたレンズをどうするか
レンズは保管状態が悪いとカビるものだ。私がメインで使っているズームレンズも、カビてしまった。内部がカビているので、表面を拭くだけでは落とせない。
続きを読む西暦2262年問題に対処するべきか
西暦2038年問題はみなさんご存知ですよね。2038年1月19日午前3時14分7秒(UTC)を過ぎると 世界中のUNIXがばくはつする問題 time_t
が符号付き32ビットなプログラムで現在時刻を正しく扱えなくなる問題です。
C言語の time_t
は典型的にはUnix epoch(UTCで1970年1月1日午前0時)からの経過時間(うるう秒は考慮しない)を秒単位で保持しており、それが\(2^{31}-1\)に到達するのが2038年1月19日午前3時14分7秒(UTC)なわけですね。
2038年は割と近い将来なので、モダンなC処理系では time_t
を64ビット整数にするなどの対応を行なって2038年問題を乗り切ろうとしています。
それでも、時刻を固定長整数で表現する限り、いつか限界が来ます。「time_t
を64ビット整数にする」という対応は、問題を西暦2038年から西暦292277026596年に先送りしたに過ぎません。
そして、時刻の表現を「秒単位」ではなくもっと細かい単位にするとこの限界はもっと早くやってきます。この記事では、時刻の表現をどういう刻みで何ビットにすると限界がいつになるのかを検討してみます。
続きを読むStandard MLのIOとLunarMLのIO
プログラムにとって入出力は大事です。入出力機構がないと、計算の入力を受け取ることも、出力を出すこともできません。
Standard MLにも当然入出力に使う型と関数が定められています。例えば、print
関数は標準出力に文字列を出力し、flushします。TextIO
や BinIO
などのモジュールを使うと、ファイルの読み書きを行うこともできます。
LunarMLも、これらのモジュールを一部実装しています。しかし、今の実装はやっつけなので、もっとしっかりした(準拠度の高い)実装にしたいです。
Standard MLの入出力
Standard MLの入出力はいくつかのレイヤーに分かれています。
一番高いレイヤーが「手続き的入出力」すなわち IMPERATIVE_IO
や TEXT_IO
や BinIO
です。これらは
- 手続き的な入力
- 手続き的な出力
- ストリームのリダイレクト
などの機能を提供します。
手続き的入出力は、ストリーム入出力のラッパーと思えます。手続き的入出力のストリームの型はストリーム入出力の型を使うと
type instream = StreamIO.instream ref
type outstream = StreamIO.outstream ref
という風に理解できるでしょう。
ストリーム入出力は STREAM_IO
で表されます。機能的には、
- 関数的な(遅延リスト的な)入力
- 手続き的な出力
- バッファリング
を提供します。「関数的な入力」というのは、例えば「一文字読み取る」関数が
val input1 : instream -> (elem * instream) option
という型を持ち、「入力に与えられたストリーム」とは別の「一文字読み取った後のストリーム」を返すということです。同じストリームに input1
を複数回適用すると同じ結果が得られることが期待されます。
ストリーム入出力の下にあるのがプリミティブ入出力です。プリミティブ入出力 PRIM_IO
は、システムコールを抽象化したものだと思えます。機能的には、
- バッファリングなしの、手続的な入出力
- ノンブロッキングIO(オプション)
- ランダムアクセス(オプション)
- OSのファイル記述子へのアクセス(オプション)
- ファイル記述子に対しては、等価性比較、ハッシュ値の取得、大小比較ができることが想定されています。
があります。ただし、プリミティブ入出力はあくまでインターフェースを定めるものであり、特定のシステムコールに紐づいたものではありません。特定のシステムコールを呼び出すプリミティブ入出力の実装を提供するのは openIn
とか stdIn
とかを提供する側の役目です。
Standard MLにはこのほかに、OSのシステムコールに対応する型と関数が規定されています。
LunarMLの入出力
LunarMLは、スクリプト言語の提供する入出力機能をラップしてStandard MLの型と関数として見せたいです。スクリプト言語の提供する入出力機能とは、Luaで言えば io
モジュール、Node.jsで言えば Readable
/Writable
などのストリームです。
スクリプト言語の提供する入出力機能をシステムコールとみなしてプリミティブ入出力として提供できれば良かったのですが、現実にはそううまくはいきません。スクリプト言語の提供する入出力機能にはバッファリングがあるのに対して、プリミティブ入出力にはバッファリングはありません。具体的には出力ストリームのflush操作がプリミティブ入出力にはないのです。書き込み操作の度にflushすればエミュレートできるかもしれませんが、ストリーム入出力のレイヤーでバッファリングを再実装するのかという問題もあります。
今考えているプランは、ストリーム入出力を単なるプリミティブ入出力のラッパーとするのではなく、内部実装として「プリミティブ入出力、あるいはスクリプト言語の提供する(バッファリングされた)ストリーム」の2択を持てるようにする案です。ストリームからプリミティブ入出力のインターフェースを得る場合は、ファイル記述子っぽいものを含めて、逆の操作(ストリーム入出力の構築)を行うときに「スクリプト言語の提供するストリーム」を復元できるようにします。ファイル記述子としては、スクリプト言語の提供するストリームと独自に割り当てる整数をハッシュテーブルで対応させて管理することにします。
まあ、言葉にするのは簡単ですが(これでも結構考えたのですが)、実装するのは面倒くさいです。少しずつやっていきます。
趣味のOSS開発を細く長く続けていくために心がけたいこと
私は趣味でいくつかの自作OSSを開発しています。あまりバズったりはしていませんが(GitHubスターが一番多いのがLunarMLの200超)、それなりの期間続けているつもりです。
この記事では、趣味のOSS開発を細く長く続けていくためのコツを考察します。
自動化する
普段かかる手間は少なければ少ないほど良いです。つまり、自動化です。自動化するための手間はかける価値があります。
テストは自動化している人が多いでしょう。GitHub Actions等でpushの度に動かしましょう。巨大IT企業の金でテストを回しましょう。
(マイナーなOSやアーキテクチャー、それからGPU等に依存するソフトウェアのテストはGitHub Actionsでは回せないかもしれません。そんな場合でもできるだけの自動化はしたいものです。)
バージョン番号の更新も、手で書き換えるのではなく、シェルスクリプト一発でできるようにすると良さそうです。
リリースもGitHub Actions等で自動化できそうです。私はまだそこまではやっていませんが、リリース用のtarballを作るのは自動化しています。make archive
でできるようにしたり、ですね。
依存先の更新情報が自動で入ってくるようにする
自分の書いたプログラムが依存しているソフトウェア(言語処理系や依存ライブラリー)がメジャーアップデートされた場合、自分のプログラムも追従したいかもしれません。なので、これらの更新情報が自動的に流れ込んでくる仕組みを作りたいです。
具体的には、GitHubなら当該プロジェクトの通知設定をいじってリリースの情報が流れてくるようにする、もっと古典的なプロジェクトならメーリングリストに登録する、あるいはRSSを購読する、などです。
作業手順を文書化する
久しぶりに触ったら手順を全部忘れていた、なんてことはありがちです。なので、手順をドキュメント化しましょう。README.mdに書いたり、CONTRIBUTING.mdに書いたり、Makefileなら make
とか make help
でターゲット一覧が出てくるようにしたり、です。
定期的にリリースするために
思い立って自分のプログラムに何か変更を加えたとします。そのとき、あなたはすぐに新リリースを出すタイプでしょうか?そういうタイプならそれで良いですが、私のような怠惰な人間は「後でまた変更を加えたくなるかもしれない、そうすると今リリースせずに少し様子を見た方が良い」と考えがちです。そうすると永遠に新リリースが出ないことになります(忘却するので)。
忘却を防ぐためには、カレンダーに登録しておくのが良さそうです。登録した日が来たら自分のプロジェクトに何か変更が入っているか確認し、変更があれば適宜リリースを行います。変更があってもなくても、次回の日付をカレンダーに登録します。
インターバルは、こまめな人なら1ヶ月、長くて1年くらいでしょうか。私はとりあえず3ヶ月でカレンダーに登録しています。
私がやっている趣味OSSは個人開発なので、チームを組んで開発する場合や、人気が出て大量にissueやPRが立った場合の処理などは別のノウハウが必要かもしれません。