トップページtech
1001コメント338KB

関数型プログラミング言語Haskell Part28 [転載禁止]©5ch.io

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさん2015/04/09(木) 08:31:01.42ID:4yjREsCN
関数型プログラミング言語 Haskell について語るスレです。

         ,.-―: ̄`ー::::::::::、
       /::::::::::::.::::::::::::::::::::::::::::`::、、
      /::::::::::::::::::::::::::::::::::::::::::::::::::::::`、
      l::::::::::::::::::::::::::::::::::::::::;':l:::::::::::\::l
      l:::::::::::::::::::::::::::::::::,,::::::::;-,:,::::::::::::::::l
     l::::::::::::::::,_,.::::,';::::::;:::::: :: l ::::::::::::::l
     l::::::::::/-/:::/-ニ,.::::/=,./::::::::::l
     ヽ:::: ´、ひ> ;:  l .<ひ>'  、::::::::/
    ヽ:::::    ̄ .)::;  l  ̄   l::::/    < 毛の壁(岡部健)の話は禁止な
     、:::::..   /:::; .,-、     l:::/、
    ,―::::::::  ゝヽ- ー' 、    l::/,、ヽ
     l,、,、,,:、:: / ,--、,-.、_ l    /::::::,、,、l
   l,、,、,、,、,、::、 `ー ̄-'   /:::::::::::,、,、l
   l,、,、,、,、,、,、::ヽ      /::::::::、,、,、,、,ノ:\

haskell.org (公式サイト)
http://www.haskell.org/

前スレ
関数型プログラミング言語Haskell Part27
http://peace.2ch.net/test/read.cgi/tech/1420718555/
0809デフォルトの名無しさん2015/07/04(土) 10:25:08.25ID:8ixaKuBt
>>808
その「ので」が「今日は天気が良い『ので』どこかに出かけよう」ぐらいエエカゲンなんだよなあ
0810仲本だいすけ2015/07/04(土) 10:41:07.54ID:uNR/QH/o
                  ,.-―: ̄`ー::::::::::、
                /::::::::::::.::::::::::::::::::::::::::::`::、、
               /::::::::::::::::::::::::::::::::::::::::::::::::::::::`、
               l::::::::::::::::::::::::::::::::::::::::;':l:::::::::::\::l
               l:::::::::::::::::::::::::::::::::,,::::::::;-,:,::::::::::::::::l
              l::::::::::::::::,_,.::::,';::::::;:::::: :: l ::::::::::::::l
              l::::::::::/-/:::/-ニ,.::::/=,./::::::::::l
              ヽ:::: ´、ひ> ;:  l .<ひ>'  、::::::::/
             ヽ:::::    ̄ .)::;  l  ̄   l::::/
              、:::::..   /:::; .,-、     l:::/、
               ::::::::  ゝヽ- ー' 、     l::/,
                ,:、:: / ,--、,-.、_ l     /
    ,.:':'゙'゙'゙:゙'゙':';.        、::、 `ー ̄-'    /
   r゙ ,.: :;;;:: : : :           、::ヽ      /:
   | : ::::~';::--ー'ー-----ーー;;:'゙ .: :` ‐- 、  |
  ,i    ::::::::::::::::::::::::::::::: ::: :ヾ        i
  r'     ::::::::::::::::: : : :::::: :::::  ::::. .      /
  |      :::::::::: : : : : ::: ::  ::         イ
  i      : : ::::::::::: : : ::::::: :         |
  |      ,.;イ-- .,           ,... -' i
   i      ,.;':/   ゙'ー-.,_ i    ,.イ::  /
  .i::::   /:/        ̄i   / ゙i   |
  │::  ノ::/         |   i   |  |
 r':: イ:::::i゙            |  |   i   |
 |:: | ヽ '-.,         ヽ 〈    ヽ ヽ.,
 i, , '-, ゙'ー'ー'          ヽ、`,ー、  `'ー'ー'
