質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

関数型プログラミング

関数型プログラミングとは、関数を用いて演算子を構築し、算出し、コンピュータプログラムを構成する枠組みです。

Q&A

解決済

4回答

5528閲覧

関数型プログラミングって何なのですか!?

退会済みユーザー

退会済みユーザー

総合スコア0

Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

関数型プログラミング

関数型プログラミングとは、関数を用いて演算子を構築し、算出し、コンピュータプログラムを構成する枠組みです。

0グッド

6クリップ

投稿2017/08/16 23:55

react.jsとreduxを使ってコードを書いてると、reducerやaction creatorなどの関数をよくimportして使いますが、オブジェクト指向とは勝手が違うので、こんな関数ばっか使ってて良いものなのかと不安になります。

そもそも、オブジェクト指向で関数やユーティリティクラスが敬遠される理由って何なのでしょうか?(敬遠されてますよね?)

関数を多用するということは、OOPで敬遠されてるものを多用するってことになると思うのですが、関数を多用して上手いことアプリケーションの設計って出来るものなのでしょうか?

□補足
reducerはpure functionですが、action creatorはpure functionではないですね。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_Victorique__

2017/08/17 00:44

とりあえずググってみてその上での疑問などを載せた方がいいんじゃないですかね
退会済みユーザー

退会済みユーザー

2017/08/17 10:29

簡単にググってはいるんですけど、よー分からんですね。higher order xxxもpure functionも普段、自然と使ってるんですけど、関数型プログラミングを意識していたことはなく。。。ダメだ、よくわからん。
_Victorique__

2017/08/17 12:18

その"何"がよー分からんのか書かないと回答する側も分からない訳ですよ。俗に言う何が分からないのか分からないってやつです。
guest

回答4

0

「関数型言語」に関するFAQ形式の一般的説明
(同記事の"蛇足"にありますが、執筆者のバックグラウンドがしっかりした信頼できるドキュメントだと思います。)

実際に関数型プログラミングをサポートする言語を、あなた自身で触ってみるのが近道ではないでしょうか?

投稿2017/08/17 01:40

編集2017/08/17 01:43
yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/08/17 03:37

オススメはSCALAでしょうか? ハスケルでしょうか? 求人で見かけるのはSCALAかな。。
yohhoy

2017/08/17 12:23 編集

関数型プログラミングはパラダイム(≒設計方法)ですから、今お使いのプログラミング言語にも適用可能です(実際には向き・不向きがありますが)。 書籍「関数型プログラミングの基礎 JavaScriptを使って学ぶ」 https://www.amazon.co.jp/dp/4865940596 などもご参考に。
guest

0

ベストアンサー

そもそもの所「敬遠されてますよね?」がfalseなんで、質問文の大部分が息してないかな…

敬遠されてますよね?

関数型プログラミングと、オブジェクト指向プログラミングは
それぞれが単体で副作用の管理が出来るという話であって、相反するものではないから共存可能だよ。
それを証拠にScalaやF#みたいな折衷案な言語も多数存在する。

OOPが敬遠されるのは腕が伴わないエンジニアでも動作はする糞みたいなコードが作れるのが原因。
関数型言語もちゃんとした腕が伴わなければ読みづらく処理効率も悪い糞なコードになる。
昔よく言われていたPHPerなんかと同じで、優れたエンジニアも多いけど、のけぞるコードを書く人も多く、風評被害にあってるのと一緒。

因みに折衷案にするとこんな使い分けな印象

  • 関数型:リスト操作が上手い、宣言的に書く事でバグを減らせる、スマートな演算子を使ってシンプルに書ける
  • オブジェクト志向:連想配列に型を持たせたり、プロパティやメソッドを保証する

関数型プログラミングって何なのですか!?

対義語はオブジェクト指向プログラミングではなく命令型プログラミング。
命令形プログラミングの象徴がx = x + 1

命令形プログラミングはマシンの都合に寄り添った書き方なんで、
参照透過性がなかったり、副作用があったりという犠牲を払う事が多い。
結果的に速度出やすいがバグが多くなりがちという泣き所がある。

関数型プログラミングは命題を書くように意識することで副作用を管理する。
参照透過性があり、かつ副作用のない関数はテストし易く動作を保証しやすい。

投稿2017/08/17 15:28

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

私の解釈です。これが正しいという保証はありません。


私は「関数型プログラミング」とは「副作用が一切無い道具だけでプログラミングする時の標準的な考え方」と考えています。

いわゆる関数型プログラミング言語を使用すること、関数型プログラミングを考慮したライブラリを使用すること、副作用が一切無い純粋関数を使用すること、全ての変数や関数が参照透過性を有していること、高階関数を使用していること、等々は「関数型プログラミング」の必要条件でも十分条件でもありません。あくまで、考え方、書き方、スタイル、ロジック、アルゴリズムであって、何で実現しているかは関係ありません。もちろん、オブジェクト指向であるとかないとかも一切関係はありませんし、関数であろうがメソッドであろうが、関数型プログラミングである場合もあれば、ない場合もあります。

もうちょっと具体的な話をしましょう。有名な例として整数値の配列に対して全ての値の和を求めるというのがあります。コードはJavaScriptで書いてみました。

  1. 配列arrに複数の整数値が順番に入っている。
  2. 和を入れる変数sumを用意し、0に初期化する。
  3. arrから一つ整数値を取り出し、それを変数valueにいれる。
  4. sumとvalueを足して、その結果をsumに入れる。
  5. arrが空で無ければ、3.に戻って繰り返す。
  6. sumの値を出力する。

