「モナド」を含む日記 RSS

はてなキーワード: モナドとは

2017-02-16

ノマド」は「ノーマッド」と書いて欲しい

スタバ仕事をすることもプログラミングすることもない身としては、「ノマド」も「モナド」も「はてなでたまに見るよく分からない概念」でしかなく、ごっちゃになってはググっての繰り返しだった。

しかノマドロマサガ2ノーマッドが同じ由来だと気付いた瞬間混乱は消え去った。

これは特殊パターンだとしても字面が似すぎているから改称した方がいいと思う。

2016-05-25

http://anond.hatelabo.jp/20160525213232

バグがあって、ストリームに変な値が入った時、どこがバグなのか、追跡するのが困難でしょ?

第一に、それは、ストリームFRPの値の定義)の問題であって、ユニットテストすれば良い。もしくは単にFRPログを取れば良い。

グローバル変数ではそういうことはできない。FRPでは、岡部氏のFRPライブラリ特にそうだけど、基本的ミュータブルな値同士が関数リアクティブ連携されて常に整合性を保っているのだからグローバル変数の、各所で更新されたそれぞれの値によって全体の整合性が損なわれないように気を配らなければいけないという(テスト自体困難な)問題は発生しない。それがFRPの唯一とも言えるメリットだとも言える。

使用する関数問題じゃないし、「印」として引数に加えても別に構わないと思うが、君のいうグローバル変数問題と一緒というのはまったく違う。

岡部氏との争いって「OCamlGUIアプリ純粋関数型(状態渡し)で簡潔に書けるか」ってところじゃないよね?

いや、それがそもそもの発端であるブログの経緯には書かれている。説明されている方式GUIアプリまで書けるのか?と疑念が呈されたことがきっかけ。

岡部氏はFRP状態関数の外部に持ってても純粋関数型だ、と言ってて、そこで争ってるんだよね?

この論点は聞いたことがない。岡部氏がこだわっているのは非手続き型の宣言型で、純粋がどうとか議論はされてないように思う。

あと、OCamlGUI状態渡しで書いたら簡潔で無いのを「書けない」、「不可能」って言ってるのはわざと印象操作しようとしてるよね?

原理的に可能かという議論ではなく、実用的な範疇か?という議論。反対派ブログで出てきたコードは、本人が認めるように普通のやり方ではなく、実用的なコードだとは思えない。あと、FRP状態渡しは同じ複雑さだという主張も崩されている。そこが重要

Haskellで書けて、OCaml冗長になっても、書けるなら「書ける」、「可能」だよね?

段階を踏んだ上で、非FRPHaskellのIOモナドコードを誰かが書いたらいんじゃない?当面、最初OCamlの話だったのに、いきなりHaskellやElmのコードで書いて、そういうのがごちゃまぜに、何がどの言語でできるのかできないのか、誤魔化しがあると見做されたか制限されたんでしょ。実際には、OCaml関数型では冗長しか書けないと実証されたけど、そういうのがバレないように、別の言語を利用していたと看破されて当然の状況だと俺は思うね。

俺の書き込み他人といきなり結び付けられたから、電波だな、と思ったの。

俺1人か、とか、らくだや住井が含まれてない根拠とか、関係無いよね。

関係ある。君ひとりは、そうじゃない、と君ひとりが言ってもそれが本当だとは確認のしようがないし、

書き込みをみれば、君以外の書き込みもすべて、その一派ではない、とでも言いたそうだ。

http://anond.hatelabo.jp/20160524164501

関数型という枠組みの中にミュータブルな時間要素が純粋に収まるようにしているのがFRPだろ。

ストリーム関数の外部に持つFRP純粋関数型っていうのは少数派でしょ。

関数の結果が引数以外で決まるわけだからさ。

多分、純粋とかの定義もまた違うんだろうね。

関数型の拡張」で全部丸く収まると思うんだけど。

いやそもそも岡部氏が複雑なアプリになるとFRP必要

これはGUIアプリ(対話的なアプリ)ってことでいいのかな。

コンパイラだとかをFRPで書かないでしょ。

ユーザから入力リアルタイムに処理するプログラムにはFRP有効だよね。

事実、「駱駝」は「状態渡しはむしろ異常」って書いた上に、

OCamlでは」じゃないの?

全部純粋関数型(引数戻り値に収める、状態渡し)にするのを良しとするHaskellと違って、OCaml副作用部分的に使うのが普通で、IOモナドみたいな入出力までも純粋に書くための道具立てが揃ってない、それでちょっと冗長になる、ってことでしょ?

OCamlの元々の推奨スタイルならもっと短く書けるんでしょ?

俺はそう読んだけど。

それっぽい書き込みほどそうやって、事実誤認だ、と強調するから、なんで当事者でもないのに、そんなことが断言できて、電波だということになるんだ?

だって駱駝でも住井でもない面識も無い俺の書き込みが住井扱いされるんだもの

いやだから、どの関数で読み書きされようと、誰が書き換えようとも、時間にたいしてイミュータブルな定数なんだから、定数は定数なのよ。

いやだからグローバル変数使ってるプログラム欠点をそのまま持ってるじゃん

グローバル変数使ってるプログラム欠点説明する必要ある?

2016-05-24

http://anond.hatelabo.jp/20160524145224

よーわからんw 岡部氏は、自作ライブラリHPで、

FRP純粋理想とする関数型+時間で変化するストリームを値にマップして扱うリアクティブプログラミングの組み合わせ

まり関数型の拡張っていうなら誰も反対無いと思うんだけど。

FRPライブラリサブタイトルに、 library that provides first class reactive value 'over time' と書かれている、これ拡張じゃないのか?

https://www.npmjs.com/package/timeengine

HaskellのIOモナドみたいな別の抽象化DISりつつ、FRPこそ正しい関数型みたいに言うから荒れるんじゃないの?

IOモナドDisってるのかどうかまでは知らない。しかし、すでに出たサンプルからFRPの効力がまざまざと見せつけられている。

荒れるのは自由だけど、両方正しいとかそういうのじゃなくて、間違っている電波だみたいな叩きしかなくて、要するに感情論で反対派は反発しているだけでOK?

あるよ。

関数がどのパラメータ依存して、何を結果として返すのか明確になる。

グローバルな値を参照したり書き換えたりしてたら、関数の中身読まないとわからなくなる。