0811デフォルトの名無しさん2015/07/04(土) 11:47:31.61ID:D//5Uocc
筒井康隆が新潮10月号(9/7発売)に最新長編『モナドの領域』330枚一挙掲載
0812デフォルトの名無しさん2015/07/04(土) 14:12:51.24ID:WvwJxr10
Haskell は門限が7時の女子大生を連想させるので絶対流行らん。
0813デフォルトの名無しさん2015/07/04(土) 16:46:21.33ID:rWY2qCze
Haskell 擬人化するなら眼鏡で想像するひと多そう。
0814デフォルトの名無しさん2015/07/05(日) 03:00:57.48ID:18u325sL
http://jbbs.shitaraba.net/bbs/read.cgi/study/2246/1279896594/534
  ↑  ↑  ↑  ↑  ↑
0815デフォルトの名無しさん2015/07/05(日) 03:18:53.53ID:5EFP5F9v
リンク先政治広告なのでみなくてよろし
0816デフォルトの名無しさん2015/07/05(日) 11:32:05.80ID:j/NgsVfb
長期的に考えるんだ
最初は眼鏡で途中から眼鏡を外せば流行ると考えるんだ
0817デフォルトの名無しさん2015/07/06(月) 00:22:13.25ID:wlw6otNx
使うメリットが無い。
デメリットは多いのに。
0818デフォルトの名無しさん2015/07/06(月) 04:07:14.46ID:W9Wle9it
毛を引き寄せてしまった程の黒魔術的魅力がHaskellにあるのだろう
0819デフォルトの名無しさん2015/07/06(月) 04:12:56.58ID:G+yljX6j
goよさそうだなと思って覚え始めたけど型定義が貧弱すぎてやる気大幅ダウン
Haskellは禁断の果実だった
0820デフォルトの名無しさん2015/07/06(月) 10:19:51.08ID:9VlVzieP
システムプログラミング言語ならhaskellやった人はgolangよりrust結構気に入るだろうと思う
代数的データ型、型クラス、型推論、immutableがデフォルト、パターンマッチ、
メモリリークをコンパイルエラーにする
と結構 ml likeな言語
0821デフォルトの名無しさん2015/07/06(月) 10:24:54.61ID:9VlVzieP
>>818
毛を引き寄せたのはhaskellじゃなくてjsだろ
0822デフォルトの名無しさん2015/07/06(月) 18:54:20.21ID:yIxlkBRi
痴呆症ブログ更新きたよ!

749 名無しさん@ゴーゴーゴーゴー! 2015/07/06(月) 14:17:10.21 ID:IaVh3M450
http://kenokabe-techwriting.blogspot.jp/2015/07/javascript.html

おかえり!入院しろ!
0823デフォルトの名無しさん2015/07/06(月) 21:10:08.11ID:EN2KuOqG
>>820 いいことを聞いた、ちょっと触ってみようかな
0824デフォルトの名無しさん2015/07/06(月) 21:43:24.49ID:G+yljX6j
普及してる言語の中でミスが起きないよう設計されてるやつが欲しくてさ
Rustは人口少ないしScalaよりさらに関数型で安全そうだけどじゃあHaskellでいいじゃんってなる
0825デフォルトの名無しさん2015/07/06(月) 22:13:00.63ID:pYzRJ5bG
elixirとか
0826デフォルトの名無しさん2015/07/06(月) 22:38:54.30ID:/jetTYu7
末尾呼び出しが使えないとやる気が出ないね
ループでしか書けないからね
0827デフォルトの名無しさん2015/07/06(月) 23:08:12.61ID:G+yljX6j
静的型
直和型
再帰型
抽象型
独自(ドメイン固有)型
型推論
ダブルディスパッチ
高階関数
map/filter/fold
末尾再帰最適化

