- 1 名前:名無しのプログラマ [2015/08/09(日) 17:46:33.69 ID:Icb40LOY.net]
- for,while使うの嫌いで基本的に再帰多用するんだが、だめなの?
皆から敬遠されてる気がする
- 75 名前:デフォルトの名無しさん [2015/08/12(水) 23:00:43.40 ID:ALDJfVhA.net]
- >>73
>だけどデータがリスト構造なだけなら >普通にループを使ったほうがわかりやすい。 んなわけねーだろ
- 76 名前:普通に再帰使うわ []
- [ここ壊れてます]
- 77 名前:デフォルトの名無しさん [2015/08/12(水) 23:01:27.55 ID:ALDJfVhA.net]
- あ、まさかリストが再帰構造でツリーの一種だってことを理解してないとか?
- 78 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:10:56.27 ID:Pci5W2YJ.net]
- >>73
リストは最も基本的な再帰構造だと思うんだけど haskell data [a] = [] | a : [a] deriving (Eq, Ord) scala sealed trait List[+A] case class Cons[+A](head:A,tail:List[A]) extends List[A] case object Nil extends List[Nothing]
- 79 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:16:15.63 ID:S25mloU+.net]
- >>76
それは何の反論にもなってない。 リストはツリー構造のサブセット。 ツリー構造の柔軟性の一部を禁止してシンプルにしたもの。 そのシンプルなデータ構造に対してはシンプルな処理を 使ったほうがわかりやすくなるのは当たり前。 再帰よりもループのほうが単純なことしか出来ないが、 単純なことしか出来ないから、余計なことを考える必要がなくなる。 シンプルな構造にも複雑な構造にも複雑な構造用の道具を使うのではなく シンプルな構造にはシンプルな構造用の道具、 複雑な構造には複雑な構造用の道具を使うことが、 適切に道具を選ぶということ。
- 80 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:16:55.97 ID:Pci5W2YJ.net]
- length :: [a] -> Int
length [] = 0 length (x:xs) = 1 + (length xs) ループより分かりやすくね? まぁ リストの長さなら def length[A](list:List[A]):Int = list.foldLeft(0)((total,_)=>total + 1) みたいにfold使った方がいいかもわからんが
- 81 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:18:07.58 ID:S25mloU+.net]
- >>79
よくわからないので、ループで書いてくださいw
- 82 名前:デフォルトの名無しさん [2015/08/12(水) 23:18:53.71 ID:ALDJfVhA.net]
- >>78
伺いますけど、あなたのリストにはループに使うインデックスついてるんですか? appendとか恐ろしく高コストで使えない不思議なリストですね でもそうじゃないとインデックスでのアクセスはO(n)なんでねえ なんでリストを扱ったプログラミングしたことないくせに偉そうなんだろ
- 83 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:20:08.29 ID:S25mloU+.net]
- >>81
え?append? なんでオーダーなんか出てきてんの? 今までそんな話全くしてない。 話がずれてるね。
- 84 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:20:45.20 ID:Pci5W2YJ.net]
- 同じ「単純な事」しかできないなら
高階関数使ったほうがよさげじゃね? fmap, foldr, >>=, <*> なんかを使ったほうがいいと思う
- 85 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:21:38.26 ID:S25mloU+.net]
- >>83
そうだよ? 高階関数を使ったほうがもっと良い。 高階関数の話は上の方でしている。 ただ再帰を使って書く必要ねーなって話。
- 86 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:23:21.20 ID:Pci5W2YJ.net]
- >>79
foldのほうが分かりやすいけど 再帰のほうは リストの長さは空だったら0 空じゃなかったらtailの長さに+1したものって宣言的に買い取るだけ
- 87 名前:デフォルトの名無しさん [2015/08/12(水) 23:23:52.85 ID:ALDJfVhA.net]
- >>82
なんで「そんな話」が出てくるのかわからないなら 再帰もリストもまったく知らないってことなんですけどねえ 低レベルだわあ
- 88 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:24:48.52 ID:S25mloU+.net]
- > リストの長さは空だったら0 空じゃなかったらtailの長さに+1したもの
つまり、それ何をやってるの? 日本語で、一言で言うと・・・?
- 89 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:24:50.58 ID:Pe25qO3w.net]
- メモリはベタ配列みたいなもんなんだから
むしろツリーはメモリ上の配列に表現されてるようなもんなんじゃ まともなバイナリフォーマットって大抵オフセットもってたりしてシンプルにデコードできるようになってる 糞古いフォーマットでハフマンみてーなのだとどーしても再帰の使用を考えるようになるんだけど これは今の計算機が持ってるほぼすべての並列化機構を機能不全にするのよね
- 90 名前:デフォルトの名無しさん [2015/08/12(水) 23:25:35.07 ID:JsRAlNhV.net]
- C/C++だと、リンクリストはループで扱ったほうが良いんだよね。
HTMLを取り扱うクラスを書いてみたんだけど。 このスレ程度のデータ量でも簡単にスタックオーバーフローする。 タスクマネージャで見ると、ほんの数メガバイト、しかも大部分は ネットワークキャッシュに使われてるような状態なんだけども。 まあ、C++使いは十分注意したほうが良いと思う。 あと、マシンスタックの大きさはWindowsなら簡単に設定できるわけだけど、 そんなことはせずに、素直にループにした方が良いマナーだと思う。
- 91 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:25:50.72 ID:S25mloU+.net]
- >>86
苦笑w 話の内容はわかってる。 そんな話は俺はしてないといってる。 わかってるから、俺はしてないといえるわけだよ。 OK?
- 92 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:27:05.85 ID:Pci5W2YJ.net]
- >>84
個人的には 問題にあった適切な高階関数 > fold > 再帰 > 末尾再帰 >ループ で読みやすさが変わるイメージ
- 93 名前:デフォルトの名無しさん [2015/08/12(水) 23:27:56.05 ID:ALDJfVhA.net]
- >>90
リストをループで処理するとか言うアホに言われましても どうぞmapをループでお書きくださいな # 配列とリストの区別もついとらんとはねえ
- 94 名前:デフォルトの名無しさん [2015/08/12(水) 23:30:43.07 ID:ALDJfVhA.net]
- >>89
末尾呼びにしなきゃそりゃそうなります
- 95 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:30:43.36 ID:Pci5W2YJ.net]
- リストって再帰が一番やりやすいデータ構造だと思うんだけどなぁ
>>87 リストの長さ
- 96 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:31:51.38 ID:S25mloU+.net]
- >>92
> どうぞmapをループでお書きくださいな これでいい? function map(list, callback) { let ret = []; for(item of list) { ret.push(callback(item)); } return ret; }
- 97 名前:デフォルトの名無しさん [2015/08/12(水) 23:32:45.32 ID:JsRAlNhV.net]
- リンクリストの解放で、デストラクタがネストするのも気を付けたほうが良い。
これ、コーディング中は小さなデータでテストしてるから気が付かないことがあると思う。 というか俺はそうだった。 特定のサイトでだけスタックオーバーフローするので何かと思ったら、 デストラクタが再帰するのであった。
- 98 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:33:03.35 ID:6ZXtaURL.net]
- レスを読む限り、mapのがよく問題を分離できるし並列もできるから
ループの方がよっぽど要らないような
- 99 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:35:11.79 ID:S25mloU+.net]
- >>94
「リストの長さ」っていうより 「空だったら0 空じゃなかったらtailの長さに+1したもの」っていう方が 日本語の言葉として明らかに長いよね?
- 100 名前:デフォルトの名無しさん [2015/08/12(水) 23:35:36.01 ID:JsRAlNhV.net]
- >>97
C++だとコンカレントは遅くなること多いんだよな。 コンカレントが入って喜び勇んで使ってみたけど、まあまだ使える時代じゃないと思った。
- 101 名前:デフォルトの名無しさん [2015/08/12(水) 23:36:17.69 ID:ALDJfVhA.net]
- >>95
mapをmapで定義してくださってどうもありがとうございます >>94 触っちゃダメ
- 102 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:36:36.85 ID:S25mloU+.net]
- >>97
> レスを読む限り、mapのがよく問題を分離できるし並列もできるから > ループの方がよっぽど要らないような mapとループの話じゃなくて、 ループと再帰の話で、再帰使うまでもない所で 再帰使う必要ないよって話をしてるんだよ。 要らないとは誰も行ってない。 シンプルな道具を適切に使いましょう。
- 103 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:38:07.01 ID:Pe25qO3w.net]
- CPUの並列化機構がマルチスレッドぐらいしかないとか思ってると勘違いが起こる
- 104 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:38:19.63 ID:S25mloU+.net]
- >>100
> mapをmapで定義してくださってどうもありがとうございます どこがmap? for...of ループの話? ほれ、for...of ループ の説明 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of
- 105 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:39:14.64 ID:6ZXtaURL.net]
- >>96
自分もコピーコンストラクタの再帰バグとかよくやりますw C++は基本的部品は自分で書かず、 よくテストされてもの使った方がいいですね
- 106 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:39:27.31 ID:S25mloU+.net]
- for...ofループを使ってダメなら、
function map(list, callback) { let ret = []; for(let i = 0; i < list.length; i++) { ret.push(callback(list[i])); } return ret; } って書くだけだけどね。
- 107 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:40:41.46 ID:6ZXtaURL.net]
- >>101
いえいえ、ループを引き合いに出してるので、 その2者なら再帰よりもループのが要らないでしょうと
- 108 名前:デフォルトの名無しさん [2015/08/12(水) 23:40:57.52 ID:JsRAlNhV.net]
- >>102
SIMDとかは更にまだまだ時代じゃないような気がする。 特定の環境に合わせてシコシコこさえるくらいの時代。
- 109 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:42:37.68 ID:S25mloU+.net]
- >>106
「要らない」の理由がおかしいんだよ。 再帰でループが実現できるのは知ってる。 君は、大は小を兼ねる理論で、 大があれば小はいらないという考え方だろうけど、 俺は大には大を、小には小を使った方が いい(わかりやすい)と言ってるわけ。
- 110 名前:デフォルトの名無しさん [2015/08/12(水) 23:44:25.03 ID:JsRAlNhV.net]
- >>104
俺もそれはそうだと思う。 最初、イテレータを持つようにしてみたんだけど、何となく汚く見えたんで std::shared_ptr使ってノードを表現したら、デストラクタがネストするバグを こさえてしまった。 でも、結果的に、感動的にうまく動くアルゴリズムができて満足。 色々勉強になった。
- 111 名前:デフォルトの名無しさん [2015/08/12(水) 23:46:49.96 ID:JsRAlNhV.net]
- まあ、俺に言えることは、HTMLを取り扱うなら、リンクリストが予想に反して最強ってこと。
- 112 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:53:27.52 ID:Pe25qO3w.net]
- >>107
パイプライン
- 113 名前:デフォルトの名無しさん mailto:sage [2015/08/12(水) 23:58:30.93 ID:6ZXtaURL.net]
- >>108
私は再帰を代替にしろ、という話は一切してないですよ 率直に言って、あなたの主張は再帰を相手にしなくてもいい一般化ですし、 他人を下と決めつけてかかって煽ってるようにしか見えません。
- 114 名前:デフォルトの名無しさん [2015/08/13(木) 00:02:20.41 ID:AIiQbQBJ.net]
- >>112
ひどいいいがかりだな
- 115 名前:デフォルトの名無しさん [2015/08/13(木) 00:03:45.02 ID:AIiQbQBJ.net]
- 〉他人を下と決めつけてかかって煽ってるようにしか見えません
レッテル張り
- 116 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:04:44.19 ID:Vkqae3ee.net]
- >>108
ここは言語の違いだと思うけどjavascriptみたいな手続き型で再帰を特にサポートしていない言語は 再帰は基本的に使わない方がいいけど 関数型プログラミング言語だとむしろループより再帰の方が書きやすいし自然だから よっぽど高速化したい時じゃないとループ使わないと思う(ループだとそのコードみたいに破壊的代入が含まれるし)
- 117 名前:デフォルトの名無しさん [2015/08/13(木) 00:09:22.93 ID:G0UckYXU.net]
- >>114
レッテル貼りとは、太平洋戦争の頃に使われた言葉で、現代の若者は ラべリング問題と言わないとわからないらしい。 あと、レッテル張りとは、レッテルを瓶に貼る前に水でピンと張る工程のことで、 それは、昭和初期のラべル職人以外には通じない言葉らしい。
- 118 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:14:19.60 ID:Vkqae3ee.net]
- 個人的にパターンマッチがない言語で再帰にはつらみを感じる
- 119 名前:デフォルトの名無しさん [2015/08/13(木) 00:15:41.46 ID:AIiQbQBJ.net]
- >>116
常識で考えろよ、昭和初期のラベル職人以外には通じないことを ここで言うと思うか?バカじゃね。
- 120 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:16:00.68 ID:NebXzry6.net]
- >>116
もう何の話かわからないけど、無駄に知識がついてしまった
- 121 名前:デフォルトの名無しさん [2015/08/13(木) 00:17:24.90 ID:AIiQbQBJ.net]
- >>117
パターンマッチはifで書けばいいし、再帰はループで書けばいい。 いきがるな。
- 122 名前:デフォルトの名無しさん [2015/08/13(木) 00:18:56.16 ID:AIiQbQBJ.net]
- ループで書けるものを再帰で書くやつって結局ヒッピーなんだよね。
ラリってるだけ。
- 123 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:23:14.84 ID:Vkqae3ee.net]
- >>120
ifはパターンマッチ漏れをコンパイラが警告してくれないんやで val a = list match { case Nil => Nil case head :: tail => tail } をifで書くと var a; if(list.isEmpty){ a = Nil } else { a = list.tail } だろ 辛い
- 124 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:24:32.15 ID:NebXzry6.net]
- >>117
JavaScriptならswitch(true)で頑張れば、ある程度は代替できそうですが、 基本的に静的型言語じゃないと真価を発揮できない気がしますね
- 125 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:24:38.47 ID:Vkqae3ee.net]
- >>121
言語の違い、データ構造の違い
- 126 名前:デフォルトの名無しさん [2015/08/13(木) 00:27:11.91 ID:AIiQbQBJ.net]
- >>124
ループを再帰で書く奴はミーハーで頭の中ハコスカなだけ
- 127 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:28:36.37 ID:FUyksqfE.net]
- アホばっか
再帰的なアルゴリズムなら再帰を使えばいいし 反復なアルゴリズムならループを使えばいいし どちらでもいいなら気分でかけばいいじゃん? どっちか一方しか使わない使えないでは話にならん
- 128 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:33:41.96 ID:Vkqae3ee.net]
- ループを再帰で書くというのがなんか違う
むしろ最初に再帰が浮かび後からループにいやいや書き換えるのではないか
- 129 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:38:27.39 ID:FUyksqfE.net]
- >>127
アルゴリズムの考え方が先行して考えられると思うけど
- 130 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 00:57:49.87 ID:NebXzry6.net]
- >>128
ループや再帰処理それ自身がアルゴリズムなので、 強いて依存先として挙げるならデータ構造じゃないかと
- 131 名前:ID:JsRAlNhV mailto:sage [2015/08/13(木) 01:30:53.70 ID:1C0y4JfF.net]
- ちょっと深夜のランニングをしてきたわけだが、誰にレスするべかな?
反論者と擁護してくれる人の両方がいるな。
- 132 名前:デフォルトの名無しさん [2015/08/13(木) 01:35:10.57 ID:G0UckYXU.net]
- 末尾再帰云々言ってる人は、コンパイラがループに変換してくれるから
再帰を使うべきって話ですか?
- 133 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 01:35:43.95 ID:1C0y4JfF.net]
- >>113
> レッテル張り 全くだね〜w >>115 > ここは言語の違いだと思うけどjavascriptみたいな手続き型で再帰を特にサポートしていない言語は > 再帰は基本的に使わない方がいいけど というか逆だね。(一部の?)関数型言語のような、 ループを再帰よりも書きづらくしているものに限って言えば、 再帰を使うしか無いよ。仕方なく。 そういう言語以外は、再帰よりもループのほうが簡単に書ける。 (データ構造自体が再帰に適している場合は除く) > ループだとそのコードみたいに破壊的代入が含まれるし 破壊的代入はするよりもしないほうがいいのは確かで、 俺もコードレビューなどで破壊的代入はするなって言ってるけど、 それは方針であって絶対的なもんじゃない。 破壊的代入をしたほうがわかりやすい場合もある。 よく言われるように手段と目的を履き違えるな問題だよ。
- 134 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 01:37:43.32 ID:1C0y4JfF.net]
- >>126
> どっちか一方しか使わない使えないでは話にならん 俺もそれを言ってる。 再帰を知った奴がなんでも再帰を使って 解こうとしている。それに対して警告してる。 まだまだだよって。
- 135 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 01:38:45.50 ID:1C0y4JfF.net]
- >>131
> 末尾再帰云々言ってる人は、コンパイラがループに変換してくれるから ↓ 俺が最初のほうで書いたレスw 24 自分:デフォルトの名無しさん[sage] 投稿日:2015/08/11(火) 18:24:05.65 ID:Ghx6BuLg ループで実装する ↓ (意味なく)再帰にしたい! ↓ 再帰にするとスタックがー、関数呼び出しがー、どうのこうの ↓ 末尾最適化される再帰にすればいいんだぜ!フフン ↓ 末尾最適化されるような再帰コードを書く ↓ コンパイラがループの実装に戻す 結論 人間がループを再帰に変換し、 コンパイラが再帰をループに戻すという無駄!
- 136 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 01:43:20.43 ID:1C0y4JfF.net]
- >>127
> むしろ最初に再帰が浮かび後からループにいやいや書き換えるのではないか 女性の列の中から男の娘を探しなさいって言われた時、 前から一人づつ見ていくという方法を思いつく人は多くいると思うが、 俺「一人だけ確認した。あとは俺に頼む」→俺「はーい、わかりました。俺も同じことをしまーす。」→俺「以下同文」 という考え方をする人は滅多に居ないと思うが。
- 137 名前:まーた連続書き込み規制だよ mailto:sage [2015/08/13(木) 01:50:39.52 ID:kS/o56L+.net]
- >>117とか>>120とか>>122とか>>123
そういう場合、switchを使うんだけど ちょっと数が増えただけで、循環的複雑度を調べるツールで 複雑だって言われるんで、これぐらいいいじゃねーかと思いながら (※注 そのツールを導入したのは俺wしきい値を8に設定してるのも俺w) 関数テーブル呼び出し的なコード(意味わかるよね?)に書き換えるんだけど、 そうしたらやっぱり前よりわかりやすくなって、 やっぱりswitchいらねーか、とか思ってしまうw 関数テーブル呼び出し的なコードにすれば、パターンマッチ漏れは nullを関数呼び出しすることになって、実行時エラーになってはくれるよ。
- 138 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 01:54:14.37 ID:NebXzry6.net]
- 元から再帰で無理矢理書くことを勧めてる人は、そういないんじゃないかと
私は相手をその手の人間と決め付けて話す事が、 おかしいといってるだけですよ
- 139 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 01:59:57.44 ID:kS/o56L+.net]
- >>137
> 元から再帰で無理矢理書くことを勧めてる人は、そういないんじゃないかと うん、こいつらぐらいかな? 適切なものを選ぼうとせずに 何でも再帰、再帰のほうがわかりやすい。 再帰使うほうが頭いい、(理由ないけど)普通に再帰だわ とか言ってる人。 25 名前:デフォルトの名無しさん[] 投稿日:2015/08/11(火) 20:07:51.21 ID:SPQSl72c [2/2] 再帰のほうがわかりやすいと思えない子が 26 名前:デフォルトの名無しさん[sage] 投稿日:2015/08/11(火) 20:55:40.81 ID:I9e7/X97 [1/2] 再起が得意かどうかで頭の良さが決まる 33 名前:デフォルトの名無しさん[] 投稿日:2015/08/11(火) 23:39:17.34 ID:BomPGBV/ [2/2] 再帰苦手なのは練習不足なだけ 理解が早いのは完全に地頭がいいだけじゃね? 74 返信:デフォルトの名無しさん[] 投稿日:2015/08/12(水) 23:00:43.40 ID:ALDJfVhA [5/11] >>73 >だけどデータがリスト構造なだけなら >普通にループを使ったほうがわかりやすい。 んなわけねーだろ 普通に再帰使うわ
- 140 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:00:23.27 ID:NebXzry6.net]
- >>135
それってfoldかfilterで良くないですか? そう言う意味で、再帰よりループのが不要に見えるんですが
- 141 名前:デフォルトの名無しさん [2015/08/13(木) 02:03:39.26 ID:G0UckYXU.net]
- まだ関数型言語の時代は来てないんで、手続型前提で良いんじゃないですかね。
- 142 名前:デフォルトの名無しさん [2015/08/13(木) 02:06:24.18 ID:G0UckYXU.net]
- 関数型がうまく機能する時代にはC++のようなマルチパラダイムの言語に取り込まれて
結局、純粋な関数型言語の時代は来ないんじゃないですかね。
- 143 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:07:07.66 ID:kS/o56L+.net]
- > それってfoldかfilterで良くないですか?
> そう言う意味で、再帰よりループのが不要に見えるんですが え? 君、foldかfilterでいいにしても、再帰の話してないよね? foldもfilterもループでも再帰でも書けるわけだから。 高階関数呼び出しを行うそれらの関数を使えば ループ(または再帰)が不要になるっていう話なら別に否定してない。 俺もよく使うし、上の方でも書いたよ。 >>54 > 最近ではMIMEメールのパースとか、連想配列の > 全ての値の処理とかで使ったかな。 > > 再帰を使うことはめったにない。そしてミスをしやすい所でもある。 > だから再帰を使うときは、再帰を考慮しなくていい形に置き換えるようにしている。 > つまりJavaScriptでいうmapやreduceの形にする。再帰部分と処理部分に分けて再帰部分を隠ぺいする。 > 通常書くのはコールバックで呼ばれる処理部分のみ。 > そうすることで可読性も大きく上昇する。 再帰はわかりづらいからtraverseみたいな形にすることで再帰を内部に隠ぺいする。 ループを内部に隠蔽してfoldかfilterがあればループが不要だというのなら、 同じ理由で、再帰を内部に隠蔽したtraverseで良いから、再帰は不要だって言えばいいの?
- 144 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:13:00.97 ID:NebXzry6.net]
- >>142
必要性の比較として、その手の関数で簡単に書き下せるloopの方が、 再帰より不要ではないですか?と言う意味ですよ 実装としては、さすがにループが完全になくなるとは思ってません
- 145 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:15:06.80 ID:kS/o56L+.net]
- そういや高階関数使える言語ばっかりになったよな。
>>141 > 結局、純粋な関数型言語の時代は来ないんじゃないですかね。 俺もそう思う。 高階関数は便利だけど、純粋な関数型言語まではいらないかな。 あとScalaでいうval、再代入不可能な変数も欲しいけど。
- 146 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:19:20.99 ID:NFzWJ2Cc.net]
- 何でこんなに伸びてるの…
- 147 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:19:45.60 ID:kS/o56L+.net]
- >>143
そもそもの話が、「ループで簡単に書けるようなもの」を 再帰でわざわざ書くなって話なんだよ。 正確に言うと、再帰を使わないでいいような処理に 再帰を使うなという話。 だから、その手の関数で簡単に書き下せる処理に 再帰を使うなっていう話でも有る。
- 148 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:20:52.90 ID:kS/o56L+.net]
- >>145
話が再帰してるから (ループをわざわざ再帰にしてみました!)
- 149 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 02:24:57.75 ID:NebXzry6.net]
- >>146
では、それを踏まえた上でどう思います?
- 150 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 03:17:20.09 ID:kS/o56L+.net]
- >>148
最初っからおんなじ 再帰は可読性悪いんで 使わずに済むなら使わない方がいい。
- 151 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 03:18:50.05 ID:WDxyRHha.net]
- あとどうしても必要な場合は
- 152 名前:、
内部に隠蔽して、再帰であると意識せずに また再帰のコードを見ずに、処理できるようにした方がいい。 [] - [ここ壊れてます]
- 153 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 03:30:05.42 ID:NebXzry6.net]
- >>149
いえ、そうではなく、二者択一で 再帰とループで、必要性が高いのはどっちだと思います? もちろん、高階関数や各種操作関数での置き換えを踏まえた上での話です 必要と思うならどういう場面なのかなと
- 154 名前:>>150 mailto:sage [2015/08/13(木) 03:31:16.05 ID:NebXzry6.net]
- 最後の行は削除忘れです
- 155 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 03:36:08.86 ID:WDxyRHha.net]
- >>151
お前バカじゃね? 足し算と掛け算どっちが必要かって 言ってるようにしか聞こえん。 適切なものを使えよ。
- 156 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 03:39:48.62 ID:WDxyRHha.net]
- そういや実務で再帰使う必要せいってねーな。
あっても隠蔽するから両手で数えられるほどしか無い。 片手でもいけるかもw
- 157 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 03:51:07.78 ID:NebXzry6.net]
- >>153
私はそこまで一般化はしてないですし、適材適所も否定してません それと必要性の比較も関係ありませんよ 例えばgoto文も適材適所ですが、必要性は低いと思ってます 再帰がループと同程度に必要と思うなら、そう言ってくれればいいです 違う場合に、その先の話がしたいだけなので
- 158 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 04:15:21.85 ID:NebXzry6.net]
- ループが本当に必要な部分というのを、議論してみたかったんですが
どうあっても再帰は不要といいつつ、ループが必要とは言わないんですね…
- 159 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 04:27:48.44 ID:WDxyRHha.net]
- >>155
実践では再帰はあまり使いません。 必要性の話をするのなら それが現実では?
- 160 名前:デフォルトの名無しさん [2015/08/13(木) 07:42:46.93 ID:GBQWWFg+.net]
- クイックソートもループで書くんですか?
- 161 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 07:48:57.17 ID:FXSompvo.net]
- アスペかよ
- 162 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 08:21:16.88 ID:Iax2S8IU.net]
- >>158
実用的なクイックソートはループ。 まさか再帰でしか実現できないなんて考えとるんか?
- 163 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 08:52:19.31 ID:GBQWWFg+.net]
- >>160
再帰より可読性の高い、ループでのクイックソートの実装は寡聞にして知りません。
- 164 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 09:30:01.18 ID:Iax2S8IU.net]
- ループ方式も可読性は高い。
特別なことはやらないから、誰でもすぐ実現できるはず。 Cどころか昔のVBのようなへぼ環境でも 何百万ものデータを高速にソートできてしまう。
- 165 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 09:53:04.16 ID:GBQWWFg+.net]
- 例えばこれ
https://github.com/lattera/glibc/blob/master/stdlib/qsort.c 本来の再帰アルゴリズムを、非再帰で記述するために状態を自前のスタックで管理しなきゃならない。 余計なコードが必要な分、可読性は低いですね。
- 166 名前:デフォルトの名無しさん [2015/08/13(木) 10:07:42.74 ID:Q4WJ33HH.net]
- >>163
FSF、Microsoft、そしてAppleが再帰を避けるのは何故か考えてみては。
- 167 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 10:10:35.79 ID:wsd38m6J.net]
- 再帰関数をスタック無視して設計するような馬鹿じゃなけりゃ、
どっちでもいいよ。 金太郎飴をループで切るか再帰で切るか、程度の話しかしてない みたいだしな。その関数がその構造のどこまでのデータを扱うのか ってことを意識してりゃ別にいい。 再帰でよその子をいじったりとかするのは馬鹿のやること。
- 168 名前:デフォルトの名無しさん [2015/08/13(木) 10:13:00.13 ID:1x08JE5T.net]
- 論点がずれてないか?
>>163は可読性について論じているのに
- 169 名前:デフォルトの名無しさん [2015/08/13(木) 10:27:03.54 ID:Q4WJ33HH.net]
- >>166
わざわざglibcのソース引っ張り出してるとこからして、本人も言いたいことが自分で分かっていないのでは? Cで再帰するコードを書けば、たいていのチェッカが警告するし、品質保証からお叱りを受けるはず。 やってはいけないことの一つとして、ほとんどの企業で明文化されているはずです。 そして良く知られるMISRA-Cも通りません。 こういう状況下で、glibcのソースを引用して再帰するべきと主張するのはおかしい。 glibcでも再帰は避けている、再帰するべきでないという主張になるのが当然だと思う。 そうなっていないという事は、本人が一番自分の主張をわかっていない。 と思うのです。
- 170 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 10:30:12.83 ID:NebXzry6.net]
- さすがにこれを可読性が高いとは言うのは無茶じゃないかと
- 171 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 10:30:37.05 ID:Iax2S8IU.net]
- 可読性が悪いかどうかじゃなく、
再帰の場合よりも良くなくてはいけないと? 理解困難なコードでなく実用性があるのなら採用するでしょ。 プログラマはソート処理のコードは使いまわして 比較関数を用意すればいいだけだし。
- 172 名前:デフォルトの名無しさん [2015/08/13(木) 10:32:46.72 ID:GBQWWFg+.net]
- >>167
可読性の話をしてるんですが?
- 173 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 10:38:27.46 ID:WDxyRHha.net]
- >>163
> 本来の再帰アルゴリズムを、非再帰で記述するために状態を自前のスタックで管理しなきゃならない。 だから適切なものを選べって言ってるじゃん。 誰が、再帰が適切なものまで、 ループにしろって言ったよ? ループで済むものを再帰でやるなって話。 ほんと>>42で書いた4の段階のやつだなお前は。
- 174 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 10:40:07.80 ID:WDxyRHha.net]
- >>169
> プログラマはソート処理のコードは使いまわして > 比較関数を用意すればいいだけだし。 そういう場合、そのソートは何に使われるかわからないから 往々にして、速度が一番早い方法を選ぶんだよね。 つまりループで実装。
- 175 名前:デフォルトの名無しさん mailto:sage [2015/08/13(木) 10:41:21.58 ID:A9RCljrX.net]
- ソースがコンパイラにどう最適化されて実行時にどう動かされるかを考えてると
可読性の基準が変わってくるでしょ 再帰で触感的に記述できるのは再帰構造持ったアルゴであって 本来行うべき実行じゃないから非直観的なんよ 可読性として表現したい対象がそもそも違うのよね
|

|