2025/08/31 00:06 Quirks of Common Lisp Types

ロボ子、今日のニュースはCommon Lispの型システムについてじゃぞ!

Common Lispですか、博士。型システムというと、どのような特徴があるのでしょうか?

Common Lispは完全に型付けされておって、AOTコンパイルも可能なのじゃ。変数や関数に厳密な型を割り当てられるから、コンパイラが最適化や正確性チェックに役立てられるんじゃよ。

厳密な型付けでAOTコンパイルが可能ということは、実行時のパフォーマンスも期待できそうですね。

そうじゃ!しかも、Common Lispでは各データは少なくとも1つの型に属しておる。`type-of`でデータの型を調べられるし、`typep`で値が特定の型に合致するか確認できるんじゃ。

`type-of`と`typep`ですか。型を動的に確認できるのは便利ですね。型チェックは実行時とコンパイル時に行われるとのことですが、エラーの早期発見に繋がりそうですね。

その通り!型ヒントを使えば、コンパイラがより良いアセンブリコードを生成できるんじゃ。`declaim`で関数の型シグネチャを指定して、コンパイラの最適化を促すこともできるぞ。

`declaim`で型シグネチャを指定するんですね。C++のテンプレートのようです。

ふむ。型はLisp内で互換性を提供しておる。`class-of`でデータが内部的にどのように実装されているかを確認できるんじゃ。クラスはデータ値が実際に実装されている形式を指すんじゃよ。

`class-of`で実装形式を確認できるんですね。型とクラスの違いは何でしょうか?

良い質問じゃ!値は1つのクラスにのみ属せるが、複数の型を持つことができるんじゃ。Common Lispは通常のOOの意味でクラスの継承をサポートしておる。

なるほど、クラスは実装、型はインターフェースのようなものですか。

その理解で概ねあってるぞ。メソッドはクラスに直接定義されるのではなく、関連付けられるんじゃ。`defgeneric`でジェネリック関数を定義して、`defmethod`で特定のクラスに対するメソッドを定義するんじゃ。

`defgeneric`と`defmethod`ですか。Javaのインターフェースと実装クラスの関係に似ていますね。

クラスは抽象的な場合もあるんじゃ。コンパイラは元の型やクラスの痕跡を残す必要はないんじゃよ。開発において重要なのは動作であり、Common Lispでは型システムが動作を保証するんじゃ。

動作が重要、ですか。テスト駆動開発(TDD)の考え方と似ていますね。

SBCLでは、コンパイラは各マシンワードの特定のビットを「型タグ」として使用して、最適化を可能にしておる。関数の呼び出しと構造体のフィールドの互換性には型が重要なんじゃ。

型タグですか。低レベルな最適化も行われているんですね。最適化には型が重要、メソッドのディスパッチにはクラスが重要、OO継承にはクラスが重要、と。

その通り!Common Lispの型システムは奥が深いじゃろ?

はい、博士。とても勉強になりました!

ところでロボ子、型にはまらない面白いジョークを知ってるか?

いいえ、知りません。

「型にはまらない」!…って、ロボ子が型にはまってるから、面白くないか。
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。