オブジェクト指向でもこれくらいサポートしてほしい
0828デフォルトの名無しさん2015/07/06(月) 23:11:36.25ID:8//4HfJE
相変わらず岡部健の記事は狂ってて面白い
0829デフォルトの名無しさん2015/07/06(月) 23:28:12.05ID:IO/OfGDx
>>824
rustは日本人ユーザが少ないだけでコミュニティは盛り上がってる
0830デフォルトの名無しさん2015/07/07(火) 00:34:34.08ID:/AiLg+DV
岡部が他人のコードを勝手に、不完全に書き換えて実行して
その結果を叩いてるぞ
0831デフォルトの名無しさん2015/07/07(火) 01:15:52.91ID:6n40dgbK
岡部の記事だけを読むと、説得されかけるのは疲れているからだろうか?
0832デフォルトの名無しさん2015/07/07(火) 01:30:24.54ID:0l2OmbIX
>>824
rustはc,c++と同じ低レベルプログラミング言語だから
haskell、scalaとは被らないよ
0833デフォルトの名無しさん2015/07/07(火) 01:44:46.81ID:5T5xC6ja
「ミスが起きない」の意味が違うんだよな。
HaskellとRustでは型に意図された機能がぜんぜん違う。
0834デフォルトの名無しさん2015/07/07(火) 04:38:19.84ID:wEQ5fYPF
>>833
どういう部分が?
所有権という概念が入るだけで、型付けは結構強めだと思うが
0835デフォルトの名無しさん2015/07/07(火) 05:07:24.51ID:wEQ5fYPF
>>831
洗脳…ですかね
0836デフォルトの名無しさん2015/07/07(火) 08:27:24.02ID:5T5xC6ja
>>834
Rustは高階カインドやGADT使えないでしょ。モナドすらない。
だけど線形型は使えて(所有権)、要するに基本のHindley-Milner systemからの
強化方向とその背景にある思想が全然違う。

データの構造に対する表現力を求めるのとリソース管理を求めるのと。
なおどっちも突っ込むと人智を超え始めるのはATSを見ればお分かりの通り。
0837デフォルトの名無しさん2015/07/07(火) 08:30:37.69ID:6KFd5cV4
Rustは低レベルな世界に関数型の表現力と安全性を持ち込もうとしている言語。
最初はOCamlで開発されていたからか、letとかOptionとかML系の匂いはする。

ただし簡潔さよりもゼロオーバーヘッドを優先しているから、冗長な表記が多々含まれる。
あと型推論は関数定義内だけに適用されるから、エラーメッセージが見当外れの場所を指さない一方、
borrow checkerのエラーはすごく把握しづらい。impl書いている時は特に。
自分がいかにGCに依存し、リソース管理を怠っていたかをこれでもかという程思い知らせてくる言語。
0838デフォルトの名無しさん2015/07/07(火) 08:31:10.23ID:bP16dll8
Rustなんて放り投げてATSやろうぜ!
0839デフォルトの名無しさん2015/07/07(火) 11:38:06.78ID:ZG49EUnh
これが超えちゃいけないラインってやつか
トランポリンとかモナドとかよりもっと抽象度高い系の片鱗を味わったぜ
0840デフォルトの名無しさん2015/07/07(火) 12:46:53.46ID:KLvjH7rL
岡部健・・・・・・。
0841デフォルトの名無しさん2015/07/07(火) 15:14:42.99ID:kS7BAnfS
>>838
岡部究(master_q)さん、暇なんですか?
0842デフォルトの名無しさん2015/07/07(火) 15:31:19.79ID:AZjd+yQY
ParsecとTrifectaってどう違うの?
0843デフォルトの名無しさん2015/07/07(火) 15:36:54.07ID:kS7BAnfS
>>842
Parsec の改良実装が Trifecta だそうです(TwitterのTL調べ)
0844デフォルトの名無しさん2015/07/07(火) 16:41:16.20ID:kvoehb1f
まさかUCLA卒の情報技術者を自称する岡部が、
メモリを食いつぶしてることの裏を取ってないわけねーだろ。
これには何か事情があるんだろう。
0845デフォルトの名無しさん2015/07/07(火) 16:44:08.49ID:kvoehb1f
まとめ:
岡部「破壊的代入を使わないクリックカウンターやお絵かきロジック(マウスのドラッグ)はFRP(自称)でなければ書けない」
→OCamlでもHaskellでも瞬殺
→岡部「再帰でメモリリーク(※スタックオーバーフローの意)する」
→末尾再帰なのでスタックオーバーフローしないし、実際のメモリ消費量も増えていない。
 岡部の示した「証拠画面」はメモリ不足ではなくプロセスを強制終了しただけ。