短いプログラムならそれでもいいけどね。

別の誰かが書いてたように、上位スコープ内に定義されてるDOMでも、数学ライブラリでもなんでも、引数関数に渡すのか?

グローバルな値を参照したり書き換えたりして

いやだから、定数なんだから書き換わらないんだよ、FRPストリームconst 定数なんだから

関数型のわかりやす説明であって、住井派に反対してるとか、岡部路線とかじゃないよね、と。

オブジェクト指向と対比して考え方をまず学ぶって岡部路線、住井グループはそれを目の敵にしていて集団的攻撃している様をみたプログラミングコミュニティは逃げ、その後、不毛な大地のみが残った。

http://anond.hatelabo.jp/20160524142313

FRP純粋理想とする関数型+時間で変化するストリームを値にマップして扱うリアクティブプログラミングの組み合わせっていうなら、別に誰も反論しないと思うけど。

まり関数型の拡張っていうなら誰も反対無いと思うんだけど。

HaskellのIOモナドみたいな別の抽象化DISりつつ、FRPこそ正しい関数型みたいに言うから荒れるんじゃないの?

全部の時間依存関数にそういうことをする意味はない

あるよ。

関数がどのパラメータ依存して、何を結果として返すのか明確になる。

グローバルな値を参照したり書き換えたりしてたら、関数の中身読まないとわからなくなる。

短いプログラムならそれでもいいけどね。

初心者からFRPのことまで考えてないんだろう。

関数型のわかりやす説明であって、住井派に反対してるとか、岡部路線とかじゃないよね、と。

2016-05-22

http://anond.hatelabo.jp/20160520083417

「滅多なことが言えなくなった」としたら、nonstarter氏のブログのように

岡部氏に反する意見を言うと激しく荒らされるからですね。

迷惑がかかるといけないのでリンクしませんが、

住井氏は関数型言語に関する世界最高峰の国際会議委員長ですね。

エリオット氏のブログは、岡部氏が引用していない部分を読むと、

C言語の「プリプロセッサが」Cプログラムを「生成する」ので、

HaskellのIOモナドがIOアクションを生成するのと同様に

純粋関数型言語とみなせる、という主旨のことが書かれていますね。

岡部氏は「プリプロセッサ」という部分を引用していないようですが。

2016-05-20

http://anond.hatelabo.jp/20160520153456

OCamlでは」普通に副作用を使うライブラリしかいかスケールしない、って書いてあるのに

なんで勝手一般化して、Haskellとかでもスケールしないことにしたいの? 本当に牽強付会オンパレードですね。

http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b#comment-d9a8cdf2efc67044c158

OCaml の全ての GUI ライブラリ状態副作用を使うことを前提にメインループ設計されているからです。これを乗り越えるとすると @Lambada さんのようにメインループ自体自分で書く事になり、一般的にはスケールしません。HaskellGUI ライブラリでは普通状態State なり IO を含む GUI モナドを使って書く事になりますが、そのような GUI ライブラリOCaml 上で作れば同じような事が出来るはずです。OCaml でそこまで純粋関数型のコードを書く事に実用意味があるとは思えませんが。

http://anond.hatelabo.jp/20160520135548

一応説明すると、Elliottの元記事

HaskellのIOモナドが「IOアクションを生成する純粋関数プログラム」なのと同様、

Cのプリプロセッサは「Cプログラムを生成する純粋関数プログラム」って言ってるのね。

から「cpp + C言語処理系」は「Haskell + 処理系」と同じく純粋関数型だと:-)

http://anond.hatelabo.jp/20160520052648

http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b#comment-d9a8cdf2efc67044c158

いずれにせよ、状態機械数学構成では状態遷移が状態入力から状態への関数として表現されるというだけのことではあり(状態渡し)、

状態遷移が複雑になれば状態遷移を純粋関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)

って自分で(状態渡し)は困難になる、「状態渡しはスケールしない」って認めちゃってるんだが、

モナドと一緒ってことにして、Haskellモナドの話にすり替えたいってことなのかな?

状態渡しはスケールしない」とこの人物が自分で認めてることは消えないよね?

http://anond.hatelabo.jp/20160518170332

これのどこをどう読んだら「状態渡しはスケールしない」になるんだ……

ひょっとして状態渡しをモナド化したのがStateとか、基本的なことを全く理解していない?

http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b#comment-d9a8cdf2efc67044c158

OCaml の全ての GUI ライブラリ状態副作用を使うことを前提にメインループ設計されているからです。これを乗り越えるとすると @Lambada さんのようにメインループ自体自分で書く事になり、一般的にはスケールしません。HaskellGUI ライブラリでは普通状態State なり IO を含む GUI モナドを使って書く事になりますが、そのような GUI ライブラリOCaml 上で作れば同じような事が出来るはずです。OCaml でそこまで純粋関数型のコードを書く事に実用意味があるとは思えませんが。」

2016-05-17

http://anond.hatelabo.jp/20160517022608

>それをユーザから見て命令変数への破壊的代入ではなく参照透明な関数インターフェースで実現するのがいわゆるモナドや(誰かの独自解釈ではない本来の)FRP

はい、戯れ言への反論がkenokabeよりBlogでされました。

http://kenokabe-techwriting.blogspot.jp/2016/05/frp.html

http://anond.hatelabo.jp/20160516152330

それをユーザから見て命令変数への破壊的代入ではなく

参照透明な関数インターフェースで実現するのが

いわゆるモナドや(誰かの独自解釈ではない本来の)FRP

http://elm-lang.org/examples/time

view : Model -> Html Msg
view model =
  let
    angle =
      turns (Time.inMinutes model)

    handX =
      toString (50 + 40 * cos angle)

    handY =
      toString (50 + 40 * sin angle)
  in
    svg [ viewBox "0 0 100 100", width "300px" ]
      [ circle [ cx "50", cy "50", r "45", fill "#0B79CE" ] []
      , line [ x1 "50", y1 "50", x2 handX, y2 handY, stroke "#023963" ] []
      ]

HaskellライブラリもElmのような言語も、サンプルもJavaScript実装

ググればWikipediaで出てくるレベル

https://en.wikipedia.org/wiki/Functional_reactive_programming#Implementations

2016-01-27

ええ、最初は軽い気持ちだったんです。

