1 ポイント 投稿者 GN⁺ 2024-12-11 | 1件のコメント | WhatsAppで共有
  • 最小限の文法で計算を構成しようとする体系で、1つの演算子 と適用だけで最小性・チューリング完全性・反映性・モジュール性をすべて扱う
  • 文法は E::= △ | E E で、 が3つの値に作用するときに計算され、値は葉・茎・分岐ノードからなる自然な二分木である
  • 組合せ論理の KS を Tree Calculus の中で表現できるためチューリング完全性を持ち、λ-calculus と異なり再帰関数を正規形で表現できる
  • プログラムも値として扱われるため、自己適用による イントロスペクション と反映が可能で、size size が 168 に評価される例がある
  • 部分項が部分木として現れるため、共通機能のブートストラップ、シリアライズ、プログラム解析・最適化、静的・動的タイピングといったデモにつながる

1つの演算子で作る自然な二分木

  • Tree Calculus は Barry Jay が発見したもので、サイトには彼の書籍とブログ、Johannes Bader が開発したデモへのリンクがある
  • 中核的な特性は minimalTuring-completereflectivemodular の4つに整理されている
  • 最小性

    • Tree Calculus には1つの演算子 しかない
    • 文法は E ::= △ | E E という形である
    • 視覚的には はツリーノードで、E1E2 に適用すると E2E1 のルート右側に付く
    • 値は自然な二分木で、ノードは leafstemfork と呼ばれる
    • 実用デモ
      • portability: 複数のプラットフォームで単純かつ安全なインタプリタを作れる
      • emit-json: クロスプラットフォームな設定生成に適した例を示す

チューリング完全性と反映

  • チューリング完全性

    • 組合せ論理の KS 演算子を Tree Calculus で表現できる
    • K = △ △
    • S x = △ (△ x)
    • 組合せ論理の K/S 基盤が完全であるため、Tree Calculus も チューリング完全 である
    • λ-calculus と異なり、orange/brown のような不動点構成によって再帰関数を 正規形 で表現できる
  • 反映性

    • triage {l, s, f} = △ (△ l s) fleafstemfork に対する場合分けを行う
    • 自然数 n△^n △ で表現できる
    • 0 テストは triage {true, K false, K² false} で構成される
    • プログラムも値であるため、intensional プログラムは自己適用によってイントロスペクションと反映を行える
    • 例のプログラム size は引数のノード数を数え、size size168 に評価される
    • 実用デモ
      • serialize-anything: プログラムのシリアライズ可能性を扱う
      • halting-problem: 停止問題をより単純に定式化する
      • fusion: プログラム解析・最適化を関数として表現する
      • gradual-typing: 静的タイピングと動的タイピングを関数呼び出しとして扱う例を示す

モジュール性とデモ

  • 部分項は 部分木 として表現される
  • ページ上部の size プログラムは triage を使ってノードを再帰的に数える
  • 実用デモ

