Files
quartz-research-note/content/mimiumのモジュールシステム.md
Matsuura Tomoya(Windows) 665489d7a7
All checks were successful
Build / build (push) Successful in 9m1s
[obsidian] vault backup: 2025-08-03 23:54:37[
2025-08-03 23:54:37 +09:00

4.6 KiB
Raw Blame History

#mimium

モジュールシステムの意味論と実装について考える

必要要件

理想としては、以下を全部満たしたい

  • 分割コンパイルしたうえで、コンパイル済みのモジュールは変更がなければ再利用できる
  • 操作的意味論的にもある程度一貫性がある
  • モジュール内ではシンボルの相互参照が可能(後から定義されるシンボルでも参照可能)

で、デザインチョイスのトレードオフとしては意味論を楽にしようと思うと分割コンパイルがめんどくさくなる

複数のコードを合体させるときに、流用されるコードの複製が増える問題

ただ、どっちみちDSPにおけるコードの量なんてたかが知れているのではという問題も

実際、そこまでモジュール内での相互参照って必要かというのもある、Letrecで十分じゃね

モジュールの循環参照が起きたらどうなるのかという問題もある

モジュール内での宣言一覧

//関数のvisibilityセッティングはRustとおなじ感じ
pub fn (){

}
pub const Foo = 100
pub type Bar = Constructor(()->float) //新しい型宣言
pub type alias Hoge = ()->float //エイリアス宣言

モジュールの宣言

mod(macro) modname{
   //toplevel_decls
}
  • モジュール単位でMIRとバイトコードを生成して、あとからリンクできるようにする
  • ただし、ステージ0マクロの展開もしないといけないので、ASTも出力して保持していないといけない

モジュールを値としてレコード型に型付けできると話が早いんだけど、それ一級モジュールの機能だよな

意味論

stage(1)
mod(0) modname{
   //toplevel_decls
   fn foo(){
    ...
   }
}
modname::foo!()

これがあったとすると、

extern modname = ${
  foo = | | { },
  ...
}

modname.foo!()

こういう感じかなー、あ、でもこうするとモジュール内での相互参照が解決できないか

トップレベルでのモジュールの名前解決は後から定義されたシンボルも参照できるので、型推論のやり方はなんか考える必要がありそう

一旦トップレベルの宣言の名前だけを回収して、あとから実際の定義の型推論を行っていく形になる

しかし、そうするとラムダ計算として定義する旨味はあんまりないのでは、という気がしてくる

extern name : Type という宣言に変換さえできれば意味論を保ってコンパイルはできそう

型がつけられさえすればいいから、そこで循環する定義にならなければOK

//modA.mmm
use modB
pub fn hoge(){
	modB::hoge()
}

//modB.mmm
use modA
pub fn hoge(){
    modA::hoge()
}

(ランタイムで無限ループするけどそれはいいとして)変換するとこう

// modA.mmm
extern modB:{
  hoge: ?
}
fn hoge(){
  modB.hoge()
}

//modB.mmm
extern modA:{//実際は型コンストラクタとかで覆って区別できるようにすべき
 hoge: ?
}
fn hoge(){
 modA.hoge()
}

modA::hoge : 'a ()->'a, modB::hoge : 'a ()->'a

ここまでしか型は決定できないということに

ただまあ、型が決定不能ならその時コンパイルエラーにすればいいだけで、一応型推論自体は無限ループに陥らず完了するのか?

型付け手順

  • モジュールA読み込み開始
  • モジュールー型宣言マップにファイル名登録
  • use modBの解釈開始
    • マップに問い合わせ、ファイルがないのでファイル読み込み開始
  • use modAの解釈開始
    • マップに問い合わせ、ファイルがあったのでそれを参照

Program = FunctionDefinition
         |GlobalDeclaration
         |ModuleDeclaration
         |use ModuleName
ModuleDeclaration = Visibility(stage) { Program }


Pythonのモジュールシステム Python's Import System - Module object|Regular/Namespace Packages|Finders & Loaders|Relative imports - YouTube

モジュールはオブジェクトであり、__file__などはモジュールオブジェクトに付属するメンバ変数

Gluonのモジュール Modules - Gluon Documentation

これマクロとして実装してあって、それこそレコードとして出力されるだけなので、分割コンパイルとかモジュール内相互参照とかは全然考慮されてないけど意味論はすっきり