星田さんの記事に対するコメント。
> 2022/09/10
良く書けてますよ。取り敢えず動けば勝ち。
なんせ二年以上前より技術力が上がってる、って証明なんで。
一つだけ、様式に付いて。
ここではletで束縛する必要がなく、いきなり名前付きletで束縛してO.K.です。
(let loop ((list-x (string->list x)) (list-y (string->list y)) (count 0)) ...
「名前付きletは再帰用」って意識が大きいんだろうけど、と、同時にこれは単なるletの亜種だ、ってのも事実。
従って、これで束縛可能なモノは束縛しちまいましょう。
書く量が減らせるトコは減らしちゃった方がいい。
まぁ、今んトコ手癖なんだろうけど、要するにリファクタリングの範疇です。
> 2022/09/11
教科書のOcaml版クイックソート、コメントだらけで意味不明だったのでFilterを使って出来そうじゃないか?と作ってみることに。
発想がいい。その通りです。
検索したらWIKIにご丁寧にSchemeで書かれたクイックソートの例が。そうそう!こういうのが書きたかったの!
うん、実はそれ書いたの俺だ(笑)。
ええとね、Haskellが知名度が上がった頃、「Haskellならクイックソートがこんなに短く書けるんだよ!」ってのがサンプルとして良く話題に上がってたのね。
C言語でのソース見てみれば分かると思うんだけど、フツー、非力な言語で書けば、かなり長いし煩わしいわけ。クイックソートの実行効率はいいにしても、書くのがホンマメンドイ。僕がそう感じるだけ、じゃなくってみんな結構そう思ってるわけ。
そこにHaskellが「関数型言語ならクイックソートがこんなに短く書けます!」って一種デモった。Wikipediaに挙げたコードは、そのHaskellでの典型的ヴァージョンをSchemeで書き直したヤツです。
星田さんみたいに、もう、match使えて準クオートも使えるなら、Gaucheなら次のようにして書いてもいいと思う。
興味深いのは(compose not func)ですかねぇ・・なるほどこれで「ではない手続き」を簡単に実現できる!あれ?なんか随分前にCametanさんの記事で教えてもらってた気がする・・まあ、忘れる生き物ということで。
そう、composeマジで便利なのよ。何気ないトコでラムダ式で関数合成したりローカル関数を作ったりする手間を省いてくれる。ラムダ式なんてタダでさえ字数が多いから、二重になったりするのを毎回歓迎するわけにもイカンしね。
この「何気ない」ってのが大事で、それが場合によっては大掛かりで肥大化する原因となる箇所なんだ。
んで、以前、出てきたcomposeの使用例は「回転行列」の辺りかな。
分かってなかったのは組み上げるというのは「ループで回したその後」の事だと思ってた事で、組み上げるところまでをループに入れても大丈夫(なように出来る)ってところですかねぇ
そう、理論的な話をすると、再帰をletで束縛しても構いません。
特にクイックソートみたいに、本質的に末尾再帰で書けない関数の場合はこのケースのようにletで束縛しても全然良いです(※1)。
`記法で解決!なんですけど、逆に言うとコレ知らないと詰んでるって事なんだろうか?という疑問が湧きました。終了条件の `(,n)の時は(list n)で行けたけど・・色々とListで囲って試したけど無理でした。
多分これで大丈夫なんじゃないかいな。
※1: 末尾再帰で実は書けるが、継続受け渡し方式で書く必要があり、なおかつ、理論的にはそれがこのクイックソートのように再帰部分がletで束縛されるのと同じ意味になる。
「SchemeとActor理論」を学び終えたら、「なんでも継続」を読んでみよう。この辺の理論的な解説が書いてある。
いずれにせよ、letによる束縛を用いなければ、
と書くか、
と書くのと同じ事となる。