約 1,200,421 件
https://w.atwiki.jp/1548908-card/pages/934.html
削除修正おねがい 言葉による入り口リンクが消されてると、削除依頼になかなか気が付くことができません お手数ですが、気が付いた場合やミスページ削除依頼はここにリンクでも貼ってください 過去消した覚えの有る方もお願いします@管理人 削除修正おねがい 修正ページ作成したため不要(テンプレ) 削除修正おねがい TGブレード・ガンナー WAXX-10000←正しくはTGブレード・ガンナー MAXX-10000です。 ï¼(P)DT1 幻影ã®å¦ç²¾ ã°ã‹ ãªã³ æÂÂé»Âã®ç«Âç PSPTF3ãÂÂãÂÂ㯠罠ãÂȋÂÂã®ãÂÂã¼(P)TF3 ãÂÂã£ã¼ã«ãÂÂãÂÂã¦ã®ã²ãÂÂã«(P)TF3 ã¢ã³ã¹ã¿ã¼ãÂȋÂÂã®ãÂÂã¼(P)TF3 ã¿ãÂÂã°ãÂÂã©ã¼ã¹ãÂȋÂÂã©ã¼ã¨ã´ã¡ã¼(P)TF3 ä¸Âç¼ã®ç¾章B3/ãã³ãã ã¶ãÂȋ«ãªãÂÂã¥㋼ã¿ã¼ åµä¸Âã®é Âè¨Âè é»ÂéÂÂã®ãÂÂã ã³ã¯ã«ã¹ ã©ã¤ãÂÂã«ç»場@以上全て荒らしです 一部リンクが不安定な箇所が有るようです。発見したら追記お願いします。 (2008にジャンプしたりします) 2008のパックのリンク先は、編集後に「○×(P)08」の様に変更頂ければ、大丈夫です。 魔鏡導士リフレクト・バウンダー プロト・サイバー・ドラゴン キメラテック・オーバー・ドラゴン キメラテック・フォートレス・ドラゴン サイバー・エンド・ドラゴン サイバー・ツイン・ドラゴン サイバー・オーガ サイバー・オーガ・2 サイバー・フェニックス ドリルロイド クリボー 融合呪印生物-地 融合呪印生物-光 融合呪印生物-闇 おとり人形 タイムカプセル 封印の黄金櫃 融合 洗脳-ブレインコントロール 団結の力 光の護封剣 月の書 隠れ兵 正統なる血統 聖なるバリア-ミラーフォース- 激流葬 未収録カード
https://w.atwiki.jp/midkiseki/pages/620.html
t
https://w.atwiki.jp/mopsprogramming/pages/126.html
Mopsで定義されたワードは辞書に保管されます。これはForth系環境の特色でもあります。実行されるべきコードと処理されるべきデータが、そこに格納され、必要に応じて呼び出されます。辞書の内容は下(アドレスの数値が小さい)から上(同大きい)へと伸びていきます。 PowerMopsおよびiMopsの辞書は一つではありません。データ辞書とコード辞書の二つに分かれています。それぞれがハンドルないしポインターでヒープメモリー上に確保され、必要に応じて拡大します。このような分割は、PPC MacintoshないしIntel-Macでの実行可能コードのフォーマットが、実行コード部分とデータ部分を区分けして保存することによって実行効率の向上を図っていることに対応したものです。PowerMopsに実行ファイル形式はPEF形式と呼ばれ、IntelないしARM上での実行ファイル形式はMach-Oフォーマットと呼ばれますが、どちらも、上のような実行コードとデータ部分を分離する方式が採用されています。 このように、辞書はメモリー上に存在するため、その場所はアドレスによって指定されます。辞書にコードをコンパイルしていくと、次第に辞書は埋まってきます。辞書の空き領域の先頭のアドレスがわかれば、次にどこからコードを記録していけば良いのかがわかります。この値は、変数で保守されています。 辞書の実行コード領域の空き領域の先頭を示す変数は、CDPです(おそらく、CoDe Pointerという意味でしょう。)。これはValue変数ですが、辞書のコード領域を確保するワードでは自動的に動かされます。自分自身でずらすことによって、スペースを確保することもできます。 データ領域の空き領域の先頭を示す変数は、DPです(おそらく、Data Pointerということでしょう)。これもValue変数です。例えば、ALLOTのようなワードは、このDPを必要な幅だけ進めます。"HERE"は、Forth標準ワードで、辞書の空きスペースの先頭を示すもので、ワードとして実行されると、その値がスタックに積まれます。Mopsでは、"HERE"は、DPの方の値を取り出すワードです。HEREの値は自分で変えることはできません。 Mops環境上では、当然のことながら、辞書は読み書き自由です。しかし、いったん辞書が保存され、あるいはアプリケーションがインストールされて、一つの実行ファイルに固められてしまった後は、コード領域にはもはや書き込みはできません(Read Only)。CDPを使って自らコードを辞書に書き込んだりするときには、このことに注意しなければなりません。 もっとも、普通のアプリケーションで、CDPやDPを自分で使う必要がでてくることは、ほとんどないでしょう。むしろ、Mopsシステムの機構の説明と考えてください。 関連項目: データをコンパイルする コードをコンパイルする トップページへ 目次へ
https://w.atwiki.jp/xopsfan/pages/13.html
XOPSとは
https://w.atwiki.jp/mopsprogramming/pages/12.html
昔、といっても想像を絶するほどの昔ではありません。でも、まあ、幼稚園児が「わたし、これ、むかしはできなかったんだよね~」ということもありますので、この「昔(むかし)」という概念はイチヂクシル、もとい、イチヂルシク認識主観相対的なことばであるということになります。 ま、最近ちょっと余りに手持ち豚さ、もとい、手持ち無沙汰なので、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アプリケーションならユーザーも沢山(絶対数では)集められるでしょうから、消えてしまう心配はないですよね。 トップページ
https://w.atwiki.jp/props/
土地と建物に関わる人達の業界横断型トークイベント PROPS プロトーク PROPS プロトークは、建築や不動産という業界の枠にとらわれず、ITや社会起業など、 土地と建物に関わるさまざまな分野の人達が共に語り合うトークイベントです。 メンバーの方は、ページ上部右側の【このウィキに参加】から登録申請をしてください。 編集の際は 編集手順 をご覧ください。.
https://w.atwiki.jp/mopsprogramming/pages/175.html
iMopsのビルドの方法は、配布物中にテキストファイルで含まれていますが、一応、ここでも説明します。 まず、iMopsに、ソースファイル Prepareロードします。 // Prepare ENTER リターン(改行)キーと別個のエンターキーがない場合は、fn+Returnで等価です。 次に、続けて、ソースファイル im.ldをロードします。 // im.ld ENTER これは、コード・ジェネレータを含むたくさんのソースファイルをロードして、その後、自動的に、iMopsフォルダ中にiMopsという名前の実行ファイルを生成します。 ここで、いったん、iMopsを終了します。その後、iMopsのアプリケーションパッケージを開いて、iMops.app/Contents/MacOS/iMopsという位置にあるファイルを、前で生成されたファイルと交換します。 再び、iMopsを起動して、今度は、ソースファイルAdditionsをロードします。 // Additions ENTER いくつかのソースコードファイルがロードされて、メッセージの後、静かになります。一秒もかからないくらいです。 そこで、SAVE-DICというコマンドをiMops上で実行します。 SAVE-DIC ENTER このコマンドで、やはり前と同じように、iMopsフォルダ中にiMopsという名前の実行ファイルが生成されます。 再び、iMopsを終了し、また、iMops.app/Contents/MacOS/iMopsという、前に置き換えたファイルを、さらに、上で新しく生成されたiMopsファイルに置き換えます。 これで、iMopsは新しくなりました。 注意点としては、 もともとの実行ファイルiMopsは、失敗したとき元に戻すために、例えばiMopsフォルダ内に適当な名前の専用フォルダを作って、とっておきましょう。 iMopsファイルを生成するとき、iMopsフォルダ内に同じiMopsという名前のファイルがあると警告もなしに上書きしてしまうので注意。アプリケーション自体は、表示名と違ってiMops.appなので、上書きされることはありません。 何度もコンパイルすると、名前が同じファイルがたくさんできるので混同しないように。 くらいでしょうか。 自分でバグをフィックスしたときには、この方法で新しいiMopsが得られます。 ただし、注意しておきたいのは、im.ld段階でロードされるコードジェネレータの部分の修正をきちんと全体に反映させるには、二回ビルドする必要があります。というのは、一回目のコードジェネレーターのコンパイルは、修正前の現在のコードジェネレータで行われるからです。新コードジェネレーターになってから、もう一度、ソースをコンパイルすれば、全体が、新しいコードジェネレーターでコンパイルされることになるわけです。 目次へ トップページへ
https://w.atwiki.jp/mopsprogramming/pages/14.html
トップページ 概観 Mopsに入り込む前に、このやや長たらしいマニュアルの構成を概観しておくのが、もっとも役に立つでしょう。 Mopsドキュメンテーションの本体は三つの区画に分かれています。 Mopsは、本格的なMacintosh開発用言語として、また、初心者や一過性のプログラマがMacのパワーを手に入れることを学ぶための言語として、それらどちらでもあるものとして設計されています。 このマニュアルは、その両方を受け手として書かれていますが、ある部分はその中間を狙っています。 このマニュアルは次のような主要部分に分けられています。: 概観 この章 全1章 第一部 チュートリアル 全22講座 第二部 参照 全14章 第三部 クラス 全12章 第一部;チュートリアル この導入部分は、経験の如何を問うことなく、全ての人にむけられています。それは、このマニュアルの中であなたが取り組む最初の部分となるべきものです。わたしたちは、Mopsマニュアルの大部の区画を費やして21の講座からなるチュートリアルに充てました。これは、初心者、特にこれまでにコンピュータをプログラムした経験が無い人にとっても、また、もっと経験豊富なプログラマーにとっても、Mopsの本質的な要素に対する見通しを与えてくれるものとなるでしょう。わたしたちは、すべてのMopsユーザーに対して、その経験を問わず、このチュートリアルを完遂することをお勧めします。もしも、Mopsが、あなたが既に知っている言語に部分的に似ていることに気付いたとしても、チュートリアルを読めば、思っていたよりももっと重大な違いがあることがわかるでしょう。チュートリアルにある講座を参照しながら、10から12の区分されたセッションを数日で終えるように計画してください。MopsはForthに基づいています。このForth言語を知っているなら、そのことはきっと役に立つでしょう。Mopsは伝統的なForthに、他のとても有用なツールと並んで、オブジェクト指向パラダイムのパワーを追加しています。 第二部;参照 この部における6つの章は、Mopsについて、その細部の解説を数多く提供しています。そこには、チュートリアルで触れられた話題についてのかなり拡張された説明が含まれています。この部は、チュートリアルを読み通した後になってからお読みください。 第三部;クラス マニュアルのこの部は、ひとたびMopsプログラムを書き始めたならば、以後、もっともよく利用される参照セクションの一つとなるでしょう。それは、Mops言語の中の、Macintoshのユニークなやり方に対してあなたのプログラムの考え方を伝達する助けとなるために書かれた部分について、その詳細な説明を含んでいます。各章は既定義クラスの各カテゴリーに充てられており、そのクラスの一般的な議論から始まっています。あなたは、プログラムを書く前に、第三部の内容に慣れておくべきでしょう。 さらに、Mopsパッケージは、Mopsの多くの部分に該当するソースコードリストを含む、たくさんのファイルを含んでいます。これらは、実質的には、あなたにとって追加的なドキュメンテーションになります。チュートリアルの中に、これらを利用可能な参照文献に組織するための方法について、その解説を見つけることができるでしょう。 独立(スタンド・アローン)アプリケーションの開発 Mopsは、独立のダブルクリックできるアプリケーションをつくるのに利用できます。このようなアプリケーションでは、ユーザーは、それがどの言語で書かれているのかを気にする必要がありません。そのユーザーは、Mopsの辞書やインタープリターに触れることはありませんし、その必要もありません。この制作の手順の解説はチュートリアルに書かれています。 あなたのMopsシステムに含まれているもの 【変更の可能性があるため、省略】 System, Tool box classesおよびDemoフォルダ中のソースコードの大部分は、追加的なドキュメンテーションとしてばかりではなく、変更版Mopsをコンパイルしたいときのためにも提供されています。 あなたが圧倒的な高頻度で開くファイルは、Mops.dicかMopsFP.dicかPowerMopsのいずれかになるでしょう。これらはMopsのワードと既定義クラスの大部分を含んでおり、この基盤上にあなたはプログラムを組上げることになるのです。 このマニュアル中に用いられる規約 このマニュアル全体を通じていくつかの約束事があります。あなたはこれを知っておくべきでしょう。 チュートリアルでは、あなたがコンピュータに打ち込まなければならない、たくさんの例を提示してあります。あなたが打ち込む文字とコンピュータがスクリーン上に生成する文字とを区別するため、あなたが打ち込むべき文字はスタイルが設定されています。コンピュータのプロンプトその他の反応は、正規等幅字形で印字されています。 マニュアルやMopsソースコードの中に、例えば、bArrayのように、奇妙に思える場所が大文字になっているMopsワードを見かけることも、多々あるでしょう。このようなスタイルの大文字化は経験のあるプログラマーの間では、読みやすさのためによく使われるものですが、Mopsを習得するのに何らかの大文字化の枠組みをマスターする必要などはないと考えてください。Mops自体は大文字小文字を区別しません(case insensitive)。この意味は、あるワードを、全部小文字ででも、全部大文字ででも、あるいはそれらを取り混ぜてでも書くことができ、Mopsはそれを同じワードとして認識するということです。Mopsについてもっと経験を積めば、わたしたちが設定した大文字化の標準がもっと解るようになるでしょう。 経験豊かなForthおよびSmalltalkプログラマーへの特別な注意 MopsはForthを基礎としており、そのオブジェクト指向機能はSmalltalkに多くを負っています。SmalltalkかForthの経験のあるプログラマーは、Mopsの振る舞いに関する何らかの結論に、以前の経験を基に飛躍してしまうことのないように注意し、チュートリアルを注意深く読み通すようにしなければなりません。 歴史 Mopsは、Charles Duffによって開発され、Kriya Inc.によって販売されていたNeon言語から派生した、オブジェクト指向プログラミングシステムです。KriyaはNoenのサポートを停止し、Neonという名前の所有権だけを留保して、そのソースコードをパブリックドメインに解放しました。 MopsはNeonの完全な再実装であり、多くの付加的な拡張も加えています。これもまた、パブリックドメインです。 このマニュアルの多くの部分は、2000年9月に公開されたMS Word形式のMops 4.0マニュアルから直接に取り入れられています。オリジナルのHTML公開は2003年にGnarlodiousによって完成されました。 その際、素材のいくつかの部分は、OSXの出現を反映するためアップデートされました。この改訂作業は継続中ですが、ウェブサイトとしてはバージョン付けはおかしいように思われるので、このマニュアルはバージョンナンバーを持っていません。そのかわり、このページのタイトルバーに「最終更新日」が記入されています。 Mops Mopsという名前は、"Mike s Object oriented Programming System"の略称ということもできますが、Mikeはコンピュータの世界ではもうたくさんの略称が溢れていると感じているので、これ以上増やすのは申し訳ないと考えています。そこで、わたしたちは、Mopsを、MOPSではなく、Mopsと綴ります。 Mikeは、長期にわたり、Mopsユーザーが、その開発を分担することで、持続的なMops開発の努力に貢献してくれることを望んでいます。一人の人間の、細切れの時間での作業のため、Mikeには、大仰で騒々しい付属機能で満ち満ちたMac用開発システムを生産する商業的な輩に一人で対抗することなどは望むべくもありません。Mikeとしては、Mopsの核部分や基礎的システムコードのような低層の実装に集中できるのが望ましいのです。 チュートリアル目次 トップページ
https://w.atwiki.jp/xops/pages/16.html
オリジナルマップやオリジナルミッションを作成することが出来るXopsToolsについての解説のつもり まずはXOPSの中にあるドキュメントの説明をプリントアウトし、 それを見ながら作りましょう。 それだけで作業効率は大幅にアップします。 blockeditor pointeditor
https://w.atwiki.jp/mopsprogramming/pages/13.html
Mops概説(Mops Roundup) The Mops Programming Language トップページ この記事は、とても役に立つ事柄を含んでいますが、Ed Williams氏が書かれたもので、もともとはe-zine ATPM -- About This Particular Macintoshに二部構成(Part1 およびPart2)で掲載されたものです(素材は少し変更されています)。この記事は、Mops/PowerMopsの初心者ユーザーまたはこれから利用するかもしれない人に向けて書かれています。 プログラミング言語 Mops はじめに パーソナルコンピューティング経験のなかでも実りが多いのは、役に立つものであれ何であれ、自分のプログラムを書くことです。これは少し危険なことです----常習者、あるいは少なくとも癖になってしまうかもしれないからです。いずれにせよ、少しはMacでのプログラミングに関心があるというのであれば、ぴったりのフリーウェアプログラミングシステムがあります。その名はMops。それは、Macintoshだけのためにデザインされているのです。Mopsシステムは、飽くことを知らない有能なオーストラリア人プログラマであるMike Horeによって、過去15年以上に渡って、暇をみつけては開発され続けてきました。現在配布されているシステムのサイズからいえば、Mopsはまさに最高のMacソフトウェアとしての価値をもつといえるでしょう(7.4MBを$0で割ってみれば判ります----いえいえ、これは実行できません。) Mops, ForthそしてOOP Mopsの非凡さは、デザイン上本質的にMacintosh用プログラミング言語になっているという点にあります。それはAppleScriptが本質的にMacintosh用スクリプト言語であるのに匹敵します。この事実は、それらのどちらにおいても(比較的)容易に利用できるという性質をもたらしています。----もっとも、プログラミングは決して容易なわざではありませんが。そのうえ、Mopsは古いものと新しいものの最良の部分を継ぎ目なく混ぜ合わせているという点でユニークです。その言語は、一般に利用されている最古のプログラミング言語に属するForthに基づいています。MopsはそのForthバックボーンに、非常に堅牢で完全な形のオブジェクト指向プログラミング(OOP)を付け加えました。MopsのOOP実装はOOPシステムが提供すべきものとされるほとんど全ての事柄を含んでいます。多重継承さえ備えているのです。 MopsはMacintosh専用ですから、必要なMacツールボックスおよびシステムサービスを提供するために別段のAPIやフレームワークは必要ありません。ある意味、それらは組込まれています。ですから、どんな種類のMacプログラムも作れますし、(コールバックルーチンなどを含んでいる)シェアードライブラリ(これはシステム拡張を速やかに駆逐しつつあります)も構築することができます。G4 MacintoshモデルのAltiVec実数コプロセッサも、ウィザード水準のベクトル計算プロセッシングのためにサポートされています。(PhotoshopがG4ではなぜこんなに速く走るのか不思議に思ったことはありませんか?) OSXより前のMacのプログラミングサービスをまだあまり御存じない方へ:ツールボックスというのは、OSが提供する途方もなく多くのサービス---- 明らかなものをいくつかあげれば、ウィンドウ、メニュー、ダイアログ ---- への、伝統的なプログラミングインターフェイスを提供するものです。ツールボックスは、数多く定義された"Syscall"の一つによって呼び出され、実行時にはシステムが割り込みをします。最近のOSの幾つかのバージョンでは、CarbonLibというシェアードライブラリが、"カーボン化"されたプログラム---- MacOS9とMacOSXで両立できるようにつくられたもの ---- については、これらの呼び出しの大部分を受け持ち、両プラットフォーム上で、同じ、あるいは類似のサービスを提供することを目指しています。 Forth その歴史 Forthという言語はいくつかの歴史的背景をもっています。Charles H. Mooreは独力でForthを発明したという栄誉が与えられるべき人です。;彼のアイディアが形を取るのは、1950年代のスミソニアン天文研究所でのことです。そこで彼は、その言語がどうあるべきかについて、いくつかの鍵を見つけました。Mooreは1969年までにはForth言語の開発を完成しており、その名前で呼んでいました。初めはIBM 1130ミニコンピュータ用でした。Mooreは、なかでもコンピュータグラフィックスプログラムをForthで書きました。マイクロプロセッサの発明に伴って、Forthは埋込み型コントロールプロセッサでは当たり前になりました。この種のデバイスではコントロールソフトウェアのための領域はごく小さなものです。巨大なプログラミング開発システムなどお話にもなりません。Forthはクロスコンパイリングに役立ち、小さなマシン語プログラムを生産しました。 ANSI Forthスタンダードは存在してはいますが、実際のForthの世界は、おたがいにも、そして標準からも少しずつ異なる、たくさんの変種によって特徴付けられます。ですから、確かにMopsは十分にForthの一員としての地位を確立してはいますが、そのコードのバックボーンは(Forthそのものというよりも)Forth風というのが合理的でしょう。Mopsは実際、特に、Macintoshプログラミングのため、便宜のため、そしてオブジェクト指向オペレーションのために、Forthの規格にはないForth風のwordの定義を数多く追加しています。(Mopsは容易に標準にしたがったANSI Forthコンパイラに変換できます。そして、同じくらい容易に元に戻すことができます。) Mopsは高水準のOOP構成に服する優れたForth風言語ということができます。OOPの上着を着たForthと言うこともできるかも知れません(が、そういうべきではないでしょう)。コードは、他の全てのForthベースの言語と同様、三つの主要な特徴で性格付けられます。:顕在的なスタック、演算子後置(Postfix)記法、そして、言語の拡張性です。 Forthが進化していた時代には、プログラムが利用可能なメモリーは、現在の水準から見れば僅少なものでした。したがって、Forthの記号法の風変わりな性格は、その発明者の恣意や目新しさのために採用されたものではありません。メモリーが安価で豊富となった今となっても、コンパクトなコードが生成されるということは、その実行速度のためには、なお当時に劣らぬ価値があります。 Mops V.4は、Mopsページからダウンロードすることができます。このウェブサイトはたくさんのその他の有用で入門的なアイテムを含んでおり、Forthのドキュメンテーションおよびリソースへのリンクがあります。この中には、この記事の後の方で引用する『Forthの進化(The Evolution of Forth)』も含まれています。 現時点では、PowerMopsのカーボン化されたバージョンV. 5.xが、OSXとの互換性を目指して、利用可能となっています。"古い"標準的なMopsは、Macintosh plusにまで遡る68kプロセッサのためのプログラムを生成します。(‘legacy’コンパイラというべきでしょうか。)より新しいPowerMopsはPowerPCマシンにネイティブにコンパイルし、FATアプリケーション(68kおよびPowerPCマシン両用)もビルドすることができます。 露出スタックと"うしろ向き"記号法 コンパイラの大部分は内部的にスタックオペレーションを広範に利用しますが、効率化のため、Forthではひとつのスタックがいわばオープンにされており、プログラマーがコントロールできるようになっています。これは、データスタック、またはパラメタースタックと呼ばれています。それは、ひとつのForthワードないし手続から、別のそれにデータを渡すために用います。 第二のスタックであるリターンスタックは、大抵は、データではなくて、プログラムのリターンアドレスを含んでいます。しかし、習熟したForthプログラマーなら、それを(一時的にデータを保管するために)利用することも可能です。無限定に"スタック"というときには、いつもデータスタックを意味します。これは、この言語の性質上、プログラマーによって管理される必要があります。(アセンブリ言語のプログラマーも、一般に、これもまた効率化のために、コード内で一つまたはそれより多いスタックを採用します。) Mops --- そしてその他のForthベースの言語でも同様---は、普通の押し下げスタック(push-down stack)を用います。これは後入先出(LIFO)リストともいわれます。Mopsのコーディングスタイルと‘文法’、つまり、正しく言語を拡張する方法は、LIFOリスト操作の表現が適切であるかどうかにかかってきます。 ForthのエキスパートであるElizabeth Ratherは、Association for Computer Machineryに提出された彼女のペーパー「Forthの進化」の中で簡潔に述べています Forthの明示的なスタック使用は、被演算項が演算子に先立つPostfix記法を導く。演算の結果がスタックに残されるため、複数の演算を無理なく連結することができる。そして、一時的データ保管のために変数を定義する必要はほとんど生じない。 (このペーパーは、Ms. Ratherが、常にMooreと"同室にある"か、さもなければ"隣室にある"かのいずれかであった人であるという点で、歴史的に非常に注目すべきものです。彼女自身もこの言語に影響を及ぼしました。)彼女がここで述べているのは、スタックプログラミングはpostfix記法/逆ポーランド記法(RPN)の利用へと、作業への適合性ゆえに自然に繋がるということであり、スタックを利用すれば、変数宣言が必要になる場面は劇的に減少するということだと思います。実際、ヒューレット-パッカードの携帯電算機もRPNを利用してますが、----御想像の通り----スタック指向でもあります。 図1は、一つのスタックの三つの継続する‘ライフ’の段階ないし時点を記述したものです。TOSはスタック最上位(Top Of Stack)を表わしています。 スタック模式図 図1: スタックの三つの段階 次は、全く単純なMopsワードの定義です。これをADDと名付けます。理由は明らかでしょう。: ADD ( n1 n2 -- sum ) + ; ワードAddがすることは、それが呼び出されたときにスタックにおかれているはずの二つの数値を足しあわせることだけです。このワードのスタックコメント(括弧の中)にある記号n1とn2がスタック上に予定される数値を示しています。記号‘sum’は、このワードを呼び出したルーチンに戻ったときには、それはスタックのトップに(この算術計算の性質に従った)結果を残すだろうということを示しています。この定義にある唯一つのコードは、一つの加法演算子ないしプラス記号であることに注意しましょう。 さて、スタックの図に戻りましょう。;一番左の絵は、Addを呼び出す直前のスタックの状態を表わしています。スタックの内容は、入れ子状になった(一部分だけ実行された)いくつかのワードが利用することになっている値と、ツールボックスルーチンによってスタック上に押し込まれた情報といったところです。中間の絵は、ワードAddを呼び出す側によってスタックに押し込まれた二つの整数を表わしています。これらはワードAddの呼出し専用に押し込まれたものです。 右側の絵は演算の結果がトップスタック上におかれることを表わしています。二つのことに注意しましょう。:ひとつには、Mopsの演算子は、その被演算項を一様に消費する、というか使い切ることであり、ふたつめは、スタックの最上位(TOS)のポインタはMopsが自動で面倒を見てくれるということです。(一般に、被演算項がスタック上に残ることは決してありませんが、中間的結果やもっと複雑な処理過程は残ります。) 下は、もう少し面白いMopsのコードサンプルです。 Value TEMP ( at top level ) SUM-OF-SQUARES ( n1 n2 -- n3 ) DUP * - Temp DUP * Temp + ; Value宣言はTempという名前の大域変数を作り出します。‘ ’(コロン)は新たな語を定義するためのForthワードです。コロンからワードの定義が始まり、その後にはその新ワードの名前がきます。この場合には、SUM-OF-SQUARESです。(二乗和演算(sum of squares)とは、二つかそれ以上の個数の数の二乗をつくり、それらを足しあわせるものです。)括弧内に書かれたコメントは、スタック効果コメント、ときには、スタック記録と呼ばれます。スタックコメントはオプションであって、純粋に記録のためのものでしかありませんが、Forthプログラミングでは非常に重要なものとみなされています。コメントを利用すれば、定義されたワードが、実行される際に入力としてスタック上に何を必要とし、出力としてスタック上に何を残すのか、を明確にすることができます。スタックコメントが非常に複雑になることもあり得ますが、そんなときこそ、まさにコメントが最も必要なときと言えるでしょう。 この例でも、このワードが呼ばれる際にスタックの上位に二つの整数があることが必要です。これはn1とn2が表わしています。呼び出し側のワードと呼び出されるワードとの間でこの点に関して齟齬があった場合には、コンピュータ世界は大混乱に陥ります。呼び出されたワードが、それに属していないスタック上のデータを‘喰って’しまったなら、スタックはすぐに辻褄が合わなくなるでしょう。(n2、というより入力パラメターの一番右に書かれた記号はいつもスタックの最上位の値を表わしていますが、このことはこの場合には重要ではありません。)記号n3は、ここで定義されているワードが、終了したときにはスタック上にひとつの値を押し込むだろうということを示しています(性質上、計算された自乗和がそれです)。 スタックコメントは決してデータスタックの地図ではない、ということに注意して下さい。スタック上には、与えられたワードの実行に関連する値より下の方にも、たくさんの値が存在しているかも知れません。下の方のデータアイテムは、それを消費するであろう別のワードに属するものです。 ワードDUPは、スタック操作専用のもので、n2で表わされているトップスタックの値をコピーして、新たなトップスタックセルを作り出します。積演算子‘*’は、トップスタックの値とその直下の値とを掛け算します。その際には、それら二つの値を費消して、積の値が入った新たなトップスタックセルを作り出します。Mops特有の演算子である‘- ’(‘中に入れる(gazinta)’というひらめきに溢れた名前で呼ばれていますが)は、トップスタックの値を、この例のTempのような、ある種の変数に割り付ける格納演算子です。したがって、n2の二乗はスタックから取り除かれ、今度はn1がトップになります。(もちろん、ここでn1,n2といっているのはそれで表わされているデータの値のことです。) コードの2行目は、n1で表わされる値の二乗を前と同じようにして作り出しますが、続いて、単にその名前を書くことを通じてTempの値をスタック上に押し込み、スタックの最上位の値(n2の二乗)とスタックの上から二番目の値(n1の二乗)を足しあわせます。これらの被加算項は、どちらも加法演算によって費消され、その和が、このワードの戻り値としてスタックに押込まれます。(ワードSUM-OF-SQUARESは、いくつかの他の言語では関数と考えるのが適切なものでしょう。)スタックコメントは、文字どおりには普通の意味のプログラムコメントとは別個のものであるとしても、その有用性ははっきりしたものであると思います。 ワード‘;’ (セミコロン)は、ワードの定義を終了させるものです。この短い2行のコードの中で、随分多くのことが起こっていると思いませんか?同じルーチンの、変数の宣言を必要としない、もっと巧妙で本来的なバージョンは、次のようになります。: SUM-OF-SQUARES ( n1 n2 -- n3 ) DUP * SWAP DUP * + ; 非常に便利なワードSWAPは、これも専用のスタック操作子ですが、上ふたつのスタックセルの値を取り替えます。何も費消しません。これだけたくさん説明してきたのですから、残りは研鑽を積まんとする皆さんへの演習として残します。それぞれのワードひとつひとつに集中しましょう。まったく簡単です。 名前付きの入力パラメターや局所変数を用いて、目に見える形でのスタック操作を大部分隠してしまったり、制限したりする方法も、プログラマーにはいくつか利用できます。時として、あまりに複雑な操作が必要になってしまって、それらのような魔法の変数を用いる必要が生じ得ます。(名前付き入力パラメターと局所変数は、Mops特有の言語機能です。) Mopsのスタック指向がもたらす、プログラマにとっての直接の利点は: 速くてコンパクトなコードが生成できる。(Mopsプログラムは、ときとしてアセンブラコードに比肩しうるものとなります。) 大域変数を大きく減らすことができる、というのは、入力・出力パラメターはどちらもスタック上におくことができ、スタックを直前の結果を保存するために利用することができるからです。これは、プログラマーにとっては間違いを起こし易い面倒な作業を省き、プログラムに必要なメモリも減らすことになります。 Mopsの手続は外部変数を使わない限り本来的に自己呼出し可能(Re-entrant)であって、これはコードを単純化するのに決定的に有利です。(再帰性(Re-Entrancy)とは手続が実行中にそれ自身を呼び出しうる能力のことで、非常に便利なものであり、ある種のアプリケーションでは不可欠なものでもあります。)大部分の言語が何らかの再帰性を提供していますが、特別な追加的コンパイラコードを用いて行っています。これに対してMopsの手続は単純かつ生来的に再帰的です。 通常の高水準Mopsワードだけを使ったMopsプログラムは、生来的に(Dijkstra/Parnasの定義の意味で)構造化・モジュール化されています。EXITとEXECUTEを使った場合だけは例外となります(これらはプログラムコントロールを逸らすものです)。プログラミング理論においては、構造化され、かつ/またはモジュール化されたプログラムは信頼性が高いとされています。私の解釈では、これは隠れた‘しくじり(gotchas)’を含みにくいということになります。 ワード、ワード、そしてワード Mopsが持つForth的単純性のもうひとつの側面として、成語規則(どうすればその言語の有効な基礎的要素を形成できるかを教える規則)が非常に単純であることがあります。Forthにおけるシンタックス的要素、ないし識別子とは、空白文字で区切られた文字列である、おしまい。この文字列には空白文字(空白、タブ、改行)を除けば、どんな文字を混ぜてもかまいません。この文字列は、好きなだけ長くても短くてもかまいません。 Mopsの文法は、上で見たような(空白で区切られた と;)新たなワードを定義するための単純な記号と、その他のいくつかの同じように単純な記号とから成っています。もちろん、Mopsにはたくさんの異なる種類のワードがありますが、成語的にはそれらはすべて同じものです。OOP構成にはいくつか追加的な規則が必要になりますが、それらも非常に少なく、かつ単純です。実際、Forthはシンタックスを必要としていないため、それを持たない、という人もいるくらいです。シンタックス上の単純さによって、この言語の三番目の主要な特徴がもたらされます。:利用者による拡張可能性です。 通常の(高水準の)Mopsワードは次の三つのカテゴリーに分類されます。:名前付きデータアイテム、名前付き手続、定義用ワード。定義用ワードにより、利用者は名前付き手続、つまり新たなMopsワードとアクションワードと呼ばれるものを定義できるようになります。実行可能ワード、あるいは‘被定義ワード’は、機能的には他の言語におけるルーチン・サブルーチン・関数に類似し、場合によっては他の言語のコマンドに相当するものもあります。例えば代数がFortranのメタファーないしモデルであるのと同様、Forthのメタファーは自然言語の散文です(‘動詞’が最後にくるドイツ語であるという人もいます。)。非常に多様な範囲に渡る機能的にも様々な要素を、任意の文字列で表わすことができます。予約語は実際上存在しません( と;が数少ない例外に属します)。辞書中のほとんどどんな語でも、その名前を再定義することができます。 Forth言語系でワードという言葉が強調される源泉のひとつは、辞書という機構が用いられいることにもあります。例えば‘+’のようなMopsの既定ワードの全て、そして---ある時点では---利用者のプログラムを包括する全ワードが、辞書内に存在しています。大まかにいえば、まさに辞書こそが、利用者のプログラムそのものなのです。(その辞書の解釈は、小さくて迅速なマシンインストラクションの仕事です。)概念的には、辞書の下に、コンパイラ/インタープリタ プリミティブを含む小さな核が存在しています。 これらの成語的考察全体から導かれるのは、利用者が既存のワードを組合わせて自由に新たなワードを作り出すことができる、完全拡張可能言語です。このことによって、プログラムを容易に整理整頓(factor)することができるようになります--これは非常に重要なプログラミングテクニックです--。 ベテランであるPhillip J. Koopmanは次のように述べています。: Forthプログラムを書くということは、その言語を拡張して、あるアプリケーションの実装に必要な関数の全てを包含するようにする、ということと同値である。したがって、Forthでプログラミングするということは、アプリケーション専用の言語拡張を作り出すことと考えることができる。このパラダイムは、非常に速い編集/コンパイル/テスト周期と相俟って、生産性を著しく増大させるものであるように思われる。各Forthワードが書かれる毎に、それをキーボードからテストして、直ちにプログラマーにフィードバックすることができるのである。 言語の拡張は、プログラムのためにコンパイルされるコードに反映されます。辞書は、はじめにはMops言語の定義しか含んでいませんが、利用者プログラムでの定義を全て含むように、文字通り拡張されます。プログラムがスタンドアローン、つまりダブルクリックで起動可能なプログラムとしてインストールされる前であれ後であれ、そのプログラムの実行とは、結局のところ、辞書を解釈することに帰するのです。 Mopsプログラムの解釈 Mopsプログラムがスタンドアローンで実行されるようにコンパイルされたときでも、プログラムはなおインタープリタモードで実行される、という見方について、補強しておいた方がいいかも知れません。このような実行モードは、しばしば貧弱なパフォーマンスと結びつきますが、Mopsプログラムに関してはそうではありません。 Postfixの解釈可能言語としては、Mopsは、CやJAVAやPascalのような他の今日のポピュラーなプログラミング言語よりも、PostScriptとより多くの共通点を持っています(構造化コードはPascalと共通ですが)。他方、AppleScriptはインタープリタ言語ですが、‘超高速化’よりも使い易さに重点をおいて設計されています。 例えば、上で定義したワードSUM-OF-SQUARESの定義を、何かのプログラムソースに組込む前に、Mopsのデータ入力ウィンドウに入力して呼び出すことによって、インタラクティブ解釈モードでテストすることができます。とても親しみやすいものです。下の図2のように、SUM-OF-SQUARESの定義をMopsのデータ入力(および編集)ウィンドウに入力しました。横線から下の部分です。 定義部分を選択してEnter(リターンでなく)キーを押します。しかしそれをした後も、図のウィンドウの上側部分に見られるように、スタックは空っぽ(empty)なままです。Mops2これは、SUM-OF-SQUARESの定義がコンパイルされてMopsワードとして辞書に移されたからです。(ワードとしての‘コロン’「 」によってMopsはコンパイルモードに入ります。) 図2 ワード定義の入力 図3では、12と24の二つの値が入力され、SUM-OF-SQUARESが単純に名前を書くことによって呼び出されています(キー入力の後Enterキーを押します)。Mopsは、解釈モードでは、数値をスタック上に置き(標準的な動作です)、名前に適合するワードを辞書内に探します--この場合には、そう遠くまで探すまでもありません--。そして、見つかったなら、適合するワードが実行されます。最後には、sum-of-squaresの結果をスタック上に見ることになるのです。 もしもエイリアンのような高速視力を持っていたなら、ワードSUM-OF-SQUARESによって喰われてしまう前の二つの数値がスタック上に見えたことでしょう。もちろん、スタック上の値それ自体をまずenterして、SUM-OF-SQUARESを起動する前に見てみることもできます。Mops上でテストもっと複雑なワード定義を辞書に読み込んだときには、キーボードの前に座って、入力の値の組合わせを様々に変えて、日がな一日テストを続けることもできます。 図3 テストのために値を入力する プログラムの小さな断片部分を他の大部分から独立にテストすることができるということの利点は明瞭でしょう。 Mopsのオブジェクト指向 さて、Mopsのユニークなオブジェクト指向特性に話を遷しましょう。この特徴を備えたフリーウェア言語は、私の知る限りでは、他にはありません。Mopsの唯一人の領主であるMike Horeによれば、オブジェクト指向プログラミング(OOP)は"この言語の本当の力の源泉"であり、付け加えさせてもらえば、それはその主要な"ウリ"です。オブジェクト指向は、完全な形であれ部分的なものであれ、今日ではとてもポピュラーなので、この記事でその利点と美点を売り込む必要はないでしょう。 続く3つの節では、OOPの背景を成す考え方を、いくぶん抽象的に説明しています。OOPの概念をもう良く知っているのなら、"クラス宣言の実例"まで跳んでもかまいません。概念の説明は、Xerox PARCのメンバーでSmalltalkを開発した、Adele Goldbergの見方に従います。彼女は、OOPの発明者と呼ばれるに相応しい人です。ともかく彼女は、確かにかつてPARCスタッフの一員であり、Alan Keyの印象的な言葉によれば、"両手に稲妻をもあやつる"訳者註人でした。 訳者註 訳に自信がありません。原文は"dealt lightning with both hands"です。 目的 OOPの主要な目的は、プログラムの複雑さをより上手く管理することです。OOP実装を行うならば、最初の段階でのプログラムないしシステムの信頼性を向上させるだけではなく、同じくらい重要なことですが、コードの保守管理可能性を拡大させます。 モデル OOPのモデルは、独立した、互いにコミュニケートするオブジェクトというモデルです。このモデルによれば、あるオブジェクトは、もうひとつのオブジェクトにメッセージを送り、それを受け取ったオブジェクトだけが扱い方を知っている、ある操作を要求します。この操作がどのように実行されるかを決めるのはメッセージを受け取ったオブジェクトだけです。したがって、"コンピューティングは、オブジェクトに内在する能力とみなされ、これはいつもメッセージを送ることによって起動される"(A. Goldberg)ことになります。 上に引用された内容からは、Forth、Modula、Algol、およびPascalといった言語が提供するものよりも高い水準のプログラミングパラダイムが導かれます。---これがもっと低水準のパラダイムに無理なく馴染ませられるものであることは、MopsにおいてForthとOOPが継ぎ目なく結合されていることが証拠になります。 基礎的概念 オブジェクト指向アプローチが要求するのは、たった5つの十分に定義された諸概念だけです。:オブジェクト、メッセージ、クラス、メソッド、インスタンスです。 実践上の区別からはじめましょう。:クラスは、ランタイムエンティティーであるオブジェクトを作り出すソースプログラムエンティティーと考えることができます。クラス定義は、オブジェクトのクラスを記述します。ひとつのクラス定義から、ひとつ、ないし複数の同等なオブジェクトを作り出すことができますが、それらオブジェクトのデータの値は、実行時には通常は互いに異なります。辞書内にコンパイルされた静的オブジェクトは固有名を持たなければなりません。個々のオブジェクトは、そのクラスのインスタンスと呼ばれます。 ひとつのオブジェクトは、データのために確保されたある量のメモリーと、ひと組のオペレーションないしメソッドから成ります。データとオペレーションの性質は、そのオブジェクトが表現しているものに依存します。それは、基礎的なデータオブジェクトから、スクリーン上のウィンドウ、ひいては、問題空間におけるあるエンティティーの複雑なモデルに至るまで、広がりうるものです。(例えば、Mopsのデモプログラムは、一群の数学表現を象った、眼を見張るようなパターンを造り出します。)オブジェクトのデータは、論理的にはそのメソッド、つまりそのデータ上に必要なオペレーションを実装するコードとパッケージ化されます。これは、論理的データ-コードカプセル化として知られています。 もうひとつのオブジェクトが、関連するデータを持っているオブジェクトにメッセージを送ることによって、特定のデータを保存、取り出し、加工などすることを求めることができます。この文脈では後者が受け手と呼ばれます。受け手は、そのメソッドセット中に対応物があるメッセージだけを認識します。オブジェクトの肝要な性質は、それ自身のメソッドによってしか、そのメモリーにアクセスすることはできない、ということです。メッセージの肝要な性質は、あるオブジェクトのメソッドを起動する唯一の方法であるということです。 これらの二つの性質の組合わせにより、ひとつのオブジェクトの実装は他のどのオブジェクトの実装のどんな特性にも依存し得ない、ということが保証されます。これは基礎的な利益であるばかりではなく、プログラム開発中、およびとりわけプログラムの保守管理において、実際的な利益にもなります。小さなプログラムを開発していたとしても、あるオブジェクトのクラスの実装を他のものに影響を与えることなく変えてみることができるということはうれしいものです。 Mopsのオブジェクトは一般に、そのデータ構造を構成し暗黙裡にメソッドを補助する、ひとつあるいは多くのもっと下位のレベルのオブジェクトを含んでいるという意味で、合成構造となっていることに注意しましょう。ですから、OOP規則にしたがって、合成されたオブジェクトは、それが含んでいるオブジェクトに‘内部的な’メッセージを送ることができますし、実際に常にそれを行っています。この内部的なメッセージは数多くのレベルで起こり得ます。したがって、ハイレベルのオブジェクトのメソッドは、そのオブジェクト自体ばかりでなく、それ以外の数多くのオブジェクトからも流れ出ている、オペレーションの滝と考えることができます。このことは、インフォーマルな書き方ではありますが、非常に重要なポイントです。 内部的メッセージを送ることは、最終的にはマシンコードに近い原始的なオペレーションで定式化されたメソッドに行き着く連鎖、と考えることができます。内部的メッセージは継承と相俟って非常に高次元の情報隠匿を提供します。プログラマーは、そのプログラムによって起動されるメソッドの大部分について、定義を見ることはありません。;採用しようとするメソッドの名前を知り、理解するだけでいいのです。 最後に、Mopsでは、メッセージは、それ自体はオブジェクトの一部ではないコード、つまり通常のMopsワードから送ることもできます。 クラス宣言の実例 Tic Tac Toeゲーム(三目並べ)を書いていると仮定しましょう。スクリーン上に起こっていることを継起的に記録する、ある種の‘雑用係’オブジェクトが必要であると判断したとしましょう。そのオブジェクトは、プレイフィールドをモデリングするデータレコードを必要とします。各マスに、“誰がそこに打ったか”コード(-1,0,1のどれか)で、印をつけることができなくてはなりません。さらに、そのオブジェクトは、高水準のゲーム遂行ないし決定コードに必要な情報を提供できる必要があります。そのような情報の例としては、‘ボード上のあるパス(行、列、対角線)にまだ誰も打っていないスペースがあるかどうか”や“ボード上のあるパスの数値的状態(-3から3まで)は何か”があります。 下は実際のゲームの実装に使われたクラス定義を略記したものです。(スタック記録の記号‘--’は入力と出力を仕分ける記号です。ですから、スタック記録‘( -- )’は、そのワードが、スタック上にはじめには何の値も期待せず、おわりには何の値も押込まない、というか生産しないということを表わしています。) 三目並べコードサンプル (コードの)2行目が非常に重要です。そこではサイズが9のデータオブジェクトとしてwArrayクラスのデータ構造が宣言されています。このクラスは改めて定義する必要はありません。というのは、この定義は、数多くある他の既定クラスと同様、既に存在しているので、オブジェクトを宣言するだけでいいからです。(後で見るように、そのクラスに特有のメソッドも一緒に‘タダで’付いてきます。)したがって、我々のインスタンス変数、つまりivarは、9-セルのインデクス付きwordアレイです。 最初のメソッドの定義は、‘clearX board_Arr’によってそれ自身を定義しており、これは実際には内部的なデータオブジェクトであるboard_Arrへのメッセージであり、それに対するメソッドclearX は既に定義されています。(‘clearX’の‘X’はTic tac toeのXプレイヤーとは何の関係もありません。;それは作り付けのMopsメソッドの名前の一部でしかありません。) メソッド名はコロン( )で終わらなければならないことに注意して下さい。これは、ほとんど唯一といっていいくらい数少ないMopsの成語規則のひとつです。 次のメソッドFINDZCELL の定義は、‘コード’とboard_Arrへの内部的メッセージとの結合を示しています。そのクラスのオブジェクトは、メソッド‘at ’をどうやって実行するかを知っています。これは、DOループによって提供されたインデックス値を入力としてうけ取ります。 メソッドPUTOMK は、コンピュータが動いたときに利用されますが、スタックから何も受け取らない一方で、O-markコードの値と(大域)セルロケーションであるcelLocをスタック上に押込み、メソッドto と結び付けているという点が、少し面白いでしょう。全てのwArrayクラスオブジェクトが知っているメソッドto には、これら二つの値が必要なのです。;つまり、格納されるべきものとそれが格納される場所です。PUTXMK はプレイヤーがマスをクリックしたときに呼び出されます。(プレイフィールドを受け持つ別のオブジェクトが対応するXおよびOをスクリーン上に書き込みます。) ワード‘;CLASS’は定義を終了させます(‘;’がワード定義を終了させ、‘;m’がメソッド定義を終了させるのと同じです)。したがって、この例の最後の行は、定義の一部では全くなく、BoardRecordという名前のscorekeeperクラスのオブジェクトインスタンスの宣言のサンプルです。そのように、つまり宣言によって生成されたオブジェクトは静的オブジェクトであり、これを含むプログラムのMops辞書の中にコンパイルされます。(Mopsプログラム内のオブジェクトの大部分、しばしばその全てが、静的オブジェクトです。動的オブジェクトは、もう少し手間がかかります。) Mopsの既定クラス Mopsはたくさんの既定クラスを提供しています。これらは、単純なbyte/wordデータオブジェクトからMacintoshウィンドウ、メニューバー、ないしダイアローグに至る範囲のオブジェクトを定義しています。プログラマーとしてはもちろん後半の方の類のオブジェクトに主要な関心があるでしょう。というのは、大部分のプログラムは、ひとつないし複数のウィンドウ、メニュー、ダイアローグを必要とするからです。;そしてそれらを一からプログラムするのは、いわば、‘おぞましい’ことだからです。例えば、直接にMacツールボックスを用いてウィンドウをつくるのは、実際、悩ましい、間違いを犯し易い仕事です。さらに悪いことには、それにはかなりのMac内部に関する知識も必要で、これは、もし避けられるのであれば、大部分の人にはどうでも良いことです。 グラフィカルユーザーインターフェイス(GUI)オブジェクトに関するMopsの既定クラスは、OOPの継承メカニズムを用いて、そこで必要とされる汚らしい低レベルコードを隠しています。例えば、一般に用いられるWINDOW+クラスは、それが必要とする複雑なデータ構造やメソッドの一部の定義を、多くの他のもっと単純なクラスに帰着させているということができます。つまりWINDOW+クラスのインスタンスは、高度に合成的なオブジェクトとなっています。プログラマーはしかし、全く単純なWINDOW+の下位クラス(これはWINDOW+クラスの全てのデータとメソッドを継承します)を書くことで、上位クラスのいくつかの機能を上書きし、あるいは変形することもできます。 しかしながら、例えばWINDOW+クラスに属するオブジェクトを単純に宣言して、例えばそれがツールボックスにおいて‘生きている’ようにするメッセージなど、いくつかのメッセージを送るだけでよいこともしばしばです。既定オブジェクトのためのクラスの定義はソースプログラム中に書き込む必要はありません。というのは、問題の定義は普通はソースプログラムが読み込まれる前に、見えない形で予めロードされているからです。(そのいくつかは辞書のコアグループに属し、いつでもそこに存在しています。)しかし、プログラマーは、自分が用いるオブジェクトに提供されている機能を理解し適正なメッセージを送ることができるためには、そのオブジェクトが該当する既定クラスの定義を熟知していなければなりません。 ドラッグ、拡大、アップデートといった標準的なMacintoshウィンドウの動きは、Mopsのウィンドウクラスが自動的に処理するので、プログラマーは、システムレベルのコードをひっきりなしに書き直すことから解放され、アプリケーションレベルの問題に集中することができます。Mopsのツールボックスクラスの全てについて、ある程度までは同じことがいえます。 MopsはViewオブジェクトもサポートしており、WINDOW+クラスとあわせて広く用いられます。ビューは基本的には、描画を行うことができるウィンドウ内の長方形領域を定義します。ビューは‘子供’ビュー(サブビュー)を持つことができる他、様々な面白い性質を持っています。ビュー構成は、MacApp, TCL, PowerPlantあるいはCocoaといった大部分のMacintosh APIやフレームワークでもサポートされています。 では、一般にオブジェクトはどのようにして生成されるのでしょうか?既に見たように、全てのオブジェクトは、ソースプログラムにおいてクラス定義で定義された、オブジェクトのクラスの1インスタンスです。あるオブジェクトが静的に設置されるのが適当な場合には、上で見た(BOARDRECORD)ような単純なオブジェクト宣言でそれを作り出すことができます。この宣言は、そのクラスのオブジェクトのインスタンス化といわれています。静的オブジェクトの利点は、(動的オブジェクトに比べれば)全てが単純でトラブルが無いことです。また、メッセージ対オブジェクト結合がいつも静的(早期)結合(速い)であることもあげられます。潜在的な欠点は、辞書内にコンパイルされ(‘固着され’)るので、もう邪魔ものになってしまった後でも、プログラム空間を占拠し続けるということです -- これは大きなプログラムでは問題となり得ます --。 その代替物が動的オブジェクトです。これは実行時(runtime)にプログラムのヒープ上に生成されます。その際の構図は少し込み入っています。PowerMopsの最近のバージョン(V.4.x以上)では、動的オブジェクトを生成し管理するための非常に単純なメカニズムである‘Reference’が提供されていて、大部分の交渉を障害なく操作できるようになっています。他方Mops(68k)では、将来のオブジェクトのためにツールボックスからオブジェクトハンドルを得(objHandle宣言)て、オブジェクト生成ステートメント(handleオブジェクトへのnewobj メッセージ)を送らなければなりません。そのようにして生成されたオブジェクトは、そのハンドル名またはインデックスによって参照されます。後者の‘伝統的’方法による場合には、動的オブジェクトに通常割り当てられるヒープのリロケータブルブロック管理に多大な注意を払わなければなりません。 Mops既定クラスの例 下は、基本的なデータクラス定義の例で、クラス名がVarの32ビット整数変数のためのものです。しかし、コードからわかるように、これは、この継承の系譜のなかで最も原始的なものというわけではありません。基本的なデータ定義は皆そうですが、そのメソッドは、通常の高水準のMopsワードで定義されてはおらず、効率化のために低水準のワードで設計されています。この理由は、基本的なデータオブジェクトのためのメソッドは、プログラム内で断トツで頻繁に実行されるメソッドだからです。 class VAR super{ longword } m + inline{ obj +!} ^base +! ;m m - inline{ obj -!} ^base -! ;m ;class このオブジェクトのivarのためのデータオブジェクト宣言が無いことに注意して下さい。これは上位クラスのLongwordが供給してくれるので必要ないのです。メソッド+ と- はそれぞれ増加と減少に当たりますが、これだけでは変数上のオペレーションとしては不十分なように思われます。ここでもまた、上位クラスであるLongwordがローンレンジャーのごとく救助に現れます。Longwordは、とりわけGet , Put ,およびClear のメソッドを既に持っているのです。したがって、VARは暗黙の裡にこれらのメソッドを持っているのです(継承)。Longwordは他にも多くの基本的データクラスにとってジェネリックな上位クラスとなっていて、それらの下位クラスに共通のメソッドの全てを定義しています。VARのクラス定義は、ジェネリックな上位クラスからの継承に依存しているという点で、多くのMopsの基礎的クラスにみられる特徴をみせています。 このほとんど対極にあるのがMenuクラスの定義です。25個くらいあるうちの適当ないくつかを、下に挙げておきましょう。これには普遍的に用いられるワードも含まれています。(この例はPowerMops V.4.xから引かれたものです。もっと後のバージョンのPowerMopsではコードは変わっているかも知れませんが、実例による理解という目的のためには適当な例といえるでしょう。) メニュークラス定義コード 上位クラスx-Array(execution tokenのアレイ)は、このクラス定義がそのデータ構造に関してx-Arrayを継承していることを示していますが、クラス定義においてはこのアレイのサイズを固定する必要はありません。サイズの特定は、このメニュークラスのオブジェクトのインスタンス化のためにオブジェクト宣言をするまで延期することができますし、普通はそうします。(これは直観的にはアレイ型クラスの特徴ではありません。)サイズの特定によって与えられたメニューオブジェクトのアイテムの数が決まるのですから、プログラムがこの値を自分できめる必要があることは明らかです。 普通は、どんなプログラムもInit メソッドにあたるメッセージを送るでしょう。これは、メニューオブジェクトの全アイテムに動作を割り当てます。--- 例えば、ファイルメニューの新規アイテムをユーザーが選択した場合のプログラムの反応などです。また、プログラムは大抵、非-リソース-ベースのメニューのためのNew か、リソース-ベースのメニューのためのGetnew のどちらかを呼ぶでしょう。どちらのメソッドもメニューレコードをツールボックスに渡します。どちらのメソッドも完全にサポートされています。 リソースベースのメニューについては、プログラマーは、アップルのフリーウェアであるResEditのようなリソースエディタを用いて、‘menu’リソースとして、文字通り各メニューの絵を描きます。これは全く易しく、私には他の方法は考えられません。リソースベースのアプローチは、プログラムがずっと単純になり、全く一般的に用いられています。平均的なMopsプログラムには、ともかく他にもいくつかリソースが必要となるでしょうから、メニューリソースをそれに追加するのもそれほど大変ではありません。 GetItem とPutItem メソッドによって、いわば実行時にメニューアイテム名をいじりまわすことができます(これはユーザーを全く混乱させてしまうかも知れませんが)。 プログラムの多くはCheck およびUncheck メソッドを用いるでしょう。;前者はクリックされたアイテムの名前の脇にちいさなチェックマークを付け、後者はそれを消します。ワード‘1+’はトップスタック上にある数値に1を加えるための簡便法です。 大文字と小文字で書かれた分かりやすい名前、たとえばGetMenu, InsertMenu, SetMenuItemText, CheckItemなどは全てシステムコール、ないしSyscallです。これらはMacツールボックスサービスを起動します。知っておくべき重要な点は、Mops自体に属する名前と違って、Syscall名は大文字/小文字を識別する(case sensitive)ということです。(徹底してそうです。ツールボックスはMopsでは極めて特異な存在です。) 下位クラスと上位クラス 全てのクラス定義はオブジェクトのひとつのクラスを定義しますが、そのような定義はみな、同時に別のクラス定義の下位クラスでもあります。上位クラスもまたプロト・クラスオブジェクトでない限り、それ自体ひとつの下位クラスです。つまり、全てのユーザー定義クラスと既定クラスは、Objectクラスを除けば、直近の上位クラスを持っているということです。(ひとまずは、多重継承の可能性は措いておきましょう。これをすれば、クラスは複数の直近上位クラスを持つことができます。) したがって、ユーザー定義クラスは、その上位クラスの連鎖からivarとメソッドをともに継承します(継承とオーバーライド(上書き)については後述)。このことは、(ツールボックス等を通じて)オペレーティングシステムと交渉し、典型的には系譜中にMopsの既定ツールボックスクラスを含んでいるようなユーザー定義クラスには、とくにあてはまります。そのようなクラスは普通は下位クラスと呼ばれたりしますが、これは厳密には観点の問題です。 継承とオーバーライディング クラス定義はその上位クラス(とその上位クラスとその…上限まで続く)のインスタンス変数とメソッドの両方を継承します。クラス定義は、その上位クラスの名前をオーバーライドしなければなりません。クラス定義はその上位クラスのインスタンス変数をオーバーライドすることはできません。;それは無条件に継承されます。クラス定義は、その上位クラスのメソッドに加えて新しいメソッドを付け足したり、上位クラスのメソッドと同じ名前のメソッドを定義することによって、上位クラスのメソッドのいくつかをオーバーライドすることができます。(Objectクラスだけはひとつもivarを持たないので、そこからは何のivarも継承されないということに注意しましょう)。 実践的留意点としては、下位クラスで定義されることなく継承されるメソッドの数が増えればそれだけ、結果としてできるプログラムは(他が皆同じとすれば)小さくなります。 多重継承 他のオブジェクト指向言語のいくつかとも共通ですが、Mopsは多重継承を提供しています。これによれば、クラスは複数の直近上位クラスを持つことができ、その結果、人が父と母を持ち、その両方から性格を受け継ぐのと同じように、二つあるいはそれ以上の異なる系譜線をもつことができます。多重継承が可能であることによって、二つかそれ以上の既存のクラスに由来する諸機能を新しいクラスにおいて混ぜ合わせることができるようになります。(初めは単一継承クラスで経験を積みましょう。)これは必要な場面では非常に強力な機能で、しばしば、完全なオブジェクト指向実装の試金石とみなされています。Mopsの既定クラスのいくつかは、主としてハイブリッドなデータ構造を得るために、多重継承を採用しています。 メッセージ束縛 Mopsは、早期ないし晩期のメッセージ対オブジェクト結合を達成するための、様々な方法を提供しています。静的(早期)結合(early bind)v.s.動的(晩期)束縛(late bind)は、本質的には実行スピードとプログラミング上の柔軟性とのトレードオフです。晩期結合では、メッセージの受け手は実行時までわかりません(というか、実行時に決まります)。これは、複雑でいくぶんか秘教めいた主題ですから、Mopsは可能な結合モードを広範にサポートしている、といっておけば十分でしょう。有名なSmalltalkシステムは、全ての場合について晩期結合しか提供していません。 結論 一人の人間の努力によるものであるため、Mopsは、最も安定したプログラミングシステム、というわけにはいきません。;他方で、Mopsの"技術サポートスタッフ"は、実際、非常に聡明です。開発者であるMike Horeは、実際の問題のレーポートを快く受け入れることで知られ、通常は、非常に迅速に修正か回避方法を返答してくれます。更に加えて、数多くの経験豊かなMopsユーザーが、システムのあれこれの分かりにくい点について、よろこんで説明ないし助言してくれます。大部のMopsマニュアルは編成替えの余地はあるものの、注意深く読めば十分な情報が含まれており、また大部分が明瞭に記述されています。 私が最初にMopsに出会った頃には、Forthから受け継がれたものである‘逆向き’記法は、控えめにいっても苛つかせるものでしたが、そんなことも全くすぐに克服されてしまいました。スタックプログラミングの側面には、それに十分に習熟してしまった後では、そのあまりの経済性、効率性等々にショックを受けました。しかし、私はなおもオブジェクト指向プログラミングのファンであり、これが、Mopsが私を惹き付ける理由となっています。私は、MopsのクリーンなOOP実装方法が気に入りました。その多くが直観的なのです。 Mopsシステムは四つの部に分かれた370ページを超えるマニュアルを含んでいます。第一部のチュートリアルを除けば、MopsのForth言語的側面を完全にカバーすることは意図されていません。私は、このギャップを埋めるための、よいForthレファレンスが必要であることに気付きました。これについては、FORTH inc.から出ている Forth Programmer s Handbook が、優れた価値のあるものとして推薦できると思います。ともあれ、OOP(あるいはそれを用いるForth)が好きか、あるいは、できれば試してみたいという人には、Mopsは良い‘買い物’であると、私は思います。 著作 © 2002 Edward Williams 邦訳 Nao Sacrada トップページ