JavaScriptは関数型プログラミング言語ですか?


135

関数がファーストクラスのオブジェクトであり、クロージャーや高次の関数があるからといって、JavaScriptは関数型プログラミング言語と呼ばれるに値するのでしょうか?それが欠けていると私が思う主なものは純粋な関数であり、lispのような他の関数型言語のように「感じる」ことはありません(ただし、それが関数型言語にならない理由としては本当ではありません...)


12
@slashmais:いいえ!これは、純粋に関数型言語になることを妨げるだけです。ML(少なくとも現代の方言)も不純です-しかし、誰もそれらを機能的ではないと呼ぶ勇気はありません;)

4
一般的に関数型と見なされている言語はたくさんありますが、それらは純粋ではありません。それが要件である方法がわかりません。厳密になりたい場合は、ほとんどのいわゆるOOP言語もOOPではありません。最終的に、すべての言語の約95%がノーパラダイム言語になります。
2010年

6
なぜそれが重要なのですか?C ++でコーディングするとき、言語が「OOP」であるかどうかは気にしません。私はそれが特定のOOP機能を持っていること、そしていくつかの関数型プログラミング機能、そして多くの命令型プログラミング機能、そして多くの一般的なプログラミング機能を持っていることを気にしています。しかし、それが「-a」のOOP言語であるか、FP言語であるか、または他の何かであるかは問題ではありません。同様に、JSでコーディングする場合、それがFPであるかどうかは問題ではありません。重要なのは、FP機能の多くをサポートしていることです。これは間違った質問のようです。
2010年

3
@hvgotcodes:そう?そうではないというルールは絶対にありません。私の経験則では、それを使用して関数型のスタイルでプログラミングできる場合、それは関数型言語です。Javascriptにはファーストクラスの関数、クロージャー、ラムダがあるので、それは可能だと思います。私が考える限り、それは関数型言語です。もちろん、純粋なものではありませんが、FPを通常検討しているほとんどの言語(SMLなど)はそうではありません。だから本当に、ほぐすだけでいいと思います。それがあなたの目を震えさせる場合、あなたは医者に診てもらう必要があります。
jalf

3
@jalf、絶対に。質問の動機は、自分よりも賢い仲間や人々が何を考えているのか知りたいということでした。
hvgotcodes、

回答:


180

同様の質問に自分の答えを繰り返す、

関数型プログラミング言語の定義は受け入れられていません。

関数型言語をファーストクラスの関数とラムダをサポートする言語として定義した場合、そうです、JavaScriptは*関数型言語です。

不変性のサポート、代数的データタイプ、パターンマッチング、部分的なアプリケーションなどの要素も考慮する場合、JavaScriptは関数型言語ではありません。


以下の関連するブログ投稿(およびその下のコメントも)を読むことをお勧めします。


29
普遍的な定義がないことを指摘し、JSにはない典型的な関数型言語機能のいくつかの例をもたらすための+1。

1
:(1.7で見つめ)のJavaScriptのMozillaの実装以降のバージョンは、割り当てを構造化代入の形でパターンマッチング持っdeveloper.mozilla.org/en/New_in_JavaScript_1.7#section_20
jbeard4

JavaScriptはパーシャルという概念を持ち、パラメーターを部分的に適用するので、JavaScriptがこれをサポートしていないというステートメントは正しくないのでしょうか。
johnbakers 2013年

2
@OpenLearner、部分的なアプリケーションは、Cでさえも、私が考えることができるほとんどすべての言語でサポートされています。とにかく「サポート」の特定の定義については。JSの場合も同様です。重要なのは、部分適用が簡単で、その言語のファーストクラスかどうかです。JSではそうではありません。もしあなたが私が何を意味しているのか知りたければ、OCamlかHaskellを見てください。
missingfaktor 2013年

JavaScriptは不変性をサポートしています。
FKA

26

それはマルチパラダイム言語だと思います。

編集:それはマルチパラダイムであり、機能的な構成が含まれています。


ええ、私はそれがミックスといくつかの異なるものであることに同意します。
アシュリーグレノン

5
しかし、それ機能的であるかどうかの質問には答えません。マルチパラダイムであることは、複数のパラダイムをサポートすることを意味します。これらのパラダイムの1つは関数型プログラミングですか?
2010年

15

「関数型プログラミング」という用語を哲学的な議論のポイントにまで引き延ばすと、この問題は再び開かれるかもしれません。しかし、「C ++は本当にプログラミング言語なのか?」

より日常的なレベルでの質問に対する答えは「いいえ」です。

関数型プログラミングとは、プログラムが制御フローではなく関数の評価として概念化されていることを意味します。コードは関数の説明であり、制御フローの固有の概念はありません。

