ノータブルコード16 - APLプログラマはいかにC言語を書くのか - 2021-06-23 - ククログ

ククログ

株式会社クリアコード > ククログ > ノータブルコード16 - APLプログラマはいかにC言語を書くのか

ノータブルコード16 - APLプログラマはいかにC言語を書くのか

あまり世の中で知られてない言語として配列処理(Array-Processing)言語という一群の言語があります。いずれもAPLというプログラミング言語から発展したもので、J・Q・Kといった言語が代表的です。これらの言語は「Array Processing」の名前の通り、配列、とくに多次元配列の処理に特化しています。

APLの流れをくむ言語の最大の特徴は、極限までに切り詰められた簡潔さです。この言語を使うといくつかの記号を組み合わせることで、複雑な配列操作を表現することができます。例えば、フィボナッチ数列を生成する関数を例にとると、Kでは{x{x,+/-2#x}/!2}という16文字で表現できます。もっと複雑な例を出すと、ライフゲームは、わずか138バイトで実装できます

APLはどこで使われているのか

この言語はどこで使われているのかというと、これは圧倒的に金融です。例えば、APLは1980年代にテラバイト単位の株価データを扱うリアルタイム取引システムを構築するのに利用されていました。中でも特に、米国の投資銀行モルガン・スタンレーはAPLの牙城として知られていました。

このあたりの事情は、債券調査部に所属していたリチャード・ブックステーバー氏の回顧録に詳しく記されています。

モルガン・スタンレーのIT部門は、APLという難解でエレガントなプログラミング言語の追従者たちの巡礼所だった。仮にAPLが宗教だったとすれば、モルガン・スタンレーは司祭職への正式な血統の資格を主張できただろう。APLの創始者の息子が債券調査部で働いていたからだ。
(中略)
モルガン・スタンレーはAPLを単に使っただけではなく、債券調査部のリソースの大部分を、新しく改良されたバージョンの言語を開発する家内工業に振り向けた。債券調査部を取り仕切るために、プラットの退職後に分析的自己売買部門(APT)から異動してきたジョエル・カプランもまたAPLの巡礼者の一人だった。カプランはこう言ったことがある「私の名前はJから始まり、姓はKから始まる。私の立ち位置は明らかだろう」(KとJはAPLの派生言語である)彼はAPLを複雑なアプリケーションを開発し、それを競合よりも素早く実現するための秘密兵器として位置づけていた。

Richard Bookstaber "A Demon of Our Own Design" (2007) p43-45 より 1

APLから見たC言語

面白いのは、このAPLの世界では、Cの書き方もAPL風になるという点です。つまり、APLプログラマはC言語を普通のプログラマとは全く違うやり方で扱います。

たとえば、K言語のオープンソース実装ngn/kから、乱数生成関数の実装を取り出すとこんな感じです2

S V rndL(L*r,Nn){S UL a=0xd5a986ae75c9a33b,b=0x1016d8e3483a8f0f,c=0x81f9e6260eb8e5df,d=0xfa9b718d8d0769bf;
 i(n,r[i]=a+d;O UL t=b<<17;c^=a;d^=b;b^=c;a^=d;c^=t;d=rot(d,45))}
 A rnd(Ln,Lm)_(Y(n==NL,Ed(m<0)n=-m)
 Au=aL(absL(n));rndL(uL,un);Y(m,Y(m<=1ll<<32,i(un,ul=(UI)ul*(UL)m>>32))E(i(un,ul=(UL)ul%m)))
 Y(n<0,n=-n;El(n>m,u)i(n,Lk=m-n+i;Lv=((UL*)uL)[i]%=k+1;L*p=&ul;j(i,Y(ul==v,*p=k;BR)))Ay=rnd(n,0);m2(y,i(n,SWP(ul,uL[(UL)yl%(i+1)]))0))u)
S A rndD(Ln)_(A x=AT(tD,rnd(n,0));i(n,xl=xl&-1ull>>12|1023ll<<52)x)

普通のCプログラマから見ると、あたかも難読化されたコードに見えるのですが、実はAPLプログラマにとっては、これは普通に読めるコードです。

Kona(Kの別のオープンソース実装)の作者はこのような独特のスタイルを次のように擁護します3

この普通ではないスタイルは、Cを限りなく簡潔に書こうとする努力の副産物である。このようにCを書くことにはたくさんのメリットがある。このスタイルに馴染んだ人にとっては、伝統的なコードよりずっと速く読んで理解できる。簡潔さは規律を生み出してバグも減らせる。この利点のいくつかは実際に試してみるまでは分かりづらいかもしれない。

文芸的プログラミングとの比較

少し前に、この連載でクヌースの文芸的プログラミングについて話しました。文芸的プログラミングの背景にあるのは「プログラミング言語は形式的すぎて、人間が理解するのは難しい」という認識でした。従って、あたかも数学者が数学的なアイデアを純粋な数式と言葉の文章の両方で説明するように、形式的なコードと冗長な自然言語の2つを織り交ぜることでコードを飛躍的に分かりやすくできるのだ、というのがクヌースの偉大な洞察でした。

面白いのは、APLの世界から見ると問題が全く逆になることです。彼らにとっては、C言語のようなプログラミング言語は、むしろ冗長すぎるのです。APLプログラマにとってC言語のプログラムが理解しづらいのは、言語自体が処理を簡潔に記述するだけの表現力を備えてないからで、それは正しい記法(と抽象化)を導入することで解決されるべきものです。

もちろんAPLプログラマも読解を補助するためにコードにコメントを書きます。しかし、それはあくまで問題を解決する真のコードが発見されていないがゆえのもので、彼らの理想では、真に短く簡潔なコードはそれだけで自明なのです。

AW: 私は一度もコードにコメントを書いたことがないね。常にコード自体がコメントになるように書こうとしているから。
BC: 自分のコードを見て「これは一体何をしようとしてるんだ?」と思ったことはないんですか?
AW: いや、たぶん無いね。4

まとめ

今回のノータブルコードでは、APLから見たC言語について紹介しました。これについてもっと深く知りたい方は、K言語の創始者のアーサー・ホイットニーの実際のコード(と解説)がGitHubで公開されていますのでそちらを参照ください。

  1. 邦訳に、リチャード・ブックステーバー「市場リスク - 暴落は必然か」(日経BP, 2008)

  2. ngn/k/f.c by Nick Nickolov, licensed under AGPL

  3. Coding Guidelines - “This is a very unusual style of C” より

  4. "A Conversation with Arthur Whitney" (acmqueue, 2009) より