ええ、最初は軽い気持ちだったんです。型もなくて簡単だからって…。phpをやるようになって から確かに気分は良かったんですよね。

でもそのうちphpだけじゃ足りなくなってくるんですよ。javascriptのような流行ものにも手を出したりして。そうするとcsshtmlだけなんかじゃもう物足りないんですよ。

そのうちpythonrubyなんていういわゆる”スクリプト系”ですか?流行のものにはほとんど手を出してしまっている状態で。コストが安いじゃないですか?手を出しやすいんですよね。

node.jp?やってましたね。あの頃みんなハマってましたよね。

だんだんそれらなしでは生活できなくなってしまって。立ち上げているのはほとんどCUI画面ですよね。

ええ、端末一つでは足りないのでtmuxscreenなんかのマルチプレクサを使ったりしてね、もう完全に中毒症状が出ていたんですよね。vimrcをいじるようにもなっていてね。一日中vimscript書いては悦に浸って、考えるとちょっとあれですよね。

そのころはいつでもやめられると思っていたんですよ。

でもjavac#に手を出してしまったんです。phpとかrubyなんかよりはやっぱり重量感がありますよね。IDEも何個も試してみたり、vimだけで環境を整えようとしたり、結構無茶しましたよね。

テストもいっぱい書いて、なんでこんな辛いことしてるんだろうとか。

そして、みんなそうなんのかもしれないけど、やっぱりc++に手を出すことになってしまって。もう強すぎて今までのものとは全然違いますよね。でもこの頃には副作用も出ていたんです。

あれオブジェクト指向ってなんだっけってね(笑)テンプレートリフレクション?混乱しますよね。でもだんだん慣れてくるですよね。もう後戻りできないところまで来ちゃったかなとか思いますよね。

今では中毒症状のせいか幻聴も聞こえてますね。モナドモナドって。なんか良くわからない言葉が聞こえてます

抜けられる自信は無いですね…。今でも一日に10時間以上はやっていますから…。

2015-02-26

関数型言語使ってる時の気持ちよさは、ベーシックべた書きの頃と同じ

ひょっとすると、これはべたべたな一直線の手続き書き時代以来の「全てが一直線に並ぶ気持ちよさ」なのかもなぁ、と思った。

Haskellなんかを書いてると、究極的に、関数型言語におけるプログラムとは、一引数関数の深い深い一直線の入れ子みたいに感じられる。

(いやまぁ、タプルとかもあるけど、原則的に)

構造化⇒OOPと来て、プログラミング言語Go to hellを廃し、色んな物をDRYに書けるように進化してきたけど、その結果色々なものが並列にばらばらっと並んでいる感じになった。

OOP大本smalltalkメッセージパッシング原則の時点で、対等な二つの並列に並んだオブジェクトのやりとりがベースになっている。

勿論オブジェクトは大体内部に別のオブジェクトを抱えていたりして、親子関係があるのは普通だけれど、子同士はやはり並列に順序なく並んでいる。

この並列性のおかげで、例えばそれこそメッセージパッシングをそのまま引き継ぐErlangなんかは、高いスケーラビリティと耐久性を持つわけで、これ自体は素晴らしい発明だ。

ただ、やっぱり並列なヤツラが、ごちゃごちゃっと同時にあって、そいつらが同時にガチャガチャなんかやってたら、神の見えざる手的に、なんとなく全てが上手く噛み合って、プログラムが動きます、って、これどうしても全体像を把握しにくい。

人間脳みそって、そんな同時並列のものを把握できるようには、出来ていないんだと思う。

上手く動いてはいるんだけど、何で上手く行ってるのか分かるんだけど、分かりにくい。

この気持ち悪さが、今日もどこかのITおじさんを全部staticな書き方に走らせ、OOPわかんねー、と首をかしげながら、何となく使ってる人達の心を、巨大なメソッド作りに導いているのではないかな、と。

なんてったって、Scalaなら並列処理でさえ、モナドなFutureで事実上直線に繋いでいってかいちゃう(Akkaもあるけどあれはオブジェクティブな側面なので)わけで、これは凄く懐かし気持ちいいと思う。

かくして関数型言語は「なんかとにかくきもちいいぃぃぃぃ」な信者を量産している。そしてOOP派との間に、意味分からん溝だけが広がっていく。

2014-10-09

Haskellerが嫌い

Haskellerが嫌い

Haskellはきらいじゃないけど

Haskellerのあの偉そうな感じが受け付けない

Haskell先進的だからだろう

自分

Haskellが好きです」

って言って

相手に

「え? まだそれ? 面白いの?」

って言われないと確信しているあの感じ

しろ言語ユーザ自分よりフィロソフィーが足りないと思ってそうなあの感じな

普通は尖った言語なんて使ってたらそうなっちゃもの

先進的な言語を使うこと自体が悪いわけではないけど、

Haskell好きだけはここ十年くらいプログラミング言語DISを受けていないから結果的に奴らは増長しているのだ

しろHaskellを使っていることがなんかステータスになると思っているのだ

これからは目を爛々と輝かせたHaskellerに上から目線

Haskellが好きです」

と言われたら

「あーIOモナド副作用じゃないよ詐欺言語だよねー」

と返事を返すことにしよう

そうしようじゃないか!

http://anond.hatelabo.jp/20141009194334

2014-07-17

関数型入門以前

これ読んでも関数型分からないけど、入り口の前あたりに立つために

関数型言語覚えたらなんの役に立つの

プログラマとしての引き出しが増える。

って書くと「そんなもんどんなプログラミングテクニックだって一緒だわ」って言われそうだけど、でもそうとしか言い様がない。

とりあえず、オブジェクト指向と同じで、プログラム構造化して、複数レイヤーに切り分けて部品化していくテクニックだとは言える。

ただオブジェクト指向とは大分切り口が違う。何ていうか、割と直交する切り口でプログラム構造を切り分けていく。

なので、関数型とオブジェクト指向と両方憶えるだけで、大分切り口の引き出しが増える。

オブジェクト指向関数型両方憶えると、プログラマとしての引き出し増やすのに効率が良い、って思えば良いかも。

具体的にどう切り分け方が違うの?

オブジェクト指向は、プログラムの各部品を「あれの中のこれの中のそれの中にあるあれ」みたいな感じで組み合わせる。

部品が更に細かい別の各部品で構成されていて、それぞれの部品が噛み合わさって、複雑な一つのプログラムを構成するような切り方。

