Forthで脳をマッシュしますか?

画像



オブジェクト指向プログラミングに夢中になっているあなたの脳を、新しくて珍しいもので引き伸ばしたいという欲求が時々あります。 もちろん、このような状況では、Haskell、Erlang、Lisp、OCamlなどの関数型プログラミング言語が助けになります。 しかし、今でも彼らを驚かせることはほとんど不可能です。 いいえ、まったく違うものが欲しいです。 この状況では、積み重ねられたプログラミング言語であるForthが私たちの助けに駆けつけます。







Ubuntuオペレーティングシステムの一部としてForthでのプログラミングを検討します。 他のオペレーティングシステム用のコンパイラのリストは、 ここにあります 。 また、 オンラインの Forth インタープリターを使用することもできますが、うまく機能しませんが、耐えられます。 次のようにインストールできるgforthを使用します。



sudo apt-get install gforth
      
      





すべてをインストールするとすぐに、次のコマンドを実行してFortモードで対話モードで起動できます。



 gforth
      
      





しかし、「Hello world」を書く前に、この言語の構文と通常の構文の違いについて少しお話ししたいと思います。 確かに、多くの人は中置記法に慣れています(演算記号がオペランドの間にあるとき)、一部の人は前置記法に怖がりません(演算子がオペランドの前にあるとき)が、フォートは彼自身のやり方で行きました-彼は逆ポーランド記法、つまり後置記法を使います。 たとえば、2つの数値を追加するには、次のように記述します。



 1 2 +
      
      





この操作の結果、3が得られます。しかし、これは砦のすべての機能とはほど遠いものです。 最初は、この言語の中心は辞書の一種です。これは、データ操作のサブセットを実行できる一連の単語です。 さらに、言語自体の主要な単位はWORDです。 既存の単語を使用して(DUP-スタックの最上部にある要素を複製し、SWAP-スタックの2つの上位要素を交換するなど)、独自の単語を定義できます。 一般的に、これはまさに既存の単語から、さらに多くの新しい単語までの単語の定義です。これがフォートの主要なプログラミングメカニズムです。



異常なことに、すべて聞こえますよね? 一見、これは非常に複雑に見えますが、実際には、Fortはコンパイラーの実装の観点からも、言語の構文要素の観点からも最も単純なプログラミング言語の1つです。



さて、紹介は表明されているようで、この言語でHello worldを見ることができます:



 ." Hello world"
      
      





このコマンドをインタラクティブモードで実行すると、応答として次のようになります。



 Hello world
      
      





しかし実際には、何も表示されません! 原則として、他のプログラミング言語の他のHello worldと同様です。 Forthプログラムを書くためのいくつかの基本原則を見てみましょう。



Forthはスタック言語です。つまり、転送されたすべての値はスタックにプッシュされ、それらに対して何らかの操作を実行すると、スタックからポップされます。 たとえば、Forthインタラクティブシェルで次の操作を実行して、スタックに4つの要素を配置します。



 1 2 3 4
      
      





次に、演算子を使用して、スタック( "。")から最上位の要素を抽出します。 スタックからすべてのアイテムを引き出します。



  . . . .
      
      





次の結論が得られます。



 4 3 2 1 ok
      
      





つまり、FILOの原理が動作していることがわかりました。スタックに配置された最初の要素は、スタックから最後に削除された要素です。 次の算術演算を実行してみましょう:(2 + 4)* 5 /10。その結果、3が得られるはずです。Fortでは、この操作を次のように記述できます。



 2 4 + 5 * 10 / .
      
      







スタックの一番上の要素を表示するには、式の最後にドットが必要です。 ポイントが完了すると、この要素が必要な結果になります。



しかし、そのような計算だけで、あなたは遠くまで行かないでしょう。 数値を二乗する単語の例を使用して、独自の単語を定義する方法を見てみましょう。 これを行うには、DUPスタックの最上部の要素の重複を思い出す必要があります。



 : POW DUP * . ;
      
      





以上で、次のように使用できる独自の単語を定義しました。



 4 POW
      
      





その結果、16が得られます。ここで書いたことをさらに詳しく見てみましょう。 まず、コロンの後、単語に名前を付ける必要があります。次に、スペースの後、単語の本文を説明し始めます。 最初に、スタックの一番上の要素を複製し、次に一番上の2つの要素を乗算する必要があると言います。 ですから、実際には、べき乗という言葉があります。フォートのすべてをスペースで区切る必要があることを覚えておく必要があります。たとえば、このようなレコードは機能しません。



 :POW DUP * . ;
      
      





実際、単語を定義するメカニズムは非常に柔軟であり、それを使用すると、さらに複雑な単語を取得するために使用できる非常に複雑な単語を作成できます。



Fortには分岐演算子(if)とループ(do ... loop)もありますが、これらは単語の定義でのみ使用できます。 また、ifを使用する機能が1つあります。 分岐を使用して何かを書きましょう:



  : testif dup 1 = if ." One" else dup 2 = if ." Two" else dup 3 = if ." Three" then then then drop ;
      
      





ところで、Fortは大文字と小文字を区別しないため、dupとDUPはまったく同じです。



コードからわかるように、要素を比較する前に毎回、そのコピーを作成します。 これは、比較中に要素がスタックからポップされるという事実のために必要です。つまり、再び使用することはできません。 これは、3つのコマンドを順番に実行することで確認できます。



 1 2
      
      





 <
      
      





 .S
      
      





ここでは、最初に2つの数値をスタックに配置してから、スタックの2つの上位要素を比較する操作を実行します。 彼女はそれらを取り出して比較し、結果をスタックに置きます。 3番目のコマンドは、スタックの内容全体を表示します。これは、単一の単数形になります:-1。 Forthのマイナス1はブール値の「真」であり、ゼロは「偽」です。



したがって、次のブランチで比較に使用できるように、最上位要素を複製します。 基本的に、次のように記述した場合:



 : testif dup 1 = if ." One" else dup 2 = if ." Two" else 3 = if ." Three" then then then ;
      
      





同じ結果が得られますが、コードの可読性が低下するため、このオプションは受け入れられません。 コードを2ワード(dupとdrop(スタックの一番上の要素を削除))減らしましたが、読みやすさは低下しました。



次に、ループを見てみましょう。



  : doloop 10 0 do cr ." Some text" loop ;
      
      





ここでは、テキストを10回印刷します。 まず、単語を定義し、次に逆の順序で(同じスタック言語を持っている)スタックの境界を示し(10 0を行います)、次にいくつかのアクションを実行し(この場合、テキストを毎回新しいシンクで印刷します)、それがループであることを示します(ループ)。



一般に、多少複雑なものを書くために、Fort言語の構文要素のセットを所有しています。



与えられた数の階乗を計算する単語を定義しましょう:



 : FACTORIAL recursive dup 1 > if dup 1 - FACTORIAL * else drop 1 endif ; : OURLOOP swap 1 + swap do i . i ." ! = " i FACTORIAL . cr loop ;
      
      





さて、実際に私たちの言葉を実践してみてください



 17 0 OURLOOP
      
      





この言語が興味を持っている場合は、安全にさらに深く掘り下げて、その言語に捧げられている文献とリソースを調べてください。 たとえば、この記事を準備するために、Leo Brodieの本「Starting FORTH」を使用しました。この記事は、 Webリソースとして入手できます。



この言語は、たとえば、脳を上手くノックし、プログラミングの考え方の境界をHaskellほど悪くはしない。 そして最後に、Forthに関するジョーク:



「マスターオブスピーチミステリーのジェダイヨーダが明らかになりました-フォートでは、それはただの古いプログラマです」



All Articles