読者です 読者をやめる 読者になる 読者になる

レガシーコード生産ガイド

私に教えられることなら

Forthの使用例 / 名前について / Closureについて

forth

Forthの使用例

ForthHubというコミュニティから招待が来ていたので入ってみた。(enthusiastってほどでもないけど……)

その中でForthのUse Caseについての質問があって、面白いものがいくつか挙げられていたので、何を作っているかより、コーディングスタイルに注目して簡単に見てみる。

HSML

Hierarchical Music Specification Language。どちらかというとgenerative寄りっぽい?

ソースがかなり読みやすい。マルコフ連鎖のツール(よくわかってない)などOOPとローカル変数が躊躇なく使われている。なんか躊躇するようになっていたので安心する。ワード定義ワードやfoo{ ... }fooみたいな書き方も多い。

あとcase-insensitiveは何のメリットがあるんだろう?衝突が増えるだけでは?と思ってたけど、ワード定義時は大文字で使用時は小文字ってわかりやすいと思った。それに、大文字と小文字で衝突するようなネーミングは、特にForthにおいてはかなり良くないかも。

4thAcademy

こちらも音楽作成用。Atari ST用なのかな?:apってなんだろな……Forthmacsという処理系のライブラリかな?

(音楽の方の)コードプログレッションがコード中に書いてあったりいろいろと面白い。

Mako

Javaで書かれたVMで動くゲーム制作用のForth。2スタックある以外は命名も動作も普通のForthというところ。gamesディレクトリのサンプルは作りこんであって面白い。Linuxoracle-jvmだと音がややおかしいけど。。

特にSalad笑ったんでやってみて欲しい。(大丈夫なのかこれ)

f:id:phaendal:20160321193108p:plain

リファレンスツール等も整備されてるし、相当参考になりそう。というか使おう。

ZoG

アブストラクトゲーム、ボードゲームなどのメタ・ゲームエンジンとのこと。基本はZRFというLispライクな言語で書き、拡張したい場合にAxiom開発環境でForthライクな言語でPluginを書けるとのこと。コードを見ると普通のForthみたいだ。

Forthで楽なとこと面倒なとこ、(シンプルな)Lispで楽なとこと面倒なとこ、はかなり正反対に噛み合ってるという印象なので、Forthの上にLispVM作って補完するのはアリだなあと思った。ちょうどForthの上にGC作ってるし。

Forthでの名前について

最近rui ueyama氏のブログを読み返してて、はい、はい、その通りでございます……と自戒することしきりだった。その中でもオッと思ったのはGoの変数名が短い理由(あるいはGoがほかの言語と違う理由)というエントリ。

リーダブルコードなどを読んで、意味のわかる名前にしないといけないな、文章として読めるようにするのだ!と、思い、なるべく長くてわかりやすい名前をつけるようにしてた。

例えば伝統的なForthなら、スタックの一番上の値を辞書に置くワードは,なんだけど、「記号なんてわかりにくい!push-dictや>dictなどとすべきだ!」と思って、実際にそう書いていた。

でも書いてるうちに段々慣れて、かつ面倒になってきて、RFR64では伝統的な名前を使うことにした

結局いつもいつも同じ意味で使う名前、特にワード名なら、数文字の短い名前にした方がわかりやすい。コードも物理的に一覧性がよくなり、思考が文字に囚われないからイメージのまま作業できる。

また滅多に使わない名前も、sp0sp@ぐらいなら、data-stack-basedata-stack-pointerより読みやすいし全然覚えていられる。

めちゃくちゃ短いゴルフみたいなコードを書くのはどうかと思うけど、必死に長い名前をつける必要も無いのだなあと思った。

ForthとClosureについて

JavaScriptSchemeを書くときはLexicalClosureを使うのがとても好きで、好きというか完全に慣れていて、コードに重複する部分があればとりあえずClosureを使って短くしていく。

Closureを使ったよくある例がこんなの

function makeAdder (n) {
    return function (x) {
        return n + x;
    }
}

var inc = makeAdder(1);

なんだけど、ForthだとそこまでClosureは必要無いかもしれない。

: inc 1 + ;

結局これだけで十分で、make-adderをわざわざ呼ぶより早い。

ワード名を定義してしまうけど、定義を見えなくする方法はいくらでもあって、逆に単体で呼び出すことができればテストがしやすい。

Concatenativeなので、ワードのどこでも大体切り出すことができる。データから自動的に手続きを生成したい場合も、別の単純なやり方で解決できる事のほうが多そう。

GCを用意して、変数に束縛した手続きの呼び出しを楽にして〜といろいろ考えてたけど、実用のためなら別に必要ないかもな、と思った。ただ実用とは別に関数をこねくり回すの好きなので、近いうちに実装したいとこではある。

広告を非表示にする