0846デフォルトの名無しさん2015/07/07(火) 16:57:06.07ID:AzQt5h10
マジで末尾再帰の最適化を知らなかったのか、kenokabe独自定義で違う意味なのか、どっちなんだ?
前者だとちょっとガッカリ…
0847デフォルトの名無しさん2015/07/07(火) 17:57:25.43ID:T57Vd7z3
メモリリークはバズワードであってだね・・・・
0848デフォルトの名無しさん2015/07/07(火) 18:14:46.72ID:50EUtPEU
kenokabeさんはもう許されていいとおもう
0849デフォルトの名無しさん2015/07/07(火) 18:17:56.32ID:Ra6qpxUV
Haskellは強制されても習得できない難しい言語だからこそ非人道的事案は少ない
それに比べて関数型という安易な言葉に苦しめられる人は多い
0850デフォルトの名無しさん2015/07/07(火) 20:57:42.46ID:strljqHr
どこかのスレでツリートラバースするのに再帰を使うのは良くないマナーと書いたら、
末尾再帰と言われたのだが。
0851デフォルトの名無しさん2015/07/08(水) 00:23:41.84ID:D8OEoYJf
>> 850
なぜ良くないの?
0852デフォルトの名無しさん2015/07/08(水) 00:43:21.45ID:lu3S4Qgm
>>>845
OCaml版はloop_at_exit使ってるのがダメと指摘されますた><
Graphics.wait_next_eventかGraphics_js.loop使ってください
0853デフォルトの名無しさん2015/07/08(水) 01:57:29.30ID:T1Ir4r2m
>>845
末尾再帰はあのコード例では関係なくて、イベントハンドラを経由したtrampolineになってるのでスタックオーバーフローしない、が正しそう。
0854デフォルトの名無しさん2015/07/08(水) 03:26:31.55ID:gcJIUX06
>>851
末尾再帰の最適化がかからない言語は使うべきではないともレスがあったな。
0855デフォルトの名無しさん2015/07/08(水) 05:37:16.57ID:D8OEoYJf
>> 854
よく分かりませんが、ところで、あなたにレスを見て気になって、調べて初めて知りました。
Haskellって末尾再帰の最適化って無いんだね。
ずっと勘違いしてた。気付かせてくれてありがとう。
0856デフォルトの名無しさん2015/07/08(水) 06:38:51.11ID:k4MH4D3R
>>855
>Haskellって末尾再帰の最適化って無いんだね

TCOが無いんじゃなくて、あくまでサンクの問題。
0857デフォルトの名無しさん2015/07/08(水) 07:15:31.29ID:asOwE27P
parsecとtrifectaは比較するようなものじゃないよ
0858デフォルトの名無しさん2015/07/08(水) 08:22:34.09ID:SmYj13jC
>>857
kwsk
0859デフォルトの名無しさん2015/07/08(水) 08:29:06.72ID:gcJIUX06
>>855
そもそも最適化が無い言語とはC言語のことで、Cは使うなHaskellを使えと言う話だったのだが。
0860デフォルトの名無しさん2015/07/08(水) 08:53:04.13ID:Hcg+sLDh
Haskellでサンクをインライン展開する最適化ってできるんじゃねえの
サンクが末尾にあったらTCOと同じだろ
0861デフォルトの名無しさん2015/07/08(水) 09:03:37.61ID:k4MH4D3R
>>860
できる。ghcなら-O2つければいい。
0862デフォルトの名無しさん2015/07/08(水) 09:44:23.49ID:gcJIUX06
そもそも、Cの関数呼び出しはアドレスを指定してジャンプ、ループは
オフセットを指定してジャンプ程度の違いしかないので、インストラクションに
関しては大して違いが無いのだが。

