Factorは、 Slava Pestovによって開発されたスタック指向プログラミング言語です。動的型付け、自動メモリ管理、強力なメタプログラミング機能を備えています。この言語は、自己ホスト型の最適化コンパイラと対話型統合開発環境を備えた単一の実装を有しています。Factorディストリビューションには、大規模な標準ライブラリが含まれています。FactorはBSDライセンスに基づくフリーかつオープンソースのソフトウェアです。
スラバ・ペストフは2003年にビデオゲームのスクリプト言語としてFactorを作成した。[ 1 ]初期の実装は、現在JFactorと呼ばれ、Javaで実装され、Java仮想マシン上で動作した。初期の言語は構文の点では現代のFactorと表面上は似ていたが、現代の言語は実用的には大きく異なり、現在の実装ははるかに高速である。
言語は時間の経過とともに大きく変化しました。当初、Factor プログラムは、Java のリフレクション機能を使用して Java オブジェクトを操作することに重点を置いていました。当初から、設計思想は、Factor で記述されたプログラムに合わせて言語を修正することでした。Factor の実装と標準ライブラリがより詳細になるにつれて、特定の言語機能の必要性が明らかになり、それらが追加されました。JFactor には、プログラマが独自のクラスを定義できるオブジェクト システムがなく、ネイティブ Factor の初期バージョンも同様でした。この点で、Factor はSchemeに似ていました。今日では、オブジェクト システム は Factor の中核をなす部分です。タプルクラス、コンビネータ インライン化、マクロ、ユーザー定義の構文解析語、最新の語彙システムなどのその他の重要な言語機能は、その有用性が明らかになるにつれて、段階的に追加されました。
Factorのごく初期のバージョンから外部関数インターフェースは存在しており、JFactorにも同様のシステムがありました。これは、Factorが通信する必要のある外部ライブラリごとに実装のC言語部分にプラグインを作成するよりも優れた方法であり、宣言性が高く、コンパイルが速く、記述が容易であるという利点があります。
Java 実装は当初はインタプリタのみで構成されていましたが、後にJVM バイトコードへのコンパイラが追加されました。このコンパイラは特定のプロシージャのみで動作しました。Factor の Java 版は、C 言語と Factor で書かれたバージョンに置き換えられました。当初はインタプリタのみで構成されていましたが、インタプリタは異なる状況で使用される 2 つのコンパイラに置き換えられました。時間の経過とともに、Factor 実装は大幅に高速化しました。[ 2 ]
Factor は、動的型付け、関数型、オブジェクト指向のプログラミング言語です。コードは、ワードと呼ばれる小さな手続きを中心に構成されています。典型的なコードでは、これらは 1 ~ 3 行の長さで、7 行を超える手続きは非常にまれです。他のプログラミング言語では慣用的に 1 つの手続きで表現されるものが、Factor では複数のワードとして記述されます。[ 3 ]
各ワードは固定数の引数を取り、固定数の戻り値を持ちます。ワードへの引数は、逆ポーランド記法を使用してデータスタック上で渡されます。スタックは、ワードへの呼び出しを整理するためだけに使用され、データ構造としては使用されません。Factor のスタックはForthのスタックと同様の方法で使用されます。そのため、両方ともスタック言語とみなされます。たとえば、以下は現在の出力ストリームに「 Hello, world 」を出力するコードスニペットです。
「こんにちは、世界」プリント
printioは、スタックから文字列を受け取り、何も返さない語彙内の単語です。文字列を現在の出力ストリーム(デフォルトでは、端末またはグラフィカルリスナー)に出力します。 [ 3 ]
階乗関数Factorでは、次のように実装できます。
:階乗( n -- n! )重複1 > [ [1..b]積] [ 1を削除] if ;すべてのデータをスタックだけで受け渡す必要はありません。レキシカルスコープのローカル変数を使用すると、プロシージャ内で使用される一時変数を格納およびアクセスできます。動的スコープの変数は、スタックを使用せずにプロシージャ呼び出し間でデータを渡すために使用されます。たとえば、現在の入力ストリームと出力ストリームは、動的スコープの変数に格納されます。[ 3 ]
Factor は柔軟性と言語拡張性を重視しています。[ 3 ]マクロシステムに加え、Factor 構文の任意の拡張も可能です。Factor の構文は、新しいタイプの単語定義やデータ構造用の新しいタイプのリテラルを可能にするために拡張されることがよくあります。また、 XMLライブラリでは、XML を生成するためのリテラル構文を提供するために使用されています。たとえば、以下の単語は文字列を受け取り、その文字列を強調した HTML ドキュメントである XML ドキュメント オブジェクトを生成します。
: make-html ( string -- xml ) dup <XML <html> <head><title><-></title></head> <body><h1><-></h1></body> </html> XML> ;この単語dupはスタックの最上位項目を複製します。<->これは、XMLドキュメントの該当箇所をスタック内の項目で埋めることを意味します。
Factorには、この言語で完全に記述された大規模な標準ライブラリが含まれています。これらには以下が含まれます。
Factorには外部関数インターフェースが組み込まれており、C、Objective-C、Fortranプログラムとの通信が可能です。また、 GLSLで記述されたシェーダーの実行と通信もサポートされています。[ 3 ] [ 9 ]
FactorはFactor言語とC++で実装されています。元々はJavaの実装をベースに開発されました。現在では、パーサーと最適化コンパイラはC++で記述されています。ガベージコレクタや特定のプリミティブなど、言語の基本的な部分はC++で実装されています。
Factor は、コンパイルされたコードとデータがイメージに格納される多くのSmalltalk実装と同様に、システムイメージベースのモデルを使用します。 [ 10 ]プログラムをコンパイルするには、プログラムをイメージにロードしてイメージを保存します。特別なツールは、特定のプログラムを実行するための最小限のイメージを作成するプロセスを支援し、結果をスタンドアロン アプリケーションとして展開できるものにパッケージ化します。[ 3 ] [ 11 ]
Factorコンパイラは多くの高度な最適化を実装しており、新しい最適化技術の研究対象として使用されてきました。[ 3 ] [ 12 ]