星田さんの記事に対するコメント。
RacketだといちいちDisplayしなくても見られるしNewlineしなくてもリスナー(?)部分では改行されてるから楽でした。
Paizaの設計がマズイ為、って言い方も出来るし、実際問題、Gaucheをローカル環境で使うならわざわざdisplayする必要もない。
ただ、僕が一般に、星田さんみたいに慣れてればいいんだけど、オンライン環境をプログラミング初心者に薦めない理由はまさにこれ。一見、ブラウザで実行すると環境が要らない、とか言うんだけど、見た通り面倒臭いんだ。
ところで、Paizaの設計はマジでマズイのか、と言うとそうじゃなくってセキュリティの問題だ。
つまり、REPLをオンラインに公開すると、「悪意のあるコード」がそのまま入力されて実行される環境を許してしまう、って事なんだよな。
一旦テキストで入力してもらえれば実行させる前にセキュリティチェックが可能なんだけど、インタプリタはそうじゃない。もし、Paizaのハードディスクを全部消去しろ、なんて命令をGaucheを介して行われれば目も当てられない(実際、Gaucheを含み、多くのLisp処理系はOSにアクセス出来る機能が提供されている)。
それが理由で多くのオンライン実行環境では剥き出しのインタプリタをブラウザを通して公開する、なんつー危険な事をやってないわけ。
まぁ、そういった理由もあって、Google Colabみたいな形式はむしろ珍しいんだ。多分何重にもセキュリティガードしてんだろうな、と言う話。
そしてLetrec・・これも何回も練習で書いたけど忘れてました。
まぁ、忘れてもいいけどね(笑)。
ただし、この形式の考え方がSchemeでは増えている。具体的にはdefine-valuesの登場です。
define-valuesの登場で、複数の関数を一気に定義出来るようになりました。
と言うかこのサンプルが難解でしたw。まずeven?っていかにも組み込みでありそうな名前なので混乱しました。
当然、even?もodd?も仕様書に定義されてます。
逆に言うと、何故にletrecが使われる例になってるのか、ってのもそれが理由。
ローカル環境内で、「元々ある関数名」で別の関数を作っても、そのローカル環境を抜けた際に元に戻る、と言う事。letrec内で定義された関数名は元々の関数名をシャドウしても、letrecが形成したスコープを抜けた時点で、その効果は消えてしまう。
そういう「レキシカルスコープ」の効果を考える際にも良い例です。
アルゴリズムも面白いけど最初謎だった
こういう再帰を相互再帰、と呼びます。関数Aと関数Bをお互い呼び出し続ける。
その「呼び出し」が末尾呼び出しなら、やっぱり末尾再帰最適化が起こります。
そしてマップ数500オーバーとか (・。・;
マップ生成のアルゴリズムとかあるんだろうか?素人考えだと、最初にクリア状態のマップを作っておいて、そこから自動で1マスずつマップを「荒らす」事で作れそうではあるけど・・
まぁ、理論的には作れるかもしんない。
まさか500面全部手打ちでは無いですよね?恐ろしい・・
実はその「まさか」だ(笑)。
と言うのも、色々倉庫番調べてて、海外の倉庫番ファンのサイトとか覗いたんだけど、
「欧米では倉庫番Perfectと倉庫番Revengeが出てないんで、やりたかった・・・」
とか書いてたの発見して、じゃあPerfectとRevengeを移植すっか、とか気の迷いが生じたわけ(笑)。
Perfect 306面とRevenge 306面で・・・と言うのがネタなのね。
そのせいで大変な思いしてるわけだ(笑)。