関数型言語は、プログラム部品を「あれをした物にこれをした物にそれをした物にあれをする」みたいな感じで組み合わせる。

もっというとプログラム全体を簡単に記述するできるDSLがあって、そのDSLを簡単に実装するためのDSLがあって、DSLの入れ子構造で一番小さい部品シンプル関数、みたいな切り方。

どう使い分けたら良いの?

ケースバイケース。

ではあるんだけれど、シンプル部品を大量に組み合わせて構成するのがしっくりくるならオブジェクトで、部品数が少ないんだけど一個一個が複雑な動作する構成にしっくりくるのが関数型……かも?

関数型言語の紹介見てると、何かひたすらイミュータブルなデータを弄繰り回す説明ばっかり出てくるんだけど…

関数型言語たる条件として「関数が第一級オブジェクト」ってのがあるんだけど、関数が第一級オブジェクトだとイミュータブルなデータを素直に扱える。

で、イミュータブルなデータ構造使うと色々便利、ってことで実例として一番出てくるという。

何か型型言ってるんだけど、型くらいC言語にすらあるわ。メモリ領域の確保量を示すあれが何でそんなに重要なの?

関数型言語エポックメイキング的な言語が三つくらいあって、元祖Lispとその流れ汲んだMLMLの一種で関数型をある種の到達点に持っていったHaskellって感じ(独断偏見)。

で、このうちのMLって奴が、プログラミング言語に型システムがついてるんじゃなくて、型システムプログラミング言語がついてきた存在だったりする。

型で色々やるために生まれたわけで、まぁなんというかそもそも型と密接な関係にあって、Haskellもその流れを汲んでて、こいつが超有名になった、って感じ。

おかげさまで、型使って色々やったりする方法が日々考えられているわけです、静的型付関数型の世界では。

クロージャって、大まかな概念wikiとかで理解したけど、関数型でどう使われてるの?

関数型言語ではよく「関数関数を引き取って、合成した関数を返す関数」みたいなのが使われるんだけど、関数関数の合成って、それ合成された関数がもともと引数として与えられていた関数憶えてないと無理やん? 自分自身の構成部品憶えてられないわけだから

クロージャあると憶えててくれるわけですよ。

そんな感じで高階関数実用的なレベルで使うのには大体必須と言う。

モナドとやらは何に使うものなの? 何が便利なん?

関数型言語DSLを作りまくる言語みたいに書いたけど、モナドちょっと複雑なDSLを簡単に作らせてくれる仕組みだと思っとけば良い。

Haskell副作用が一切ない純粋関数型言語って言うけど、副作用なしでどうやって入出力してるの?

まず純粋定義だけど「全ての関数は同じ引数を与えられた際、必ず同じ値を返す」ってことで、これがいわゆる副作用がないって状態だ。

で、これって逆に言えば「プログラムである関数に対して、絶対に同じ引数を与えさえしなければ、その関数がどんな値を返したところで、事実上純粋だと言えてしまう」ってことでもある。

本末転倒感があるんだけど、HaskellではIOモナドという仕組みと特別main関数を使って「呼び出すたびに絶対に違う引数自動的関数に与えてくれる仕組み」を実現していて、こいつを使って入出力する。

うん……凄い本末転倒。ちなみにこの自動的に与えられる引数はRealWorldって名前がついていて、要は「刻一刻と変わり続け絶対に同じ状況にならない現実世界の状態を引数に取っちまっているようなもんだからしょうがないだろ?」的な感じ。

2014-06-19

http://anond.hatelabo.jp/20140619010953

純粋なrandom関数は、引数に渡したseed値に対して、同じseedには必ず同じ値を返す。

一つ前の乱数を再びseedにするやり方で、いくつもの乱数純粋に取り出せるよ。

もちろん初期値が一緒なら、起動するたびに同じ答えが返るけど。

で、初期値を起動するたびに変えたいってのを純粋にやるなら、IOモナド使うことになる。

手続き系とFPどっちのが分かりやすくなるかは、ケースバイケースだから使い分けろ、ってのは正しい。

追記:

ってよく見ると、ランダム値列の作り方じゃなくて、あくまでどうやって返す関数書くか、ってことか。

それならIOモナド使うまでもないので、自分的に書きやすScalafp形式で書いてしまうけど

val rands = Seq(10,20,1,6,8,0,0,0,20,10)

def f(xs: Seq[Int]) = xs.slice(0, xs.scanLeft(0){_ + _} takeWhile {_ <= 50} size)

f(rands)

でいけると思う。

2014-05-15

未来の為の寛容さ

関数本と称したデタラメ本なんかどれだけ高く平積みしたところで、どうでもいいと思ってるよ。間違って買っちゃった初心者右往左往するだろうが、きっといつかは正しい知識に戻ってくるだろうし、それで諦めちゃう人はどのみち辞める定めなんだろう。たとえQiitaとかで議論を吹っかけられようと、話し合いが成立しないと判った時点で席を立てばいい。煽られようとワザワザ付き合ってやる必要はない。でも実際のお前らは腹を立て、戦い、傷ついてPTSDになって、数スレを消費した。そんなナイーブなお前らが、今回の事件は何故かスルーできた。

悪意のカタマリだろうと、他愛のない道化はむしろ放置でいいと思うんだよ。色んな奴がもっと好き勝手に書くべきだ。ちゅーんさんはモナド本を書いていいし、漫画解説する関数型があっていいし、遅延評価解説本は望まれている。市井プログラマー素人技術本を書いていいんだ。関数型プログラミング繁栄はそういう態度の先にあると思う。選択肢は多い方がいい。その中で、何が本当に重要かは読者が決める。ヘンテコリンな奴をありのまま受け入れる寛容さは必要だと思うんだ。

でも今回のはそれに収まらない。重要さのレベルが違うだろ。どこぞの馬の骨じゃない。あの子日本Haskellコミュニティの若手ホープじゃないか。今は女性関係で腹を立てているだけかもしれないが、将来トップに立った彼に「あなたライブラリは負の価値しか持ちません」っつって包丁画像突きつけられたらどうする。Slackでは「勉強会に参加する学生が少ない」とか嘆かれてたけど、俺が学生なら、もはや頼まれても行きたくない彼女言及しなければ安全? 俺はそんな風には全然思えないし、正直不安だよ。



