エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

プログラミング言語 Factor のプログラミングで仕事の疲れを癒す

この数ヶ月は、仕事でも私的なことでも負担の大きな時期で、気分の低空飛行もまた致し方なしという感想。

ようやく気持ちも多少は上向いてきたので、そろそ好きなことをして諸々の疲れを癒す時期かと。

そんなわけで、この数日 Factor をいじっています。

Factor programming language

factorcode.org

ja.wikipedia.org

なぜ Factor かと問われれば、ただの偶然でしかないのですが。 しかし、異なるパラダイムの言語のコードを書くのは、頭の使い慣れていない部分を使うことにが多く、プログラミングを再び新鮮な経験に変えてくれます。

インストール (macOS)

Mac のばあいは Homebrew を使うのが簡単です。

$ brew install factor

インストールするとアプリケーションに Factor が追加されます。

起動するとウィンドウが開きプロンプトが表示されます。 ここで Factor のコードを試すことができます。

アプリケーションをインストールすると、コマンドラインツールも同時にインストールされます。

Factor がインストールされたディレクト/Applications/factor/ の中に factor という名前で格納されています。

$ /Applications/factor/factor
Factor 0.100 x86.64 (2281, heads/master-80a4633f05, Sep 11 2024 14:22:41)
[Clang (GCC Homebrew Clang 18.1.8)] on macos
IN: scratchpad

パスが通っていないと思いますし、因数分解を実行する factor がインストールされていることもあると思いますので、フルパスで指定して実行してください。

Hello world

正確な話を省略すると。 Factor はスタックを使った逆ポーランド記法構文なので、値に対して操作が後ろに置かれます。

"Hello world" print
# コード 動作
1 "Hello world" 文字列をスタックに push する
2 print スタックから値を pop しコンソールに出力する
1 2 + 3 * .
# コード 動作
1 1 値をスタックに push する
2 2 値をスタックに push する
3 + 値を 2 つスタックから pop する、2 つの値を加算する、結果の値をスタックに push する
4 3 値をスタックに push する
5 * 値を 2 つスタックから pop する、2 つの値を乗算する、結果の値をスタックに push する
6 . 値をスタックから pop する、整形してコンソールに出力する(いわゆる pretty print)

条件分岐

制御構造も同じように組み立てます。

と、その前に。 quotation にも触れておきます。

式そのものを値として扱うために quotation というしくみがあります。 Lispquote と同様のしくみです。

Factor では [] で囲みます。

[ 1 2 + ]

値を . で表示すると、そのままの内容が表示されます。

[ 1 2 + ] .
[ 1 2 + ]

評価には call を利用します。

[ 1 2 + ] call .
3

これを踏まえて。

Factor の if は 3 つの値をスタックから pop し、1 つ目の値が真であれば 2 つ目の値を評価し、1 つ目の値が偽であれば 3 つ目の値を評価する、という動作になります。 見てきたように、操作は値の後ろに置かれるため、if は最後に配置されます。

1 2 = [ "EQ" ] [ "NE" ] if print
# コード 動作
1 1 値をスタックに push する
2 2 値をスタックに push する
3 = 値を 2 つスタックから pop する、2 つの値を比較する
等しい場合は t (真)を異なる場合は f (偽)をスタックに push する
4 [ "EQ" ] 値をスタックに push する
5 [ "NE" ] 値をスタックに push する
6 if 値を 3 つスタックから pop する
1 つ目の値が t であれば 2 つ目の値を f であれば 3 つ目の値を評価する
7 print 値をスタックから pop する、その値をコンソールに表示する

ここで [ "EQ" ][ "NE" ] は評価されると "EQ""NE" となり、つまり「文字列 "EQ" をスタックに push する」もしくは「文字列 "NE" をスタックに push する」という動作になります。

関数の呼び出しもスタックを利用します。

そもそもたとえば + という関数(Factor ではこれらを word と呼ぶようです)は、スタックから 2 つの値を取得してその和を push するという動作からも分かるように、

既視感

最初こそ構文につまづくものの、特に if が末尾に配置される条件分岐は今読んでいる部分がどこなのか戸惑ったものの、すぐに慣れてきました。

慣れたというよりも何かを思い出した気分。

どこかでこんなプログラミングをしていたという既視感。

思い出しました。 Z80アセンブラでのプログラミングです。 当時はたしかにスタックを駆使したプログラミングをしていました。

そういうものと把握すると、戸惑う構文だったものが、見慣れた構文に感じてきます。

二つの経験の間には何十年も開きがあるわけですが、こういった「肌感覚」のようなものは消えないものなのだな、と思った次第。

いつか読むはずっと読まない:語り継がれるもの

最初に読んだのが 40 年くらい前の話。 それから何回か読み返してはいるはずですが、それも前世紀。

昨年末、最終巻が国内で刊行され、最近になって重い腰を上げて第一巻から読み返しています。

作中の景色が近年の SF 作品と異なり、書かれた時代背景を反映しているのを感じます。

あらすじは忘れようもないのですが、それでも読み進めるごとにわくわくさせられます。 陳腐な言葉になりますが、この作品の面白さは本当に色褪せません。