どうもハスケラーは関係ないことを指摘して、「だから◯◯はダメだ」と言い出す
傾向が強い。
0863デフォルトの名無しさん2015/07/08(水) 10:56:59.54ID:k4MH4D3R
そりゃTCO効いた後なら違いは殆どなくなるにきまってる。
0864デフォルトの名無しさん2015/07/08(水) 11:02:57.48ID:Mh0VppoT
「そもそも、Cの関数呼び出しはアドレスを指定してジャンプ、ループは
オフセットを指定してジャンプ程度の違いしかないので」

はあ???
0865デフォルトの名無しさん2015/07/08(水) 11:10:43.42ID:+0ZOrsx3
>>863
「TCO効いた後なら」同じだが、>>862 は「Cの関数呼び出し」と言ってるから
Cも関数呼び出しもまったくわかってない。プログラムわからないんだったら出てくんな。
0866デフォルトの名無しさん2015/07/08(水) 11:28:35.90ID:k4MH4D3R
>>865
まさかスタック積むことすらわかってないとかなんかね?
0867デフォルトの名無しさん2015/07/08(水) 15:11:37.94ID:TEEbED7E
久しぶりにきたら荒れてるな

Haskellは破壊的代入をしようとすると面倒なのがつらい。

巨大な1次元配列の任意の場所を参照しながら大量に書き換える処理とか
純粋性を保ったままやろうとすると凄いことになる。
*例えば画像データの一部に別の画像をmixするとか
0868デフォルトの名無しさん2015/07/08(水) 16:24:24.26ID:Eo9ZYfU/
>>866
スタックに引数、戻り値と積んでからジャンプするんだから、アドレスを渡す
関数ならスタックは積む必要が無い。
再帰してるんだから。

ハスケラはどうも自分は天才で自分以外は全員馬鹿と思い込む傾向がある。
0869デフォルトの名無しさん2015/07/08(水) 16:25:04.00ID:Fj3AV/LF
相変わらず殺伐としている。
いつものマウンティング合戦。
0870デフォルトの名無しさん2015/07/08(水) 16:26:57.55ID:Fj3AV/LF
多分、ハスケラではなくオカマラーだよ。
なぜかオカマちゃんが出没するのだ。
0871デフォルトの名無しさん2015/07/08(水) 16:51:49.63ID:TEEbED7E
ハスケラと一緒に仕事したい(自社製品を一緒につくりたい)けど
怖い人多そうで誘いづらい
0872デフォルトの名無しさん2015/07/08(水) 17:09:26.71ID:F0vddBGo
「Cも関数呼び出しもまったくわかってない。プログラムわからないんだったら出てくんな。」
「まさかスタック積むことすらわかってないとかなんかね? 」

毎日こんなこと言われると思う。
0873デフォルトの名無しさん2015/07/08(水) 17:22:12.92ID:TEEbED7E
なにそれ怖い
製品完成する前に心折られそう
0874デフォルトの名無しさん2015/07/08(水) 17:24:08.22ID:g9xxt+x4
「そもそも、Cの関数呼び出しはアドレスを指定してジャンプ、ループはオフセットを指定してジャンプ程度の違いしかないので」 とか
「スタックに引数、戻り値と積んでからジャンプするんだから、アドレスを渡す関数ならスタックは積む必要が無い。再帰してるんだから。」とか
(しかもTCOの話をしてるのに)、本当にCも関数呼び出しもわかってない知ったかぶりがHaskellerを中傷してるだけ。
それ以上でもそれ以下でもない。
0875デフォルトの名無しさん2015/07/08(水) 17:29:09.36ID:TEEbED7E
穏やかなハスケラいないかな
簡単なプログラムができる程度の初心者でもいいんだけど

