GitHubにワークシートをアップしました。
このワークシートの検証として、我が家の中3の娘に実際にやってもらいました(micro:bit等のブロックプログラミング経験者ですが、JavaScriptを含むテキスト入力でのプログラミングは未経験者です)
ちょっと明日から旅行で詳しくは掛けないのですが、このワークシートに盛り込む内容の選別はかなり苦労したんですが、以下のようなまとめ方をしてみました。
基本として絶対に必要な、関数に関する内容
- 関数という言葉と、それが数式や数値のみを扱うものではないという認識。なぜなら、関数という「数学用語」からくる誤解(例:数学で習った関数みたいに数字ばかりを扱うものに違いない)を解消するため
- 引数という言葉と、それが関数でどのような役割をするか
- オブジェクトという概念と、それがいくつかの関数をまとめる機能を果たしていること、およびそれらの関数が密接な関係にあること(high cohesive)
- 関数には名前が付いている、そして名前はその関数が行う仕事を表す(例:add)、だが同時に arbitrary でプログラマーが適当に選んだ名前を付けることが出来る
- 引数をとらない関数もある(数学的な関数の定義に外れるものもある)
- 関数は戻り値があるが、無い場合もある
- 関数の呼び出し方
重要だが厳選した結果、省略した内容
- 引数には型がある(型やデータを扱う内容のワークシートに defer する
- 引数は構造体をとることも出来る(型の内容の一部)
- 引数のデフォルト値(特定の言語への依存が大きいと感じる)
- 副作用という概念
- ref や out の種類の引数(副作用の一部)
- 実装が1つの式でない場合に{}で括るやりかた(1行ずつ入力するスタイルに向かないし、制御文等の内容に defer する
- グローバル関数と静的関数(スコープの扱いに関するワークシートに defer する
- オブジェクト指向言語での関数の機能、例えばvirtualや、public/protected/privateの扱い(広すぎる。そもそもJavaScriptでデモすべき内容でない
従来の関数の初歩的教材にあまりみられないが盛り込むべきだと判断し、実際に盛り込んだ内容
- 関数の名前が、関数そのものと本質的には分離しているという認識(ラムダ式を代入することで、従来の
function
予約語を使った定義より、その分離がより直感的に理解できる - アロー関数を用いた関数の定義
- カレー化(関数型プログラミングがもたらす恩恵を享受する選択をより容易に出来るように準備する)文法的には、なんの先入観もない未経験者だからこそすんなりと受け入れられる書き方(動画で私の娘が難なく理解出来ている様子が観察されました)
- 関数を入れ子にした状態と、クロージャの効果。実際は未経験者がワークシートに従って
a => b => c => a+b+c
を入力して、そこに3つの関数が存在することを認識することはない。よってクロージャの認識も生まれない。ここは時間的にも学習の発展の見地からも「触れない」ことにした - カレー化された関数に部分適応をする。これも直感的に関数の引数は途中まで渡した(固定した)状態でも存在できるし、引数の値を変えていくらでも specialized された(そして別の名前を付けられた)関数を派生できるという直感が生まれる
まとめ
このような内容の教材はどうでしょう? 特に、無名関数の概念、もっと広い味方としては「関数の名前」と「関数そのもの」が分離しているという事実をより自然に受け止められるプログラマーは、非同期処理やTaskで表されるパラレル処理などに苦手意識を持ちにくくなるのではないか、と思うのです。