…いや、だからどうしろって言う意見はない。どうすればいいかは判らない。お前らの冷静さにビックリしたというのが感想だ。他人が頭ごなしに言っても伝わらないだろうし、本当に必要なのは排斥することじゃなくて、自分の考えを親身になって聞いてくれる仲間だと思う。ただ正論ねじ伏せるのでなく、それでいて「単なる腰抜け」じゃない誰か。

彼はスレ民でもあった筈だが、ム板のこのスレはそういう話に適さないだろう。俺たちが場を提供することはできない。勝手だが身内に期待したい。圏論の話ならいつでも歓迎です。

以上、スレ汚し済まなかった。コードポイントフリーにする作業(たのしい)に戻ります

--------------------------

この文章は当初2ちゃんねるプログラムHaskellスレに投げる予定だったが、スレ汚しになると判っていて書くのもどうかと思い、失礼してこちらに置きました。あとリツーイータビリティ。(この記事リンクフリーです)

2014-04-22

http://anond.hatelabo.jp/20140410183410

すごい今更だけど、1に対してだけ少し。

基本的に、まだ発展途上にあるものほど、理論面が強調されがちなんだと思う。

今の関数型言語は、まだデザインパターンが、色々発案されだしているけど、確立しきっていなかった頃のJavaオブジェクト指向時代、みたいな感じ。

Javaで言うデザパタは、関数型言語では大体、モナドとしてまとめられるわけだけれど、そのモナドを色々発明するために、圏論をしっておくに越したことはない、みたいな感じなんじゃないかと。

もっとも、そろそろすでに出てきているデザパタモナドを利用するだけの、純粋学習者も増え始めている頃合だから、気になりだしては来るタイミングなんだろうけど。

2014-04-10

プログラム中級者が感じる関数型の違和感

なんだか話題になってるから書く。

やっと初心者を脱して中級者になりかけてるプログラミング学習者が関数型言語に何を感じているかを書こうと思う。

1 圏論かいらないんじゃないの?

Haskellが短いコードプログラムを書けるというのは分かる。

forループmapやfoldで抽象化する利点も分かる。

それでやりたい処理のほぼ全てがまかなえるということも実感している。

副作用のない小さな関数を合成して大きな関数を作る利点も分かる。

再利用性も上がるし、どこからどう影響を受けているかが簡単に分かるからバグも出にくい。

ただ、Haskellの基礎になってる圏論が何の役に立つのかは、まったく分からない。

むしろ邪魔なんじゃないかと思う。

ファンクターやモナド概念圏論で扱われているのは分かるけど、圏論なんて名前だけ知ってればコードを書くのに不都合はないだろう。

圏論必要なのはHaskell設計する人であって、使う人ではないと思う。

なのに、やれクライスリ圏だ自己関手の圏だのと、うるさいったらありゃしない。

Linux上で開発環境整えるのにカーネルコードを読めって言うぐらい的外れだと思う。

いや、知識として持っとくのはいいだろうけど、役に立たんだろ。

2 言うほど新しい機能ないような?

Rubyが羊の皮をかぶったLispとはよく言われることだけど、関数型言語オブジェクト指向言語とそこまで違いがあるような気がしない。

純粋言語ではできないけど、クロージャに内部状態を保持してもらって無名オブジェクトみたいな使い方をすることはあると思う。

その無名オブジェクトもっとあれこれデータ関数詰め込めば、いつの間にか普通にJavaC#で使うようなクラスのできあがり。

その間はなめらかにつながっていて、不連続に切れるようなもんじゃない。

関数プログラミングと言いつつ、オブジェクト指向の考え方は利用できる。

上級者はデザインパターンdisるのが好きかもしれないけど、逆の考え方をするべきだと思う。

デザインパターンオブジェクト指向言語欠点を補うための苦肉の策じゃないよ。

関数プログラミングの基礎的なパーツだと思う。

からちょっと見た目がすっきりするだけで、結局やることはオブジェクトプログラミングと変わりはないと思う。

3 なんか選民思想にとらわれて無い?

関数プログラミングコミュニティの人って、業務でクソコードメンテさせられて、その現実逃避に美しいコードに擦り寄っているように見える。

もちろん、美しいコードを書けるなら書いた方がいいし、現代的な言語を使えるなら使ったほうがいいと思う。

けど、適材適所というか、オブジェクト指向言語でも、やってやれないことはないわけで。

役に立たない圏論をありがたがる所とか、どうもイキがってるように見える。

せいぜい生産性が倍になる程度で、他の要素が悪ければ帳消しになるような利点でしかないに違いないのに。

開発プロセスとかを見直す方が仕事を楽にしてくれるんじゃないのかな?

http://anond.hatelabo.jp/20140410134501

id:minamiyama1994 さん、反論してくださってありがとうございます

Haskellファンのご意見がいただけて嬉しいです。元増田です。

記事全体で「関数型言語」と呼ばれているものは「関数型言語一般」ではなく「Haskellや一部OCamlの話題を含むごくごく一部の言語」の話である

わかりにくくてすいません。記事では「関数型言語」の話はしていません。「関数型プログラミング」の話をしました。

関数型言語」は範囲がよりボンヤリとした表現です。たとえばC言語関数型言語かどうかをみても賛否両論にわかれるでしょう。

私が記事を書いた目的は、”関数型プログラミングに縁のない人に関数型プログラミングをわかりやすく紹介したい”でした。

その目的のため、「関数型言語」という表記を注意深くとり除き、代わりに「関数型プログラミングサポートした言語」という言い方をしています

このスタンスの上で、

関数型プログラミングをフルにサポートした言語”の代表として、Haskellを紹介し、

関数型プログラミングへのサポート片手落ち言語”として、LispErlangなどを扱いました(それらのファンの皆、ごめんなさい)。

言語パラダイムの話題」と「言語の話題」と「ライブラリの話題」と... を混同している

関数型プログラミング初心者の方は、それらの差異なんてどうでもよい、と考えるのではないでしょうか。

関数型プログラミングとは何が良いのか、を大雑把に知りたい。

そうなのではと考えて、あえて区別せずに記事を書きました。

「たとえばモナドを知っていれば、30分程度でパーサー(解析機)を理解することができて」? モナドはそんな限定的用途のものではないし、パーサの理解とは無関係だ(単にライブラリ設計の問題)。それにApplicativeスタイルのほうがパーサが書きやすいという人もいるだろう

