関数型言語一般 [無断転載禁止]©2ch.net
関数型言語について。
言語同士の比較、おすすめ、不満点など。 >>95>>96
高階関数の返値としての関数ポインタは、引数の値毎に別のポインタを返さなきゃならんわけよ。
引数の種類が限定されていればできなくもないだろうけど。 >>104
>引数の値毎に別のポインタを
こういうこと?で返値の「関数ポインタの引数の数や型」が揃っている保証がないと?
f(int v){
switch(v){
case 1:
return 関数ポインタ1;
case 2:
return 関数ポインタ2;
...
}
} 引数じゃねえな。その高階関数の値域が限定されていれば、だ。 >>100は遅延評価がIOをどう効率的に解決するかが分からないという事。
あと遅延評価より「手が空いている時に先に取得/計算しておく」
という仕組みが最強だろうという考えもあって書いた。
そこまで考えると遅延評価なんて何がうれしいのか分からない >>105
揃っているかどうかは(コンパイラがチェックしてくれるだろうから)関係ない。
その「関数ポインタ1」や「関数ポインタ2」をあらかじめ全部用意しておかなきゃならんというだけ。 >>108
コンパイル時に静的に存在している関数のポインタしか扱えないということ? >>100だけど参照透過性が必須ならDBやネットワークは扱えないか。
しかし更新されない読み取り専用のDBがあったら話は別だ。
地理・住所系DBとかでしばしばそういうのはある。
遅延評価なら必要になった最小の部分のみDBから取得する事になるだろうが、
DBはネットワーク越しになっていたりするから一度にまとめて取得した方が良い場合がある。
遅延評価による無駄な計算の回避という主張点がどうなのかという話。
さっき書いた通り関数ポインタを渡して必要な場合のみ呼び出すという事でも無駄な計算を回避できるし、
読み取り専用DBの例は必要になった値のみ作成するというアイデアが必ずしも効率的ではない事を示している。 ストレージアクセスは4KBアクセスに最適化されているし
ネットワークもある程度のサイズに最適化されている。
そういうサイズを下回るくらいの細かなアクセスは性能を向上させない。
だから1オブジェクト単位とかまとまった単位での取得は性能を劣化させない場合がある。
遅延評価は読み取り専用DB(参照透過を保証できる)に無駄に細かい単位でのアクセスをするんじゃないか?と
その思想を聞いた限りでは思ったのだけど。 これらのシステムはある程度まとめて情報を用意するというスタイルが基本になる。
・オブジェクトを使う
・オブジェクトを使わないが正格評価
しかし遅延評価はそれを避ける事を理想としているように聞こえる。
(そうでないなら遅延評価の目指すところは何?)
>>100でサブルーチンのコストの話を出したが、
特殊なクラスタで仮想的な1台のコンピューターを扱う場合、
サブルーチンが水面下でネットワーク処理をする場合がある。
そこまで考えると関連性が高い値をまとめて作成したり
少なくとも値の作成タイミングをプログラマーが制御できたほうが良い可能性がある。 >>104が言ってるのはもしかして
Javaのラムダみたいに呼び出し元のローカル変数をコールバック関数から参照できるという話?
いわゆるクロージャー?
そうか、関数ポインタだと呼び出し元のローカル変数を扱おうとした場合
それらローカル変数分も高階関数側に宣言しなきゃならない。
ところがそれらローカル変数は呼び出し箇所それぞれの事情で存在しているもので
高階関数側に宣言するのはおかしい、みたいな話か。
それでも1つ任意データへのポインタを持たせて
そのポインタからのバイナリフォーマットについて呼び出し側が留意するなら
クロージャーと同じ話になるだろうけど。 ローカル変数一覧へのポインタAと関数ポインタBを高階関数に渡して
Bを呼び出す時にAを渡して、Aの扱い方はBに任せる、
という事ならクロージャーと同じ事ができるはずだ。 C++のファンクタはJavaの関数型インターフェースに相当するものか
ffcallでCでもクロージャが簡単にできるみたいだ。
やはりCと関数型の差異はイミュータブルと遅延評価しかない。 モナドは、例えばサブルーチンとgotoは違うモナド、みたいな事?
言語側が勝手にやるモジュール化のための基本処理をモナドと言っている? なんとなくわかった
値という概念の亜種みたいなもので、
関数型言語では「現在のプログラムの状態は?」と聞かれた時
値だけで説明できずモナドをまじえて説明するのか。
そうする事でユーザー入力みたいな純粋関数にしえないもの、つまり
「参照透過性を破壊する性質の値」をモナドとして扱う事で
一旦プログラム状態の説明としては参照透過性があるという事になるわけだ。
要するに参照透過性を破壊する値にある種のマーカーがついてて、
参照透過性を前提としたあれやこれやをする時に問題が生じそうなら
そのマーカーがついてるとこだけ注意すればいいみたいになるのだろう。 モナドはアクションが実装しているインターフェースみたいなもので、
”アクションをつないで行ける”という機能性を指すもの、か C/C++/C#、それとあとjavaとpythonをかじってみたいな流れで来てるんだけど幅を広げるためにちょっと関数型言語に手を出してみようかなって
ざっと見た感じすごいhaskellから入るのがいいんでしょうか すごいハスケルは型のことそんな書いてないからその辺求めるなら別のがいいかも
モナモナとかにはいいかもね >>123
Haskell人気でイマイチ表に出ないけど、利用実績十分のOCamlやろうぜ。
C#やってるならF#でもいいぞ! https://www.quora.com/What-functional-programming-language-should-one-start-to-learn-functional-programming
ここなんかでもそうなんだけど関数型言語はじめの一歩ってことでRacketってのがおすすめされること多いみたいなんだよね
このスレでは名前の一回も出てきてやしないけど。もともと学習用?の側面が大きいらしい
日本語の資料ぜーんぜん無いのが辛いところだけど Haskellの表記の簡潔さを知ったらあの括弧責めは耐えられないなぁ >>126
Racketの処理系ではSchemeが動くからSchemeを勉強すれば良い
>>127
> Haskellの表記の簡潔さを知ったらあの括弧責めは耐えられないなぁ
Schemeには括弧は多いがHaskellのようにやたらと色んな概念がてんこ盛りにはなっていない
Schemeは作用順の評価戦略を採用したλ-計算に最小限のデータ種別(実行時の型チェック)と最小限の命令的な代入操作(set!など)を追加しただけで
概念的には極めてコンパクトな言語だよ(Revised^6は例外としてね)
他方、Haskellは関数型のAdaと揶揄されることもあるように、委員会言語の常で取り入れられる概念は何でもかんでも取り入れて複雑極まりない言語に仕上がった
表記上は括弧がなくてオフサイド・ルール(インデンテーションによる括弧の代わり)を採用しているので見掛けだけは簡単かも知れないがな >>128に大事な1行を書き忘れてた
> Racketの処理系ではSchemeが動くからSchemeを勉強すれば良い
つまりSchemeの教科書は日本語でも何冊かあるからってことです >>128
>概念がてんこ盛り
例えば?
自分としてはライブラリなんかには色々入っているけど
素の言語仕様は簡素で学習しやすい言語だと思ったけどな。
型の制約があることで却って初学者に抽象的な奥深さによる
幻惑を与えないとも思う。 land of lispで勉強始めたんだけどめっちゃ脳が疲れる
いやー全く未知の概念 Coconutってこのスレでいい?
ttp://coconut-lang.org/
>>111
遅延評価がアリなら、
MathematicaのSelectTuplesみたいなのを用意しなくても(つまり、Tuplesが
遅延評価してくれるのなら)、
組合せ爆発によるメモリ不足は回避出来るのかも。
ttps://resources.wolframcloud.com/FunctionRepository/resources/SelectTuples
組合せが全部メモリに載る様な「小さな」問題なら、予め全組合せを計算して、
条件とかに合わないのを弾く事も出来るけどね。 確かにHaskellは他の言語に比べれば多くのことができるけど、
Haskellを使えるようになるためにそれらを全て理解してないと行けないかと言われたらそんなことはない
結局Haskellに限らずどんな言語でも学習する内容を取捨選択する必要があるだけであって、
Haskellが色々できることを問題と捉える必要はない。
問題なのは、学習者が取捨選択するための基準が不透明なのと、
それらを理解してないことに対してマウントとってくる輩がいることかな。 『Land of Lisp』を読んでいるんですがその中で、
「純粋関数」と「副作用のある関数」を分離せよ、とあるんですが
「こうやって分離するんやで」みたいな設計方法について
書かれた本ってありますか? みたことないの
非純粋関数型について書かれたものだったらどっか章さいてるかもしれんけど
副作用起こすところなるべくまとめて途中ではやらないようにするってだけな気はするが >>141
テスト駆動開発とかレガシーコード改善ガイドとかあの辺読んだ方がわかりやすいよ。 みなさんありがとうございます。
>テスト駆動開発とかレガシーコード改善ガイド
読んでみます。
あと、調べてたらIOモナドというのも副作用の分離に効果がありそう?
これで思い出したのが、この前読んだSICPの画像言語の章で、
そこではPainterオブジェクトで画像出力(副作用)を包み、それを
使って関数同士を合成してました。
これも1つの副作用の分離で、IOモナドとも関係あるのかな???
うーん というよりハスケルではIOモナドでしか副作用できんし。
副作用を行うところを明確に分離してるって意味では合ってる 今ある言語の話ではなく、設計の話
配列のsplice(破壊的slice)を参照透明な感じにしようと思ったら、
array.splice(...)は直接arrayを変えられないから、変更後のarrayとslice部分を返す必要がある
同様に、状態を変更するメソッドも変更後の自分と返り値を返す必要がある
xs = [1, 2, 3, 4, 5]
zs, ys = xs.splice(1, 3)
print zs #=> [1, 5]
print ys #=> [2, 3, 4]
なんかダサくね?そうでもない?
別の方法としては、!みたいなプレフィックスを付けて、その場合のみオブジェクトを置き換えるというもの
ys = xs.splice!(1, 3) # xs = [2, 3, 4] も同時に行われる
print xs #=> [1, 5]
print ys #=> [2, 3, 4]
これは参照透明ではないし、xsが定数か変数かによって左右されてしまう
いい方法がないものか・・・ 前者でいいじゃん
人を最も驚かせないシンプルな仕様が良い 関数型プログラミングをサポートしている言語
ACL2 / APL / Arturo / ATS / Ayrch / Binary Lambda Calculus / C++ / Ceylon / Clio / Clojure / Common Lisp / Curry / D / DataWeave / Dylan / EchoLisp / Egison / Ela / Elisa / Elixir / Elm / Erlang / Excel / Falcon / Fantom / FormulaOne / Frege / formulae / Golo / Guile / Haskell / Hope / Ioke / J / JavaScript / Joy / Jq / Kitten / Lang5 / Lean / Leon / LFE / M2000 Interpreter / Mathematica / Mercury / MLite / Morfa / Nemerle / NGS / Objeck / OCaml / Ol / Order / Oz / PARI/GP / Perl / Perl 6 / PowerShell / Pure / Purity / Raku / Ruby / Rust / Scala / Scheme / SequenceL / Sidef / SkookumScript / Standard ML / Thyrd / Trith / TXR / Ultimate++ / Unlambda / Ursala / Visual Prolog / Wart / Wolfram Language / Wortel / XQuery / Standard ML / Thyrd / Trith / TXR / Ultimate++ / Unlambda / Ursala / Visual Prolog / Wart / Wolfram Language / Wortel / XQuery 関数型プログラミングしか出来ない言語に絞って欲しい