いかにしてJavaScriptを教えるか

経緯

ドワンゴ様から恵贈頂いた。

高校生からはじめる プログラミング

高校生からはじめる プログラミング

…読んでみたけど、HTML/CSS/JS の初歩的な部分を、初学者にやらせるとこうなる、という素朴な世界観で、CSSフレームワークもJSライブラリも出てこない。いや、出せと言ってるわけじゃない。理解せずにフレームワークを使う習慣がつくと、スクリプトキディ的な振る舞いによっていくし、教える側としても、変数が大きくなってコントロールできないのが問題だろう。

じゃあ基礎を抑えたとして、この先どう教えるといいんだろうな、というのは、たしかに自分も前から考えてはいて、それを書いてみる。

この文章のターゲット

JavaScriptを教える人、またはポインタがあれば自学できる中級者以上

追記: すべての初学者にJSを教えろという内容じゃなくて、ある程度コンテキストあってJSを学ぶ人がどういう経路で学ぶべきかというものを書いたつもりだけど、自分がマウントして気持ちよくなりたいがために意図してそこ無視してる人が多くて怒っています

提案: 初心者にNode.jsから教える

理由はいくつかある。

  • ES2015のES Module 以外はだいたい実装された環境
  • パッケージマネージャが最初から付いている
  • REPLが付いている
  • パッケージマネージャによってモジュールを分割する慣習が得られる
  • Node.jsツールチェインに抵抗がなくなる
  • サーバーエンジニアにもクライアントエンジニアにもモバイルにも派生できる
  • レガシーな jQuery 方面の慣習に引きずられていない

ただ、黒い画面に抵抗があったり、画面をゴリゴリ動かすのに最初から行きたい人は、Nodeから入るとモチベーションが削がれるかもしれない。そういう人には create-react-app から入って、しばらくそれ縛りでReactアプリを触らせるのがいいと思う。結局、そうやってると、これもあとからNodeツールチェインの理解が必要になる。段階的に、Babel、Webpackと触ることになるだろう。

TypeScriptとAngularは、最初からそれを使ってる会社での研修ではない限り、学習用途にはあまり勧めない。AngularはAngularの世界観が強くて、おそらくJSのルールなのかAngularなのかの区別がつかないし、TSも同じ。TSの慣習は、JSの雰囲気とやや距離がある。TSをやるのはJSやってからで遅くはない。

学習段階のブロッキング要素

  • 後方互換を切ることができずに残っている構文上のBadParts郡
  • 過去に書かれたES2015以前のドキュメント
  • 全体的にテストを書く強制力が弱く身につかない
  • プロジェクトごとにフレームワークが違う

テスト、まともなエンジニアなら、これだからJSは!と憤りがちなのは知ってるんだけど、GUI環境はそもそもテスト書く難易度が異常に高く、Unityなんかのゲームエンジン方面も同じ問題を抱えている。書けるけど難しい。TS/Flowを使って、型で強く固めるのも、結局テストを書かずにある程度カバーしたいという需要から来ている。

とはいえ、テストのターゲットがピュアなJSオブジェクトのうちはテストを書けるし、環境依存のDOMやその他のオブジェクトを、ピュアな部分から切り離す慣習を持つようにするのが、Nodeを使うと自然に身につく習慣なので、そこを頑張るように仕向けたい。これもNodeを勧めてる理由の一つ。

補足: サーバーエンジニアとしてのJavaScript

USだとそうでもないのだが、Node.jsを国内で運用してる会社が少ない。その為運用経験が足りなくて、採用されづらい。Nodeを使うような会社だったらRubyを使うだろう。とはいえ、npm の慣習は基本的に、rubygems の模倣だったので、LLでOSSのモジュールを組み合わせて、という体験が得られるので、学習段階の言語としては無駄にはならない。もちろんクライアントにも経験は生きる。

プログラミング言語としての JavaScript をどう捉えるか

雑に書くのは簡単だが、真っ当に運用しようとすると突然難しくなる。知識があれば、何を使っていいか、何を使っていけないかわかるが、それが身につくのは泥臭い経験の先である。ベストプラクティスは常に更新されていて、参考にして良い資料はここ3年に書かれたものに限る。

メインストリームは主に Babel/TypeScript だが、Babel も Flow が使われるようになってきているし、全体としては型ありきの固い環境を志向している。ただ、OOP周りでは、クラス記法は入ったが、あまり使われようとする気配はなく、Record + Pure Function による関数型的な方向性に寄っている雰囲気が強い。ライブラリが提供するAPIなどにその傾向が見られる。これは、JSが主に通信で使われていて、シリアライズ/デシリアライズを頻繁に行うためだと自分は考えている。

言語として物足りなくなった場合、Flowで型を拡張したり、Babelの構文を足したり、Lintツールで全く違う言語のような縛りにして遊ぶことが出来るので、長期的に物足りないということはないだろう。もうちょっとしたらWASMも来るし、そこからぜんぜん違う方面へ脱出できる環境を、これから自分は頑張りたい。

JavaScriptに投資して幸せになれるか

昔は片手間専用だったけど、今はこれ一本で一通りのことができるようになってはいる。ただ、フロントエンド以外で品質が高くなるかは、それ専用のプラットフォームに劣る。劣った分を技術で取り返したい場合、できなくはないが、そこそこのコストがかかる。

プログラミング初学者は、最初に見た言語を親だと思ってついていく習性がある。今のJavaScriptは、そこから脱出するきっかけを提供してくれない。これは勿論悪い意味で。

僕は雑に使える言語が、JSの他には RubyPythonScala という感じだが、やはりJSでなんでもなぎ倒してしまえるので、あまり触ることがない。よくないと思う。

とはいえ、目先の問題を解決するには良い言語だと思っているし、勉強した分の見返りはある。今一番プログラマの大統一言語に近いのは、「残念ながら」、JavaScriptだと思う。ここの「残念」のニュアンスは汲み取ってほしい。僕はそもそもJSという言語はそこまで好きではない。

あわせてよみたい / tagomoris.hatenablog.com