Javascript関数型プログラミング言語_JavaScriptスキル
関数型プログラミング言語
関数型プログラミング言語は、関数型プログラミング パラダイムの使用を容易にする言語です。簡単に言えば、関数型プログラミングに必要な特性を備えていれば、関数型言語と呼ぶことができます。ほとんどの場合、実際にはプログラムが機能するかどうかはプログラミング スタイルによって決まります。
言語を機能させるものは何ですか?
関数型プログラミングは C 言語で実装できません。関数型プログラミングは Java では実装できません (多くの回避策を使用して関数型プログラミングに近似したものを除く)。 これらの言語には、関数型プログラミングをサポートする構成要素が含まれていません。これらは純粋にオブジェクト指向であり、厳密には非関数型言語です。
同時に、オブジェクト指向プログラミングは、Scheme、Haskell、Lisp などの純粋関数型言語では使用できません。
ただし、一部の言語は両方のモードをサポートしています。 Python は有名な例ですが、他にも Ruby、Julia、そして最も興味深いのは Javascript などがあります。 これらの言語は、この 2 つの異なる設計パターンをどのようにサポートしているのでしょうか?これらには、両方のプログラミング パラダイムに必要な機能が含まれています。 ただし、JavaScriptの場合、機能的な特徴が隠されているようです。
しかし実際には、関数型言語には上記よりももう少し必要なものが必要です。関数型言語にはどのような特徴があるのでしょうか?
特点 | 命令式 | 函数式 |
---|---|---|
编程风格 | 一步一步地执行,并且要管理状态的变化 | 描述问题和和所需的数据变化以解决问题 |
状态变化 | 很重要 | 不存在 |
执行顺序 | 很重要 | 不太重要 |
主要的控制流 | 循环、条件、函数调用 | 函数调用和递归 |
主要的操作单元 | 结构体和类对象 | 函数作为一等公民的对象和数据集 |
関数型言語の構文では、型推論システムや匿名関数などの特定の設計パターンを考慮する必要があります。一般に、言語はラムダ計算を実装する必要があります。 また、インタプリタの評価戦略は、非厳密なコールオンデマンド (遅延実行とも呼ばれます) でなければなりません。これにより、不変のデータ構造と非厳密な遅延評価が可能になります。
译注:这一段用了一些函数式编程的专业词汇。lambda演算是一套函数推演的形式化系统(听起来很晕), 它的先决条件是内部函数和匿名函数。非严格求值和惰性求值差不多一个意思,就是并非严格地按照运算规则把所有元素先计算一遍, 而是根据最终的需求只计算有用的那一部分,比如我们要取有一百个元素的数组的前三项, 那惰性求值实际只会计算出一个具有三个元素是数组,而不会先去计算那个一百个元素的数组。
メリット
関数型プログラミングは、最終的に習得すると大きなインスピレーションとなるでしょう。この種の経験は、実際にフルタイムの職務プログラマーになるかどうかに関係なく、プログラマーとしての将来のキャリアをより高いレベルに引き上げます。
しかし、私たちは今、瞑想を学ぶ方法について話しているのではなく、より良いプログラマーになるための非常に便利なツールを学ぶ方法について話しているのです。
全体として、関数型プログラミングを使用する実際の実際的な利点は何ですか?
クリーナーコード
関数型プログラミングは、よりクリーン、シンプル、そして小規模です。デバッグ、テスト、メンテナンスが簡素化されます。
たとえば、2 次元配列を 1 次元配列に変換する関数が必要です。命令的手法のみを使用する場合は、次のように記述します:
function merge2dArrayIntoOne(arrays) { var count = arrays.length; var merged = new Array(count); var c = 0; for (var i = 0; i < count; ++i) { for (var j = 0, jlen = arrays[i].length; j < jlen; ++j) { merged[c++] = arrays[i][j]; } } return merged }
関数型テクニックを使用すると、次のように記述できます:
merge2dArrayIntoOne2 = (arrays) -> arrays.reduce (memo, item) -> memo.concat item , []
var merge2dArrayIntoOne2 = function(arrays) { return arrays.reduce( function(p,n){ return p.concat(n); }, []); };
译注:原著中代码有误,调用reduce函数时少了第二个参数空数组,这里已经补上。
どちらの関数も同じ入力を受け取り、同じ出力を返しますが、関数例はより明確です。
モジュラー
関数型プログラミングでは、大きな問題を同じ問題を解決する小さなケースに分割する必要があります。これは、コードがよりモジュール化されることを意味します。 モジュール型プログラムは説明が明確で、デバッグが容易で、保守も簡単です。各モジュールのコードの正確性を個別にチェックできるため、テストも容易になります。
再利用性
関数型プログラミングにはモジュール形式の性質があるため、多くの共通の補助関数があります。ここにある関数の多くは、さまざまなアプリケーションで再利用できることがわかります。
次の章では、最も一般的な機能の多くについて説明します。ただし、関数型プログラマーとして、何度も使用される独自の関数ライブラリを必然的に作成することになります。たとえば、行間の構成ファイルを検索するために使用される関数は、適切に設計されていれば、ハッシュ テーブルの検索にも使用できます。
カップリングを軽減します
結合とは、プログラム内のモジュール間の多数の依存関係です。関数型プログラミングは、グローバル変数に副作用がなく、互いに完全に独立した、第一級の高次の純粋関数の記述に従うため、結合が大幅に軽減されます。 もちろん、関数は必然的に相互に依存しますが、入力と出力の 1 対 1 マッピングが正しい限り、1 つの関数を変更しても他の関数には影響しません。
数学的正しさ
最後の点はより理論的なものです。関数型プログラミングはラムダ計算に根ざしているため、数学的に正しいと証明できます。 これは、成長率、時間計算量、数学的正しさを証明するプログラムを必要とする一部の研究者にとって、大きな利点となります。
フィボナッチ数列を見てみましょう。概念実証の問題以外ではめったに使用されませんが、概念を説明する優れた方法です。 フィボナッチ数列を評価する標準的な方法は、次のような再帰関数を作成することです:
fibonnaci(n) = fibonnaci(n-2) + fibonnaci(n–1)
一般的な状況も追加する必要があります:
return 1 when n < 2
これにより、再帰が終了し、再帰呼び出しスタックの各ステップがここから蓄積できるようになります。
詳細な手順を以下に示します
var fibonacci = function(n) { if (n < 2) { return 1; }else { return fibonacci(n - 2) + fibonacci(n - 1); } } console.log( fibonacci(8) ); // Output: 34
しかし、遅延実行関数ライブラリの助けを借りて、数式を通じてシーケンス全体のメンバーを定義することにより、無限シーケンスを生成することが可能です。 最終的に必要なメンバーのみが最後に計算されます。
var fibonacci2 = Lazy.generate(function() { var x = 1, y = 1; return function() { var prev = x; x = y; y += prev; return prev; }; }()); console.log(fibonacci2.length()); // Output: undefined console.log(fibonacci2.take(12).toArray()); // Output: [1, 1, 2, 3, 5,8, 13, 21, 34, 55, 89, 144] var fibonacci3 = Lazy.generate(function() { var x = 1, y = 1; return function() { var prev = x; x = y; y += prev; return prev; }; }()); console.log(fibonacci3.take(9).reverse().first(1).toArray()); //Output: [34]
第二个例子明显更有数学的味道。它依赖Lazy.js函数库。还有一些其它这样的库,比如Sloth.js、wu.js, 这些将在第三章里面讲到。
我插几句:后面这个懒执行的例子放这似乎仅仅是来秀一下函数式编程在数学正确性上的表现。 更让人奇怪的是作者还要把具有相同内部函数的懒加载写两遍,完全没意义啊…… 我觉得各位看官知道这是个懒执就行了,不必深究。
非函数式世界中的函数式编程
函数式和非函数式编程能混合在一起吗?尽管这是第七章的主题,但是在我们进一步学习之前, 还是要弄明白一些东西。
这本书并没要想要教你如何严格地用纯函数编程来实现整个应用。这样的应用在学术界之外不太适合。 相反,这本书是要教你如何在必要的命令式代码之上使用纯函数的设计策略。
例如,你需要在一段文本中找出头四个只含有字母的单词,稚嫩一些的写法会是这样:
var words = [], count = 0; text = myString.split(' '); for (i=0; count < 4, i < text.length; i++) { if (!text[i].match(/[0-9]/)) { words = words.concat(text[i]); count++; } } console.log(words);
函数式编程会写成这样:
var words = []; var words = myString.split(' ').filter(function(x){ return (! x.match(/[1-9]+/)); }).slice(0,4); console.log(words);
如果有一个函数式编程的工具库,代码可以进一步被简化:
var words = toSequence(myString).match(/[a-zA-Z]+/).first(4);
関数がより機能的な方法で記述できるかどうかを判断する方法は、ループと一時変数 (前の例の "words" 変数や "count" 変数など) を探すことです。 多くの場合、ループや一時変数を高次関数に置き換えることができます。これについては、この章で後ほど説明します。
JavaScript は関数型プログラミング言語ですか?
最後に自問する必要がある質問があります。JavaScript は関数型言語ですか、それとも非関数型言語ですか?
JavaScript はおそらく世界で最も人気があるが、最も理解されていない関数型プログラミング言語です。 JavaScript は C の装いをした関数型プログラミング言語です。 その構文は明らかに C に似ています。つまり、C のブロック構文と中置語順が使用されています。そして、それは現存する言語の中で最悪の名前を持っています。 想像するまでもなく、JavaScript と Java の関係について、その名前がそれが何であるかを暗示しているかのように、どれほど多くの人が混乱しているかがわかります。 しかし実際には、Java との共通点はほとんどありません。ただし、Javascript をオブジェクト指向言語に強制するアイデアはまだいくつかあります。たとえば、Dojo や easy.js などのライブラリは、JavaScript をオブジェクト指向プログラミングに適したものにするために多くの作業を行っています。 Javascript は 1990 年代に誕生しました。当時、世界中でオブジェクト指向プログラミングが叫ばれていました。私たちは、JavaScript がオブジェクト指向言語であることを望んでいたからだと言われていましたが、実際にはそうではありませんでした。
その正体は、そのプロトタイプ、つまり 2 つの古典的な関数型プログラミング言語である Scheme と Lisp に遡ります。 JavaScript は常に関数型プログラミング言語です。 その関数は第一級市民であり、入れ子にすることができ、クロージャと複合関数があり、合理化とモナドが可能です。これらはすべて関数型プログラミングの鍵です。 Javascript が関数型言語である理由をさらにいくつか挙げます:
• Javascript のレキシコンには、関数をパラメータとして渡す機能が含まれており、型推論システムがあり、匿名関数、高階関数、クロージャなどをサポートしています。 これらの特性は、関数型プログラミングを構成する構造と動作にとって重要です。
• JavaScript は純粋なオブジェクト指向言語ではありません。そのオブジェクト指向設計パターンのほとんどは、プロトタイプ オブジェクトをコピーすることで完成します。これは弱いオブジェクト指向プログラミング モデルです。欧州コンピュータ製造者協会スクリプト (ECMAScript) - Javascript の公式形式および標準実装 - の仕様のバージョン 4.2.1 には次の記述があります:
「JavaScript には C、Smalltalk、Java のような実際のクラスはありませんが、オブジェクトを作成するためのコンストラクターをサポートしています。一般的に言えば、クラスベースのオブジェクト指向言語では、状態はインスタンスによって保持され、メソッドはクラスによって保持され、継承はEMACScript では、状態とメソッドはオブジェクトによって保持され、構造、動作、および状態は継承されます。
言い換えれば、JavaScript は純粋な関数型言語ではありません。遅延評価と組み込みの不変データが欠けています。 これは、ほとんどの通訳者がオンデマンドではなく名前で呼ばれるという事実によるものです。また、JavaScript は末尾呼び出しの処理方法により、再帰の処理があまり得意ではありません。 ただし、これらの問題はすべて、いくつかの小さな考慮事項で軽減できます。無限シーケンスを必要とする非厳密な評価と遅延評価は、Lazy.js と呼ばれるライブラリを通じて実現できます。 不変性はプログラミング スキルだけで実現できますが、言語レベルに依存する制限はなく、プログラマーの自制心が必要です。 末尾再帰の除去は、トランポリンと呼ばれる方法によって実現できます。これらの問題については第 6 章で説明します。
JavaScript が関数型言語なのか、オブジェクト指向言語なのか、その両方なのか、あるいはどちらでもないのかについては常に多くの議論があり、今後も議論は続くでしょう。
最後に、関数型プログラミングは、関数を巧みに変更、組み合わせ、使用することで簡潔なコードを記述する方法です。そして、JavaScript はこれを実現するための優れた方法を提供します。 本当に Javascript の可能性を最大限に活用したい場合は、JavaScript を関数型言語として使用する方法を学ぶ必要があります。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