JavaScriptには制御フローがあり、命令型言語として概念化されています。その設計目標から、それは明らかに関数型言語ではありません。


1
設計目標は?どういう意味ですか?最後に確認したところ、そのインスピレーションの源の1つはSchemeでした。その設計目標の1つが関数型プログラミングをサポートすることであったことはかなり明白だと思いますと同様などの他のパラダイムのバケツ
jalfを

2
これについて適切な基礎を自分で書いた場合、C ++と同様に関数型プログラミングをサポートします。たとえば、Haskellで命令型構文を少しの作業でエミュレートできます。それにもかかわらず、JavaScriptの構文は、関数の評価ではなくワークフローのように考えられます。そのため、私(またはほとんどの関数型プログラマ)は、「関数型」という用語の適用が広すぎると考えています。
shuhalo

@ user411768:言語が機能するかどうかは、その標準ライブラリの設計に依存すると言っていますか?その定義を聞いたことがありません。Javaには、C ++(現在)にはない機能的なスタイル(クロージャーや無名関数など)でプログラミングするために必要なほとんどのツールがあります。JSはC ++よりもずっと多くのFPになると思います。言語がFPスタイルでプログラミングすることを強制しないという事実は、それを「機能性が低くなる」ことにはしませんか?
jalf

1
(i)標準ライブラリは、構文機能と同様に、標準の一部であり、特定の慣用的および概念的なスタイルを強調しています。たとえば、「C ++ with STL」は「C with classes」とは大きく異なります。影響があります。(ii)JavaScriptは、オブジェクト指向、ファーストクラスの市民機能を特徴としています。この機能は、命令/機能的二分法とはかなり直交しています。ただし、カレーを直接実装することも、純粋さを提供することも、これを意図したこともありません。(iii)それに関する私の最後の言葉、投稿の最初の段落を参照してください。
shuhalo

3
JavaScriptとC ++が同じ関数型プログラミングの便利さを提供するという記述は、間違いです。JavaScriptを使用すると、同じことを実現するためにC ++で実行しなければならない厄介な構成要素がすべてなくても、関数型プログラミングは非常に単純でシンプルになります。C ++では関数型プログラミングは本当に推奨されていないと著名に主張するすばらしいC ++プログラマーはたくさんいますが、JavaScriptで関数型プログラミングを行うことに関する記事は豊富にあります
johnbakers

9

「関数型プログラミング」言語という言葉は最近非常に多用されており、ほとんど役に立たない。2つの主要な意味があります。

  1. ファーストクラスの機能を持っています
    • JavaScriptはこれです!
  2. ラムダ計算で使用される関数に基づいており、永続的な可変状態を回避することに重点が置かれています(多くの場合、関数に渡されるパラメーターで置き換えられます)。
    • 一般的に書かれているように、Javascriptはリモートではありません!

あなたの意味を選んでください、そして質問は答えられます。


「関数型プログラミング」を使用して、関数が一次市民である言語を参照するソースはありますか?
shuhalo

@ user411768:実際には、ウィキペディアの記事にリンクされた別の回答者がその定義を使用しています。en.wikipedia.org/wiki/Javascript — Joel Spolskyも、「プログラミング言語でこれを実行できますか?」でこの定義を暗示していました。「関数型プログラミング」の恩恵に投稿
チャック

あなたはJavaScriptをあなたの第二の点を使用していない、一般的に書かれたとして、それを注意してください、それは確かにそれは確かにありませんので、言語は、このような機能をサポートしていないこと、およびことを正確にやっていないプログラマがあることを意味するものではありません
johnbakers

@OpenLearner:ええ、そうですが、Javaや、一般に厳密に必須であると見なされている他の多くの言語についても同じことが言えます。関数形式で書くことはできます、それは言語の幸福な道ではありません。
チャック

...しかし、最新のJSはそれをサポートします。
Erik Reppen 2013

3

関数型プログラミングの具体的な定義はないと思いますが、「関数型プログラミング」と考える人の多くはJavaScriptで実行できます。この記事の良い簡単な例を以下に示します。


2

私にとって、Javascriptは命令型言語と関数型言語の両方であり、どちらの方法を使用することも、両方の方法(egad)を使用することもできます。または、1つのパラダイムを使用し、もう1つのパラダイムに決して触れないことを選択できます。それはあなた次第です。私は、あなたのように、Javascriptを関数型言語と呼ぶべきではないと思います。関数型プログラミングのパラダイムに出入りできるからです。おそらく、関数型プログラミングのパラダイムのみを使用することを制限するために、ある種のプラグマがあれば、それは有用だと思います。しかし、要約すると、それはいくつかの関数型プログラミング機能が組み込まれた命令型/手続き型言語であると言えます。


その理由により、F#はもはや機能的とは言えません。
Eric Mickelsen、

