- 記法(Notation) は思考を助ける重要な道具であり、数学とプログラミング言語の両方で中核的な役割を果たす
- APL言語は、数学的記法の利点をプログラミング言語の実行可能性と汎用性に結びつけようとする試みとして開発された
- 優れた記法の特徴として、簡潔さ、明確さ、示唆性、詳細の下位化、形式的な証明可能性などがある
- さまざまな数学的構造(多項式、変換、グラフなど)を APLで効率よく表現し変換できる
- 記法の導入と学習は文脈の中で自然に行われるべきであり、記法の構造性と汎用性も重要である
思考の道具としての記法
- 化学、植物学などの科学分野でも、体系的な命名法が学問の発展を促進してきた
- ジョージ・ブールは、言語それ自体が思考の手段であることを強調した
- 数学的記法は、思考を支援する言語の代表的な例であり、思考の負担を減らし、思考力を高める
- A.N.ホワイトヘッドとチャールズ・バベッジは、数学記法の重要性を強調した
プログラミング言語が思考の道具となる可能性
- プログラミング言語は 汎用性 と 明確性 という強みを持つ
- コンピュータによるアイデアの実験や、明確な思考実験が可能である
- しかし、ほとんどのプログラミング言語は数学的記法に比べると、思考の道具としての役割が弱い
- APLは、明瞭性と精密さを志向し、思考を支援する記法として設計された
優れた記法の主な特性
- 問題表現のしやすさ: 問題から直接導かれる構造を容易に表現できなければならない
- 示唆性: 表現された形が類似または拡張された問題を示唆すべきである
- 詳細の下位化: 複雑な詳細を単純化し、思考を助ける構造を提供する
- 簡潔さ: 最小限の記号と規則で広範な表現を可能にしなければならない
- 形式的な証明可能性: 記法が形式的証明と演繹的推論に適していなければならない
APLの基本的な記法技法の紹介
- ベクトル、行列などの配列ベースの構造を自然に扱う
- 関数および演算子はベクトル/行列に要素ごとに自動適用される
- リダクション(
/)、スキャン(\)、内積(.)のような演算子(operators)で関数合成を表現する
⍳, ⌽, ⍴, +, ×, * などの基本記号で豊かな数式を構成できる
- すべての関数は右優先規則に従い、括弧なしでも自然な数式を書ける
問題解決と思考促進の例
- 三角数、階乗などの数学的数列を簡単な数式で表現する
- 多項式の表現や乗算、微分などの演算を一貫した規則で簡潔に処理する
- グラフ理論(木、推移閉包、全域木)も配列演算で明確に表現できる
- 順列、ブール代数、数体系変換(素因数分解)など多様な分野へ拡張できる
形式的証明と構造化された思考
- すべての演算と式は明確に実行可能な形で表現されるため、コンピュータによる自動検証が可能である
- 数学的帰納法、全探索、恒等式の列挙によって、さまざまな形式的証明の例が示される
- リダクションとスキャンの分割(identity)および内積演算の結合性と分配性を形式的に証明する
- ニュートン対称関数、多項式の乗算および微分公式を直接証明する
APLと伝統的な数学記法の比較
- APLは関数の明確な定義、一貫した配列演算、豊かな記号体系を提供する
- すべての演算に優先順位規則の代わりに右優先の実行規則を適用する
- 数学記号の使用に伴う複雑さを減らし、形式的操作(formal manipulation)を支援する
- 構文は簡潔で規則は一貫しており、初心者にも熟練者にも有利である
記法の導入と学習方法
- 別個の「言語講義」なしに、文脈の中で必要な記法だけを自然に紹介する方式を強調する
- 具体的な問題状況の中で新しい記号を直感的に学習する
- 記法そのものの難しさよりも、記法が示唆する多様な可能性と拡張性を認識することが重要である
APLの拡張可能性と提案
- 複素数処理を含む関数拡張の提案
- unique elements および summary 関数の標準化が必要
- より一般化された演算子(operator)の導入により、ベクトル微積分など追加の主題を支援できる
- 言語設計の明確性と推論能力の向上を目指す
効率性と明確性のバランス
- 明確で分析可能な記法をまず定義し、その後に最適化によって効率を高める方式を推奨する
- アルゴリズムの明確化は、その後の最適化やコンパイラ最適化にも役立つ
- APLで書かれた基本表現は、学術的探究と産業的応用の両方に貢献する可能性がある
1件のコメント
Hacker News の意見
記法はシェル展開のように「ある式を別の式に置き換えるもの」程度に見られがちだが、実際にはずっと深いもの
教授が、偉大な発見はしばしば新しい記法とともに現れると説明してくれたが、新しい記法とは「この問題を考える新しい方法」を意味する
今日の多くの未解決問題も、強力な記法が生まれれば解けるようになると見ている
これは本当に強力だが Lisp 的なやり方に近く、APL や Clojure 的なやり方は基本型を本当に有用にする方向
10 個のデータ構造にそれぞれ 10 個の関数を用意するより、1 個のデータ構造に 100 個の関数を持たせる方式で、APL では DSL を作るというより、データを非常に慎重に設計して配置すれば、残りはうまくはまるという感じ
Richard Feynman は十代のころ三角法を学びながら、サインとコサインの記法が気に入らず、公式を単純にしてノイズを減らすために独自の数学記号を作った
その後も Feynman diagrams や slash notation のように、物理学の考え方と表現方法を同時に新しく作り出した
小さな例として CoffeeScript が登場したとき、ラムダの短縮記法やさまざまな構文上の便利さのおかげで、JavaScript の書き方が大きく変わり、考えやすく、読みやすく、直しやすくなった
SML/Haskell と Lisp 系も同じように感じる
Brian Greene と Barry Mazur の短いクリップも気に入ると思う: https://youtu.be/8wQepGg8tHA
歴史的に APL を押しのけたのは、奇妙なキーボードだけでなく、IBM の Lotus 1-2-3 と、ほどなく登場した MS Excel でもあった
エンジニア、学界、会計士、MBA たちは TI-59 や HP-12C より優れた道具を必要としていたが、コンピュータサイエンス側は記号処理、AI、LISP に没頭しており、結局その場所を業界が占めた
APL はスプレッドシートよりはるかに大きな影響力を持ち、より多くの問題を解けたはずなので、惜しい偶然だった
もともとのビジョンは、手で書ける一貫した実行可能な数学記法だったが、ついに達成されなかった
興味があるならこの記事を読む価値がある: https://mlajtos.mu/posts/new-kind-of-paper
お金を払わずに問題解決ができ、有料顧客の前にコンパイル結果を配布するときに費用が発生する
解法が特定の部分集合に合うなら、April に移して Common Lisp から提供する形にもできる
ただし APL の人たちは概して非常に学究的なので、エンジニアリング作業を素早く簡潔にこなせる一方で、平均的なソフトウェア会社で関数ランクやネイピア的関手の話を持ち出すと、同僚は医療的な助けが必要なのではないかと疑うかもしれない
ソフトウェア開発のかなりの部分は、顧客やユーザーが話し、考える方法を表現する、やや形式的な技術言語を発明する作業だが、Iverson 系の言語ではこれが容易ではない
Java は長い間、各メソッドにどのビジネス用語が入り、どれが出ていくのかを明示させてきたため、その点では組織の概念をコードにマッピングしやすかった
APL でもデータや関数に名前を付けることはできるが、長い名前や名前空間構造を持ち込んで外部組織をコードにマッピングした瞬間、簡潔さと優雅さを失う
ML 系の精巧な型システムでも、開発者は発明された準言語的なオントロジーと組織・プロセスを直接結び付けることに苦労し、より頻繁に数学的または学術的な概念を選ぶ
両方をこなせる人がいれば可能だが、普通は顧客の世界へ翻訳する側だけが得意でも十分な場合が多い
昨年 The Array Cast が 1982 年の Iverson インタビューを再公開した: https://www.arraycast.com/episodes/episode92-iverson
かなり興味深く、Turing 講演よりも取っつきやすい
1979 年の APL は、今日のように奇妙で周縁的な言語ではなかった
当時はプログラミング言語が今のような世界的な大衆現象ではなかったため、ほとんどすべてが奇妙で周縁的に近く、C も当時はかなり新しかった
少し寛大に見れば、APL は密度の高い C からそれほど遠くない抽象化に見え、配列上のポインタ操作を直接実装せずにコンピュータをプログラムできるようにしてくれた
APL [1] や J [2] の構文で数学を学ぶ教材もかなりある
Iverson はもともと APL を数学のためのより良い構文として使っており、プログラミング実装は数年後に登場した
[1] https://alexalejandre.com/about/#apl
[2] https://code.jsoftware.com/wiki/Books#Math_for_the_Layman
以前、今は終了している型理論ポッドキャストを聴いたことがあるが、非常に難解な内容だった
基本概念は、ほかの有用な概念にもつながっている
サピア=ウォーフ仮説も似ているが、逆に考えるとさらに興味深い
完全ではない言語には、考えられないこと、あるいは考えにくいことがあり、だとすれば、私たちが使っている言語では表現も思考もできないものがあるのかと問うことになる
ここでいう「言語」と「思考」は、通常より広く捉えることができる
たとえば、社会的相互作用のルールは、私たちの相互作用の仕方を決めるのだろうか? Zeynep Tufekci は『Twitter and Teargas』で、Twitter はフラッシュモブを可能にする一方、持続的な社会変革を難しくすると述べている
誰かをフォローする、コメントする、いいねする、といった社会的メカニズムが、互いに相互作用する方法を決めたり可能にしたりするのだろうか? 別のメカニズムなら、よりよい集団的思考を可能にするかもしれない
音楽もある。記譜法ではなく、音楽は別の方法ではうまく表現できない何かを表現しているのだろうか?
いくつかの外国語を学んだ立場からすると、特定の言語でだけ考えられ、母語である英語では考えにくいものがたくさんある
たとえばウクライナ語とロシア語の「гулять」には、英語では捉えきれない意味が多く、その言語を学ぶ前はそうした意味について考えたことがなかった
「Гулять」は文字どおりには「歩く」だが、経験を求めて歩き回ること、性的経験を含む意味でも使われる
誰かがあまりに早く結婚したとして「не нагулялся」、つまり「十分に歩き回らなかった」と不満を言うことができる
英語にも “sow his wild oats” のような似た表現はあるが、「歩く」という一つの動詞にそれほど多くの意味が込められると、人生を歩んでいくという思考そのものが変わる
アラビア語を学んだときも、その言語でだけ生まれる意味や考えが多く、英語で説明できないからではなく、簡潔に表現する表記法がないために長い文章が必要になる
ある人は言語を通じて別の思考へ旅することを好み、ある人はその可能性の前で身動きが取れなくなる
いつものように、成功はバランスと、その両方にある
数学者やコンピュータ科学者にとってはあまりにも明白な事実なのに、この考えは言語学者や「教育者」の間では非常に論争的である
言語学における類似物はサピア=ウォーフ仮説で、どの言語を学ぶかが思考様式を決定するという主張である
自然言語は文化的対象であり、文化をたとえ弱い半順序としてでもマッピングすることは、学界ではタブーのように見なされている
教育にも大きな影響があり、学生が直面する問題を本当に推論できるようにする表記法を学ばせてもらえない場合がある
この部分は正直よく理解できない
どの言語の話者でも同じ数学やコンピュータプログラムを学べるという事実が、それを示している
話し言葉や書き言葉が思考に必須なのかも疑問である
少なくとも言語なしでも可能な思考の大きな領域があり、人間もかつては言葉を持たなかった、あるいはごくわずかしか持たなかったし、コミュニケーションしようとする考えや意図が単語と言語を作った
だから、学習した言語を思考の基本モデルと見るのは奇妙に感じる
たとえば、ある社会が海の色と草の色を同じ単語で呼ぶからといって、その2色の違いを経験できないと主張することがある
経験を似た形で記憶にエンコードするという程度ではなく、違いを見分けられないという言い方である
ある言語にない音はそもそも聞こえない、という主張も似ている
ここでの表記法の議論は、それよりも語彙が探索に使えるという方向に近い
単に何かの音を聞いたというのではなく、音楽を聞き、特定のコード進行などを聞いたと言えるようになる、というようなことだ
今、APL でプロジェクトを開発している
長い間バックログに入っていたものだが、今は実際にコードを書いている
興味を持ち始めた時点から、1行もの以上のものを書けるようになるまでには、かなり長い時間があった
その過程の初期にこの論文を見つけ、吸収するように読み、今ではその概念が思考の完全な土台になっている
実際に建築プログラムで NAATOT を教えている
ソフトウェアアーキテクチャではなく、建築設計のほうである
Iverson の核心を生かすように編集した版を使い、実際の数学・プログラミングは、要点を示し、学生が設計と表現ツールの可能性を別の形で考えるよう挑戦させるのに十分なだけ残した
つまり、アイデアを形成する過程、自分自身や他者に表現する方法といったものを扱っている
もっと緩やかで開かれたプログラムで機会があるなら、学生が建築設計の領域に適用する自分だけの記号・表記体系を作る授業を運営してみたい
以前作っていた Freeform ノートアプリを完成できなかったのが残念だ
SVG を通じてスタンドアロンのウェブページにコンパイルされるアプリで、STEM 分野でよくある技術的コンテンツには本当に素晴らしいアイデアだったと思う
以前の化学ノートの例はこちら: https://colbyn.github.io/old-school-chem-notes/dev/chemistry-1010---fall-2021/week-14-acids-and-bases.html
今はどんなシステムを使っているのか気になる
数年間、APLを一種の魔法のように眺めていたが、今年初めに時間を取って学んだ。
APLでは、ツイート1つに収まるほど驚くほど大量のコードを詰め込めることに驚いた。
面白いが、使うのは難しかった。
書き終えると、ほとんどいつも「これを書くのにこんなに時間がかかったのか?」と思い、別の道具を使うべきだったのかと考える。
しかし実際には、別の道具ならはるかに時間がかかったはずだという点が、直感にはなかなか合わない。
難しく時間を食っているように感じる部分は、実は問題の仕様をより圧縮された形で整理することを強いられる過程なのだ。
より急だがずっと短い道を登るのに似ていて、より大変に感じるが、実際には作業は少ない。
だからAPLを学んで使うべきなのだと思う。
「数学表記は普遍性に欠け、主題・著者・文脈によって異なる解釈をされるべきだ」という論文の前提には、個人的には同意しない。
問題の可視化や人間工学から切り離された表記法には大きなコストがあると思う。
複雑さを大きく隠すことで「ユーレカ」的な気づきや思いがけない同値性を生み出せる表記法を好む学者もいるが、場合によってはむしろ曖昧で、誤りを生みやすくなる。
それでも、思考過程を伝える重要な道具であることは確かだ。
ある領域や近接する領域群に標準表記法を1つだけ置くことは、推論や問題解決における創造的・芸術的・探索的な側面をかなり抑え込むと思う。
Terry Taoによる表記法についての優れた説明もある: https://news.ycombinator.com/item?id=23911903
数学にはLeanやCoqのような「エンタープライズ」推論システムを作ろうとする取り組みがあり、その場合には普遍的な表記体系が妥当だ。
しかし個人的な探索なら、何でも適当に組み合わせるほうがよいこともある。
個人的には教育の場でより苦労した。
代数の授業などで、教師が表記法に関する個人的な決定や好みを一貫して、あるいは率直に扱わないとつらかったし、型理論と機械的証明理論を学ぶことで数学の力が大きく伸びた。
論文の「細部の従属」という概念は、十分に掘り下げられていないと思う
APLアプリケーションを長く読み書きしているうちに、この概念は抽象化とは根本的に異なる複雑性管理の方法を指しているのだと分かってきた
私たちはAPI、ライブラリ、モジュール、パッケージ、インターフェースのような抽象化の壁に囲まれており、その結果は高く積み上がった抽象化の塔、APIをつなぎ合わせる開発者、ハードウェアとの断絶、性能推論の難しさといったおなじみの問題になる
APLは別のアプローチを非常にやりやすくしてくれる
抽象化を設計する代わりに、単純な式で簡単に操作できるようデータを慎重に設計する
通常ならライブラリ関数やDSL用語が置かれるところに、プリミティブ演算を直接書くようなやり方だ
例えば文字列テーブル、キー配列、値配列を使って、ベクトル値と内部化されたキーを持つハッシュマップ風の構造を作り、挿入・出力・削除をAPL式でそのまま扱える
この方法の良い点は、各式がブラックボックスではないため、特定の必要に合わせて自然に調整できることにある
通常のハッシュマップ挿入なら新しいキーを追加するコードが必要だが、ここでは既存キーに値だけを追加すればよいという共通の不変条件を活用する
ライブラリAPIなら、使われないコードパス、複数の挿入関数のバリエーション、あるいはデッドコード除去のための精巧な型推論が必要になっていただろう
そうしたアプローチは、ドメインと無関係な関心事をコードベースに染み出させる
細部を隠す代わりに従属させれば、必要なだけドメイン固有の細部にアクセスでき、関係のない細部は必要になるまで背景に静かに置いておける
もちろんAPL式にかなり慣れている必要はあるが、Pythonエコシステムのようなものを深く学ぶより、はるかに大きな負担というわけではないと思う
実際にはAPLの記号は背景に消えていき、英単語を文字単位ではなく単語・句単位で読むように、意味のある構文として見え始める
ほとんどの言語では不可能だが、言語が十分に簡潔で表現力を持っていれば、かなり広い範囲で再び可能になる
Arthur Whitneyがスクロールを本当に嫌っている、という考えがいつも頭に浮かぶ
20個のファイルを開いて「定義へ移動」を追い回す必要もない
プログラム全体が1ページに収まれば、そうしたものは消え、目の動きで探索するようになる
本気で時間をかけて学ぶべきだと感じる
ここ数週間経験してきた苦労とも深くつながっている
強く結合しすぎたレガシーPythonコードを見ているのだが、これまでのあらゆる「改善」の試みは、間違ったデータモデルの上に抽象化をさらに重ねるものだった
コードを線形に読んでも、どのメソッドが入力オブジェクトを変更するのか分からない
あるものは変更し、あるものは変更せず、ときには変更せず同じ入力引数をそのまま返すこともある
同じインターフェースすら共有しない複数の計算器をファクトリが返す遠回りの海よりは、いっそ解析して理解できるマジック文字列の方がましだ
すべての演算が O(n) だからだ
汎用演算子は使えるが、値のペアがドメインロジック上何を意味するのか、各演算で正しい構造をどう維持すべきかを慎重に理解しなければならない
初めてプログラムを読む人は、プリミティブ演算ではなくビジネスドメイン上の意味を理解するのに同じように苦労するだろう
改善があるとすれば、複雑性を別の場所に置いたからではなく、コードと実際の値が同時に見えるからだと思う
複雑なプログラミングを容易にするのは、実行時データとコードの演算が並んで見えることであり、だからこそIDEツールはデバッガやインスペクタを改善し続け、プログラムが各段階で何をしているのかを見せようとしている
この文脈では、演算の一部を抽象化しようがデータ構造の一部を抽象化しようが、良くて簡潔な新しい抽象化を作ることは依然として良いことだ
例の挿入コードの大半は、目的の追加作業ではなく、インタプリタが入力させてくれる形を必要な形に変えるデータ整形だ
⍪←が実際の追加で、↓⍉↑()()()はAPLとインタプリタの入力パーサの限界を回避するための入力解析と変換に近い削除コードも、
'buggy'を入れ子配列の単一要素として探すために包むなど、問題領域と無関係なBoolean配列を作らなければならない「ベクトル値のハッシュマップを作る」という言い方も、実際のハッシュ化がないので誤解を招く
重複キーの確認もなく、ハッシュの選択や速度と分布の調整もできず、キーが順番に追加されて検索も遅くなる
Dyalog APLには高速検索のために配列を内部ハッシュ化対象として標示する魔法のインタプリタ命令であるI-Beam 1500もあるが、内部抽象化が漏れ出している点を常に覚えておく必要がある
「成功の穴」、「方法は一つだけ」、「最初に思いついた方法が正しい方法であるべき」、「異なる作業は異なって見えるべき」といった言語・ツール設計上の良いアイデアがAPLには欠けている
PythonやC#では
kv={'a':1, 'b':2}のような構文がそのまま動き、括弧やコロンを抜かすと明確に間違って見え、エディタとコンパイラが助けてくれるAPL実装は入出力で
⎕NGET、⎕CSV、⎕JSONのような魔法のインタプリタ関数に依存しており、エラー処理・ロギング・デバッグも弱い式全体が一つとして実行され、フックとフォークのため簡単に分割することも難しい
結局、さまざまな配列形状、
⊂3がなぜ何もしていないように見えるのか、⊆と⊂の違い、スカラ拡張などを正確に感覚で理解していなければ、実験や学習も可能にならない「キーがあれば更新し、なければ追加する」のようなすぐアクセス可能なパターンも、APLでは分岐の仕方から考え直さなければならない
Pythonなら
if/elseとkey in map、C#ならif/elseとmap.Contains(key)で済むことが、APLでは基本機能を再実装する悩みに入り込んでしまうAaron Hsuの主張と似ているが、「消防車」と言えず「火を止める仕事をする人の車」と言わなければならないUp-Goer 5やToki Ponaのような感じだ
[1] https://docs.dyalog.com/latest/CheatSheet%20-%20I-Beams.pdf
[3] https://aplwiki.com/wiki/Scalar_extension
[4] https://xkcd.com/1133/