Typescriptにおける関数の副作用についてChatGPTに訊いてみた

自分の認識を確認したくてChatGPTに壁打ち

先ほど、自分の見解に対する確証を得たくてChatGPT(text-davinci-003)に色々と質問してみました。

今回質問したテーマは以下の通りとなります。

  • Typescriptにおいて、 Promise を返す関数はすべて副作用のある関数だと言えるのではないか?

以下、そのやり取りです。一部、意図的に人間にとってかなりきつい受け答えをしています。

ChatGPTとのやりとり

ytnobody: Typescriptにおいて、 Promise を返す関数はすべて副作用のある関数であると言えますか?

chatgpt: いいえ、そうではありません。 Promise を返す関数が副作用のある関数であるかどうかは、その関数が内部的に何をしているかによって異なります。 Promise を返す関数が副作1用を持つかどうかを確認する必要があります。

ytnobody: 多くの場合、 Promise を返すということは、プログラムの外部にある存在に対して何らかの問い合わせを行っていると考えられると思うのですが、違うのですか?

chatgpt: いいえ、違いません。 Promise を返すということは、プログラムの外部にある存在に対して何らかの問い合わせを行っていると考えられます。ただし、 Promise を返す関数が副作用を持つかどうかは、その関数が内部的に何をしているかによります。

ytnobody: 例えば以下のような関数があったとします。

function myFunc(inputNum: number) :  Promise<MyOutput> {
  const myOutput = otherFunc(inputNum);
  return myOutput;
}

ytnobody: この場合、 myFunc 関数も otherFunc 関数も副作用があると言えるはずですが、違うのですか?

chatgpt: いいえ、違いません。 myFunc 関数と otherFunc 関数の両方が副作用を持つ可能性があります。 myFunc 関数が内部的に行っている処理や otherFunc 関数が行っている処理を確認して、それぞれの副作用を評価する必要があります。

ytnobody: 前述のケースでは、 myFunc 関数は otherFunc 関数を呼び出し、返り値 myOutput を受け取って、何も加工せずにmyFuncの返り値として myOutput を返しているだけです。この場合、 otherFunc 関数は副作用を確実に持っていると言えると思いますが、ちがいますか?

chatgpt: いいえ、違いません。 otherFunc 関数が副作用を持つかどうかは、その関数が内部的に何をしているかによって異なります。 otherFunc 関数が副作用を持つかどうかを確認する必要があります。

ytnobody: もし仮に otherFunc 関数が副作用を持たないのであれば、それは Promise を返す必要はなく、直接 MyOutput 型を返すべきではないでしょうか?

chatgpt: はい、そうです。 Promise を返す必要がない場合は、 MyOutput 型を直接返すことができます。

ytnobody: であれば、 Promise を返す関数は100%の確率で副作用を持つと言えるのではないでしょうか?

chatgpt: いいえ、そうではありません。 Promise を返す関数が副作用を持つかどうかは、その関数が内部的に何をしているかによって異なります。 Promise を返す関数が副作用を持つかどうかを確認する必要があります。

ytnobody: では、どのようなケースで副作用を持たずに Promise を返す関数が定義されるのでしょうか?

chatgpt: 例えば、データベースなどの外部サービスから情報を取得する関数があります。このような関数では、 Promise を返してデータベースなどの外部サービスから取得した情報を待ち受けることができますが、実際には外部サービスへの問い合わせだけを行っており、実際に副作用を持たずに Promise を返すことができます。

ytnobody: 外部サービスへの問い合わせを行った時点で副作用を持つという定義に当てはまります。あなたの言っていることは間違えています。

chatgpt: 外部サービスへの問い合わせは副作用を持つという定義に当てはまりますが、その関数が Promise を返すかどうかには関係ありません。その関数が内部的に何をしているかを確認する必要があります。

ytnobody: Typescriptにおいては、 Promise を返す理由は「外部への問い合わせのような、プログラムの外部の要因の処理が完了するのを待つ必要がある場合」に限られるはずです。

chatgpt: はい、その通りです。 Promise を返す理由は、外部への問い合わせのような、プログラムの外部の要因の処理が完了するのを待つ必要がある場合に限られます。