JavaScript文字列置換法とFAQの詳細な説明 この記事では、javaScriptの文字列文字を置き換える2つの方法について説明します:内部JavaScriptコードとWebページの内部HTML。 JavaScriptコード内の文字列を交換します 最も直接的な方法は、置換()メソッドを使用することです。 str = str.replace( "find"、 "置換"); この方法は、最初の一致のみを置き換えます。すべての一致を置き換えるには、正規表現を使用して、グローバルフラグGを追加します。 str = str.replace(/fi

それで、あなたはここで、Ajaxと呼ばれるこのことについてすべてを学ぶ準備ができています。しかし、それは正確には何ですか? Ajaxという用語は、動的でインタラクティブなWebコンテンツを作成するために使用されるテクノロジーのゆるいグループ化を指します。 Ajaxという用語は、もともとJesse Jによって造られました

10の楽しいjQueryゲームプラグインして、あなたのウェブサイトをより魅力的にし、ユーザーの粘着性を高めます! Flashは依然としてカジュアルなWebゲームを開発するのに最適なソフトウェアですが、jQueryは驚くべき効果を生み出すこともできます。また、純粋なアクションフラッシュゲームに匹敵するものではありませんが、場合によってはブラウザで予期せぬ楽しみもできます。 jquery tic toeゲーム ゲームプログラミングの「Hello World」には、JQueryバージョンがあります。 ソースコード jQueryクレイジーワードコンポジションゲーム これは空白のゲームであり、単語の文脈を知らないために奇妙な結果を生み出すことができます。 ソースコード jquery鉱山の掃引ゲーム

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

このチュートリアルでは、jQueryを使用して魅惑的な視差の背景効果を作成する方法を示しています。 見事な視覚的な深さを作成するレイヤー画像を備えたヘッダーバナーを構築します。 更新されたプラグインは、jQuery 1.6.4以降で動作します。 ダウンロードしてください

Matter.jsは、JavaScriptで書かれた2D Rigid Body Physics Engineです。このライブラリは、ブラウザで2D物理学を簡単にシミュレートするのに役立ちます。剛体を作成し、質量、面積、密度などの物理的特性を割り当てる機能など、多くの機能を提供します。また、重力摩擦など、さまざまな種類の衝突や力をシミュレートすることもできます。 Matter.jsは、すべての主流ブラウザをサポートしています。さらに、タッチを検出し、応答性が高いため、モバイルデバイスに適しています。これらの機能はすべて、物理ベースの2Dゲームまたはシミュレーションを簡単に作成できるため、エンジンの使用方法を学ぶために時間をかける価値があります。このチュートリアルでは、このライブラリのインストールや使用法を含むこのライブラリの基本を取り上げ、

この記事では、JQueryとAjaxを使用して5秒ごとにDivのコンテンツを自動的に更新する方法を示しています。 この例は、RSSフィードからの最新のブログ投稿と、最後の更新タイムスタンプを取得して表示します。 読み込み画像はオプションです

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。
