近況 2022-05-31

今月の活動 (ミローネ言語、読んだ記事など)

ミローネ言語

苦境

ロスレス構文木の復元

  • ロスレス構文木を生成できるようにした
  • もともとASTやHIRなどの中間表現を使って入力補完を実装しようとしていて、これは厳しそうに思えた
  • なぜ厳しいのかうまく言語化できない
    • カーソル位置が . の周辺にあるかどうかや、そのドットの左辺を取り出す操作や、ノードがわたるテキスト上の範囲の特定のような処理は、ASTのように種類ごとに型が異なる構造だと記述が煩雑になる
    • カッコ式のカッコの位置のような位置情報が欠損しているので正常な範囲にならない
  • いったんロスレス構文木を作ることにした
    • ロスレス構文木は空白やコメントを含めてすべてのトークンがのっている構文木のこと (Roslynコンパイラやrust-analyzerが使ってる)
  • 既存のパーサーを拡張した
    • カッコ式のような構文要素を捨てずにASTのノードにする
    • カッコの位置のような、ノードの開始・終了の位置するトークンの位置情報を持つようにする
  • トークン列とASTを組み合わせることでロスレス構文木を構成できるようになった
    • パーサーを改めて書く必要がなく、バッチコンパイルではロスレス構文木を構築しなくていいので、よい方法かもしれない

所有権を使ったライブラリの拡張

  • 先月、所有権の機能が入った
  • それを使った抽象を標準ライブラリに加えている
    • StringBuffer (可変な文字列)
    • File (ファイルストリーム)
  • 記述が煩雑でつらい
  • 型とリソースの解放手段が結合しているので汎用性がない
    • 例えばRustではスライスをソートする関数をかける。スライスがどう確保されたかは無視できる
    • ミローネ言語には借用がないのでスライスを作れない
    • スライスを表す型を作ったとする
      • スライスを使った後に元の型に戻す必要がある
      • もし別の型に戻してしまったら、リソースの解放手順が異なるかもしれない
      • 同じ型に戻ることを静的に保証できない
    • 結果としてスライスに対する操作を型ごとに実装する必要があって、汎用性が低い
      • あるいはポインタと長さのペアを使ったunsafeな関数を書いてそこに投げる
      • これはこれでOwnの付け外しとポインタのキャストなどが煩雑
      • また、unsafeな境界面が広がるほどCでいいじゃんになる
    • 解放関数を動的に決めるほうがいいかもしれない (std::unique_ptr)

副作用の表現

  • 所有型であるIOオブジェクトを渡して回ることで、副作用を表現する算段だった
  • 記述が煩雑なのは承知の上だが、記述の煩雑さは想像以上にメンタルにくる
  • IO専用のdo構文のようなものを提供したほうがいいかもしれない
    • F# のコンピュテーション式の構文を流用するとか

読んだ記事など

Narrow but Deep? - Wide Awake Developers (2020-07-27 公開)

  • インターフェイスは狭くて深いのがよいという考え
    • 狭い: メソッドが少ない
    • 深い: メソッドがパワフル

Why I no longer recommend Julia

(記事に日付が書かれていないが、2022年5月ごろに公開されたはず)

  • Julia(言語)のエコシステムにおいてcorrectnessの不具合が多いこと、それが個々の実装の問題ではなくインターフェイスを明示しないことやエッジケースの意味が規定されていないことに由来する全体の問題(systemic problems)であること、この問題が問題として認識されていないことを指摘する記事

関連記事