JavaScriptにおけるフロー制御,短絡表現および機能プログラミング


数日前、コードレビューをしている間、このようなスニペットを見ました.
React.useEffect(() => {
  someCondition && doSomething()
}, [someCondition, doSomething])
何を知っている必要はありませんReact.useEffect または何か、私はコールバック関数の本体に集中したいだけです.
私は同僚にif 短絡表現の代わりに文.なぜそれを使用するのが好ましいか尋ねましたif 代わりに、私は合理的な答えを持っていなかった.それは、ちょうど私によりよく感じました.
しかし、それが非常に主観的であるので、より良い感じは許容できる理由でありません.私にとってより良い感じは、チームの残りの部分のために必ずしもよりよく感じません.
それで、私はちょうど他の人がすることをしました:私は、それについて執着しました😅), それがよりよく感じた理由を合理化しようとすること.
免責事項:この記事は、このトピックの周りの私の推論について説明します.閉じるこの動画はお気に入りから削除されています.私は、これを「ベストプラクティス」として提案していません.
リッチなヒッキーの話を見て学んだことの一つは、常に定義から始めることです.

In computer science, an expression is a syntactic entity in a programming language that may be evaluated to determine its value.


JavaScriptの式の束は以下の通りです.
42                              // 42 
'foo'                           // 'foo'
false                           // false
const nums = [1, 2, 3]          // ??
nums                            // [1, 2, 3]
JavaScriptの値は自分自身に評価され、変数を保持する値は保持する値に対して評価されます.上記のスニペットで4行目に注意してください.JavaScriptの割り当てにおいても式です.あなたはその表情をどう思いますかconst nums = [1, 2, 3] 評価する?
まあ、評価するundefined .
Pythonのような他のプログラミング言語では、変数代入は式ではなく、文です.以下にステートメントの定義を示します:

In computer programming, a statement is a syntactic unit of an imperative programming language that expresses some action to be carried out.


ここで重要な言葉は行動です.今のところそれを心に留めておきなさい.
以下はJavaScriptのステートメントです.
for (let n of nums) { /*...*/ }
while (true)        { /*...*/ }
if (nums.length)    { /*...*/ }
代入が式(無駄な表現であるという事実)を無視して、私が自分自身でそう言うなら、式が動作としての値であると考えるのは妥当でしょう.

短絡評価


より多くの定義

Short-circuit evaluation, minimal evaluation, or McCarthy evaluation (after John McCarthy) is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression.


以下に例を示します:
true || false                 // true
コードの前のスニペットでは、最初の引数が式全体の値を決定するのに十分なので、OR演算子の右側の式は評価されません.
リテラルが自分自身に評価しているので、リテラルを使ってこのように考えるのはちょっと奇妙です.以下のように書きますので、以下のようになります.
const aCondition = true
const anotherCondition = false

aCondition || anotherCondition   // true
以来aCondition is true , 値を見上げる必要はないanotherCondition , それが何であれ.
別の例を試してみましょう.
const person = {
  get name() {
    console.log('Bayum!')
    return 'Bodoque'
  }
}

true || person.name           // true
このコードを実行すると、気づくでしょう'Bayum!' はコンソールにログオンされません.|| 演算子は既にtrue , どちらがいいか
しかし、これは何ですか?

副作用、機能プログラミングとハスケル


私たちは簡単に迂回していきます.

Haskell is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation.


印刷しているHaskellと少しの機能を書きましょう"42" コンソールへ:
doSomething = putStrLn "42"
使用ghci , グラスゴーHaskellコンパイラの対話型環境(REPLを考える)は、我々のタイプをチェックすることができますdoSomething 機能
Prelude> doSomething = putStrLn "42"
Prelude> :t doSomething 
doSomething :: IO ()
doSomething は引数をとらない関数で、返り値はIO () , or IO 単位の空括弧の集合を単位と呼び、void JavaScriptで).Haskellで副作用を持つすべての機能はIO 何かpure関数は有効な関数を呼び出すことができません.副作用を持ちたい場合は、戻り値の型は常にIO 何か
必須ではないが、明示的に型注釈を書き込むことができます.
doSomething :: IO ()
doSomething = putStrLn "42"

-- Here's another function that takes two Ints 
-- and returns another Int, just for contrast
add :: Int -> Int -> Int 
add a b = a + b
大丈夫、迂回路、十分なHaskell、トラックに戻りましょう.

短絡表現とフロー制御


関数呼び出しは、その入力だけに依存する場合は常にその戻り値で置き換えることができます.もう一つの方法は、関数呼び出しが副作用を持たない場合、関数の呼び出しがその戻り値で置き換えることができるということです.
このプロパティは、参照透過性と呼ばれます.参照透過関数も純粋な関数として知られています.
機能プログラミングを行うとき、我々の目標は、純粋な機能で書かれたコードの表面積を最大化することです:彼らはテストしやすく、理由を容易にします.プログラムのほとんどの機能については、返り値に興味を持ちます.
const whatIsThis = someCondition && doSomething()
我々が結果に興味がないならばdoSomething , それから、式の値を1に格納する価値がないでしょうwhatIsThis , しかし、式はまだ使用されているかどうかを指定します.
function doSomething() {
  console.log("42")
}

someCondition && doSomething()   // `false` when `someCondition` is `false`
                                 // `undefined` when `someCondition` is `true`
もし我々が式の値を気にしないならばdoSomething 最も効果的な関数です.しかしJavaScriptはHaskellではないので、doSomething はその実装を見ないで有効です.そしてそれでも、必ずしも理解するのは簡単なことではない.
私は、これが私がif 効果的な機能におけるフロー制御のための短絡式の代わりにステートメント:私にとっては、私たちがリターン値を気にかけないということは完全に明白ではないので、副作用です.

しかし、何かを返す効果的な機能についてはどうですか?


我々は、GHCのようなコンパイラを持っていない私たちの関数の純度を強制するが、我々はまだ効果的な関数だけが他の効果的な関数を呼び出すことができるような慣例に従うことができます.Haskellはこれをmonadsを使います.
このトピックについての説明を書く代わりに、この仕事を本当に率直に伝えてくれます.
https://youtu.be/C2w45qRc3aU