><>(Fish)に入門した

あらすじ

><>という難解プログラミング言語某ゴルフ場に入ったので、入門した。言語の名前上、ググラビリティが非常に低く日本語の情報が見当たらなかったので、ここに日本語で自分の><>入門への道中を記す。あくまで初心者が調べながら書いた文章なので、間違いが多分に含まれている可能性がある。間違いを見付けたら教えてほしい。


(この文章は、Befunger視点で書かれている。前提知識として、(某ゴルフ場の多少カスタマイズされた)Befungeの理解を要求するかもしれない。)

読みと拡張子

前述の通りググるのは難しいが、esolang wikiで一覧を見れば一発だった: Fish - Esolang


><>は英語の "fish" のように発音するらしい。wikiでは.fishという拡張子を使っているが、ゴルフ場ではfishと被るためか.fshを使っている。

俯瞰

><>はBefungeにインスパイアされた二次元言語である。スタックベースであることや一文字一命令、端でループすること、自己書き換え命令を持つところも同じで、大まかにはBefungeと同じノリだ。しかし、基本的にBefungeよりかなり高級で、その中でも特に衝撃が大きいのが

  • スタックそのものを無限に作れる
  • rotate等のスタックの深くに触れる命令がある
  • 大域ジャンプがある

の3つ。あと、ソースコードのサイズ制限は無い。ついでにゴルフ的に影響が大きそうな要素として

  • エラーになる状況が多い(スタックが底をつく、未定義命令を実行しようとする等)
  • 数値入力がない

を挙げておく。

スタックのスタック

[ で新たにスタックを作り、それを現在のスタックとする。] で現在のスタックの内容を前のスタックの上に展開する。スタックを作る時には前のスタックからいくつか値を持ってくることができ、その個数はスタックトップで指定する(スタックを作る時にpopされる)。スタックのスタックみたいな感じ。


さらに、スタックは一つのレジスタを持ち、& で出し入れができる。レジスタはスタック毎に独立していて、新たにスタックが作られると空のレジスタが用意され、スタックが削除されるとそのスタックが持つレジスタも破棄される。

スタック演算いろいろ

{} でスタックのrotateができる他、l でスタックの深さを得られる。あと r でreverse。ずるい

大域ジャンプ

. で指定した番地にジャンプできる。Befungeは大域ジャンプが一切無いのが特徴だと思っていたので、複雑な気分だ。

エラー

以下の状況でエラーになる。

  • ゼロ除算
  • スタックが底をつく
  • 未定義の命令を実行しようとする

エラーになると、何か魚のような香りがして終了する。


他にも、処理系がサポートしない精度の数値でオーバーフローするとエラーらしいけど、ゴルフ場の処理系はPython3で動いているので気にしなくてよさそう。

命令

各命令についてはwikiを見てくれーって感じなので、ざっくりとだけ書いておく。

制御

<>^v はBefungeと同じだが、/\|_# は鏡になっている。分岐は?で1マスジャンプするかどうかで行う。無条件ジャンプは ! になっている他、Befungeの ?x に、 @; になっている。あと大域ジャンプ。

リテラル

0-9に加え、abcdef で10から15まで直接プッシュできるようになっている。

算術演算

, は整数除算ではないことに注意。しかも、いろいろな場面で暗黙に整数に変換されるようなので、詳しくは処理系のソースを読むべし。さらに、出力時に小数部が0だと整数のように出力されることにも注意。


()= で比較演算が3つ揃っている。

文字列

" の代わりに ' を使うこともできる。

スタック操作

@ が3つ入れ替えになっている。あとは前述の通り []{}lr がやばい。

レジスタ操作

& 命令一つで出し入れ両方行う。

感想

Befungeよりesolang感が薄れているところは微妙。逆に言うと、Befungeより自由度が高くゴルフが難しくなり気軽に書けそうでもある。みんなもanarchy golfで><>を楽しもう。

追記(2015-10-13 17:58)

Befungeと大きく異なる点を発見した。g 命令での空白とソースコードの外の扱いである。Befungeではソースコードは80x25に整形されて空きはスペースで埋められる。しかし、><>(というかfish.py)ではソースコード外は0として扱われ、さらにソースコードの読み込み時にスペースを0として扱うようだ(そして命令フェッチ時に逆の変換を行う)。
追記ここまで

参考文献