メッセージ。 - 末尾再帰祭り、開催中!

# 末尾再帰祭り、開催中!

Schemeプログラミングの話なんだけど、0から9までのリストを作りたいとき、

(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)のほうが末尾再帰で速く処理できるのは分かるけど、可読性は落ちないの? 実際問題どっちでコーディングすべきなんだろう? 肝心かなめのところだけ末尾再帰が妥当なのかなーというのが事前の予想だけど。
2005-11-02 00:14:03 / ふじさわ / Comment: 4 / Trackback: 0

Comment

# 「consしてって最...

「consしてって最後にreverse」というのはほとんど定石みたいなものなので、慣れてしまえば迷うことはないですが、Haskellerあたりから見たら気持ち悪いのかも。
2005-11-02 06:38:57 / shiro / Comment: 0 / Trackback: 0

# Schemeで書くと...

Schemeで書くときに、reverseを避けてわざわざ
(B)を
(loop (+ counter 1) (append out (list counter)))
のようにするもちょっと変な気がします。
やっぱりconsしてreverseじゃないと。
2005-11-02 14:09:00 / いわた / Comment: 0 / Trackback: 0

# なるほど、そうなんで...

> shiroさん
なるほど、そうなんですね。なんとなくこういうのから感じるのは、「自然に見えるコードが最適なもの(正しいもの)であってほしい」ということです。それは実装/言語仕様側で無理をしろ、というのではなくて(Schemeの仕様はそれなりに正しいと信じているので)実装/言語仕様が正しいのなら、それを読んだ自分が「そっちのほうが自然だ」と思えるようになりたいという感じです。精進でござります。
2005-11-02 14:21:03 / ふじさわ / Comment: 0 / Trackback: 0

# > いわたさん そう...

> いわたさん
そうですね。ぼくもその書き方を少し試したことがありましたが、listのところに罪悪感を感じてすぐやめちゃいました(あのときは、末尾再帰にこだわってたんじゃなくて、何かのパーサーを作ってたんだっけかな?)。でもreverseはreverseで、ちょっと後ろめたい気もするんですよね(笑)。実際reverseのコストってどんなもんなんだろう。……調べてみる、か?(自問)
2005-11-03 03:15:15 / ふじさわ / Comment: 0 / Trackback: 0
コメント投稿機能は無効化されています。

Trackback

TrackBack投稿機能は無効化されています。