id:minamiyama1994 さんの仰るとおり、モナドはパーサー以外の多くの応用があります

現状多くのパーサーがモナディックパーサーとして書かれていますモナディックでないパーサーは、あまり多くのユーザーには使われないでしょう。

モナドなどの抽象的な構造が幅を利かせてるお陰で、ライブラリに秩序が生まれ、ユーザーはそれを使いやすく・読みやすくなっている、というのが私の言いたかった主張です。

(なお細かいことで恐縮ですが、ある種のモナディックパーサーはApplicativeでは書けません。その点をお忘れですよ)

テキスト処理」に対して

お前それShellやPerlRubyPythonの前でも言えるの?

GUI」に対して

GUIライブラリ設計にもよるけど、GUIってOOPの強い分野だと認識していたのだけれど、さてはて

この二つは、先人が不利な環境ですごく頑張った成果が現状なのだ、と思っています

本質的には関数型プログラミングの強みが活かせる分野のはずです。

「個人の技量の話題」

レシピ」に関しては、関数型プログラミングスタイルでは、手続きを手続きとして自然表現できるのに対し、オブジェクト指向ではできない(DSLチックなものになってしまう)、ということを言いたかったのですが、

わかりにくかったですね。

「書きやすい」

(*)関数の例で、関数型プログラミング無駄の無さを示せた、と思ったのですが…

僕自身はC++Haskellの両方を書く人間で、確かにC++の方が「短く書ける」と「感じる」ことは多い

マヂですか…反論のためのでっち上げとかじゃなくて(失礼)?(追記: Haskellの方が「短く書ける」、のタイポだそうです)

記事そのもの価値基本的にないっぽい、こういう記事撲滅されないかなぁ

Haskell布教のために有休とって4時間かけて書いたのにーw

撲滅…