1
正しい。ウィキペディアによれば、F#はまさに私がJavascriptと呼んだものです。「F#[...]は、関数型プログラミングと命令型オブジェクト指向プログラミングの分野を網羅するマルチパラダイムプログラミング言語[...]です」
Brian Onn

2

私はプログラミング言語を1つの特定のパラダイムを持つとは思わない傾向がありますが、特定のパラダイムに適していると思います。ただし、特定のパラダイムに適しているからといって、そのパラダイムを使用する必要があるわけではありません。Cでオブジェクト指向プログラムを作成し、MLで命令型プログラムを作成することはかなり可能です。言語がそのために設計されていないため、特定のパラダイムを使用して問題を解決しないのは、人為的に制限しているだけです(もちろん、特定のソリューションが優れたソリューションになるかどうかを判断するときは、言語の制限を考慮する必要があります)。


0

まあ、私はそれが関数型プログラミングだとは言いませんが、それから私、それのオブジェクト指向とちょうど今日友人が、彼はどちらかその棚の上に置いていないと述べたと言います。

だから私はそうは言いませんが、私には意見の余地があると思います。関数型プログラミングの古典的な機能はありますが、他の機能はありません。


2
JavaScriptはオブジェクト指向です。オブジェクト指向にはクラスは必要ありませんが、オブジェクトが必要です。
シークレットモード

3
JavaScriptはオブジェクト指向ではなく、プロトタイプベースです。
クリス

1
JavaScriptはプログラミングスープです。これとそれの少し。
Andrew S

0

Javascriptはまともです。それは本当にそれをプログラミングする方法に依存します。OOの方法でコーディングした場合、それはOOではありませんか?したがって、「機能的」な方法でコーディングするだけで機能します。私はそれがマルチパラダイム言語であると思いますので、それを1つだけ呼ぶのは完全に正確ではありません。


0

私は「新しい」を得るためにあなたのコードを少し書き換える@petraszd ための演算子を:

   
   function ffor(a, b, f){
     function it(i){
       if(i > b)return
       f(i)
       it(i+1)
     }
     it(a)
   }

   print("----" + new Date()+"----")

   var funcs = []
   ffor(0, 9, function(i){
     funcs.push(function(){return i})
   })

   ffor(0, 9, function(i){
     print(funcs[i]())
   })

しかし、この方法には大きなループの欠点があることは知っています...

JSの末尾再帰最適化に関する関連質問

PSここに投稿されましたcuzはコメントとして投稿中にコードのフォーマットに問題があります


0

JavaScriptでは、このようなことができます!!

// Data
var fruits = [
    { name: 'apple',  price: 5 }, 
    { name: 'orange', price: 10 }, 
    { name: 'lemon',  price: 15 }
]

// Request Data from magicURL
request('magicURL')
    .then(selectKeyOf('price'))
    .then(priceMethod('sum'))
    .then((result)=>{
        console.log(result) // 30
    })

このコンセプトをデモするためにgithubページを作成しました。私の実装を複製/表示できます


0

私たちが知っているように、関数型プログラミング言語では関数の要素(状態)を変更または変更することはできませんが、JavaScriptでは関数型プログラミング言語ではありませんが、関数をファーストクラスの市民として扱います。


-2

私が本当にJavaScriptで嫌いなのは(あなたがそれをFP言語として見ようとするなら)これは:

function getTenFunctionsBad() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push(function () {
      return i;
    });
  }
  return result;
}

function getTenFunctions() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push((function (i) {
      return function () {
        return i;
      }
    })(i));
  }
  return result;
}

var functionsBad = getTenFunctionsBad();
var functions = getTenFunctions()
for (var i = 0; i < 10; ++i) {
  // using rhino print
  print(functionsBad[i]() + ', ' + functions[i]());
}

// Output:
//   10, 0
//   10, 1
//   10, 2
//   10, 3
//   10, 4
//   10, 5
//   10, 6
//   10, 7
//   10, 8
//   10, 9

このような動作を理解するには、JSスタック環境を理解する必要があります(適切な用語かどうかはわかりません)。

スキームの例では、あなたはそのようなものを作成することはできません(OK、OK-基礎となる言語の参照の助けを借りて、あなたはそれを作ることができます):

(define (make-ten-functions)
  (define (iter i)
    (cond ((> i 9) '())
          (else (cons (lambda () i) (iter (+ i 1))))))
  (iter 0))

(for-each (lambda (f)
            (display (f))
            (newline)) (make-ten-functions))

1
うーん、Javascriptは変数への参照を保持していますが、への参照は保持していないと思います
aeracode、

1
変数のスコープを理解することは、あらゆる言語で効果的なプログラミングを行うために重要です。これにはJavaScriptだけではありません。
リッチremer 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.