C++ テンプレートメタプログラミングによるコンパイル時 Lazy K インタプリタ

※1. この記事は「KLab Engineer Advent Calendar 2020」の 16 日目にエントリしています
※2. 普段のこのブログの文体は常体ですが, 本記事においては Advent Calendar 用に敬体を使用します

Yellow duck Christmas ornament - m01229, Attribution 2.0 Generic (CC BY 2.0)

はじめに

この記事の公開日の 1 日前1に, プログラミング言語 C++ の新バージョン ISO/IEC 14882:2020, 通称 C++20 が国際標準として公開されました. これにより, いくつかの新しい言語機能や標準ライブラリが追加されます. その中でも, とくにコンセプトという言語機能は, テンプレートメタプログラミングが話題として盛んであった時代2から待望されていた言語機能のうちの 1 つなのではないでしょうか. この標準化によって, C++17 までで行う必要のあった多くの型制約のためのテンプレートメタプログラミングは, よりそれ専用の言語機能であるコンセプトを使う形に置き換えられるであろうと思われます. そのようなわけで, 今後徐々に出番を失っていくであろうテンプレートメタプログラミングを将来懐かしめるよう (?), テンプレートメタプログラミングによってコンパイル時に Lazy K ソースコードをパースして評価するインタプリタのようなものを書いてみました. 本記事では, これに関する実装と理論について紹介します. (型無し λ\lambda 計算について既知のものとします)


放物運動

放物運動に関する復習と再現.

等加速度運動をする物体の位置関数の導出

時刻 t=0t=0 における物体の位置を x0{\boldsymbol x_0}, 速度を v0{\boldsymbol v_0} とし, 加速度を考慮しない等速運動の三次元空間上の一点に対する位置関数 x(t){\boldsymbol x}(t)x(t)=x0+v0t{\boldsymbol x}(t)={\boldsymbol x_0}+{\boldsymbol v_0}t とおく. このとき, 時間 t1t_1 から t2t_2 への変化量 x(t2)x(t1){\boldsymbol x}(t_2)-{\boldsymbol x}(t_1)Δt=t2t1\Delta t=t_2-t_1 で割れば, 時間経過に対する物体の位置の対比が得られる. これは正しく速度のことであるが, これは時間 t1t_1 に位置 x(t1){\boldsymbol x}(t_1), 時間 t2t_2 に位置 x(t2){\boldsymbol x}(t_2) にあった物体の平均速度である. いま時間 tt における物体の瞬間速度を知りたいとすると, Δt\Delta t が微小量となるように極限(t2t1Δt0t_2\to t_1\Leftrightarrow \Delta t\to 0)を取れば良い.


Connector/C++ で MySQL を操作

  • 2018/07/20 09:31
  • C++

学校の関係で MySQL を触る機会が増えてきたので, MySQL の C++ 向けライブラリを一度触っておこうという忘備録.

これを実行すると, 次のように, 実在しそうでしなさそうな, 妙に怪しい雰囲気1の一覧が出力される.


C++ で Data.Tuple.Extra っぽいもの

  • 2018/06/15 01:50
  • C++

ふと, C++ でもこんなような記述, 普通に出来るべきなんじゃないかなぁと思った.

Prelude> :m +Data.Tuple.Extra
Prelude Data.Tuple.Extra> uncurry (+) $ first (*2) $ dupe 42
126
Prelude Data.Tuple.Extra> uncurry (+) $ (+42) &&& (*2) $ 42
168

取り敢えず, 似たような構文で同じような処理となるように作ってみた.


シンプルなブリッジのソフトウェア実装

以前の投稿, ARPパケットに対する挙動からネットワーク上の盗聴者を特定するにて, 実験を行うにあたりリンクレイヤー上のパケットの受信と送信を行なった. このパケットを別のネットワークインタフェースから送出するようにすればブリッジになるし, MAC アドレステーブルと照合して転送すれば L2 スイッチにもなるとのことで, 一応 Linux 上で動くものを作ってみた.

2 枚の NIC が必要であるが, Virtual Box の仮想アダプタを利用すれば良い. 実装の本質的な部分は, 異なるディスクリプタへの書き込みのみである. これを応用して, 複数個のネットワークインタフェースにも対応してみたい.