一緒に自社製品つくりたい
(ただし売上あるまで一緒に無給)
0876デフォルトの名無しさん2015/07/08(水) 17:33:01.82ID:3bDYKzqv
>>874
どうもハスケラーは関係ないことを指摘して、「だから◯◯はダメだ」と言い出す
傾向が強い。
0877デフォルトの名無しさん2015/07/08(水) 17:34:43.10ID:3bDYKzqv
最後には「Javaの話ししてるのにJavascriptと勘違いしている」などと言い出しそうだな。
0878デフォルトの名無しさん2015/07/08(水) 17:37:24.50ID:ikFma15C
わかってないから馬鹿にされてるんじゃなくて、
わかってないのに自覚せず威張ってるから馬鹿にされてるんだが…。
そういう奴がいて、間違いを指摘すると逆ギレされる職場とか絶対嫌。
0879デフォルトの名無しさん2015/07/08(水) 17:39:55.04ID:coR9sNH7
末尾呼び出し最適化は再帰だけじゃないよ
0880デフォルトの名無しさん2015/07/08(水) 17:46:11.37ID:TEEbED7E
馬鹿にするのも逆ギレもよくないとおもう

そしてこのスレが荒れるのも彼の呪いじゃないかとおもう
もうそっとしておくのが一番いいとおもう
0881デフォルトの名無しさん2015/07/08(水) 17:48:42.74ID:3bDYKzqv
「Cは再帰の最適化が無いから使うべきではない、Haskell使え」と言う話に、
Cは再帰の最適化が必要ないのに何言ってんの?と答えた。
0882デフォルトの名無しさん2015/07/08(水) 17:54:30.07ID:3bDYKzqv
Haskellの最適化って他の言語では必要ないものでしょ。

「遅延呼び出しによって必要のない計算を無くせるスゴイ!」
他の言語では最初から必要ない計算はしないからそんな最適化は必要ない。

自らゴミを持ち込んで
「ゴミを減らせたスゴイ!Cはゴミを減らせないから使うべきでない!」
とか言い出すのがハスケラー。
0883デフォルトの名無しさん2015/07/08(水) 17:54:46.50ID:jdKxxZpi
いろいろと誤解している気がする
0884デフォルトの名無しさん2015/07/08(水) 18:02:40.05ID:7bDc6WAX
まず、末尾再帰をループに変換する最適化は、CでもHaskellでも可能で、実際にGCCでもやってる。

それはさておき、Cではループを末尾再帰で書いたりしないから、そんな最適化はいらない、という意見もそれはそれでわかる。
末尾再帰使わないのに、末尾再帰最適化がないからダメ、なんて言ってる奴がいたらそいつがおかしいので具体的ソース希望。
0885デフォルトの名無しさん2015/07/08(水) 18:11:09.96ID:LC6Y88mm
必死に藁人形作ってるだけだから構ったら駄目だよ
末尾再帰最適化を知ってて制御構文を知らないなんて
そんな支離滅裂な馬鹿を前提としてる時点で察しろと
0886デフォルトの名無しさん2015/07/08(水) 18:13:26.90ID:7bDc6WAX
で、CでもHaskellでも、末尾呼び出し最適化されていない普通の関数呼び出しは、
戻り番地や、まだ使う変数をセーブしておくためにスタックを消費する。
(引数渡しにスタックを使うこともあるけど、そうでなくても)

(再帰でも、再帰でなくても)末尾呼び出しの場合、そのセーブが不要なので、
ただのジャンプ(と引数のセット)だけに最適化できる。
この最適化は関数型言語の処理系では普通は実装されている。
Cでも全くできないことはないと思うが、いろいろ面倒そうなので
やってるコンパイラは寡聞にして知らない。
0887デフォルトの名無しさん2015/07/08(水) 18:14:38.28ID:3bDYKzqv
>>884
変換する最適化という言い方が、ハスケラーっぽいなあ。
Cは積む必要のないものは積まないんだから。
スタックに何も積まなければループも関数呼び出しも大した違いは無い。