1件のコメント

 
GN⁺ 2024-12-11
Hacker News のコメント
  • Tree Calculus は、このウェブサイトの枠を超えた含意を持つ素晴らしいテーマ
    ただし、ウェブサイトが創始者であり著者でもある Prof. Barry Jay を明示していないのは残念。もっと知りたければ Jay の本を見るとよい: https://github.com/barry-jay-personal/tree-calculus/blob/mas...

    • 「Specification」ページで彼の本を参照してはいる
      出典表示はもっと明確にできるし、そうする予定だが、功績を横取りする意図はまったくない。背景はこの返信にもう少し書いてある: https://news.ycombinator.com/item?id=42375914
    • これを見た瞬間、Barry Jay の Bondi Language / Pattern Calculus が真っ先に思い浮かんだが、完全に見当外れではなかったようだ
  • かっこよく見えるが、このページは案内が少なすぎて理解しにくい
    「初心者向け」の説明のようなものがあるとよい

    • SKI 計算やその親戚である ラムダ計算のように、式を機械的に評価または簡約するための正確な規則を持つ単純な計算モデル: https://en.wikipedia.org/wiki/SKI_combinator_calculus
      SKI 計算と違う点は、自分のプログラム構造を内省できること、たとえば 2 つのプログラムが同じかどうかを判断できること: https://github.com/barry-jay-personal/tree-calculus/blob/mas...
      またラムダ計算と違い、与えられた簡約規則を適用するとプログラムが安定した 正規形へ収束し、無限の簡約列に陥りうるケースを避けられる: https://treecalcul.us/specification/, https://sci-hub.se/https://dl.acm.org/doi/abs/10.1016/j.tcs....
      そのため、プログラムをクォートしたりシリアライズして安定したデータ構造へ迂回したりしなくても内省が可能で、Lisp の 同図像性に似た面がある
    • メインのランディングページの構成はかなり奇妙
      流行のプログラミング言語やフレームワークのウェブサイトのように、一語のタイトル、少し buzzword っぽい文句、動くコード例を使っているのに、本文は過度に密で長い学術調の文章になっている。ところが、その学術調の文章だけで何が起きているのか理解できるだけの詳細はない
      しばらく段落を解析してみたが、冗長であるにもかかわらず、普通のプログラミング言語のランディングページのように「著者がこの言語の何を良いと思っているか」だけを語っており、動作の仕組みは説明していない。結局、仕様を見る必要がありそう
    • 仕様の文法 E ::= t | E E は、初見だとすべての式が単に t t t t t t t のように見えると誤解しやすい
      実際には括弧構造を保つ必要があるので、(t t) (t ((t t) (t t))) のような形になり、最上位と各括弧の中には常に正確に 2 つの部分式がある。つまり空白文字が二項演算子のように働く
      この式は括弧が多いので、この二項演算子を 左結合 とみなす。a b c(a b) ca b c d((a b) c) d と解釈される
      こう見ると、木がどこから出てくるのかが見える。終端記号が t 1 つだけなので、不要な括弧を取り除くと、すべての式は常に t で始まり、その後に複数の式が続く。最初の t をノードとして描き、続く各式について同じ手順で部分木を描けばよい
      仕様ページの意味規則は、部分木が 3 つ以上あるノードを「単純化」する方法、つまり t の後に部分式が 3 つ以上付いた式を簡約する方法を述べている
    • ページの一番上に「Tree Calculus は[目的の要約]のための[名詞句]である」のような 定義文 があると助かる
      Wikipedia の記事が通常「ラムダ計算は … のための形式体系である」「行列計算は … のための特殊な記法である」のように始まる、という感じ
    • 要約すると、プログラムと値がどちらもラベルなし木であるプログラミング言語
      ラベルなし木とは、ノードにデータを持たない木構造のデータ構造で、子の順序は存在する。Tree Calculus はラベルなし木を評価して別のラベルなし木を得る規則集合を定義している
      規則を繰り返し適用すると、無限ループに陥るか、もう変化しない木に到達する。規則は二分木には影響しないよう設計されているため、二分木を評価すると同じ木が返り、計算が終了した状態になる
      これらの規則は「Specification」ページに、プログラミング言語理論でよく使われる 小ステップ意味論 の形で書かれている
      主張されているのは、評価規則が チューリング完全 なのでどんな計算も表現でき、評価が漸近的に最適なので、どんな言語のプログラムも Tree Calculus 上でほぼ定数オーバーヘッドで実行できるということ。初見では筋の通らない主張ではないが、実際にどれほど重要なのかは明確ではない
      用途としては、一部のプログラミング言語理論の研究者には興味深く、計算理論の証明を単純化するのに使えるかもしれない。こういうものに興味があるなら、Tree Calculus よりも単純で、よく知られていて有用な ラムダ計算 を先に学ぶことを勧める
  • ホームページに “Democratizing Functions”、“Democratizing Metatheory” とあるが、意味が何であれ democratizing という言葉を乱用している印象が強い

    • この用法はかなり一般的
      Britannica の2番目の定義も「何かを誰でも利用できるようにする、誰でも理解できるようにする」という意味: https://www.britannica.com/dictionary/democratize
    • 同意。“What democratize really means” も参考になる: https://intage.us/articles/words/democratize/
      「言語は文化によって形作られ、あなたもその文化の一部だ。責任を放棄する必要はない。選択肢はある」
  • Tree Calculus の簡約規則の論理を「感覚」で理解しようとして、自分で図を作った: https://latypoff.com/tree-calculus-visualized/
    視覚的に考える人には役立つかもしれない

    • とても役に立つ。特に丁寧に書かれたテキストが良い
      ただし2番目の図 “Stem with a single leaf child” には誤りがありそう。三角形から下りる線が四角形につながっているが、その四角形は円であるべきだと思う
    • 本当に良い。これをアニメーション可能な形にすれば、ウェブサイトの Specification ページにとてもよく合いそう
  • これを推薦した人たちが、本当に何なのか理解したうえで推薦したのか気になる

    • 自分の目には ラムダ計算の別実装のように見えるし、なぜ面白いのか説明できていないウェブページも残念
    • 面白い議論が続きそうだと思って推薦した
    • 誰かが説明してくれることを期待して推薦した
  • これが構文だけ違う Lisp や Forth ではない理由を説明してもらえるだろうか?
    批判したり浅く切り捨てたりしたいわけではなく、本当に理解したい

    • Lisp は ラムダ計算に基づいているが、ラムダ計算そのものには、その中に書かれたプログラムを変更する道具はない
      この機能は有用なので、Lisp 系言語にはマクロのようなものが追加されてきたし、実装方法もさまざま。Lisp 系でよく見られる eval でさえラムダ計算の一部ではない。ラムダ計算には抽象化、適用、変数だけがあり、環境はない
      リフレクションの概念がきちんと定義されていて Tree Calculus がリフレクティブなら、構文だけ違う Lisp では確実になく、Forth ならなおさら違う
      専門家ではないので、大いに割り引いて聞いてほしい。実務的には遅い Lisp のように見えるかもしれないが、理論的にはラムダ計算とは異なり、遅い Lisp のようなものをより単純に実装する基盤として使える
    • 必須の括弧とインデント依存性がないなら、自分の好みとしてはそれだけで大きな利点
      他の好みも当然ありだが、ホモイコニシティがほとんど Lisp 方言の中に閉じ込められているのは残念
  • SKI の Z コンビネータを、ラムダ計算の例を経由して Tree Calculus に変換し、ツリーとして出力してみた
    テストはしていないが、元はツールで変換した未最適化コード。関連する背景は固定点コンビネータの文書を参照: https://en.wikipedia.org/wiki/Fixed-point_combinator

    • Z コンビネータは Z = \f. (\x. f (\v. x x v)) (\x. f (\v. x x v)) という形でもっと単純に書けるし、SKI でもより短く表現できる
  • Johannes が Tree Calculus を試して、私の本 GitHub.com/barry-jay-personal/tree-calculus/tree_book.pdf では暗黙的にしか示されていなかった可能性を明示的に示しているのを見るのはうれしい
    ついに型付き Tree Calculus ができたので、GitHub.com/barry-jay-personal でブログを書き始めた

    • 本への動作するリンクはこちら: https://github.com/barry-jay-personal/tree-calculus/blob/mas...
      右側のダウンロードボタンを探せばよい
    • “Typed Program Analysis Without Encodings” という論文にとても関心があるが、オンラインで見つけられない。どこを見ればよいのか知りたい
  • これをしばらく眺めていて、いくつか気づいた点がある。特に ラムダ計算 や形式意味論にある程度なじみのある人が足がかりを得るのに役立つかもしれない
    小ステップ意味論が何を意味するのか理解するために OCaml 実装まで降りる必要があったが、それは基本的な木構造がよく見えなかったため。定義の4つの要素の簡約式では、最初の3項に括弧を付けてみると、何が何に適用されているのかが見える。右辺も括弧が足りないように見える
    例えば (t (t) a) b -> a(t (t a) b) c -> (a c) (b c)(t (t a b) c) t -> a(t (t a b) c) (t u) -> b u(t (t a b) c) (t u v) -> (c u) v のように見るほうがよい
    また、表には構文の結合性から「当然」出てくると見なしているらしい場合が抜けているが、t a -> (t a)(t a) b -> (t a b) のように追加しておくと、E E 構文の式に意味論的な簡約をよりきれいに適用できる
    要点は、ラムダ計算でラムダを束ねて2つの選択肢のどちらかを「選ばせる」ようにするのと同じように、この Tree Calculus は与えられたノードが葉、幹、枝のどれかに応じて 3つの選択を行うように作られているという点。規則 3a、3b、3c の核心はこれで、システムの残りの機能はこの3分岐の選択の上に積み上がっている

    • この説明が最初のページにあるべきだった
      おかげで面白い計算体系には見えるが、SKI やラムダ計算よりも逆変換、シリアライズ、コンパイルに適しているかどうかは別問題。逆変換は難しく、シリアライズは簡単で、コンパイルはそこそこ簡単なほう
  • Python では、Leafを空リスト、Stemを単一要素のリスト、Forkを2要素のリストとして置き、applyを仕様の OCaml コードに合わせて実装できる
    falsetruenotを木として定義すると、not false -> truenot true -> falseが動作する

    • Racket や Scheme でも同じアイデアを使える
      LeafnullStemlistForkconsとして置けばよく、apply t-not t-falseapply t-not t-trueで同じ結果を確認できる