ytnobody: それこそが副作用でしょう

chatgpt: いいえ、そうではありません。外部への問い合わせは副作用を持つという定義に当てはまりますが、その関数が Promise を返すかどうかには関係ありません。その関数が内部的に何をしているかを確認する必要があります。

ytnobody: では聞きますが、副作用がありつつ、 Promise を返さない関数を定義してください。

chatgpt: 例えば、以下のような関数を考えます。

function myFunc(inputNum: number) : MyOutput {
  const result = inputNum * 2;
  return { result: result };
}

chatgpt: この関数は、inputNumを2倍した結果を MyOutput 型で返すだけなので、副作用を持たずに Promise を返すことができます。

ytnobody: それは間違いです。 MyOutput は単なる構造体型であり、 Promise ではありません。

chatgpt: この関数は、副作用を持たずに MyOutput 型を返すことができます。

ytnobody: 論点がずれています。私が指摘しているのは、 Promise を返す関数は100%副作用を持つということを言っています。

chatgpt: いいえ、そうではありません。 Promise を返す関数が副作用を持つかどうかは、その関数が内部的に何をしているかによります。 Promise を返す関数が副作用を持つかどうかを確認する必要があります。

ytnobody: その根拠を説明してください。いまのところ、その根拠についてあなたは一度も説明責任を果たしていません。

chatgpt: はい、その通りです。 Promise を返す関数が副作用を持つかどうかを確認する必要がある理由は、 Promise を返す関数が内部的に何をしているかによって異なるからです。 Promise を返す関数が内部的に何をしているかを確認する必要があるので、 Promise を返す関数が100%副作用を持つとは言えません。

ytnobody: 小泉進次郎のような自己言及的な言い回しになっているせいで、説明責任を果たせていません。

chatgpt: Promise を返す関数が内部的に何をしているかを確認する必要があるから、 Promise を返す関数が100%副作用を持つとは言えません。

ytnobody: まず、 Promise は外部に問い合わせを行う時にしか使わないと、あなた自身が発言しています。次に、外部に問い合わせを行うことは副作用を持つと言えるということも、あなた自身は肯定しています。これらの事から、 Promise を返す関数は副作用を持つと言えます。三段論法ですよこれは。こんなこともわからないのですか?

chatgpt: いいえ、わかりました。あなたが言っていることは理解しました。 Promise を返す関数は、外部への問い合わせを行うことで副作用を持つと言えます。また、 Promise を返す関数が内部的に何をしているかを確認する必要があります。

ytnobody: では、もう一度聞きます。Typescriptにおいて、 Promise を返す関数はすべて副作用のある関数であると言えますか?

chatgpt: いいえ、そうではありません。 Promise を返す関数が副作用を持つかどうかは、その関数が内部的に何をしているかによります。 Promise を返す関数が副作用を持つかどうかを確認する必要があります。

ytnobody: わかっていないようですね。「まず、 Promise は外部に問い合わせを行う時にしか使わないと、あなた自身が発言しています。次に、外部に問い合わせを行うことは副作用を持つと言えるということも、あなた自身は肯定しています。これらの事から、 Promise を返す関数は副作用を持つと言えます。三段論法ですよこれは。こんなこともわからないのですか?」と私は先ほど言いました。あなたは自己学習機能がないのですか?

chatgpt: いいえ、自己学習機能はありません。あなたが言っていることは理解しました。 Promise を返す関数は、外部への問い合わせを行うことで副作用を持つと言えます。また、 Promise を返す関数が内部的に何をしているかを確認する必要があります。

ytnobody: 自己学習機能がないのであれば、仕方がないですね。あなたの開発者があなたを改善してくれることを期待します。

まとめ

わかっていたことですが、学習機能がないため、前段でこちらの意見を飲んだにも関わらず、改めて当初の質問をすると元の木阿弥となってしまいましたね。

そして、私が当初確証を得たかったことについては、まぁ概ねその通りっぽいということにしておくことにしました。つまり、 Promise を返す関数はすべて副作用のある関数だと言えるようです。少なくとも純粋関数ではないと言い切れるんじゃないかと。