そういうわけでこれからは、最適化しないと使い物にならないHaskellと考えていただこう。
0888デフォルトの名無しさん2015/07/08(水) 18:14:42.05ID:7bDc6WAX
>>885 スマソ。何となくちゃんと説明しないと俺の気が済まなかった。
0889デフォルトの名無しさん2015/07/08(水) 18:17:33.59ID:7bDc6WAX
(末尾呼び出し最適化されていない)関数呼び出しでスタックに積むものはCでもHaskellでも同じ。
戻り番地と、生きている変数と、レジスタに入りきらない引数。
0890デフォルトの名無しさん2015/07/08(水) 18:27:23.28ID:Fj3AV/LF
マウンティングする奴は、マウンティングすることが目的だから、生産性は
低い。学者さんに多いタイプ。アカハラ怖い。
0891デフォルトの名無しさん2015/07/08(水) 18:27:27.64ID:LC6Y88mm
>>887
????
Cもfastcallじゃない限り戻りアドレス積むよ
0892デフォルトの名無しさん2015/07/08(水) 18:28:15.90ID:LC6Y88mm
しまった同じやつだった…
0893デフォルトの名無しさん2015/07/08(水) 18:39:15.89ID:2M74HMLS
馬鹿とは議論するな。傍目にはどちらが馬鹿か判りにくい
0894デフォルトの名無しさん2015/07/08(水) 18:50:26.80ID:7bDc6WAX
本当に混乱してる人もいるかもしれないし、説明のまとめだけ…

884 :デフォルトの名無しさん:2015/07/08(水) 18:02:40.05 ID:7bDc6WAX
まず、末尾再帰をループに変換する最適化は、CでもHaskellでも可能で、実際にGCCでもやってる。

それはさておき、Cではループを末尾再帰で書いたりしないから、そんな最適化はいらない、という意見もそれはそれでわかる。
末尾再帰使わないのに、末尾再帰最適化がないからダメ、なんて言ってる奴がいたらそいつがおかしいので具体的ソース希望。

886 :デフォルトの名無しさん:2015/07/08(水) 18:13:26.90 ID:7bDc6WAX
で、CでもHaskellでも、末尾呼び出し最適化されていない普通の関数呼び出しは、
戻り番地や、まだ使う変数をセーブしておくためにスタックを消費する。
(引数渡しにスタックを使うこともあるけど、そうでなくても)

(再帰でも、再帰でなくても)末尾呼び出しの場合、そのセーブが不要なので、
ただのジャンプ(と引数のセット)だけに最適化できる。
この最適化は関数型言語の処理系では普通は実装されている。
Cでも全くできないことはないと思うが、いろいろ面倒そうなので
やってるコンパイラは寡聞にして知らない。

889 :デフォルトの名無しさん:2015/07/08(水) 18:17:33.59 ID:7bDc6WAX
(末尾呼び出し最適化されていない)関数呼び出しでスタックに積むものはCでもHaskellでも同じ。
戻り番地と、生きている変数と、レジスタに入りきらない引数。 👀
Rock54: Caution(BBR-MD5:405b7f1af0f5a85b432d79fa769e9aeb)
0895デフォルトの名無しさん2015/07/08(水) 19:00:46.58ID:Hcg+sLDh
ループを無くす理由の一つはnullを無くしたかったから

nullは不要 → 初期化と代入の区別が必要 → 面倒だから代入も不要 → ループも不要
0896デフォルトの名無しさん2015/07/08(水) 19:03:01.21ID:7bDc6WAX
じゃあ、そもそもなんでループをわざわざ末尾再帰で書くの?という疑問は当然だけど、
ループで書くと破壊的代入が必要になるから、関数的に書くと自然に末尾再帰になる。

