見出し画像

Retro-gaming and so on

RE: プログラミング日記 2022-04-05~

星田さんの記事に対するコメント。

私はこれから呆れられそうな事を書きます(-_-;)

呆れないから心配すんな(笑)。
っつーかハッキリ言ってやる。「皆が通る道だ」(笑)。

ぶっちゃけた話、reduce/foldlを何故にLispビギナーが敬遠したがるのか。
それはprocの2つの引数と、reduce/foldlの後続する引数(初期値initとそれ以外の引数)の順序が逆だからだ。
これが初期に混乱する原因なの。これ以上の理由はない。
言い換えると、「reduce/foldlでは引数順序が逆になる」って分かれば、使うのに躊躇しなくなる、って事なのね。

例えば、だね。foldl使ってreverseを書いてみる。

(define (my-reverse lst)
 (foldl cons '() lst))

これは確かに動くんだけど。

> (my-reverse '(1 2 3 4))
'(4 3 2 1)
>

でもconsと言う2引数関数が想定してる引数順序と、foldlproc部分以外の引数の順序が逆じゃない?

(cons 'data '(a b c d e ...)) => '(data a b c d e ...) 

これがconsの正しい順序なんだけど、my-reverseの定義を見ると逆になってるでしょ?'()lstの中身がconsされていってる。
そう、だからこう考えないとならない。foldlでは後続する初期値、その他の引数の順序は逆順になるんだ、と。
これをLispビギナーは最初ピンと来ないで、結果混乱して、reduce系の関数を使うのが厭になるんだよ(笑)。

つまり、

(define (shuffle-list lst n)
 (foldl (lambda (x y)
  (shuffle y)) lst (range n)))

procにあたる (lambda (x y) ...)ylstを受け取ってx(range n)を受け取ってるわけ。
これを、順番通りにxlstを受け取ってy(range n)を受け取ってる、って解釈すると星田さんみたいに混乱しちまうんだわ。
でも心配しない。皆最初はそうやって考えて混乱の坩堝に叩き込まれるんだわ(笑)。
今日から寝る前に「foldl/reduceの引数はprocの引数と逆順」と3回唱えるようにしよう(笑)。一週間くらい唱えれば飽きるし、その頃にはそれが身に沁みて分かるようになってる(笑)。

なお、もう一度繰り返すけど、基本的なfoldlの定義は次のようになってる。

(define (my-foldl proc init lst)
 (if (null? lst)
  init
  (my-foldl proc (proc (car lst) init) (cdr lst))))

つまりさ、元々は、my-foldlの定義が次のようだったら混乱は起きなかったのね。

(define (my-foldl proc lst init)
 (if (null? lst)
  init
  (my-foldl proc (cdr lst) (proc (car lst) init))))

こうだったら、procの引数順序と後続する引数順序が一致して、Lispビギナーも混乱しなかった筈なんだよ。
でも、要するにinit(初期値)以降のリストは複数取りたかったから・・・つまり、可変長引数にするため、どうしてもリスト引数はパラメータリストの最後尾にせんとイカンかった、と言う理由があるのね。
  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「RE: プログラミング日記」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事