再帰をサポートしていない命令型プログラミング言語は何ですか?


21

私の知る限り、現代のすべての命令型プログラミング言語は、プロシージャがそれ自体を呼び出すことができるという意味で再帰をサポートしています。これは必ずしもそうではありませんでしたが、簡単なGoogle検索で難しい事実を見つけることはできません。だから私の質問は:

最初から再帰をサポートしていなかったのはどの言語で、そのサポートはいつ追加されましたか?

回答:


21

COBOLがそうするかどうかは確かではありません(確かに一度もそうではありませんでしたが)。

FortranにはFortran 90以降がありますが、recursiveキーワードを使用して、サブルーチンが再帰的であることを伝える必要があります。

PL / Iはほぼ同じでした。再帰はサポートされていましたが、どのプロシージャが再帰的であるかを明示的に指定する必要がありました。

しかし、それ以上のものがあるとは思いません。簡単に言うと、IBM(360/370/3090 / ...)メインフレームはハードウェアのスタックをサポートしていないという単純な理由から、再帰を禁止することは、IBMが言語設計で行うことでした。ほとんどの言語がIBMから来たとき、彼らはほとんど再帰を禁止しました。それらはすべて他の場所から来ているので、再帰は常に許可されます(ただし、他のいくつかのマシン、特に元のCray 1もスタックのハードウェアサポートを持っていなかったことを追加する必要があります)。


当時のコントロールデータコンピューターも再帰をサポートしていませんでした(サブルーチン呼び出しは、呼び出し命令+ 1へのジャンプを挿入するようにコードを変更した命令で行われました)。Wirthが6600でPascalを開発したとき、おそらくサブルーチンを呼び出す新しい方法を考え出さなければならなかったでしょう。
デヴィッド

@David:はい-そして偶然ではありませんが、それらはSeymour Crayによって設計されました。Pascal 6000コンパイラーを見たことがありますが、スタックフレームを生成(シミュレーション?)するために何をしたかを思い出したことはありません。
ジェリーコフィン

notably the original cray 1それでは、恐竜のクローンを作成するのに再帰は必要ありませんか?サルが木々の間を揺れるのは本当に私たち次第だと思います。
-normanthesquid

2
CAML(およびOCAML、F#)でさえ、明示的にマークされた再帰関数が必要です。
jk。

1
@Panzercrisis:IBMがx86に関与していたかどうかはわかりませんが、現在のメインフレームは1964年に市場に登場したIBM 360に直接遡るので、基本設計はx86よりも数十年前に遡ります。
ジェリーCo 14

16

ウィキペディアによると:

Fortranのような初期の言語は、変数と戻りアドレスの場所が静的に割り当てられていたため、最初は再帰をサポートしていませんでした。

http://en.wikipedia.org/wiki/Subroutine#Local_variables.2C_recursion_and_re-entrancy

FORTRAN 77では再帰が許可されていませんが、Fortran 90では許可されています(再帰ルーチンは明示的に宣言する必要があります)。

ほとんどのFORTRAN 77コンパイラは再帰を許可し、一部(DECなど)はコンパイラオプションを使用する必要があります(コンパイラオプションの章を参照)。Fortran 77標準に厳密に準拠しているGNU g77は、再帰をまったく許可していません。

http://www.ibiblio.org/pub/languages/fortran/ch1-12.html


iirc少なくとも1つのFORTRAN 77コンパイラがあり、それは技術的に再帰をサポートしていましたが、スタックフレームの総数は非常に小さいため、多くの問題で効果的に使用できませんでした
jk。

6

OpenCLプログラミング言語は再帰をサポートしていません。(OpenCL仕様のセクション6.8を参照)

そのための現在の動機は、a)ディープスタック用のスペースの不足b)大きなレジスタセットと広範なインラインの存在下でパフォーマンスを最適化するために必要な合計割り当てを静的に知ることです。

これは、シェーダー言語などの他のGPUプログラミング言語にも当てはまる場合があります。


2

小さなマイクロコントローラー用の一部のcコンパイラーは、おそらくスタックサイズが極端に制限されているため、再帰をサポートしていません。


これらのマイクロコントローラーの一部(PIC16ファミリーなど)は、ハードウェアコールスタックのみを持ち(命令でアクセスできない)、他の形式のスタックを持たないため、再帰を使用する場合、関数はローカル変数を持つことができません(データスタックが明らかに必要であるため)そのために...)参照:en.wikipedia.org/wiki/PIC_microcontroller#Stacks
エール

1

BASICは、行番号の時代には、再帰サポートが不十分である傾向がありました。当時の多くの(すべて?)BASICはネストされたgosub呼び出しをサポートしていましたが、自己呼び出しに役立つ方法でパラメーターまたは戻り値を渡す簡単な方法をサポートしていませんでした。

初期のコンピューターの多くは、呼び出し命令を使用して、呼び出されたルーチン(PDP8、IASファミリーのマシン、おそらく私がよく知らないアーキテクチャー)の先頭にリターンアドレスを書き込む呼び出し命令を使用していました。 「ルーチンを呼び出した命令の後の命令にジャンプする」ためのマシンコードでした。


1

サポート」の意味によって異なります。再帰をサポートするには、再入のたびにローカル変数を再インスタンス化するスタックが必要です。

言語にローカル変数の概念がなくても、「サブルーチン」の概念があり、同一変数(別名配列)間のインデックス作成を管理する方法がある場合、入力/終了ごとにグローバルインデックスをインクリメント/デクリメントできます。関数の1つ以上の配列のメンバーへのアクセス。

これが「サポート」と呼ばれるかどうかはわかりません。事実は、COBOLのようにFortran77で行ったように、ZX-Spectrum BASICで再帰関数を作成したということです...常にそのトリックで。


1

アセンブリ言語は再帰を直接サポートしていません-通常はマシンスタックにパラメーターをプッシュすることで、「自分で実行する」必要があります。


2
メソッド呼び出しをサポートする限り、再帰をサポートします。通常CALL、サブルーチンにジャンプする前にIPを自動的にスタックにプッシュするRET命令と、リターンアドレスをIPにポップする命令があります。CALL独自のエントリポイントを取得できない理由はありません。
Blorgbeard

@Blorgbeard-絶対に当てはまりますが、再帰呼び出しに必要なパラメーターを処理しないため、これは一般に理解されている意味で「再帰をサポート」としてカウントするには不十分であると主張します。
ミケラ

1
まあ、再帰呼び出しは技術的にパラメーターを必要としませんよね?void f() { f(); }再帰的です。
Blorgbeard

技術的にはありません。しかし、1つの些細なケースをコーディングできるからといって、アセンブリを「サポートする再帰」として記述する必要があるというわけではありません。再帰の最も実用的な使用にはパラメーターが必要です。
ミケラ

それが言えると思います。ただし、その場合、アセンブリはループもサポートしません(手動でCMPとJNZを作成する必要があります)。それはあなたが「サポート」と呼ぶものの問題だと思います。
Blorgbeard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.