ショボーン(´・ω・`)

http://anond.hatelabo.jp/20140409010816

いくつかまとめて反論したい

まず最初に言っておきたいけれども、僕自身はHaskellが大好きな関数型言語大好き人間である、ということを先に述べておきたい、それを踏まえた上で以下をお読みいただきたい

最初の「オブジェクト指向 v.s. 関数型プログラミング」や「ふたつのアプローチ比較」はまあ問題ないかなぁという感じ、問題があれば他の誰かに任せます

問題は「関数型プログラミングの利点」と「関数型プログラミングの得意分野はなにか」

関数型プログラミングの利点」に対して

まず「関数型プログラミングの利点」だけれども、ファンクタが云々、モナドが云々、これは「関数型言語の話」ではなく「Haskellの話」である

そこを引いてあくまでHaskellの話だと割りきって見たとしても、「たとえばモナドを知っていれば、30分程度でパーサー(解析機)を理解することができて」? モナドはそんな限定的用途のものではないし、パーサの理解とは無関係だ(単にライブラリ設計の問題)。それにApplicativeスタイルのほうがパーサが書きやすいという人もいるだろう、パーサの理解モナドの知識はあまり関係がないと言っても差し支えないのではないか

「書きやすい」に対して

「書きやすい」に関してはこれはもう「主観の問題だよね」以上の言い様がない、僕自身はC++Haskellの両方を書く人間で、確かにC++Hakellの方が「短く書ける」と「感じる」ことは多い、がしかしそれはあくまで個人の主観であり、更にはなにか明確な基準を取ったとして、やはりこれは「関数型言語」ではなく「Haskell」の話である、わかりやすく言えば「関数型言語であるLispを僕は読み書きできない」、特定言語の、主観に大きく左右される特徴を関数型言語一般の話であるかのように敷衍して話すのは感心できない

「静的型付け云々」に対して

「静的型付け」云々もこれはもう完全にHaskellOCamlの話であるLispErlangとは何だったのか

関数型プログラミングの得意分野はなにか」に対して

数値計算」に対して

多くの数値計算アルゴリズム逐次的に定義されている、関数型言語で扱いやすものではない、簡単にいえば「それFortranの前でも言えるの?」である

遅延評価はこれまたHaskellの特徴であり関数型言語一般の特徴ではないし、別に他の非関数型言語エミュレートできないものでもない、更に言えばこれが何か数値計算に対して有利な何かをもたらすかといえばそういうわけでもない

分数虚数が扱えます」、に至ってはむしろ近頃の言語で扱えない言語何かあるんですか、である、大抵の言語にはその手のライブラリはある、関数型言語に限った話ではない

テキスト処理」に対して

お前それShellやPerlRubyPythonの前でも言えるの?

「並行処理」に対して

この手の話は「ライブラリ」の話になり、言語パラダイムにより議論されるべき問題ではない、もちろん自動並列化などの問題で数学モデルに基づいていることが多いHaskellなどは有利かもしれない、が、やはりそれは特定言語特定ライブラリの話になり、関数型言語一般の話ではない、並行処理の扱いにくい関数型言語設計など容易だろう

レシピ」に対して

言語の話でも言語パラダイムの話でもライブラリの話でもない、個人の技量の話だろう、関数型言語でも下手にしか書けない人は上手には書けない

GUI」に対して

GUIライブラリ設計にもよるけど、GUIってOOPの強い分野だと認識していたのだけれど、さてはて

まとめ

最後に要点をまとめると

記事そのもの価値基本的にないっぽい、こういう記事撲滅されないかなぁ

2014-04-09

オブジェクト指向 v.s. 関数型プログラミング

近年、関数型プログラミング重要はいろんなところで叫ばれています

Javaの最新バージョン関数型プログラミングに関する新機能が加わりました。

Rubyも昨今、関数型プログラミングへのサポートが手厚くなってきています

プログラミング教科書大手オライリーからJavascript関数型プログラミングを行うための解説書が発行されました。

関数型プログラミングへの注目度は高まってきています

おそらく、みなさんは既にオブジェクト指向が何か、を知っています

でも関数型プログラミングとは何か、胸を張って語れる人は、周りに見当たらないかと思います

実際、オブジェクト指向によってプログラミングする方法は、わかりやすい解説があちこちにある一方で、

関数型プログラミングとは何か、何が良いのか、ということについての、よいまとめは見つけることはできませんでした。

この記事を読む方の中で、「関数型プログラミングを取り入れるか・取り入れないか」で切実に悩んでいる人は、おそらくいないでしょう。

この記事はあまりかいところに立ち入りません。関数型プログラミングを使う側の立場に立って、利点や向き・不向き、それが導くスタイルを書きました。

みなさんは鳥のように飛んで、高い空から関数型プログラミングとは何か、何が良いのか、を見渡してください。

ふたつのアプローチ比較

オブジェクト指向アプローチは、名前をつけてプログラムを整理する

関数型プログラミングアプローチは、汎用部品でなんとかする

オブジェクト指向アプローチ

Googleが近年リリースした言語、Goには、”継承”を直接サポートする仕組みが無いことが話題になりました。

また、Mac OSXの基幹ライブラリCore Foundationは、ライブラリ自体C言語で書かれているにもかかわらず、その設計方針は明確にオブジェクト指向です。

継承クラスは、オブジェクト指向必須条件ではありません。

オブジェクト指向本質とは、何でしょうか。

その本質とは"名前をつけて対象を識別し、それを扱うこと"、にあります

最もプリミティブなオブジェクト指向対象は、ファイルハンドラです。あるファイルを開いて、読み込んで、あるいは書き込んで、ファイルを閉じる。

これらの処理をまとめたら、わかりやすいですよね?

対象に関する処理を、対象の周りにまとめる。これがオブジェクト指向の基礎的な理念です。

識別することとイコール比較できることは、とても良く似ています

イコールによる比較は、オブジェクト指向では鬼門であることが知られています

PointクラスインスタンスとColoredPointクラスイコール演算をどう決めればいいかに、正解はありません(詳しくは"effective java"をご参照ください)。

また名前をつけて識別する対象は、フワフワしていてはいけません。

たとえば、"軍人階級"をオブジェクトにしたとしましょう。"大佐"クラスのある兵士名前フィールドや、性別フィールドを持っているでしょう。

ところで彼が昇格したときに何が起こるでしょうか。

新たに"少将"クラスインスタンスが作られます。"大佐"クラスを破棄する前に、名前性別、その他沢山のデータを引き継がなくてはいけません。フィールドを増やしたい場合はその都度コード修正を加える必要があります(*)。

なるべくイコール比較を避けたい。対象不安定なものはいけない。では何に名前をつけて、識別するか。そこにオブジェクト指向技術者の熟練度が現れるのです。

関数型プログラミングアプローチ

一方、関数型プログラミングでは、特定の何かに名前をつけるより、極力、汎用部品でなんとかしようとしま

さな関数を、集めて撚り合わせて、新しい関数を作る。

関数自体リストなどのデータ構造に詰めることもよく行われます

実は、関数型プログラミングというのは本質を表していません。

その真の名は、"値指向プログラミング"です。

関数をはじめとして、リスト・ツリーのようなコンテナ手続きを抽象化したもの、回路を抽象化したもの

あらゆる対象を値として、合成し、ときに分解し、新しい値を作ります

変数という概念必要ありません。

変数適用する処理を作りあげることが、とても簡単だからです。

四則演算定義されたデータを詰めたデータ構造もまた、四則演算可能だったり。

値をイコール比較することも、なんのそのです。

誤解を恐れずに言うと、オブジェクト指向トップダウンなのに対し、関数型プログラミングボトムアップです。

関数型プログラミングの利点

読みやすい・理解やす

関数型プログラミングサポートする言語には、沢山の汎用部品定義されています

このような構造インターフェイスとして、様々なライブラリが組まれているので、

たとえばモナドを知っていれば、30分程度でパーサー(解析機)を理解することができて、

パーサーを理解できれば、JSONパーサー・ XMLパーサー・markdownパーサー・C++パーサー ... などを理解するのはとても容易です。

理解やすいこと。これが関数型プログラミングの大きな利点です。

追記:

また、汎用部品と型のお陰で、ライブラリドキュメントが圧倒的にひきやすい、というメリットも有ります

Haskellな人がPythonにトライした結果 - Togetterまとめ

書きやす

関数型プログラミングは「厳密な事前設計必要とするため、簡単なことをやるのにも時間が掛かる」。

よく誤解されていますが、これはウソです。

スクラッチプログラムするのは、非常に手軽です。

>> map (*2) [1,2,3]
[2,4,6]

邪魔な”儀式”や、"おまじない"のコードが徹底的に撤廃されているためです。

関数型プログラミングコードは、潔癖かつ濃密です。

たとえばC言語でint hoge(int x,int y)が定義されているときhoge(3)はなんの意味も持ちませんが(コンパイルコケますが)、関数型プログラミングでは意味があり、実際に有用です。

上の例では、「掛け算をする」(*)関数は、二引数関数ですが、それに引数を渡して作られた「2を掛ける」関数(*2)は、一引数関数になります

関数型プログラミングでは、「簡単なことは簡単にでき、複雑なことは複雑にできる。ただし、間違ったことは殆どできないか、全くできない」。

多くのバグは、コンパイルエラーとして検出されます

また、静的型付けの力によって、コード補完は非常に強力になっていますインテリセンスの比ではないです。

たとえば、関数中のある表記の型を任意に表示できます(GHC/TypedHoles - HaskellWiki)。

やがてやってくる未来には、プログラムテキストエディタで書くことは時代遅れになっているでしょう。

統合環境サポートで、バグミスの少ない、スムーズプログラミングができます

そしてその環境で動くプログラミング言語は、関数型プログラミングサポートした言語なのです。

いつ関数型プログラミング

以下の様な兆候を感じたら、あなたはそのプログラム関数型プログラミングで書くべきです。

一般に、オブジェクト同士の相互作用が複雑になるほど、オブジェクト指向では手に負えなくなっていきます

そういうときは、オブジェクトを直接扱わず、替わりにその"相互作用"を扱うことで、複雑さを軽減するアプローチ有効です。

それこそが関数型プログラミングアプローチです。

オブジェクト指向の利点

初心者にとっては読みやすい・理解やす

特にオブジェクト指向有効なのはプログラミング初心者がそのコードをいじるかもしれないときです。

関数型プログラミングは、強固さと柔軟さの代償として、高い学習コストを伴います

そのため、初学者にとってはハードルが高いのです。

扱う対象があまり複雑でない時は、書きやす

オブジェクト間の相互作用が複雑でなく、着目している(名前をつけている)概念が安定しているとき

そして、プログラムをいじる人たちの間で共通理解が図れているならば、オブジェクト指向が有利です。

関数型プログラミングの得意分野はなにか

数値計算

遅延評価という機能によって、レガシー言語で扱えなかった、巨大な数を扱うことができます

分数を扱うことができます虚数もです。

関数型プログラミングで書かれたプログラムは、正確さが要求される、金融関連の業界で使われています

テキスト処理

手続きとしてパーサーを記述できるので、テキスト処理プログラムはより理解やすく、メンテナンスやすものになります

関数型プログラミングを知らない人は、「正規表現おk」と言いますが、

彼の書いた複雑な正規表現は、半年後には(書いた本人でさえ)理解できなくなっていることでしょう。

並行処理

手続き一般を扱うことができるので、途中で割り込みのある手続きの表現も容易です。

関数型プログラミングサポートしていない言語ではコルーチン(ファイバー)などをつかってなんとかするしかありません。

さもなくば、非並行処理では普通に関数として記述できるところを、並行処理のために、Builder,Strategy,Command,Interpreterパターンを駆使して書き直すことになります

Javascript使いの方は、Deferredなどの構造を使うでしょう(http://qiita.com/KDKTN/items/4c6986049d204f0645d8)。

C++使いの方はBoostで頑張りましょう。破滅的に解りにくいコンパイルエラーメッセージと格闘してください。

レシピ

もう少し簡単な例をあげます

あなたは、あるレシピにしたがって、自動的料理を行うマシン制御プログラムを書いているとしましょう。

料理レシピは、"手続き"ですよね?たとえば、カレー

1. まず玉ねぎを炒める。

2. 飴色になったら、肉を加えて炒める。

3. 野菜を加える。

4. 水を加えて煮る。

5. スパイスを加える。

しかあなたはこの手続きを関数として表現できるでしょうか。

…できませんよね?何故ならば、各ステップの"間に"、マシンのロボアームの位置や動きを調整する処理が必要からです。

これをオブジェクト指向でやろうとすると、各ステップ副作用として、それらの処理を行うことになります

そうすると、マシンが二機に増えた時などの変更量は、絶望的なものになります

あるいは関数として表現するのを諦め、手順全体をDSL記述できるようにします。

このアプローチ関数型プログラミング的です。しか関数型プログラミングサポートした言語の助けなしでは、そのDSL記述するために沢山のユーティリティコードを書かなくてはならないでしょう。

オブジェクト指向アプローチでこの問題をエレガントに解こうとすると、クラス化の粒度を上げる事になります

野菜クラスフライパンクラス、ボイルクラスフライクラス、焼き加減クラス、アームクラス野菜の大きさクラス、切り方クラス、焼き方クラス、"焦げたよ"クラスetc...

こうすると早晩レシピプログラムコードから消え去ることになります。上記のたった5行は、依存性注入のオブジェクトグラフを構築するコードに取って代わることになります。そこには沢山の挙動制御オプションとして付記されているのです。

カレーなど、ある種のレシピ限定することで、見た目の理解やすさを得ることができますが、一方それは表現力を損なうことを意味します。

C言語などではマクロを使うこともできますが、それは結局、関数型プログラミングアプローチ意味するところと同じになります。すなわち、補助のために沢山のコードを書くことになるでしょう。

GUI

iOSのAppstoreアプリは、"無料"と書かれたボタンを押すと、それが"インストール"ボタンに変わり、それをもう一度押すと、ダウンロードの進捗を表すインジケータに変わり、それを押すとダウンロードキャンセルできます

このように、位置は同じなのに、ステートに依って見た目と機能が変わるボタンは複雑です。

これをオブジェクト指向で実現しようとすると、

1. 三つの異なるボタンを同じ位置に置くか

2. 同じボタンが三つの異なる機能を持つか

という下らない問題にぶつかります

一方関数型では、"機能"、"見た目"、"状態"、を独立に扱って、それらを合成してボタンを作るので、迷うことはありません。

「同じ位置にあるUIオブジェクトは、コード上で(インスタンスとして)独立して、他から干渉を受けない」

この条件が満たされているうちは、オブジェクト指向GUIを実現することに無理はありません。

しかし、携帯端末のような小さい画面で、多くの機能を達成するためには、UI要素はコンテキスト依存的に複雑になりがちです。

近年、PCのディスプレイの大きさは、頭打ちになってきました。

画素数は増えているのですが、MacにおけるRetinaのように、複数ピクセルひとつドットを表すようになってきています

これは、ひとつの画面に置かれるボタンなどのUI要素の数は、これから先の未来で増えることはない、ということを意味します。

したがって、未来GUIプログラミングは、注意深く機能ピックアップして制限するというデザイナー努力を脇におけば、

関数型プログラミングの力を頼るしか無いでしょう。

はじめよう、関数型プログラミング

まり

Haskell さいこうなのおおおおおおおおおおおおおおおおおお!! おしっこ漏れちゃうのおおおおおおおおおおおおおおおおおおおお(゜∀。)ワヒャヒャヒャヒャヒャヒャ

1. google:すごいHaskellたのしく学ぼう を注文する。

2. Download Haskell自分のPCに導入する。

3. コンソールghciと入力して、対話コンソールを立ち上げる。

4. 次の関数コンソールに打ち込んで、結果を見る。即値で書かれているところとかをいろいろ変更してみて、感動する。

take 4 $ map (*2) [1..]

5. ステップ1で買った教科書を読んで、学ぶ。


追記:

いかがでしたか

ちまたには、関数型プログラミングの利点は変数が無いことだ、とか、より安全から、とか、より速いから、などという妄言が満ち溢れています

オブジェクト指向関数型プログラミングは、水と油ではありません。プログラマ自分プログラムに最適なアプローチを選ぶことができます

一般にはあまり知られていないことですが、Haskellにもオブジェクト指向へのサポートがあるんです(Lensライブラリ、これを使用したサードパーティライブラリ最近増えてきています)。

この記事を読んだオブジェクト指向プログラマあなたが、少しでも関数型プログラミングに(そしてHaskell)興味を持ってくださって、ホームセンター大人用オシメのコーナーが大賑わいになれば幸いです。。

アーカイブ ヘルプ
ログイン ユーザー登録
ようこそ ゲスト さん