【新人・若手・未経験のあなたへ】エンジニアとしての土台を、砂場でつくりましょう
ちょっと時間が経つだけで、作るものが変わるだけで、また新しいことを勉強しなくてはならない…
そんなエンジニアの世界においても、状況を選ばずに役に立つ「基本」は確かに存在します。
この記事では、それを身につけるための手助けをしようと思います。
この記事は アイソルート Advent Calendar 21日目の記事です。
こんにちは。
インストラクショナル・システムデザイングループのhasuda.rです。
はじめに
エンジニアとして仕事をするにあたって、必要なものは何でしょうか。
単にフレームワークやライブラリの知識があったり、プログラムの読み書きができるだけでは、十分とは言えません。
なぜか?
そういった具体的なスキルは、需要や中身の移り変わりが激しいからです。
「だからそういうスキルは必要ない」という訳ではありませんが、
言語にせよフレームワークにせよサービスにせよ、
あるものは次から次へとバージョンアップされていき、
あるものは瞬く間に非推奨となり、
あるものは彗星のごとく現れた新サービスの影に隠れ、見向きもされなくなります。
そのような事情のあるIT業界においては、具体的なスキルのベースとなる「考え方・姿勢・心構え」が必要です。
Sunabaとの出会い
私はその多くを、たまたま出会った1冊の本から教わりました。
プログラムはこうして作られる プログラマの頭の中をのぞいてみよう
この本(以下、Sunaba本)は、著者であり(元)セガのゲームプログラマの平山尚さんが作ったSunabaという言語を使って、
画面の上から落ちてくる4つの■をうまく積み上げて消す「あのゲーム」を作りながら
プログラミングの概念や、プログラムを書く時の考え方を学んでいく、というものです。
「あのゲーム」:
Sunabaという言語は、初めて耳にするという方も多いと思います。
それもそのはず、この言語は100%教育用であり、実用的なものは何一つ作れない(著者談)ので、
ソフトウェア開発の現場で使われることはまず無いからです。
にもかかわらず、私が今回Sunaba本を題材に記事を書こうと思ったのには、明確な理由があります。
この本から学んだことが、実際の業務でとても役に立っているということです。
Sunaba本が教えてくれたこと
今回の記事では、その中から私が特に大事にしたいと思っていることを
3つほど紹介したいと思います。
- 「面倒くささ」に敏感であれ
- 道具や機能の本質を理解せよ
- 目的を忘れるな
順に見ていきましょう。
※紹介するSunabaのサンプルコードは、普通のプログラムに慣れている人からしたら
突っ込みたい所が山ほど出てくるような見た目をしていますが、それについてはここではあまり触れません。
1. 「面倒くささ」に敏感であれ
どういうことか
”プログラマたるもの、面倒くさいと思うようなことを工夫なしにやってはいけない。
痛みを我慢する人も、痛みに鈍感な人も、結局は健康を保てない。悪いところを放置して、悪化させてしまう。プログラマにとっての面倒くささは、この痛みのように大切なものなのだ。” (p.460)
Sunaba本では
平山さんは、あえて冗長なコードやまどろっこっしいやり方を最初に紹介し、
「これはこのように短くできる」という具体例を示すことで、
味わった面倒くささを解消するプロセスを読者に体験させてくれます。
以下の2つはいずれも、画面に4ドット×4ドットの四角を1つ描画するプログラムです。
ここで「メモリ〇〇 → 何らかの数」というのは、1つの画素に色をつける処理になります。
#冗長
メモリ[64848] → 990000
メモリ[64849] → 990000
メモリ[64850] → 990000
メモリ[64851] → 990000
メモリ[64948] → 990000
メモリ[64949] → 990000
メモリ[64950] → 990000
メモリ[64951] → 990000
メモリ[65048] → 990000
メモリ[65049] → 990000
メモリ[65050] → 990000
メモリ[65051] → 990000
メモリ[65148] → 990000
メモリ[65149] → 990000
メモリ[65150] → 990000
メモリ[65151] → 990000
#簡潔
メモリ[1] → 0
メモリ[1] < 4 なかぎり
メモリ[0] → 0
メモリ[0] < 4 なかぎり
メモリ[60000 + メモリ[0] + (メモリ[1] × 100)] → 999999
メモリ[0] → メモリ[0] + 1
メモリ[1] → メモリ[1] + 1
読者は、点をひとつひとつ描くという面倒くさい処理を馬鹿正直に書かされてから、
「くり返し」という便利な機能を使った簡潔な実装に導かれます。
最初からくり返しを紹介されてハイ終わり、という風になっていないところがポイントです。
業務では
何も考えずに仕事でソフトウェアを作っていれば、面倒くさいことが山のように出てきます。
「他のところでも似たようなコードをいっぱい書いた気がする…」
「この処理、もっと短く書けないかな…」
「毎日この作業やってるよな…」
こういったことに気づける「嗅覚」が身についていると、コードや業務フローの改善につながり、
より少ない労力でより多くの成果が出せるようになります。
2. 道具や機能の本質を理解せよ
どういうことか
”重要なのは「こういう機能がある」と知ることではなく、さらに言えば、機能の使い方を反復練習することでもない。その機能が目的を果たす上で役立つ、ということを納得する過程である。そうすれば、君は自然にそれを覚えるし、「何を解決するための道具なのか」という本質を理解して使いこなせるようになる。” (p.212)
Sunaba本では
大抵のプログラミングの入門書では真っ先に出てくる、変数という概念があります。
何らかの値を記憶する領域に、名前をつけておける機能のことです。
改めて読み返してみて驚いたのですが、なんとこの本、全14章ある中で、変数が初めて登場するのが第7章なのです。
(本書では「名前付きメモリ」と呼ばれています)
変数が登場する前と後で、同じ動作をする2つのソースコードを比べてみましょう。
(読み解いてもらうには情報が足りないと思うので、パッと見の印象だけわかれば十分です)
実行すると、こんな画面が描画されます。
#変数なし
メモリ[55001] → 1 #手加減オフ
壁を描く()
底を描く()
#ここから落ちるプログラム
メモリ[2] → 0
メモリ[2] < 20 なかぎり
メモリ[3] → メモリ[2] #縦
メモリ[4] → 5 #横
メモリ[5] → 990000 #赤
四角() #描く
メモリ[55000] → 1 #お手紙
メモリ[5] → 0 #黒
四角() #消す
メモリ[2] → メモリ[2] + 1
壁を描く() とは
メモリ[5] → 999999 #白
メモリ[2] → 0
メモリ[2] < 20 なかぎり
メモリ[3] → メモリ[2]
メモリ[4] → 0
四角() #左
メモリ[3] → メモリ[2]
メモリ[4] → 11
四角() #右
メモリ[2] → メモリ[2] + 1
底を描く() とは
メモリ[5] → 999999 #白
メモリ[2] → 0
メモリ[2] < 10 なかぎり
メモリ[3] → 19
メモリ[4] → 1 + メモリ[2]
四角()
メモリ[2] → メモリ[2] + 1
四角() とは
メモリ[1] → 0
メモリ[1] < 4 なかぎり
メモリ[0] → 0
メモリ[0] < 4 なかぎり
メモリ[60000 + (メモリ[3] × 500) + (メモリ[4] × 5) +
メモリ[0] + (メモリ[1] × 100)] → メモリ[5]
メモリ[0] → メモリ[0] + 1
メモリ[1] → メモリ[1] + 1
#変数あり
メモリ[55001] → 1 #手加減オフ
壁を描く()
底を描く()
#ここから落ちるプログラム
回数 → 0
回数 < 20 なかぎり
メモリ[3] → 回数 #縦
メモリ[4] → 5 #横
メモリ[5] → 990000 #赤
四角() #描く
メモリ[55000] → 1 #お手紙
メモリ[5] → 0 #黒
四角() #消す
回数 → 回数 + 1
壁を描く() とは
メモリ[5] → 999999 #白
回数 → 0
回数 < 20 なかぎり
メモリ[3] → 回数
メモリ[4] → 0
四角() #左
メモリ[3] → 回数
メモリ[4] → 11
四角() #右
回数 → 回数 + 1
底を描く() とは
メモリ[5] → 999999 #白
回数 → 0
回数 < 10 なかぎり
メモリ[3] → 19
メモリ[4] → 1 + 回数
四角()
回数 → 回数 + 1
四角() とは
縦回数 → 0
縦回数 < 4 なかぎり
横回数 → 0
横回数 < 4 なかぎり
メモリ[60000 + (メモリ[3] × 500) + (メモリ[4] × 5) +
横回数 + (縦回数 × 100)] → メモリ[5]
横回数 → 横回数 + 1
縦回数 → 縦回数 + 1
言うまでもありませんが、変数ありバージョンの方が圧倒的に読みやすいし書きやすそうですよね。
(完成形ではないので、「メモリ〇〇」はいくつか残ってますが)
変数が登場する前は、こうして番号のついたメモリに値を格納していました(その方法しか教えてもらえないので)。
しかしその場合、「メモリ○○番に××の値が入ってて…」ということを全て覚えておくか、コメントに書いておかないといけません。
そこで平山さんは、章が進みソースコードの量が増えてきた段階で、
「だんだん訳がわからなくなってきただろう?そういう苦しい思いをしないために、実はこんな機能がある」
という風に変数を紹介してくれるわけです。
ここまでされてしまえば、変数というものがどんな不便を解消してくれるのか、変数がないとどんなに大変か、
ということが身にしみて理解できます。
業務では
仕事でのソフトウェア作りは、ライブラリ、フレームワーク、言語の機能など、数多くの「便利な道具」に支えられています。
何か頭に浮かんだものについて、
「それが無かったらどうなるだろう?」
「何のための道具・機能なんだろう?」
といったことを考えてみると、それらに対する理解が深まり、より良い使い方ができるようになるかもしれません。
3. 目的を忘れるな
どういうことか
”この本は、料理でたとえれば「カレーを通して料理を学ぶ本」である。何に使うかもわからない要素をバラバラに紹介することはしない。全てはカレーを作るための手段として登場する。” (p.8)
”物を作ることを目的とするならば、プログラム作りは手段である。手段であることを忘れるくらいの熱意がなければ一流にはなれないのだが、忘れっぱなしであればいいものは作れない。” (p.479-480)
Sunaba本では
もう一度、「あのゲーム」の画像を見てみましょう。
平山さんは、以下のような流れで章を進めていきます。
- 最終的な目的が「あのゲーム」を作ることである、ということを最初にはっきり示す
- 「あのゲーム」を細かい要素に分解する(キーで四角を動かす、四角を積もらせる、四角を描く、etc.)
- 要素のうち、今の状態からすぐに実現できそうなものを示す
- どうやったら実現できそうかを考えさせ、示す
- 一番いいやり方を理由とともに示し、それで実装をする
- 3~5を繰り返す
この構成のおかげで、読者は
「何のために今これをやっているのか」ということを忘れずにいられます。
1冊の本としてのまとまりがものすごく意識されていて、
学ぶ内容すべてに必然性・必要性があるのがSunaba本のすごい所です。
500ページ近くある書籍ですが、
読みながら進めていくのはまったく苦になりませんでした。
業務では
上に挙げた章の進め方は、実際の業務の参考になる部分がとても多く、
ほぼそのまま応用できると言ってもいいくらいです。
特にキーとなるのは1.の部分です。
実際の開発業務はチームで行うことが多いわけですが、その場合、チームの全員が同じ目的を共有しているというのは非常に大事です。
なぜなら、目的の認識が違っていれば、手段に関する議論が噛み合わなくなってしまい、物事が進まなくなってしまうからです。
おわりに
いかがだったでしょうか。
今回の記事で扱ったのは、具体的な技術ではなく、もう少し抽象的な「原理・原則」とも呼べるものでした。
そのため、活用のイメージが明確に思い描けるような内容にはなっていないかもしれません。
しかし抽象的であるということは、それだけ多くの具体的なシチュエーションに適用できるということです。
すぐに効き目を実感するのは難しいかもしれませんが、こういったことを認識できているかどうかが
長期的に大きな違いをもたらします。
そしてここに紹介したような内容は、
エンジニアとしてキャリアを歩み始めたばかりの人や、エンジニアを志す人にとってこそ
学ぶ価値があるのではないかと私は思っています。
Sunabaの世界へ
こちらのページにて、本の著者でありSunabaの作者である平山尚さんが
ソースコードや文法仕様、↑に紹介した書籍の前書きなどを公開してくださっています。
興味を持たれた方はぜひ、砂場に一歩足を踏み入れてみてください。
きっと、人それぞれに新たな学びがあることと思います。
明日は
アドベントカレンダーも、いよいよ終盤に差し掛かってきました。
22日目の投稿は、kaneko.kさんの「変更に強いドキュメントの心得~アジャイルでのドキュメントとの付き合い方~」です。
乞うご期待!