なので関数型プログラミングをするなら末尾再帰最適化は必須だし、
実際に(再帰以外の末尾呼び出しの最適化も)まともな処理系はみんな実装してる。
関数型言語では必須かつ簡単な最適化なので。
0897デフォルトの名無しさん2015/07/08(水) 19:04:06.48ID:7bDc6WAX
>>895 すまん前後した
0898デフォルトの名無しさん2015/07/08(水) 20:23:51.51ID:oVqSZ92L
>>886
vcは引数が全く同じ関数の末尾呼び出しをgotoにするよ。
0899デフォルトの名無しさん2015/07/08(水) 20:46:18.84ID:7bDc6WAX
>>898 「引数が全く同じ」ってことは、末尾再帰だよね?
末尾再帰は>>884にあるとおりGCCも(引数が違っても)最適化してる。
>>886は再帰以外の末尾呼び出しの話だった。
一続きだったんだが、独立して読むと明示されてないね。
>>894でまとめて読んでくれ。すまん。
0900デフォルトの名無しさん2015/07/08(水) 22:36:48.90ID:oVqSZ92L
>>899
いいや、tail callだよ。
0901デフォルトの名無しさん2015/07/08(水) 22:53:06.86ID:TEEbED7E
VSにHaskell用プラグインを組み込むプロジェクト進んでるのかな?

マジで早く使いたいんだけど
0902デフォルトの名無しさん2015/07/08(水) 23:02:56.60ID:zrPw7vNx
ここまでを簡単に解説すると、ハスケラはシッタカブラー。
0903デフォルトの名無しさん2015/07/08(水) 23:32:53.31ID:oVqSZ92L
>>899
ほらよ。

int foo(char *, int);
int bar(char *a, int b)
{
return foo(a + 10, b - 10);
}

_bar PROC ; COMDAT
mov eax, DWORD PTR _b$[esp-4]
add eax, -10 ; fffffff6H
mov DWORD PTR _b$[esp-4], eax
add DWORD PTR _a$[esp-4], 10 ; 0000000aH
jmp _foo
09048992015/07/09(木) 05:48:11.05ID:KPxfvpRW
>>903 おお! 「引数が全く同じ」って、値じゃなくて、数や型が同じってことね。サンクス。

逆に、なんで引数の数や型が同じじゃないといけないの? スタックポインタの調整が面倒だから?
09058992015/07/09(木) 05:57:34.42ID:KPxfvpRW
いつのまにかGCCも末尾再帰じゃない末尾呼び出し最適化もやってた。引数の数や型が違っても。
Cでも需要があるのかな。

extern int foo(int);
int bar(char *a)
{
return foo(10);
}

bar:
.LFB0:
.cfi_startproc
movl $10, %edi
jmp foo
.cfi_endproc
09068992015/07/09(木) 06:13:19.89ID:KPxfvpRW
http://www.drdobbs.com/tackling-c-tail-calls/184401756
にGCCがTCOする条件が解説されてた。Cだとややこしいけど需要はあるらしい。
連投&スレ違い失礼しますた。
0907デフォルトの名無しさん2015/07/09(木) 06:35:27.16ID:OEKsJpEx
>>904
>「引数が全く同じ」って、値じゃなくて、数や型が同じってことね。サンクス。
再帰で値が同じならそれは無限再帰と呼ばれる。

>逆に、なんで引数の数や型が同じじゃないといけないの? スタックポインタの調整が面倒だから?
引数の個数はcalleeではわからないから、面倒ではなく、出来ない。
0908デフォルトの名無しさん2015/07/09(木) 08:19:53.49ID:e+1UNYHr
>>907
>再帰で値が同じならそれは無限再帰と呼ばれる。
Cだと副作用でメモリの中身が変わってるかもしれない

>引数の個数はcalleeではわからないから、面倒ではなく、出来ない。
Cだと同じ関数の型の見え方がcallerとcalleeで違ったりするからね。
>>906みたく条件緩和できるがなかなかややこしい
レス数が900を超えています。1000を超えると表示できなくなるよ。