https://zenn.dev/339/articles/6832decc5ef1b4a0821b

概要

※この記事はQiita/Qrunchに書いた記事の再録です。 この記事では、以下のような事を扱います。

細かい関数に分けることと、スパゲティコードと、バグりにくいコードと...というような事について、図解を交えながら、文法的な部分から考察します。native coroutineといった用語の話以外は、必ずしもPythonに限定した話ではないので、他の言語を使用されている方もある程度は自然に読めるかなと思います。

なお、似たような観点で、コールバックやポリモーフィズムを扱った姉妹記事もあります。(こちらはJavaScriptですが)コールバックと、ポリモーフィズムと、それからコルーチンを構造的に見る

関数呼び出し

Pythonでは、defという語を用いて、関数を定義することができます。 次のコード断片では、fという名前の関数を定義します。

def f(name: str) -> str:
    return 'Hello, ' + name

f('taro')  # Hello, taro

定義した関数は、関数名の後ろに()をつけて記述することによって 呼び出す(call) ことができます。

関数を構成する要素には引数(argument)戻り値(return value) というものがあり、関数には引数を受け取って戻り値を返す、という機能性があります。関数定義において、defと書いた行の()の中身が引数で、returnの後ろに書いてあるものが戻り値です。

そもそも関数とは

中学や高校で習う数学においては、関数とは「ある二つの数量において、の値に対して対応するの値が一つ定まるとき、はの関数であるという。」などと定義されています。このような関係のとき、がによって決まる ことを強調して、というような書き方をするのでした。 「の話をしていたのに、いきなり出てくるは一体何だ?」 と思うのですが、の値に対して対応する値を計算する決め方のルールのことをと表現しているのでした。 このような関数の考え方と先程の関数定義を対比すると、は引数、は戻り値ということになります。また、高校までの数学における関数は数と数の対応でしたが、先程のものは文字列(str)と文字列の対応 になっているのでした。

しかし、Pythonに限らず、プログラミングにおける関数にはもう少し別の側面があります。 例えば、高校までの数学で、関数を呼び出すというようなことは、普通は言わないはずです。証明の問題で「関数 を呼び出すと」などという事を書いている人はほとんど居ないと思います。これは、プログラミングにおける関数には、数学における関数とは少し別の由来があることを意味します。

手続きとルーチン

プログラミングは、しばしばコンピュータに対する命令をまとめる作業に例えられます。 実際、Pythonをコマンドラインで起動すると、以下のような文字列が表示され、Pythonは命令待ち状態になります。

Python 3.7.7 (default, Mar 10 2020, 15:43:27)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>