昔、といっても想像を絶するほどの昔ではありません。でも、まあ、幼稚園児が「わたし、これ、むかしはできなかったんだよね~」ということもありますので、この「昔(むかし)」という概念はイチヂクシル、もとい、イチヂルシク認識主観相対的なことばであるということになります。
ま、最近ちょっと余りに手持ち豚さ、もとい、手持ち無沙汰なので、Mopsの歴史風の話を書いてみようかなと思ったしだいです。資料は基本的には、MacTech magazine(前はmac Tutorといったらしいですが)のArchiveと、Mikeさんに直接訊いた話です。
前史
FORTH
Mopsの基幹言語であるForth自体の歴史については、
ここを見て下さい(The Evolution of Forth (Forthの進化))。英語ですが、これを翻訳するのは私の手には余りますので御勘弁を(まだちゃんと全部読んでもいないので。終わりの方にMopsもでてきます。1960年代の終わりごろ完成されて、公には初め望遠鏡の制御等に用いられて、天文台関係ではプログラミング言語の標準語だったこともある、ということです。
NEON
Mopsの前身と目されるNEONという開発環境については他でもちょっと触れました。言語としてのNEONは、Charles Duffという方が作ったとされます。Mopsの生い立ちという点からいえば、アプリケーションとしてのNEONよりも言語としてのNEONのほうが重要になります。
NEONはMacintoshコンピュータ上で開発できる環境としてはもっとも早期のもの — MacForthの方が若干早い(1984年か)ようですが — の部類に属するといわれ、1985年にKriya Systems Inc.という会社から発売されたとのことです(1984年に出荷とのデータもある。)。当初、価格は$155だったようです。
このNEONは1989年頃まで売られていたようです。が、サポートは2~3年ぐらいで放棄されてしまったようです。話によると、初版はバグが多く、そのせいであまり数は普及しなかった。で、最初の安定版であるversion2.0が出てほどなく、Kriyaはバージョンアップをやめてしまったらしいのです。ところが、NEONの購入者に対しては、サポートとしてNEONのソースコード(全部ではないようですが)も提供されていたようです。そこで、NEONユーザーの中の何人かの人たちが、メーカーがサポートしないなら自分で使えるようにしようとしたようです。そのユーザーの中に、われらがMikeことMichael Horeさんがいたわけです。
アプリケーションとしてのNEONはともかく、言語としてのNEONはとても高い評価を得ていたようです。「このアドレスのメモリに数値を入れる」とかいうように、あからさまにローレベルなことをするForth言語が、現時点で実用化されているもっともハイレベルなオブジェクト-メッセージ形式を取り込むことができたのは、Forthという言語に備わる柔軟性の力によるものと思われます。核の部分はForthを基礎とし、Smalltalkを真似たオブジェクト指向ツールを結合する、というと、既存のもののごちゃまぜみたいですが、これが驚くほどうまくいっているのは使ってみればおわかりになるでしょう。しかし、NEONはForth++として設計されたというわけではなく、NEONという名前の言語として新たに設計されたのです。ForthとSmalltalkの「いいとこ取り」が目指されたのでしょう。もちろん、犠牲になったところはあるのでしょうし、各々の言語になれ親しんでいる人から見れば、その犠牲にされた部分こそがクリティカルだったりするんでしょうが、素人目には、ほぼ、その目標が達せられているようにみえます。また、NEONはスタンドアローンアプリケーションを作る機能を既に備えていました。
NEONの仕様としてMopsと比べた大きな違いをみると、
- 有料だった。:前も書いたように初め$155。その後値上げがあったようです。ただ、直接比較はできないかも知れませんが、現在(2007年頃)のReal BASICの標準版くらいの値段(確か、もう絶版)なわけで、当初の予定では四半期毎にバージョンアップし、その料金は年当たり$50ということだったようです。うまくやれば、けっこう今でもいけるんじゃないですかね。現在Mopsをこの値段で売り出しても、買う人はいっぱいいると思いますが(付属ツール云々は別として、できることに内在的制限はありませんし)...。
- 単一継承だけだった。:これに対してMopsは一般に認知された時点で既に多重継承を備えていました。
- 間接スレッディング(indirect threading)だった。:Mopsは当初からサブルーチンスレッディング(subroutine threading)でした。間接スレッディングはForthの実装に特徴的(古典的)なやり方で、非常にメモリー効率がよく、柔軟性もあって、特に8ビットパソコンでは非常な威力を発揮したといわれています。現在でも埋込み型システムでは優れた技巧だそうです。サブルーチンスレッディングはほとんどネイティブコードの実行に類するため、普通は実行速度が速いといえます。
日本にもNEONのユーザーという方がいらした可能性は大ですね。ちょっと興味はありますが。
Yerk
NEONは、何年かの間、約束されたバージョンアップもないまま、放置されながらも、販売は続けられていたようですが、1989年には販売も終了したようです。そして、結局、1991年の初め頃、Kriya SystemsはNEONのソースコードの公開配布を承認したのです。
もう商品にならなくなったソフトウェアのソースコードを公開するというのは、各ソフトウェア企業さんも是非見習って欲しいものです。(Kriyaという企業の当時の体質は真似ない方がいい、という感じのようですが。)開発者さんもそこのとこをよくお含みおきになって、強欲に権利を主張なさらないようにしていただければなあ、と。そうすれば、だれかが拾って、装いも新たに登場し、公共の福祉を増進し、企業および開発者も名誉を得ることになろうというものです。ま、勝手な言い分ですが。とはいうものの、Kriyaもソースコードを一般に配付することを認めるのはかなり渋ったようです。これを2年近くかけて口説き落としたのが、Chicago大学のBob Loewensteinという人だったそうです。
このKriyaによって捨てられたNEONをひろったChicago大学ではこれを改変して実用化し、後にYerkという名前で公開することになります。これは大学付属のYerkes天文観測所(Yerkes Observatory -- Yerkes部分は元は人名のようです。)で利用することが目的だったようです。Forthが当初は望遠鏡の制御とそのデータの解析(画像化)のアプリケーションのための言語として利用され評判が高まったという事情があって、天文台ではNEONがForth系であることが好ましかったのでしょう。
Yerkは、Kriya SystemsがNEONのバージョンアップとサポートを放棄したあたりからその開発は始まっていたらしく、Kriyaがソースの公開を認める前に開発され利用されていたようです。YerkはNEONのバグ修正およびカスタマイズとして出発したようです。Yerkは、NEONのカーネルにも修正を加えていましたし、新しいCPUである68020などへも対応し、新しい機能も追加していましたが、やはり「修正されたNEON」というのが相応しいようです。間接スレッディング方式もそのままだったようです。Kriyaがソースの公開を許諾したのを受けて、Yerkはソースもろともパブリックドメインとして公開されました。環境として68k Mac System7以上が推奨されています。しかし、PPCへの移植は行われなかったようです。それでも、まだ入手可能です。68k Macがあれば今でも動くと思います。68k互換モードがあれば、PPCでも動くかも知れません。うちのPPC G3 MacOS 9.2.2でも、何か不安定になる気はしますが、起動できて、計算ができました!関心のある方は、
Forth Interest Groupサイトの
Forth Compilersページからダウンロードできます(だいぶ下寄り)。この最新バージョンらしいv3.67のRead meは、上の記事の元ネタの一つです。
そしてMopsへ
Mops
MopsはアプリケーションとしてもNEONの後継のひとつと見られがちですが、実際はそうではありません。Yerkの後継でもありません。MopsはMichael Horeさんの純粋な創作物です。というのは、カーネル部分はNEONのコードを全く利用していないからです。スレッディングの方式が全然違うのですから、当然といえば当然かも知れません。マシンコード生成など低レベルの部分は、68k Mops のときから既に、NEONと全く別個に、Mikeさんが独力で実装したものだったのです。Mikeさんの説明からすれば、むしろNEON言語のもうひとつの -- つまりNEONではない -- コンパイラというべきでしょう。
Mikeさんは、1986年にMacintosh Plusを購入した際に、NEONを購入したそうです。 しかし、Mikeさんはプログラマーですから、色々といじっているうちに、もっと速いカーネルを自分で作ってみようと考えるようになったわけです。 Mikeさんの記憶では、もっと速いNativeコード方式の、NEON言語のコンパイラを自分で作ろうと決めたのは1988年頃だそうです。 Mopsの最初の核部分はMcAssemblyというシェアーウェアーアセンブラーで構築したそうです。NEONのリバースエンジニアリングもしようとしたそうですが、結局、方式が全然違うものになるので、その結果は全く利用しなかったそうです。 ところが、MikeさんがMopsを作り始めてほんの数ヶ月過ぎた頃、KriyaはNEONのバージョンアップを明確に放棄してしまったということです。
KriyaはNEON購入者にはソースコードを配布していました。そして、初期のMops のクラスライブラリー部分は、NEONのソースコードをそのまま使っていました。Mopsはフリーで配布できても、NEONのソースコードはKriyaのものなので、勝手に配布はできません。ですが、NEONユーザーならNEONのソースコードを持っていたわけですから、Mopsの核部分をもらうだけでいいわけです。初期の頃は、Mopsは、初めに辞書をコンパイルしてからじゃないと利用できないような配布の仕方をしていましたが、こんなことも、こんな歴史的事情が影響しているのかもしれません。昔は、配布物はフロッピーに入り切らないといけなかったからだ、というのが一応公式の理由ですが。
1991年頃に上に述べたようにBob Loewensteinさんの交渉によりKriyaがNEONソースコードの一般配布を認めたことで、何の気兼ねもなくMopsも一般公開できるようになったわけです。Mopsのカーネル部分はNEONのコードを含まないのですが、ハイレベルの部分、例えば、クラスライブラリのコードなどはNEONのものを使っていたことからくる法律上の問題をMikeさんは気にしていました。それが、ソースの一般配布が認められたことで、障害が無くなったということです。Mikeさんは当時、これでNEONを持っていない人にも配付できるようになったといっています。加えて、後はNEONという言語にKriyaの著作権が認められるとすれば問題にはなるが、自分は法律家ではないけれども、言語自体の利用が著作権を侵害することはないと思う、と書いています。ちなみに、私も法律家ではありませんが、日本の著作権法では、プログラミング言語自体は著作権保護の対象から明示的に除外されています(それなら誰でも見ればわかる...もっとも、自分がもらったMopsにどこの国の法律が適用されるかはわかりませんが。
このようにしてMopsもソースもろともパブリックドメインにおかれるわけです。その時点で、Mopsのバージョンは2.0だったようです。その後、1992年にPowerPC Macintoshの登場に対応してPowerMopsが登場しました。これは、68k Mopsを用いてクロスコンパイルされました。つまり、PowerMopsはそのカーネルからMopsで書かれているのです。個人的に、そのうち、PowerMops上でPowerMopsのカーネルをコンパイルするコードを書いてみようと思います。クラシック環境のない人も多いようなので。
そして西暦2000年前後にはPowerMopsはCarbon化され、2006年には64ビット版(PPC G5用)とMach-O版も提供されるようになり、現在に至ります。創作以来ほぼ18年、Mikeさんは開発を放棄しませんでした。2019年現在もなお改良・開発を続けていらっしゃいます(31年!)。Mopsシステムは、当初から個人の創作物であり、途中、例えばQuick Editを提供してくれたDouglas Hoffmanさんなど、クラスライブラリを書く等の協力をして下さった方は数人いらっしゃるようですが、基本的にはMikeさんの単独作品と考えてもよいように思われます。
個人がMopsほどのアプリケーションを作り上げることもさることながら、それを無料で公開し、十数年もの間、サポートを継続するというのは、そうあることではないと思います。このようなMikeさんの能力と労力に感謝すべきでしょう(Mikeさんは、なんか、いつも色々忙しそうですが....^^)。
言語としてのMopsは、当初はNEONと互換性があったようですが、変更されたところもあります。Mopsとしては、Mops 2.0の段階から以後、シンタックス上は現状とほとんど変化はありません(新機能の追加やワードの変化はいろいろあります)。
NEONやYerkを比べると捩れ括弧({ })を比較的多用する構文はちょっとC風といえなくもありませんが、少なくとも見た目上はNEONよりも明快な気もします(大差はありませんが)。ただ、そのかわり、Mopsでは閉じ捩れ括弧は場面に応じてかなり多様な仕事を受け持たされているわけなんですけど.....。
初期のMopsは、現在のものと対人インターフェイスが少し違っています。現在はスタックビューと呼ばれる区画がウィンドウの上の方にあって、スタック上にある数値は深さとともにそこに独立に表示されますが、初期のものは、「>->」記号によるプロンプトがあって、その右側にコードを書いてenterするようになっており、スタックアイテムの深さを表わす数値がプロンプトの左に表示されていました。どちらかということ、これがForth系の一般的なインターフェイスのようですね。このインターフェイスが現在のような形に変わったのはバージョン2.5前後からのようです(「ちどりや」さんのサイトを参照。また、“ちどりや”サイトのShin Watanabeさんからの情報も利用させていただきました。感謝いたします。)。
NEONからMopsへの仕様としての大きな変更点は、やはり、間接スレッディングからサブルーチンスレッディングへの変更です。基本的なワードの呼出しをインラインしてしまう方法を持つ場合をサブルーチンスレッディングとは区別してネイティブコード方式と呼ぶ人もあるようですが、そのような分類をするなら、Mopsはネイティブコード方式に他なりません。68kの頃の話ですが、NEONよりも実行速度は4~5倍速く、ものによっては7倍近い速さが出たそうです(Mopsのドキュメントによれば、コンパイルにかかる時間もMopsの方が短いそうです)。断片情報を継ぎ合わせて推定すると、大体、Cによるものと同じぐらいだったようです。また、生成されるコードもNEONの場合より1~2割ぐらい小さかったそうです。ハイレベルコードで書いたMopsのコードでも、他のハイレベル言語でかいた同等のプログラムと比べて断トツ速く、アセンブラで書いたコードに迫る(competitive)ほどであったようです。
普通、オブジェクト指向程度までハイレベルなプログラミング技巧を問題にする際には、きれいに整理できているかどうか(いろいろカタカナ名前がついてますが、要はそういうことですよね。それとチームで手早く注文品を作れる方法。)などを主な関心として、実行効率はあまり考えない(C++は例外だそうですが)ものらしい(限度はあるでしょうが)ですが、両方でハイスコアを達成できればそれに越したことはないでしょう。Mopsの動作速度には、スタックをレジスタでキャッシュする方式が大きく寄与しているように思います。68kで、8つのデータレジスタ、8つのアドレスレジスタで、計16本の32ビットレジスタがあったわけですし、PPCでは32本の汎用レジスタがあるので、スタックの値をキャッシュする余裕がだいぶあるわけです。
PPCもG5になり、64ビット機がでました。PowerPCはもともと64ビットの浮動小数点数レジスタ(Floating point register)を持っていたので、PowerMopsは64ビットモードも比較的早期に対応できそうな気配です。64ビットパソコンがどの程度の速さで普及するのかわかりませんが、Mopsはその波をも乗り越え、Macintosh上での「最速・最軽量・最安価」(?)の高級言語として生き残るでしょう。というか、Mopsのような素晴らしいツールは、何としても、盛りたて、存続させたいものです。
最近の問題としては、MacのIntel化があります。最大の問題は、Mikeさんはx86系が好きではないらしいということです。Mikeさんがおっしゃるには、PowerPCに対応して目に見えるバグを大体潰すまでに5年ぐらいかかった。それをまたx86に変更すると、バグを潰すのに同じぐらいかかるだろう。しかし、いま(2007~8年ごろ)から5年後、Macが同じようなCPUを使い続けているといえるだろうか?むしろ全く新しい方式が出て来て、全然互換性がなくなっているという可能性だってある。我々はいつまでメーカーの都合による引っ切りなしの仕様変更を追いかけ続けないといけないのだろうか?と。 きちんと完成させないまま、ズルズルと外観上の「バージョンアップ」だけを続けていくのは、 この業界の特徴なのかもしれません。ソフトウェア業者はむしろその方がビジネスチャンスを見いだしやすいのでしょうが、Mopsのような独立系のフリーコンパイラには、何の得にもなりません。
Mopsは設計の基本としてレジスタキャッシュによる高速化を最大限に利用しています。そのため、ノーマルなIA32の8本の整数レジスターという機構では、まるっきり別の設計でいかなければなりません。 ですが、64ビット拡張の、つまり、Mac ProかCORE2 Mac以降ということですが、 その場合は、レジスタが16本に増強されているので、レジスタの数という点でいえば、68k Mopsと同じような条件にあるわけで、結構、設計思想が活かせるのではないかと思います。
そんなこんなで、結局、私が移植しました。上に書いた理由で、64ビット限定です。かなり効率的なコード生成が実現できたと自負しています。
当初は、PowerMopsでカーネルのコードジェネレーター部分をクロスコンパイルし、残りの部分は後から拡張して辞書保存、という形実行ファイルを生成しました。その後、PPCエミュレーターがなくなってしまったので、iMops自体から、新版のiMopsを生成できるようにしました。Mac OSX 10.6以降ないしmacOS上で動きます。iMopsと言う名前で、PowerMopsと同じSourceForgeサイトからダウンロード可能です。デヴェロッパーサインというものをつけてあるので、セキュリティーを一段階下げれば、起動可能となるはずです。本来なら、AppStoreから配布できるようにしたいし、すべきだと思ってはいますが、XCodeでないもので開発したものを審査してもらえるのか、どうしていいのか今の所ちょっとわかりません。
さらに、2020年、Apple社は2年かけて、すべてのコンピュータのCPUをARM型に切り替えると発表しました。ARMはRISCで、32本の整数レジスターを持っていて、PowerPCと似たタイプのCPUとなります。いま現在、Mikeさんは、新しい理論(レジスターのグローバルアロケーション)に基づくコンパイラーモデルを、ARMの機構に対応させる修正を試みていて、大分できてきています。これはコードジェネレーター部分だけになりますが、数が多いレジスターを効果的に使って、かなり高性能な最適化コンパイラができることが期待できます。Mach-O実行ファイル形式と、
システムコールの部分は、自分が担当するかもしれませんが、ともかく、ARM-Mopsの開発プロジェクトがすでに動き始めています。
傍流
Win32Forth(2007年頃の話です。古くてすみません。)
Mac用じゃないので傍流という分類になりますが、パソコンとしては主流の方ですね。あまり細かいデータはわかりませんが、オブジェクト指向実装にNEON言語を利用しているので、偏った感想で埋めます、じゃなかった(?)、触れておきます。
1994年頃、Andrew MacKewanさんという方が、WindowsNT用にForthカーネルを書き、それにNEON言語によるオブジェクト指向を実装しました。それに、MS-DOS用にTom Zimmerさんという方が書かれたF-PCというパブリックドメインのForthからツールを移植して現在の形になったとされています。フリーでオープンソース、かつ、自分で自分自身をコンパイルできます(いわゆるメタコンパイラ)。
Win32Forthは、豊富なツールを備えた、とてもコンパクトで速いアプリケーションができる環境のようです(あまり詳しくはないんですが、ちょっと他所のPCでさわってみたことはあります。デモがカラーで派手でしたが、速すぎて眼が眩みました(*o*)。コンパイルもめちゃくちゃ速かった気がします。CPUパワーかな?1.6GHz Pentium4だったからな。とはいえ、これも10数年前のこと…2004~5年頃だったかと思います。)。説明にはC言語のプログラムと比べれば、小さなプログラムではいくぶん大きくてすこし遅いかも知れないと書いてありますが、おそらく大差ないでしょう。オブジェクト指向がサポートされているのですから、CというよりC++と比べるべきでしょう。C++のプログラムは、コンパイラや環境にもよるのでしょうが、オブジェクトをメモリー上に生成するのに時間がかかったりして若干Cよりも効率が落ちるらしいので、これと比べるとどうなんでしょうか。また、基本的にCISC CPUをターゲットにしていることにも起因するのでしょうが、アセンブラでワードを定義して効率化を図ることも結構あるらしいので、要所をこれで押さえれば実行速度としてはかなりいけると思います。
スレッディングは古典的な間接スレッディングのようです。間接スレッディングの好いところのひとつとしてツールが作りやすいということがあるらしいです。それでいろいろツールがついてるようです。その中に実行速度を測るプロファイラも完備されているようなのですが(Mopsにも68kまではあったのですが)、Win32Forthはオープンソースであるにもかかわらず、商品版環境にひけを取らないベンチマーク速度をだせるようです。Win32といったって、さまざまなCPU(基本的にはいわゆるPC/AT互換としても)の上で動くわけですから、間接スレッディングというのは合理的な選択といえるのではないでしょうか。ネイティブに近いほど、特定のCPUを向いた最適化になってしまうんじゃないかと思います。
オブジェクト指向実装の言語でみると、見た目はほとんどNEONそのままという感じです。書き方としてみれば、MopsよりもWin32Forthの方がNEONに近いように見えます。
APIの関数名も仕組みもMacintoshとは全く異なるのですから、特にオブジェクト指向部分などはMopsよりも大規模な書き直し(というか、新しく0から書いたんでしょうね)が必要だったはずのWin32Forthですが、間接スレッディングであること、クラス定義用のワードセットの類似性という点で、かえってNEONに近い感じがするのもおもしろいですね。Win32Forthのオブジェクト指向拡張部分を書かれたAndrew MacKewanさんが、ちょっと前に、またForth上でのオブジェクト指向熱が再発して来たとおっしゃってました。Forth系は好きなように拡張できるから面白いですよね。
Win32Forthは古典的な間接スレッディング方式を使っているので、ベンチマークとかを取ると遅かったりするんですが、最近、ネイティブコード方式のバージョンが開発されているという噂です。興味深いですね。
Windows環境なら開発環境の選択肢もいっぱいあるんでしょうけれども、どなたか、Win32Forthを試してみませんか?(Windows環境あったら、自分もいじってみたいです。)Win32Forthのイントロに関する日本語のサイトがないかGoogleで探してみましたが、見当たりませんでした。どなたか、何とかしてください(笑)。Windowsアプリケーションならユーザーも沢山(絶対数では)集められるでしょうから、消えてしまう心配はないですよね。
最終更新:2020年08月15日 19:57