関数型プログラミング言語Haskell Part9
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/05/17(土) 16:41:29http://www.haskell.org/
日本語サイト
http://www.sampou.org/cgi-bin/haskell.cgi
http://www.shido.info/hs/
過去ログ
関数型プログラミング言語Haskell
Part1 http://pc.2ch.net/tech/kako/996/996131288.html
Part2 http://pc2.2ch.net/test/read.cgi/tech/1013846140/
Part3 http://pc8.2ch.net/test/read.cgi/tech/1076418993/
Part4 http://pc8.2ch.net/test/read.cgi/tech/1140717775/
Part5 http://pc8.2ch.net/test/read.cgi/tech/1149263630/
Part6 http://pc11.2ch.net/test/read.cgi/tech/1162902266/
Part7 http://pc11.2ch.net/test/read.cgi/tech/1174211797/
Part8 http://pc11.2ch.net/test/read.cgi/tech/1193743693/
・2chの仕様により、行頭の半角スペースは表示されません。
コードをインデントしたいときは、代わりに または全角スペースを使うことができます。
0577デフォルトの名無しさん
2008/08/22(金) 22:12:26「記号」と言われてもいまいちピンと来ないんだが、何にせよ、
普通の手続き型言語が「記号」を処理するのと大差ない方法で処理してると思う
取り得る種類がコンパイル時に決まっているなら列挙型
そうでないなら整数とか文字列
文字列の比較のコストが問題になるなら自分でシンボルテーブルのようなものを用意する、とか
0578デフォルトの名無しさん
2008/08/22(金) 22:34:03>>310-314
0579デフォルトの名無しさん
2008/08/23(土) 09:45:26Prologでも、
1レコード512バイトをsub_atomで30項目に分解したり、更にsplitの
処理をしたりすると確かにアトムが大量発生するだろうが、
Stringとして読み込んで、終始String処理に徹すれば、アルファベットの
数、つまり高々数万のアトムで済むんじゃないの?
Stringすなわちリスト処理になると遅いから嫌なのかな。
0580デフォルトの名無しさん
2008/08/23(土) 10:00:27資源が十分にあると理屈では分かっていても、終わったら電源切っても大丈夫な処理じゃないと拒否反応がでる。
0581デフォルトの名無しさん
2008/08/23(土) 10:09:14処理速度もあるかも知れませんが、アトムだと、
foo([株式会社|R],R).
と書けるところが、Stringだと
foo(List,R) :- append("株式会社",R,List).
と書かなくてはならないということがあります。
appendを高速化する機構が欲しくなりますね。
0582デフォルトの名無しさん
2008/08/23(土) 10:35:10data Atom = Kabushiki | Dummy deriving (Show, Eq)
foo :: [Atom] -> [Atom]
foo (Kabushiki : r) = r
0583デフォルトの名無しさん
2008/08/23(土) 11:43:27http://pc11.2ch.net/test/read.cgi/tech/1193354806/
0584デフォルトの名無しさん
2008/08/23(土) 12:43:04この話おかしいよ。
foo([株式会社|R],R). の方は、
すでに株式会社というアトムが切り出されていて、リストの構成要素になっている。
一方、
foo(List,R) :- append("株式会社",R,List). のListはString。ここは、
foo(["株式会社"|R],R).
でなきゃ、フェアじゃない。
0585デフォルトの名無しさん
2008/08/23(土) 13:58:45> Prologを事務処理に使うと、住所や氏名情報などで爆発的にアトムが発生し
第五世代コンピュータプロジェクトの成果を是非参照下さい。
0587デフォルトの名無しさん
2008/08/23(土) 14:21:10058836 ◆K0BqlCB3.k
2008/08/23(土) 14:28:53それは短絡的な人たちの根拠のないうわさ。
第五は基礎研究なので企業の人たちが求めるような成果が出ないのは当たり前のこと。
0589デフォルトの名無しさん
2008/08/23(土) 14:31:33んで問題点を整理してまたいらっしゃい
059036 ◆K0BqlCB3.k
2008/08/23(土) 14:33:31述語論理による仕様記述を使った鉄道のプロジェクトが企業側で行われた例があったような。
なんだったっけ?
0591デフォルトの名無しさん
2008/08/23(土) 14:45:22開発する場合、何か問題になる点はないのか。
0592デフォルトの名無しさん
2008/08/23(土) 14:54:20必要なメモリサイズを予測しにくい点とか。full lazyな処理系全般に言えると思うけど。
0593デフォルトの名無しさん
2008/08/23(土) 14:57:02いいじゃん、Javaでつくるのが流行ならJavaで作らせれば。
どうせ枯れたシステムなんだから。
0594デフォルトの名無しさん
2008/08/23(土) 15:00:18full lazyな処理系って、よくわからない。
059536 ◆K0BqlCB3.k
2008/08/23(土) 15:11:430596デフォルトの名無しさん
2008/08/23(土) 15:17:460597デフォルトの名無しさん
2008/08/23(土) 15:26:42COBOLなんかは確定してると思うけど。
0598デフォルトの名無しさん
2008/08/23(土) 15:42:16してない。
SORTなどに内部的に使う記憶容量が不明。
0599デフォルトの名無しさん
2008/08/23(土) 15:43:11計算をできるかぎり遅延させようとするから、
下手な書き方するとすぐメモリリークする
Haskellのメモリリークは大抵の場合小規模な修正で直るけど、
どこを修正すべきか探すのに慣れとプロファイラが要る
>>596
GHC付属のプロファイラは優秀だと思う
060036 ◆K0BqlCB3.k
2008/08/23(土) 15:47:59profオプションをつけてコンパイルしたらランタイムシステムにプロファイラが組み込まれるよ。
詳しくはマニュアルで。
0601デフォルトの名無しさん
2008/08/23(土) 16:19:23ん?確定はしてなくても最大どれかけかかるかは確定してるでしょ。
グラフ簡約のヒープ消費は予測もつかんぞ。
0602デフォルトの名無しさん
2008/08/23(土) 16:27:11確定してるのかしてないのかどっちだw
0603初心者修業中
2008/08/23(土) 16:37:52ガベージコレクションにバグがない限り、
メモリーリークが起きるとは思えないのですが…。
FFIを使った場合の事でしょうか…。
0604デフォルトの名無しさん
2008/08/23(土) 17:15:44http://d.hatena.ne.jp/desumasu/20060909/1157800884
この場合のメモリーリークは単なるメモリの解放忘れって事ではなくて、
期待した解放タイミングと実際のそれとのギャップの事みたいだね。
0605初心者修業中
2008/08/23(土) 17:42:49*Main> foldr (+) 0 [0..1000000]
*** Exception: stack overflow
0606デフォルトの名無しさん
2008/08/23(土) 18:05:58しちゃってる、というのをリークに含めることもある。
0607デフォルトの名無しさん
2008/08/23(土) 18:34:57それは「マヌケ」と呼びます。
0608初心者修業中
2008/08/23(土) 18:57:56簡単にわかる場合は「マヌケ」
ちょっとわかりづらい場合は「メモリーリーク」
と呼ぶという認識でよろしいでしょうか?
0609デフォルトの名無しさん
2008/08/23(土) 19:14:20GCのある言語だと、>>606しか起こり得ない。
>>605の「溢れ」とは全然違う。
0610デフォルトの名無しさん
2008/08/23(土) 19:20:46それはスタックオーバフロの例外であって、エラーとは違う。
メモリリークしているわけではないよ。
0611デフォルトの名無しさん
2008/08/23(土) 19:22:12Haskellみたいに強い静的型付けされている言語にはメモリリークなんてありえないよー
0612デフォルトの名無しさん
2008/08/23(土) 19:26:56現象として全然違うと言う事ですね。
分かります。
0613デフォルトの名無しさん
2008/08/23(土) 19:53:14良く言われる「メモリーリーク」とは違う現象だな。
Haskellの場合、遅延評価がデフォーなので
うかつに再帰を使うと計算の途中結果が膨大な
ものになってヒープ領域が溢れてしまう。
Cの場合はただの確保したメモリの解放し忘れ。
Cでも再帰的なメモリー確保をすれば
Haskellみたいな事も起きうるはずだが。
0614デフォルトの名無しさん
2008/08/23(土) 20:06:48強い静的型付けとメモリーリークの有無はほとんど関係がありません。
GCの方がずっと関係が深いです。
0615デフォルトの名無しさん
2008/08/23(土) 20:09:24あれ考えれば分かるよな。
強い型付けでも簡単にメモリーリークは起きる。
0616デフォルトの名無しさん
2008/08/23(土) 20:56:45Data.List.foldl' 使えばいいんだけど。
0617デフォルトの名無しさん
2008/08/23(土) 21:35:430618デフォルトの名無しさん
2008/08/23(土) 21:48:31末尾再帰は最適化されるよ
0619初心者修業中
2008/08/23(土) 23:53:01遅延評価だからと認識しています。
↓参考
http://haskell.g.hatena.ne.jp/jmk/20060710/1152516465
0620617
2008/08/24(日) 00:40:37なるほど、非常によくわかりました。
(つーか前出のリンク読まずにレスして申し訳ない)
うーむ、しかし末尾再帰が最適化されることの旨みは、
・ローカルスコープの値をスタックに積む必要がなくなることと
・連続するreturnが省略されること
の2点だと思うけど、foldl のように結局は遅延評価のための
computation がスタックに積まれていて、後から順次簡約するなら
「最適化されている」とは言い難い気もするな・・・。
最適化するための然るべき変形は、一応してあるんだろうけど。
まあ seq 使うとか、回避の仕方がないわけじゃないからいいのかな?
0621デフォルトの名無しさん
2008/08/24(日) 00:54:46http://itpro.nikkeibp.co.jp/article/COLUMN/20070403/267180/?P=2
0622デフォルトの名無しさん
2008/08/24(日) 13:10:00VIP発でサイトを作ろうと思うんだ。(詳しくはWikiを見てくれ)
パートスレになるんでパー速(GEP)に移動している。
今スタッフを募集しているから、来てくれないか?
■Wiki
http://www36.atwiki.jp/vipvipschool/
■募集スタッフ
プログラム担当(特にErlang、Perl)
デザイナー(サイト上のアイコン、ロゴなど)
WEBデザイナー(サイトデザイン案に沿って、htmlやCSSを書ける)
他にも宣伝担当なども募集している。
■スレ
http://ex14.vip2ch.com/test/read.cgi/news4gep/1219068297/
0623デフォルトの名無しさん
2008/08/24(日) 16:41:26実用性でいうとやっぱErlangなのかな…
0624デフォルトの名無しさん
2008/08/24(日) 18:20:21大規模なWebサービスを構築するのに向いていると
考えたから企画者がErlangを採用したんだろうね。
0625デフォルトの名無しさん
2008/08/25(月) 09:10:25実情は単にDBのテーブルが大きいだけだったりするよな。
そもそもウェブアプリでDB以外どこが肥大化するよ?
0626デフォルトの名無しさん
2008/08/25(月) 09:11:280627デフォルトの名無しさん
2008/08/25(月) 09:20:29複数のwebサービスから情報集めたり、もしくはhttp以外のプロトコルで通信して情報を取得しなきゃいけなかったり、
別プロセスで並列キューに入れて処理しなきゃいけなかったり、システムそのものが大きくなるとこはあると思う。
それともデータサイズの規模に限定した話?
0628デフォルトの名無しさん
2008/08/25(月) 09:53:32とりあえずErlang + YAWSの事例くらいは、
念頭においてくれないと、話にならないのでは?
0629デフォルトの名無しさん
2008/08/25(月) 09:55:11> 複数のwebサービスから情報集めたり、
そういうのはAjaxでクライアント側がやるのが流行では?
まあサーバ側がやってもいいですが、HTTPセッションを入れ子にするのは
あまり筋がいい設計とは思えません。
> もしくはhttp以外のプロトコルで通信して情報を取得しなきゃいけなかったり、
まあDB接続なんかもそうですよね。
しかし「大規模になる」ような要因とはあまり考えられないのですが。
> 別プロセスで並列キューに入れて処理しなきゃいけなかったり、
fastcgiとかの話でしょうか?特段、だから大規模になるというものではないと思いますが。
> それともデータサイズの規模に限定した話?
コード自体はほとんどCMS系フレームワークをユーザ定義コンテナを定義する程度で
用が済むことが多いと思います。特に、>>622のような、いかにもCMSっぽいシステムでは。
0630デフォルトの名無しさん
2008/08/25(月) 10:00:08> コード自体はほとんどCMS系フレームワークをユーザ定義コンテナを定義する程度で
> 用が済むことが多いと思います。特に、>>622のような、いかにもCMSっぽいシステムでは。
よいCMS系フレームワークを、
容易に開発できるかどうかって話をしているんだと思いますよ。
0631デフォルトの名無しさん
2008/08/25(月) 10:54:21なるほど、わかりました。
格納するコンテンツの量は結局DBのサイズの問題になると思うので、
それ以外の「大規模」の要因というと、
・同時接続数(パフォーマンス)
・登録ユーザー数
ぐらいでしょうか。
それとも単純にコードサイズを指して「大規模」という話なんでしょうかね。
「学校」というドメインが明確になっているので、
一般のCMSフレームワークほど汎用化は要求されないし、
どのような要因でコードサイズが「大規模」化するのか興味があります。
0632デフォルトの名無しさん
2008/08/25(月) 12:22:00Apacheとか使わずErlangでサーバー構築するんじゃないの?
0633デフォルトの名無しさん
2008/08/25(月) 12:26:390634デフォルトの名無しさん
2008/08/25(月) 13:01:50マルチコアで何とかしようと考えていると見て間違いない。
Webだとすれば、WebServer以外考え難い。生徒数千でほぼ
同時にアクセスがあるとか。
0635デフォルトの名無しさん
2008/08/25(月) 13:13:150636デフォルトの名無しさん
2008/08/25(月) 13:16:410637デフォルトの名無しさん
2008/08/25(月) 13:16:520638デフォルトの名無しさん
2008/08/25(月) 13:42:02HaskellでもPerl使いを確保しておいて、単体の機能は専らCPANから取り出させて、
確保されているインターフェイスを介してHaskellで利用するというやり方は
多くなるんじゃないかな。短時間で開発する一手法としてね。
0639デフォルトの名無しさん
2008/08/25(月) 13:57:490640デフォルトの名無しさん
2008/08/25(月) 14:13:290641デフォルトの名無しさん
2008/08/26(火) 00:21:14Haskellに慣れてくるとこの実装が直感的に見えてくるんですか?
Haskellのパーサコンビネータ関連のペーパーを読んでいない状態でReadPを読んで、
data P a = Get (Char -> P a)
略
| Result a (P a)
略 なのを「え、一番直感的じゃん」
とか、
newtype ReadP a = R (forall b . (a -> P b) -> P b)
で
instance Monad ReadP where
return x = R (\k -> k x) ← これとか
fail _ = R (\_ -> Fail)
R m >>= f = R (\k -> m (\a -> let R m' = f a in m' k)) ← これとか
とか
get = R Get
ってなるを、「ああ、自明だなすげえ直感的」みたいに理解できるようになる物なんですかね。。難しすぎる。。。
0642デフォルトの名無しさん
2008/08/26(火) 00:29:58大規模になる要因なんていくらでもあるじゃん。
今時は単にUIがWebで、バックエンドが複雑化してるものも少なくないしね。
分散業務システムで多種類のプロセスを相手にすりゃ自然と規模は大きくなるかと。
何でもかんでもインターネット上でパブリックに利用可能な整理されたサービスばかりじゃないからね。
学校だって企業並みにシステムが複雑化してるとこもあるから、強ち単純とは言えないんじゃないかと。
まあ何はともあれ、ロジックが複雑になればなるほど、関数型の恩恵は大きくなるわな。
0643デフォルトの名無しさん
2008/08/26(火) 01:08:51googleを支える技術とか読んでもそんなに複雑とは思えないんだよなぁ。
台数は1台だけど自宅で似たようなことやってるもん。
0644デフォルトの名無しさん
2008/08/26(火) 08:11:38P のような再帰的な型のモナドを、
効率のために継続モナド(ReadP)で包むのは定石。
Haskell への慣れっていうより、
モナドや継続モナドへの慣れの問題な気がする。
P は問題によって様々だけど、
ReadP のとこは Control.Monad.Cont の
一般的な継続モナドと(型を除いて)同じなので、
それを理解しておくと問題に集中できていいかもよ。
0645デフォルトの名無しさん
2008/08/26(火) 08:13:320646デフォルトの名無しさん
2008/08/26(火) 08:21:08それはバックエンドで動いている他プロセスが複雑なのであって
ウェブアプリが複雑なわけではないのでは?
0647デフォルトの名無しさん
2008/08/26(火) 08:32:48機械翻訳とかではなくて?
0648デフォルトの名無しさん
2008/08/26(火) 18:38:57どうもレスありがとうございました。
>P のような再帰的な型のモナドを、
>効率のために継続モナド(ReadP)で包むのは定石。
これは初めて聞きました。どうもありがとうございます。
確かに
If we want to build monads on top of a continuation based programming paradigm,
such as stream processors or continuation based I/O in Haskell,
we need to build a monad around the continuation based operations.
って書いてあるペーパーを見付けました、その継続ベースの方法について考えながら考えていこうと思います。
0649デフォルトの名無しさん
2008/08/26(火) 18:52:430650デフォルトの名無しさん
2008/08/26(火) 19:00:04そうです、でもこれだけ読んでもこれで何がしたいのか俺には正直よく分かりませんな。。
例がなくても理論だけ聞けば全て分かるタイプの人なら大丈夫なのかもしれませんが。
0651デフォルトの名無しさん
2008/08/28(木) 06:47:20P みたいなのを継続ベースともいうけど、
ReadP を使うのは純粋に効率のためで、
そこに書いてあるのとは話が違うような。
0652デフォルトの名無しさん
2008/08/28(木) 11:12:38そう単純化されても…
0653デフォルトの名無しさん
2008/08/28(木) 14:48:420654デフォルトの名無しさん
2008/08/28(木) 21:41:23ReadPだと、PがReadPで包まれてるわけだけど、
get' = Get return
look' = Look return
sat' p = do a <- get' ; if p a then return a else Fail
char' c = sat' (c == )
string' s = do str <- look' ; scan s str
where scan [] _ = return s
scan (x:xs) (y:ys) | x == y = do get' ; scan xs ys
scan _ _ = Fail
みたいにReadPでくるまないバージョンも用意できて、それもrunで使える。
http://www.cs.chalmers.se/Cs/Grundutb/Kurser/afp/2006/Papers/parser-claessen.pdf
ここにも効率がって書いてあるけどどんな場合なのかさっぱりだ。。
0655デフォルトの名無しさん
2008/08/29(金) 14:13:46記述上は包まれた形になってるけど、実装では包みが外れた形になる。
参照: http://haskell.g.hatena.ne.jp/jmk/20061203/1165141002
Pは直接的にはうまく束ねることができないから、一旦仮想的なReadPで束ねてるって感じ?
0656デフォルトの名無しさん
2008/08/29(金) 15:53:54どうもありがとうございます。
実際にはReadPの所はR Get やR Lookなどが渡されることになりますよね。
そのあとすぐにrunで即Rはずしてますし。
>Pは直接的にはうまく束ねることができないから
これってどういう意味で仰ったんですか?
P を束ねてパーサとして使うことも、実際できる(>>654のget'など)のでわざわざどうしてReadPにするのか、
Pの>>=が左結合的に作用するのが問題らしいんですけどそれが問題になる具体的なケースについて
私にはサッパリ思い付かなかったので先人たる皆様にお聞きしたかった次第です。
0657デフォルトの名無しさん
2008/08/29(金) 17:28:28ReadP の計算で左結合になってる >>= がある場合でも、
内側の P の >>= をすべて右結合にすることで、
P の >>= の再帰が無くなって効率が良くなる。
9節の第1パラグラフに書いてある通りなんだけど。
左結合を右結合にってのは、>>= の結合則
(m >>= f) >>= g == m >>= (\a -> f a >>= g)
の左辺を右辺にするってな話。
例えば、string s >>= f でも string s の中で
>>= を使ってるので、左結合になってる。
つまりほとんど全ての場合に当てはまる。
0658デフォルトの名無しさん
2008/08/29(金) 17:29:19リストの ++ は左引数に関して再帰する。
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
そのため (xs ++ ys) ++ zs は xs に関して二重に再帰することになる。
foldr (++) [] (map show [1..10000])
foldl (++) [] (map show [1..10000])
実際これらを実行してみると前者はすぐ終わるけど、後者は "1" を10000回結合、
"2" を9999回結合、... "10000" を1回結合、みたいになって遅い。加速してくけど。
遅いだけじゃなく、中間リストを生成するので無駄にメモリを使うことにもなる。
foldl は極端な例だけど、foldr も極端で、いつも無駄が無いようにはいかない。
0659デフォルトの名無しさん
2008/08/29(金) 17:30:18xs ++ ys は、xs の最後の [] を ys に置き換える。
それを効率よくやるには、最初っから [] なんか使わないで、
1:2:3:[] を \nil -> 1:2:3:nil みたいにしとけばいいじゃんという発想。
つまり [a] を [a] -> [a] に、xs を xs ++ に、++ を (.) にする。
こうしておくと、[] を与えてリストに戻すときには、
(.) が右結合になってなくても ++ は右結合になる。
(((xs ++) . (ys ++)) . (zs ++)) []
= ((xs ++) . (ys ++)) (zs ++ [])
= (xs ++) (ys ++ (zs ++ []))
= xs ++ (ys ++ (zs ++ []))
実際 String の ++ を頻繁に使う class Show あたりでは、
できるだけ type ShowS = String -> String を使うことになってる。
shows :: Show a => a -> ShowS を使ってさっきの
foldl (.) id (map shows [1..10000]) []
をやってみると、今度は問題無く速い。
0660デフォルトの名無しさん
2008/08/29(金) 17:31:29m >>= f (P の >>=)は、m の最後の return a を f a に置き換える。
それを効率よくやるには、最初っから return なんか使わないで、
Get (\c1 -> Get (\c2 -> return [c1,c2])) を
\k -> Get (\c1 -> Get (\c2 -> k [c1,c2])) みたいにしとけばいいじゃんという発想。
つまり P a を forall b. (a -> P b) -> P b に、
m を m >>= に、>>= を \m f k -> m (\a -> f a k) にする。
以下略。
0661デフォルトの名無しさん
2008/08/29(金) 17:32:22foldr c n xs は、xs の : を c に、[] を n に置き換える。
それを効率よくやるには、最初っから : や [] なんか使わないで、
1:2:3:[] を \c n -> 1 `c` 2 `c` 3 `c` n みたいにしとけばいいじゃんという発想。
つまり [a] を forall b. (a -> b -> b) -> b -> b にする。
リストに戻すときは build xs = xs (:) [] を使う。
すると foldr c n (build xs) ==> xs c n と変換できる。
map f xs <==> build (\c n -> foldr (c . f) n xs)
例えばこういう変換を定義すれば、
(map f . map g) xs = map f (map g xs)
==> build (\c n -> foldr (c . f) n (build (\c n -> foldr (c . g) n xs)))
==> build (\c n -> (\c n -> foldr (c . g) n xs) (c . f) n)
==> build (\c n -> foldr (c . f . g) n xs)
==> map (f . g) xs
のように map f . map g ==> map (f . g) という変換ができる。
map f . map g 以外にも、他のいろいろなリスト関数の
foldr/build を使った形への変換を定義しておけば、いろいろな変換ができる。
foldr/build による融合変換ってやつ。今の GHC もこれを使ってる。
詳しくは GHC User's Guide の 8.13. Rewrite rules あたりを見てくれ。
0662デフォルトの名無しさん
2008/08/29(金) 18:19:15とても分かりやすい解説どうもありがとうございます!
ちょっと解決の糸口がつかめた感じがします、これからじっくり考えてみたいと思います。
とてもご丁寧にありがとうございました。
流石だ。。。
0663デフォルトの名無しさん
2008/08/30(土) 18:34:320664デフォルトの名無しさん
2008/08/30(土) 18:44:45ごく自然発生的なものだと思うが?
0665デフォルトの名無しさん
2008/08/31(日) 00:07:29手続き型言語 = how(どうやるか)を記述
クロージャをいかに早めに潰すかに苦心するHaskellは後者ですな
0666デフォルトの名無しさん
2008/08/31(日) 00:38:36宣言型言語=述語論理を記述
と思ったらHaskellも述語論理の仕様記述言語に非常に近い特徴を持っていることに気づく。
0667デフォルトの名無しさん
2008/08/31(日) 03:38:00> クロージャをいかに早めに潰すかに苦心
ってどういうこと?
0668デフォルトの名無しさん
2008/08/31(日) 09:45:13関数のインライン展開のようなものじゃないか
よく分からんが
関数リテラルなら展開しやすいが高階関数の戻り値のクロージャは展開しにくい気がする
だからどう書くか (how) を工夫する
人間が問題を「宣言」するだけでコンパイラが問題を解いてくれる
というのは
素朴な解決策は簡単に見つかるのだが最適化が難しい (が機械的にできる) 問題に限定されるはず
0669デフォルトの名無しさん
2008/08/31(日) 15:47:120670デフォルトの名無しさん
2008/08/31(日) 15:59:09最適化は手続き型でもやってるから、非手続き型の人はwhatの部分を強調してみたりC/C++より速くなると言ってみたり。
LLの人は最適化にあまり拘らないし、テストさえ通ればhowを直接書いてもいいやって感じだけど。
0671デフォルトの名無しさん
2008/08/31(日) 17:18:22>>600前後の流れ参照
要するに未評価の式(これはクロージャで実装されてる)を溜め込まないように注意する必要がある
0672デフォルトの名無しさん
2008/08/31(日) 20:51:420673デフォルトの名無しさん
2008/08/31(日) 21:42:38人間の性格はA型B型O型AB型の4種類に分けることができる
とか思ってそうだよな。
0674デフォルトの名無しさん
2008/08/31(日) 23:36:24血液型と性格をろくな検証なしに簡単に結びつけてしまう短絡さ
どっちをさしてるのか紛らわしいので例としては不適
0675デフォルトの名無しさん
2008/09/01(月) 01:06:10おもしろおかしい
0676デフォルトの名無しさん
2008/09/01(月) 07:57:32書き終わったって。
■ このスレッドは過去ログ倉庫に格納されています