メッセージ。 - 末尾再帰祭り、開催中!
# 末尾再帰祭り、開催中!
Schemeプログラミングの話なんだけど、0から9までのリストを作りたいとき、
(A)のやりかた
と、
(B)のやりかた
の2種類がとりあえず考えられる。(B)のほうが末尾再帰で速く処理できるのは分かるけど、可読性は落ちないの? 実際問題どっちでコーディングすべきなんだろう? 肝心かなめのところだけ末尾再帰が妥当なのかなーというのが事前の予想だけど。
(A)のやりかた
(let loop ((counter 0))(if (>= counter 10)'()(cons counter(loop (+ counter 1)))))
と、
(B)のやりかた
(let loop ((counter 0) (out '()))(if (>= counter 10)(reverse out)(loop (+ counter 1) (cons counter out))))
の2種類がとりあえず考えられる。(B)のほうが末尾再帰で速く処理できるのは分かるけど、可読性は落ちないの? 実際問題どっちでコーディングすべきなんだろう? 肝心かなめのところだけ末尾再帰が妥当なのかなーというのが事前の予想だけど。
Comment
# 「consしてって最...
# Schemeで書くと...
(B)を
(loop (+ counter 1) (append out (list counter)))
のようにするもちょっと変な気がします。
やっぱりconsしてreverseじゃないと。
# なるほど、そうなんで...
なるほど、そうなんですね。なんとなくこういうのから感じるのは、「自然に見えるコードが最適なもの(正しいもの)であってほしい」ということです。それは実装/言語仕様側で無理をしろ、というのではなくて(Schemeの仕様はそれなりに正しいと信じているので)実装/言語仕様が正しいのなら、それを読んだ自分が「そっちのほうが自然だ」と思えるようになりたいという感じです。精進でござります。
# > いわたさん そう...
そうですね。ぼくもその書き方を少し試したことがありましたが、listのところに罪悪感を感じてすぐやめちゃいました(あのときは、末尾再帰にこだわってたんじゃなくて、何かのパーサーを作ってたんだっけかな?)。でもreverseはreverseで、ちょっと後ろめたい気もするんですよね(笑)。実際reverseのコストってどんなもんなんだろう。……調べてみる、か?(自問)
Trackback