JavaScript

1const arr = [2, 5, 7, 11, 13]; 2let sum = 0; 3while (arr.length !== 0) { 4 const value = arr.shift(); 5 sum = sum + value; 6} 7console.log(sum);

上の考えのコードは随所に副作用が見られます。一つはarrがループが回る度に一つずつ減っていき、最後に空になります。もう一つはsumがループの度に値が変わります。このように副作用を前提にして考えたコードは関数型プログラミングではありません。では、副作用が無いようにするにはどうすれば良いのでしょうか?

  1. 前値preと配列arrayを引数として受け取る、次のような関数sumArrayを定義する。
    ①arrayが空であればpreをそのまま返す。
    ②そうで無ければ、sumとarrayの1番目を足した値とarrayの2番目以降から最後までで作成した新たな配列を引数として、sumArrayを再帰的に呼び出し、その結果を返す。
  2. 配列arrに複数の整数値が順番に入っている。
  3. 0とarrを引数にしてsumArrayを呼び出した結果を変数sumとする。
  4. sumの値を出力する。※

※ 細かい話ですが、最後の出力自体は副作用が伴います。しかし、今回は和を求めるという所までが重要なため、そこはあえて無視しています。

JavaScript

1const sumArray = (pre, array) => { 2 if (array.length === 0) { 3 return pre; 4 } else { 5 return sumArray(pre + array[0], array.slice(1)); 6 } 7}; 8const arr = [2, 5, 7, 11, 13]; 9const sum = sumArray(0, arr); 10console.log(sum);

関数の中の変数は、呼び出す度にそれぞれ独立していますので、何かの変数が別の何かに変わると言うことはありません。配列それ自体も常に新たな配列が生成されるため、変更されることはありません。つまりこれは、個々の動作において副作用が無いようにするためにはどのようにすべきかと言うことを考えて作った書き方、いわゆる、関数型プログラミングになります。

対して、最初の例は命令型プログラミングと言われるものです。副作用を伴う命令によってデータを変えていくのが、命令型と言われるゆえんです。

注意して欲しいのは、考え方だけを言っていると言うことです。上の例において、JavaScriptの代入は必ず副作用を伴いますので、副作用が全くないコードというわけではありません。あくまで、副作用が生じさせないで作るのであればどうすべきかという考え方を元に組み立てただけで、個々の文や式に副作用があるかないかは関係が無いのです。

では、他にどんな具体例があるのか、どういうのが関数型プログラミングなのか、そういった話をすると本が一冊書けてしまいますし、実際そういう本もたくさん出ています。また、和を求めるという方法についても、上記が唯一の方法ではありません。Array.prototype.reduceといった畳み込みのメソッドを使えばもっと簡単に書くこともできます。命令型の例もfor文を用いれば、よりわかりやすい物になる事でしょう。

つまり、どういった物が関数型プログラミングになるのかと言うことを機械的に判断できるものでは無いと言うことです。ただ言えることは、その考え方自体に副作用を前提とした処理があるかどうかが分かれ道だろうと言えます。とはいえ、モナドを用いて副作用を包み込んでいけば、命令型プログラミングの考え方でもできないことは無いはずです。そうなると、純粋関数を用いた副作用が無いからということだけでは、関数型プログラミングであるとも言えないのです。


あまりまとまりの無いような話になってしまいましたが、以上になります。ReactもReduxも関数型プログラミング用のライブラリというより、その考え方でプログラミングができるように作られているだけに過ぎません。ReactやReduxを使えば関数型プログラミングになるわけでは無いのです。ただ、ReactやReduxを使いこなし、関数型プログラミングの利点を生かしたコードにしたいというのであれば、関数型プログラミングそのものへの理解が無ければ難しいでしょう。

投稿2017/08/17 15:55

raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

そもそも、オブジェクト指向で関数やユーティリティクラスが敬遠される理由って何なのでしょうか?(敬遠されてますよね?)

知らんがなw

関数を多用するということは、OOPで敬遠されてるものを多用するってことになると思うのですが、関数を多用して上手いことアプリケーションの設計って出来るものなのでしょうか?

関数型プログラミングで、ちゃんとしたアプリケーションができるという話は聞いたことがないとおっしゃっているのでしょうけど、そんなことはないです。ただ、関数側言語を使う人が多くないだけの話です。

node.jsのフレームワークが関数型の書き方でできている関係か、最近javascriptは関数型のフレームワークは多いように感じます。

nodeで動いているシステムはそんなに珍しくないので、実績は十分にあるといっていいのではないでしょうか?

投稿2017/08/17 03:39

iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/08/17 09:58

そういうことは意図してないです。
退会済みユーザー

退会済みユーザー

2017/08/17 10:00

node.jsのexpressフレームワークも関数型プログラミングがベースなのでしょうか?
iwamoto_takaaki

2017/08/17 11:51

> そういうことは意図してないです。 どういう意図でしょうか? そんなに詳しくないですが、どちらがベースかといえばオブジェクト指向っぽい感じがします。javaで書かれたプログラムやjQueryなどに比べると、javacriptらしく関数渡しを多用してハイブリッドな感じがします。(どこからが関数型プログラミングかという点は意見が分かれると思います。) この書き方は副作用を抑える意味で、関数型プログラミングの影響がかなり強いと思います。 hayatomoさんはexpressをどのように見ていますか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問