依存性のないループから依存性のあるループへの書き直し

 リストの各要素への繰り返しはまぁ、mapで書ける。それが読みやすいかどうかは別問題として。
 しかし、前から順に要素を見ていって、ある条件が真になったらそこでループ打ち切り、みたいなコードに書き換えたくなったらどうしたらいいか?

  • 再帰を使う
  • foldを使う

 再帰を使うやり方は、named letを使うにせよループ用関数を新しく定義するにせよ、すこし大仰である。(もしかしたら他にも再帰の書き方はあるのかもしれないが、知らない…。)
 foldの場合は各要素への繰り返し自体を途中で止めることはできない。konsの中で条件判断を行うことで、擬似的にループを打ち切っているように振る舞っているだけである。よって、要素数が多い場合はループ回数が多少、勿体ない。また、konsの引数は2引数と決まっているので、ループ打ち切りかどうかの判断を下すためのフラグを表現するためには以下の2つのどちらかの手段を取らなければならない。(他にも手段はあるかもしれないが、今ぱっと思い付くのはこの2つだけ。)

  • foldの外側に変数を置き、ループが終わったらset!で更新
  • (cons flag data)という形で次のkonsに渡す

 set!を使っていいのは親の死に目と結婚式と財布を盗まれたときだけ、と小学校で先生に教わったので、set!の使用はなるべく避けたい。しかし、consでくるんでcar,cdrで取り出すというのも、なんか本質的でないコードが入ってキモい。
 書き換え自体が問題というよりも、どういう風にしたら各要素間に依存性のある繰り返しをきれいに(かつ気軽に)書けるようになるか、というのが問題の要点か。
 take-whileは意図にかなり近い関数ではあるが、リストの要素をそのまま返すという点で、欲しい関数とちょっと違う。
 結局、foldに類似した、途中でループを打ち切れる関数を自分で定義するというのが一番の早道、という結論に達したが、関数名を決めるのってそれはそれで大変ですよね…!!