はてなキーワード: 関数型言語とは
最近コンピューターサイエンスがプログラマーに必要か否かみたいな話が上がっているが、そもそもコンピューターサイエンスって何だよ。どこまでの範囲をさしてんの?
ググって出てきた情報を整理しただけなので詳しい人、補足・訂正よろしく!
https://www.acm.org/binaries/content/assets/education/cs2013_web_final.pdf
CS2013はACM/IEEE-CSによるカリキュラム標準。
ACM(計算機協会)はコンピュータ分野全般の国際学会、IEEE-CSはIEEE(米国電気電子学会)の中にあるテクニカルソサエティ。
https://www.ipsj.or.jp/12kyoiku/J07/20090407/J07_Report-200902/4/J07-CS_report-20090120.pdf
J07-CSは一般社団法人情報処理学会がCC2001CSをベースにアレンジを加えたカリキュラム標準。今はCS2013を反映したJ17-CSがあるらしいけどその辺は良く分からん。
https://www.ipa.go.jp/files/000024060.pdf
J07ーCSから抜粋。CS2013と比較するとナレッジエリアがあったり無かったり。
ましてや優れた人から教えて貰うことでもなく
ただただプログラミングを好きになってモノづくりに熱中することだ
小さい子供がプログラミングに向いているのはモノづくりが好きだからであって
これは大人でも当てはまることであって
何かのモノづくりをするという目的の元に手段としてプログラミングが選ばれ
それに熱中することでいつの間にかプログラミング能力は向上していくのだ
上司から命令されてプログラミング講座を会社の金で受講するとか
Googleを目指して学生時代にプログラミングに打ち込むだとか
そんなのは全然上手く行かないのに定年退職したジジイがラズパイ使ってロボ作りとか始めると上手く行くのはそのせいだ
GitHubが発明したPull Requestはこの楽しみを徹底的に阻害している
「ちょっとこの辺は微妙だけど他のことやりたいから適当に済ませよう」
こうした行為はモノづくりからはほど遠く必要無いものに見えてしまい
「早く動いているところを見たい」
やがて開発者はプログラミングそのものに従事して嫌いになっていくのだ
以前からプロの現場ではもっと厳しい品質管理がなされていたという人がたまにいる
PRによってアジャイルの現場に品質管理がもたらされたと主張するのだ
命名規則やコメントの書き方などルール化できるものは別にレビューなど必要無くツールで弾くことができる
バグがあるかどうかはテストで担保すべきであってレビューで見るべきではない
この手のレビュワーが好んで使う言葉として「技術的負債」というものがある
技術的負債を残さないためにもPRで品質を保つ という主張である
一方で技術進歩は止められるわけが無く10年前に必死でクラス設計したJavaのシステムは
またはレビュワーの考える言語化できない「品質」のために今日もPRはリジェクトされる
人はプログラミングを嫌いになっていくのだ
ラテン語・古代ギリシャ語・サンスクリット語のうち、最低どれか1つは読めるようになった方が良いとは思う。
少し前に、ギリシア詞華集に出てくる女性詩人をヒロインにしたマンガが一部で流行って、それで古典ギリシャ語に手を出した人が相当数いたみたいだが、何らかのきっかけでこういう古典言語に入ると広い世界が拡がってる。
それはともかく、たとえばHaskellを勉強して遅延評価関数型言語の妙味を知り、Rustを勉強してメモリ管理の大変さを知り、Goを勉強してCSP代数の面白さを再認識する、などの知的好奇心を満足させる意味で、各言語の特徴を把握した上で勉強するのはすごく楽しいんじゃないだろうか。
さらにバックグラウンドとして、簡単でも良いので半導体ゲートと同期回路がどうCPUやメモリを作り出していったか、を知ると、よりこれらの「プログラミング言語」というものの妙味を味わえるだろう。
金を儲けたければ、浅く広く勉強した上で、どれか1つの言語に絞って、深く、深く、ライブラリと同じ機能は自前で用意できる程度まで深められたなら、おそらく食いっぱぐれはない。
ならないんだよなあ。
そもそも数学とプログラミングはモチベーションが違うんだよね。数学における証明に構成的証明と非構成的証明があるように、「手続き」というのは数学のごく一部でしかない。それに対して、プログラミングは「手続き」が全てだよね(って言うと関数型とかの人があれこれ言ってくるけど、関数型言語だって結局コンパイラが手続きに落とせる範囲のものでしかない)。
機械学習については、論文書いてる奴も含めて大多数はプログラミング脳なので、最初からコードで発想してそれを論文にするために無理矢理数式で書いてるだけというものがほとんど。無理矢理書いた後付けに過ぎないから意味不明なものも多いしコードに落とせないものも普通にある。だから数式は無視して著者のリポジトリにあるコードだけ見てればいいよ。実用の観点ではコード公開されてない論文は全無視で何も問題ない。
(私は入門書(象の絵のやつ)を読んだことがあるだけで、使ったことはまだありません。)
で、関数型言語の良さをアピールするひとからは、いい意味でのの宗教性というか敬虔さを
私は感じるんですよね。
本題。「関数型プログラミングが『銀の弾丸』である という非常識な常識 2022」 と題された長い文章をみつけました。
ここ。https://kentutorialbook.github.io/functionalprogramming2022
まるで熱心な信者による経典なので、ほとんどちゃんと読んでないし読む気も起きませんが、
流し読みをしていて、目に入った 次の一節 がとても私の心に刺さりました。
ーー我々が暮らしている「現実世界」はミュータブル(mutable)なのです。
を撤回させていただいて、
( https://kentutorialbook.github.io/functionalprogramming2022/#n0.19337518569281165 )
ちなみに、ミュータブルは「可変」、 イミュータブルは「不変」の意味。
まあ私も世俗的なSEをやってるので、まっさきに、↓くらいのことは、思うわけです。
多分、プログラミングの世界での、世間一般の反応も似たようなものかと。
ところがですね。
ところがですね。これ、意見戦わせても、たぶん議論でどうにもならず、宗教間の対立みたいなものになる気がするんですね。
というのも。上の文章でとりあげられている数学やら物理やらというのは、おそらくレトリックでしかなくて。
そのレトリックで、伝えられようとしているものは何かというと、
ビジネスの世界だろうが何だろうが、本来、世界は不変なものとして記述されるべき」
なぜなら、私が隠し持っている信念が、まさにそれに近しいものだからです。
物理学の法則が成り立たとうが、物理学の通じないアナーキーな世界であろうが
世界は不変であり、私自身による世界への介入なぞありえない、と直観的に思っています。
だから 「やればできる」 「世界は変えられる」 「努力は裏切らない」 みたいな言葉は大嫌いなわけです。
この直観を私は自分で勝手に、「離人症的世界観」と名付けています。
この世界観の持ち主は多分少数派で、社会から見れば異端どころか、害悪とみなされるかも。だから、隠し持っている。
関数型言語が好きな人も、おそらく私が似た直観と似たものを隠し持っているのでは、と、
私は思うのですね。
もし、離人症的世界観に基づくコミュニケーションが社会に浸透し、
「自分の意志や感情」すら、あたかもファーストクラスオブジェクトとしての関数のように、
客観的に表明されるようなコミュニケーションが、もしこの世の中に広まれば
そうでもならないと、関数型言語は流行らないだろうな。というのが私の予想。
ま、宗教てものは、広まるときは、あっと言う間らしいですから。
ひょっとしたら20年後くらいには、手続き型言語が滅びているかも。こればっかりは分かりませんけどね。
以上!
@kis (id:nowokay) さんの以下の記事についてです。
https://nowokay.hatenablog.com/entry/2021/09/25/042831
ブコメにもあるようにちょっと内容が雑というかわかりにくいせいで賛否両論になってしまっていて、もしかしたら近いうちにアンサー記事が出るかもしれませんが、自分自身の理解を助けるためにも言わんとしていることを推測しつつ、自分の認識もまとめておこうと思い書くことにしました。明らかに誤読してそうな箇所があれば、指摘してください。
まずは前提を書いておかないと論点がぼやけると思うのでいちおう。
その他の前提:
2000年代に入って関数型プログラミングが脚光を浴び始めたのは、コンピュータ資源が潤沢になりパフォーマンスをそれほど気にしなくってよくなったことが大きな理由ではないか、という認識があります。
関数型プログラミング言語の内部実装を読んだことがないので推測ですが、データを不変にするということはその都度メモリ領域を新たに割り当てることになり、そのオーバーヘッドがプログラムのパフォーマンスに影響を与えるので、パフォーマンス要件がをシビアな場合、どうしてもメモリ割り当てや計算効率を考えるとミュータブルにせざるをえないと思います。が、ウェブアプリケーションに限っていえば、データベースアクセスやネットワークアクセスのレイテンシが大きいので、そうした相対的に細かいオーバーヘッドを無視しても(大抵の場合は)問題にならなくなった、というのが「時代」の流れなんだという認識です。
いっぽうで別の観点もあって、REST API や FaaS が一般化して、関数単位で処理を分割し、アプリケーション外部に配置することが当たり前になってきた現状があり、マイクロサービスのようにアプリケーション自体もモジュールの一単位として考えると、アプリケーション内部のモジュール同士でも関数ベースでやりとりする形になっても不自然ではないと考えられます。
元記事にもありますが、RPC の派生(実装?)として生まれた Java の CORBA や Microsoft の DCOM みたいな振る舞い付きのオブジェクト(コンポーネント)を共有しようという世界観は廃れ、REST API のような単一の振る舞い(エンドポイント)とそれにひもづく JSON のようなデータ構造のみを受け渡すやり方が一般的になったアプリケーション間通信の潮流と、計算機資源が潤沢になって再度脚光を浴びた関数型プログラミングが、レイヤーの違いを飛び越えてひとつになろうとしているのではないか、と。
つまり、元記事に書かれている「時代に合ってない」というのは、「データ構造と振る舞いが一体となったオブジェクト」のような「なにか」は、そうした背景があるために、どこにも存在する必要がなくなってきているのではないか、と解釈しました。
なので、以下のコメントはちょっと論点がずれてると思いました。
はあ?「再利用する方法としてはWeb APIが主流」って、その中身をオブジェクト指向で設計することは、全く矛盾しません。 部品化の単位は、慣習や柵などで大きく変わります。オブジェクト指向とはほぼ無関係です。
https://b.hatena.ne.jp/entry/4708813645995359202/comment/suikyojin
なんでサービスとして外とやり取りする話とサービスの内部設計の話をごっちゃにしてんだ。なんか理解度が怪しくない
https://b.hatena.ne.jp/entry/4708813645995359202/comment/ssssschang
たしかに、アプリケーション単位とアプリケーション内部のモジュール単位とでその表現形式を合わせる必要はないんですが、元記事の言わんとしていることはこの一文に端的に表れていると思います。
ソフトウェアの記述をまとめるという視点では主にステートレスな関数を分類できれば充分で、データと振る舞いをまとめたオブジェクトというのは大きすぎる、システムを分割して管理しやすくするという視点ではオブジェクトというのはライフサイクルやリソース管理の視点が足りず小さすぎる、ということで、オブジェクト指向の粒度でのソフトウェア管理は出番がなくなっているのではないか、と思います。
「オブジェクト指向でなぜつくるのか」という本がありますが、「え、いまどきオブジェクト指向でつくらなくない?」っていつも思います。内容的には、もうほとんどはオブジェクト指向関係ないソフトウェア工学の紹介になっていますね。
当該書籍は読んだので後半はまぁわかるんですが、前半は「え、いまでもオブジェクト指向でつくるのが主流じゃないの?」って思ってしまいます(オブジェクト指向の定義が「データ構造と振る舞いが一体となったオブジェクトの集まりとしてソフトウェアを組織化すること」なのであれば)。
Joe Armstrong が "Why OO Sucks" を書いたのが2000年とのことなのですが、そろそろこうした議論は収束に向かってほしいと個人的には思います(とっくに収束していると感じている方もいらっしゃるでしょうけど)。
いらねーよプログラマーとか
じゃねーよアホか
別にいらねーんだよそんな奴
今のDXで一番求められてるのはコンサルなんだよ
「今の流行はこのツールとかこういう方法で、こういう形で実装すればいいですよ!」
とか言う奴はプログラマーな
いらねーんだよ
そうじゃなくて
っていうのとか
ってちゃんと分かる奴
ただの知識としてプログラミングできますとか、つまんねーゲーム作れますとか、しょーもないオープンソースの端っこの方を書きましたとか
そんなの全然いらねーの
ちゃんと人・部署・会社・社会それぞれに応じた世界観を感じ取って
そんじゃそんな能力をどうやったら作れるか、教えてやるよ
そんだけだ
テーマはなんでもいいから社会そのものを具現化して体系化して整理する
これを毎日やるだけ
コンサル出来る奴は話聞きながらそういう絵を頭の中に瞬時に描いている
まぁ、とはいえ悪いがこの手のコンサル業界にはそういうのを小学生からずーっとやってきててなおかつ天才ってやつしかいねーから
おう!外部キー制約を語るとは、RDB を勉強しているのだな?いい心がけだ。増田は外部キー制約があると「どんなメリットがあるか知りたい」のだな?良し、答えてやろう!外部キー制約があると「変なデータが入らない」ということが開発者が『保証』できるのだ。うん、それで?って増田は思うだろう。それで、実例を挙げるけど、sex というカラムを create で作ったときに、そこに insert into で入る値が「男」「女」「その他」というデータに限りたいときが設計者にあったとする。そうすると、「 insert するのは『チンポ』でしょ?」みたいなアホを防げるだろ?もちろん、limit みたいな副クエリで実装しても構わない場合もある。型を指定して、boolean にしたい場合もある。だが、「入るのはこれだけだと思うが、後に追加で変更できる」としたら、嬉しい場合があるのじゃ。まぁ、究極的に OOP や関数型言語、または(古い)命令形言語だと、enum みたいなものなんだよ。いや、だとしたら、enum でよくね?って思うのなら、リプライくれ。答えるから。
Scala や Elm と Lisp やら Haskell と OCaml に SML と関数型のプログラミング言語を勉強したけど、これらが命令型言語に劣る理由を解説しよう。
これは、SQL も同じ問題を持っているが、関数型言語は「こういうふうに動いてね」という解釈をインタープリターやコンパイラが「推測する」必要があるのだ。つまり、書いているときにパフォーマンスをプログラマーが想像できない。
それが、現実的に厳しいのだよ。マジでコンパイラ関連は金にならない領域になってきたので、関数型言語のための独自コンパイラを作る持続可能な組織が無い。確かに、LLVM を使えば x64 や arm といった最新のアーキテクチャに対応できるかもしれないけど、フロントエンドのレベルすら応対が辛い。よって、関数型言語は C言語にてチューリング完全な同等なコードだと「いくら最速に書いても」遅いのである。
例えば if と書いたら、関数型言語は else が必須ですが、命令型言語は else 無しでも動いちゃうのですね。文系の連中が数学的な背景を加味して要件定義できると思うか?違うだろ。毎回、上に else のことについて聞いたら、プログラマーの生産性は下がるだろ。関数型言語は、上が文系だとますますだが、分岐もきっちりとおさえる必要があるから、生産性は命令型言語に劣るよ。