更新履歴てきなもの
- 2023年10月21日:タイポや言い回しなどの一部修正をしました。引き続き、多くの方の目に留めて頂き、ありがとうございます。
- 2021年08月07日:おかしな表現などの修正をしました。これまで多くの方に読んでいただいております。ありがとうございます。
- 2020年07月19日:タイポなどの修正、「まとめ」追加、「余談」追加(前の余談は余談2に移動しました)。
はじめに
10代からプログラミングに触れてきた者です。
趣味・仕事含め、かれこれ30年以上の暦になりました。いやですね、年とるって。
それはさておき。
若い頃からイラストを描いたり楽器に触れてた人が大人になってから「どうすれば、あなたのように自由に描ける(奏でられる)のか?」と問われても、きっと回答は難しいでしょう。
否、答えるとしたら「好きになること、それだけだ」という回答になるかもしれません。
同様に、私が「どうすればプログラムを書けるようになるのか」と言われたら、「プログラミングを好きになったから」と答えるしかありません。
昨今、ビジネスや教育などのシーンにおいて、プログラミングが(なぜか)注目されているようです。
私には、なぜ急にそんなことになったのか理解ができないのですが、世に言われているような、プログラミングのスキルが論理的思考を育てるとか、問題解決能力を高めるとか、そういうものは一切信じていませんし、そうだとは決して思いません。
最初にお断りしておきますが、論理的思考や問題解決能力を高めることを期待してのプログラミング学習へのモチベーションなら、即刻、プログラミングよりもはるかに効率的でベストな方法論を選択することを強くオススメします。
タマゴが先かニワトリが先かじゃないですが、論理的思考や問題解決能力がある人でプログラミングの素養がある人なら、プログラミング能力をより活用し引き出すことができると私は思っています。
この業界に身を置いて長いですが、まったく論理的思考もせずまったく問題解決できないプログラマやエンジニアを大量にみてきたからです。また逆に論理的思考も問題解決能力も持っているけれど、プログラミングとなるとツッコミどころが無数にあるという人も見てきました。
ここでは、私が30年以上を通じて培ってきたものを通じて、プログラミングを身につけるための持論を書いてみたいと思います。
雑談だと思ってお付き合い頂ければ幸いです。
継続は力なり
ハッキリ言い切ります。
継続は力です。
継続させることが一番大切です。
これができそうにないなら、申し訳ないですが、早々に退散したほうがいいです。
カッコイイと思う
「好きになる」っていう人は多いと思うんです。
でも、好きになるのは理由がある。
同じことかもしれないけど、「プログラミングができればカッコイイ」って思えばいいと思うんです。
ちなみに私がプログラミングに触れたのは小学校5年生の頃ですが、ぶっちゃけ「キーボードをバリバリと叩いてプログラミングなんかできたらカッコイイ」っていうイメージから入った気がします。
決して何かを作りたいと思って始めたわけではないです。
音楽をやってる人もカッコイイから入ってる人が多いし、絵を描いてる人も、他人が描けないものを描くことに心地よさを感じていたからではないでしょうか。
まずは「カッコイイ」が学びのひとつのきっかけだとは思います。
センスの問題は多分にある
カッコイイだけでは成立しません。
ぶっちゃけて言ってしまうと、センスの問題は多分にあります。
恥ずかしいことを書きますが、私はギターが弾けたらカッコイイと思ってギタースクールに通ったことがあります。
1年通って、できたことは、CDEFGABCを奏でることだけでした…あー恥ずかしい!
センスとは多分に興味の有無に依存するとは思います。
プログラミングができたらカッコイイ、でもそれほど深い興味がない。
この事実は、おそらく状況を悪化させます。
私が考える「センス」とは、カッコイイと思うことと興味を持つということの持続なのだと思います。
現に私は今でも、いいプログラムが短時間で完成させられることが「カッコイイ」と思いますし、そのためのチカラを身につけるために勉強を継続していますし、そのモチベーションは「プログラミングが好きだから」に他なりません。つまり興味が継続しているわけです。
まず、はじめる
案外壁なのかもしれませんが、「まず始める」ができない人のほうが大多数なのではないでしょうか。
始めなければ、始まりません(コイツ何言ってんだ?って思うかもしれないですが、ホントです)。
言語パッケージをインストールしました。
あとは、明日やろう。
ということであれば、先には進まないのです。
インストールは準備です。
ギターを買っただけではギターは弾けません。
弦を張り終わったとしても、別にギターを弾いたわけじゃありません。
まずは、1行でもいいから「プログラムを書く」ことをする。
これが、最初にやるべきことです。
何を1行書くか。
このあたりを参考にしてみてください。自分が勉強しようとしている言語から選んで、1行書いて、実行しましょう。
1行書いて、実行して、成功したら、2行目を書きましょう。
徐々に、ゆっくり、行を増やしていけばよいのです。
カンタンなところからやる
晴れて「カッコイイ」という気持ちも「興味」というモチベーションも保てた方が、そしてついに1行でもプログラムを書けた方が、その先にどう勉強すればいいのか。
まずは、カンタンなことから始めよう、ということです。
プログラミングに限らず、「パソコンを使いこなしたい」っていう言葉は、よく耳にします。
彼らの「使いこなす」という意味には、おそらく「すべての機能を理解・利用する」という意味が含まれているものと思います。
プログラミングにおいて「使いこなす」という意味は、言語仕様のすべてを理解した上で論理的かつ合理的なコードを生成するということに他なりません。
しかし、そうした意識は、初学者の時点では捨てた方がよいでしょう。
特に高度な技術というのは、基礎的なものの上に積み重ねた上で成立するものです。
よく引き合いに出されるのがC言語の「ポインタ」かもしれません。ポインタはC言語を学習し始めた人には理解が困難かもしれません。それはC言語(というよりコンピュータサイエンス)の基礎をしっかり理解できていないからというのが大きな理由であると思います。
プログラミングというのは、単一の技術ではないんですね。ITに関する様々な技術がからみあって製品やシステムを成立させているものなのです。
クルマの場合だと、エンジンスペックがとりたてて注目されたりすることが多いかもしれません。
しかしエンジンがすごくても、製品そのものはエンジン技術だけで成立しているわけではありません。
その技術をすべて、一度になんとか身につけようとしても、とてもじゃないけれど、無理です。
初学者は、まずは基礎の基礎たる「プログラミングの核心」を最初に学んでいくことが必要かと思います。
カンタンなところを、しっかり覚えましょう。
ただ、つまんないんですよね、基礎的なことばかりや、カンタンなところばかりの学習は。
だからこその「好き」「カッコイイ」といったモチベーションが不可欠なんです。
これがキモなんですよね。これさえあれば、あとのことなんか、だいたい越えられます。
自分に合う教本に出会う
最近ではググってナンボという世界かと思います。
現にこのQiitaの私の記事をググって見つけてくださった方も多いかと思います。
しかし私は、本のチカラを推奨します。
技術書は高いですが、その理由はカンタンです。
本に書かれていること以上の知識を持つ技術者が、体系的に特定の技術についてまとめ上げ、その他参考文献を記載しているという事実。
これだけで、お金をかけて買う意味があります。
情報を得るには、お金が必要です。
自分にあう技術書を選ぶコツですが、だいたいこんな感じです。
- 「まえがき」を読む。どういう目的で、どういう人を対象にして書かれ、どういう前提知識が必要なのかが書かれていることが多いです。
- 目次を読む。キーワードが列挙されています。初心者のための項目やコラムがあるかどうかも注目点です。
- 索引を眺める。キーワードが多ければ多いほど、後で調べるときに戻って読み返すページが多いことに他なりません。
残念なお知らせですが、Amazonでは出会えません(技術書選びに慣れるまでは、ですが)。
出会うには、大型書店で物理的に本を手にして、重みに耐えながら出会いましょう(技術書は文庫新書に比べて腕が疲れます)。
たまにはいいですよ、物理本屋も。
写経する(強制ではない)
1冊気に入った本を買ったら、まずは、その本を信じて読み尽くします。
この15年ぐらいで、コンピュータ書籍の棚は大手書店だけでなく中堅どころの書店でも多く取り扱うようになりました。
つまり、コンピュータ関連書籍は、それだけ増えているということです。
昔(インターネットなど一般人の手になく研究者だけが使っていた時代です)は、小さい書店には1冊も取り扱いがなく、中堅書店や大型書店でもごくわずかな棚を割かれる程度でした。
手に入れた本は、擦り切れるまで使いました。
そう、技術書は、読むのではなく、使うのです。
書き込みをするとかではなく(私は書き込みが大嫌いな人です)、書かれているプログラムを読み、書かれている解説を読み、マネして書かれている通りにプログラムを動かし、「もしかして…」という直感に基づいて、ちょっとだけプログラムを修正して動かし、動いて感動し、次の章に向かうのです。
ちなみに私が中学生のときには、C言語のバイブルといわれた、カーニハン&リッチー著の「プログラミング言語C」を図書館の勉強机でひたすら写経して自宅で読み勉強したものです。
コンピュータも持ってなかった中学生時代は、大学ノートにプログラムを書き、デバッグし(消しゴムで消して書き直した(笑))、脳内実行し、機会があれば町の電気屋に展示していたパソコンでプログラムを実行して動作確認をしていました。まあ、そういう時代だったんですけどね…。
そこまでするのは時代や環境の問題なので「それが正義」というつもりは一切ありません。
しかし、手に入れた本に書かれたプログラムを、手持ちの実機を使って「忠実に再現する」ことの意義と重要性だけは、お伝えしなければならないと思っています。
人は読んだだけでは完全には理解できないものです(天才を除く)。
理解したつもりでプログラムを書いても、だいたいバグで動きません。
人間の言語なら、多少の間違いも聴き手が勝手に補正してくれますが、プログラムはコンピュータとの対話なので、1文字違っただけでも、文法上ちょっとした入れ違いや間違いだけでも動きません。
動かなければつまらなくなり、諦めます。諦めたら、その先はありません。
少なくとも、書籍のサンプルプログラムは、検証済み(であるはず)なので、ほぼほぼ動くでしょう。
不幸にして(?)動かない場合は、自分でデバッグまでできます。
デバッグが一番勉強になります。「失敗は成功のもと」っていうでしょう?
(書籍のプログラムが動かなくて困ったら、出版社サイトに正誤表があるかどうかも確認してみましょう)
小さいプログラムをいっぱい書いて、結果を見る
大きなものを作るのではないのです。
小さなプログラム、本当に「だから?」って言われそうな、そんなのでもいいから、プログラムを書くのです。
小さなプログラムすら書けなければ、大きなプログラムは書けません。
無駄だと思うプログラム、前に書いたのと似たようなプログラム、誰かが書いたことのあるプログラム。
そうしたものを、たくさん書いて、実行して、結果を見ましょう。
結果を見れば、動いた実感がどんどん自分に入ってきます。
何を書けばいいのか?
書籍を持っているなら、サンプルプログラムをちょっとだけ改造してみましょう。
興味があることがあれば、それをプログラムで実現してみましょう。
途中で「うわ、これ今の知識では解決できない!」となることがあります。
その場合には、さらにプラスの知識を獲得するために、書籍なりウェブなりで、先を調べていきましょう。
継続が力なので、とにかくたくさんの成功経験を積み重ねることが大切です。
失敗しても、そこでは「一旦中断、別のことをしよう」としましょう。失敗ではないのです。まだ自分の技術が追いつかなかっただけなのです。
もう一歩進んだ勉強をすれば、必ず成功に変えることができます。
プログラムを改造する
成功経験を積み重ねるためにも、サンプルであろうが自作であろうが、プログラムは常に改造していきましょう。
書籍やウェブ・ブログのサンプルプログラムの変数の値を、別のものに変えて見るのでもいいでしょう。
if文の条件判断の内容を変更して見るのもいいでしょう。
プログラムが動かなくなることを恐れない
これは案外、プロフェッショナルでやってるエンジニアでも恐れてる人が多いんですが、動かなくなるようなプログラムの改変を恐るわけです(もちろん、不要な改変はしませんが)。
プログラムが動かなくなったら、直せばいいのです。
逆を言うと、直せないぐらいなら、プログラムを書くという目的は、もはや達成できません。
商売でやってるエンジニアなら罵倒して終わりですが、初学者にとっては「これはチャンスですよ」と言いたいです。
この不具合を直すと、貴重な「なぜ動かなかったのか」=「動かすために必要な知識は何か」が、人より多く獲得できると言う機会なのです(いや、プロだってそうなんですよ本当は。でもプロでも極端に失敗を恐れる人が多いのは事実です。動かなくなったら自分で直せばいいだけなんですけどね)。
プログラムは、一発では動きません。
プログラムは、あなたが書いた通りにしか実行されません。
プログラムを、あなたが正確に書く・書き直すことで、コンピュータは忠実にあなたの命令を実行して結果を出してくれます。
そことどう向き合い、付き合えるかという点は、ひとつのポイントです。
エラーメッセージを読む
ちょっとプログラミングを進めていくと、悩まされるのが「エラーメッセージ」でしょうか。
英語だし(最近は日本語のメッセージも多いですが)、言ってる意味がわからない(最近では理解しやすいメッセージも多い)でしょう。
私が経験したものでは、大学でJavaのプログラムを学生に教える授業をしていた先生が、エラーメッセージがわからずに私に聞きにきたことがあるのですが、そういうのは、もはやプログラマとしては論外です。
PHPやPythonやRubyなどのスクリプト言語や、C/C++やJavaといったコンパイラ言語であっても、エラーメッセージは常に付き合っていかなければならない対象です。
英語だろうが日本語だろうが、何が原因かを、ここを元に辿っていく他はありません。
助けてくれるのは、インタプリタやコンパイラなどの言語処理系だけなのです。
幸いにして近年では、エラーメッセージ全文をググればいろいろ出てくることが多いです。
しかし、それだけで解決できるかどうかはわかりません。70%は解決できるかもしれませんが、30%は無理かもしれません。
そういう時に大切なのが基礎力なんですね。
一旦呼吸して、インタプリタやコンパイラが指摘する行の前後を目を凝らして読みつつ、言語の文法やルールを思い出しながら、デバッグをしていきましょう。
完成させる
とにかく、どういう形であれ、自分が書いているプログラムを、自分が思うゴールに着地させます。
初学者やアマチュアであれば、「これでいい」と思えば、そこがゴールです。
他人から見れば、それはハンパなゴールかもしれません。
しかし、そんなことはどうでもいいです。
自分が思っているゴールに落ち着けばいいのです。
ゴールに着いたと思ったものの、あとから「まだ修正できるな」って感じたら、新しいゴールに向かえばいいだけです。
ゴールは常に存在します。
しかも自分で自由に決められます。
とはいえ、まずはゴールにたどり着かなければ、次のゴールには向かえません。
どういうかたちであれ、自分の思うゴールに、かならず着地しましょう。
繰り返す
1つ2つプログラムを完成させたところで、それは「あー、やったった!おやすみ!」っていう程度です。
サッカーで2〜3試合勝ったからって、終わりにしますか?
ギター弾けましたライブ1回出ました、終わり…ってなりますか?
プログラミングも、さらに自分が作りたいもの、他人が作って欲しいなって思っているものを、いかに作り込んでいくかが必要です。
特に初学者やアマチュアの方の場合は「それが役立つかどうか」ではなく「どこまで作りこむか、どこまでのめり込むか」が大切だと思います。
プラスαの技術を求める
最初に書いたとおり、「プログラミング」という営みが、プログラムを書くということだけで成立することは、非常にまれです。
ウェブのアプリケーションを作るなら、HTMLやCSS、場合によってはJavaScript、データベース(MySQLやPostgreSQL)、MVCフレームワークや、プログラミングとはまったく関係ないサーバ構築の技術やシェルスクリプト、定時処理のためのcronといったものまで知識として必要になってくることがあります。スマホのアプリを作る場合や昨今の組み込み系でも、外部との情報通信が必要な場面は多いので、ネットワークの知識が不可欠という場面もあり得るでしょう。
いまあなたが使っているコンピュータ言語が、あと10年持つと誰が保証できるでしょうか?(持つとは思いますが、ブームや人気は廃れて開発環境が更新されなくなっている可能性は十分にあり得ます)
コンピュータは「日進月歩」ならぬ「秒進分歩」と言われているほどの速度で、日々変化しています。
昨日まで知られていなかったコンピュータ言語が、GitHubやコミュニティにリリースされて、一躍ブレイクで一大言語に成り上がる可能性だって十分にあります。
しかも、その言語が、ある言語の衰退(というか置き換え)をターゲットとして開発されたものの場合、その先の予測は誰にもつけられないでしょう。
プログラミング言語を学び、流れに乗ってきたら、新しい言語やテクノロジーについて興味を馳せて見る。
これは、非常に大切なことだと私は思っています。
まとめ
ここまで書いてきた、それぞれの見出しこそが、私の言いたいことのまとめともいえます。
それでもあえて総括するならば、こうしたことを長い期間にわたって積み重ねていくことで「好きを増幅して、技術獲得に昇華させる」ということかなと思います。
特に、自らのプログラミングのチカラを育てていきたいのであれば、プログラミング以外のチカラも獲得していくべきなのは、「プラスαの技術を求める」の節でお話したとおりです。
さきに述べたように、コンピュータの技術は多岐に渡ります。すでにあまりにも多岐すぎて、ひとりの人間がすべてを吸収することは難しいはずです。
幅広くソフトウェア開発技術分野について詳しいエンジニアを「フルスタックエンジニア」と呼ぶことがありますが、そうした人たちとて、本当にすべてあまねく知っているとは限りません(ただし「フルスタック」の定義がそもそも曖昧であるということもあります)。
それでもプログラムがコンピュータシステムを動かす唯一の要素である以上、プログラミングに幅広い知識が求められることから逃げることはできないでしょう。
しかし、安心してください。
すべてを深く知らなくても、いいのです。
ほんの少しでもいいから、ちょっとずつ、広げていけばよいのです。
「それ、本当にプログラミングに関係あるの?」ということも、知識・経験として触れておくことは、とても大切だと思います。
そうした断片的な知識や経験が、プログラミングに直結するとは限りません。しかし、実はそういった知識や経験こそが、あなたがプログラミングにおいてこの先苦境に立たされた場合や、悩ましいバグに出会って呆然と立ち尽くしてしまいそうな時に、助けてくれることになるはずです。
それは知識かもしれませんし、考え方かもしれません。
個人の脳は1つのかたまりであり、どこかで分断されたり区切られているているわけではありません。
ある種の知識や考え方が、別の問題解決に繋がることは、普段の生活にだってたくさんあることは、みなさんもよくご存知ではないでしょうか。
だから、これまで述べてきたように、
「好きになる」
「たくさん書く」
「たくさん成功する」
「たくさんの+αを学ぶ」
ことが、大切なのではないかな、と私は感じています。
余談1:じゃあプログラミング教育はどう捉えればよいのか?
学校教育に導入されるプログラミングについて、私は深く理解していませんので、具体的な話をすることはできません。
しかし、この記事の最初に書いたように、日本のプログラミング教育が目指しているとされる「論理的思考力を高める」といったことは、プログラミング教育(だけ)で成し遂げられるとは、私は思っていません。
もちろん私は教育の専門家ではないので、もしかしたらプログラミング教育がそうした力を育てる可能性を秘めていることを、単に私が知らないだけなのかもしれません。
私が言えるのは、ごく簡単なことだけだと思っています。
・他の教科と同様に、興味を持ってもらう
プログラミングだけ特別なものではありません。
もっともあえて言うならば、他の基礎教育科目とは異なり、プログラミングはコンピュータサイエンス(計算機科学)のいち分野にすぎません。
私のイメージでは、国語や算数の中に突然ポツンと「現代はクルマ社会だから、エンジンについて知識を深めることで現代の社会構造を理解する力を育む」のような違和感がありました。
とはいえ、授業を受ける子どもたちにとっては、国語や算数と並んだ1科目にすぎないはずです。
なので、論理的思考力を育てるかどうかに関係なく、この記事の最初にもお話しているとおり、興味を持ってもらうことが非常に大切だろうと思います。
そこでもし好きになれたとしたら、プログラミングの力をさらに伸ばし、直接的にせよ間接的にせよ、将来社会の中で生かせる力が身につくのではないでしょうか。
・キライなら無理にやらせない
これもまた他の教科と同じだと思いますが、論理的思考云々という大人の思惑を押し付けず、キライあるいはニガテなら、わかる範囲でやらせることが大切ではないでしょうか。
誰しも経験があると思いますが、キライな教科を強要されることでコジらせてしまい、その結果、余計にキライになってしまうこともあります(私の場合、歴史がそれに該当します)。
キライにさえならなければ、何かのきっかけで好きに変わる可能性もあります。たとえ好きにならなくても、教科・科目として一定の経験を経ることで、さきほど書いたように、別のところで生かされることもあるはずです(それが論理的思考力なのか否かはさておき)。
もちろんキライになったあとでも好きに転じることはあるかもしれません。しかしそれは、よほどのことだと思います。キライになって頭に入ってくることを根こそぎ拒絶されてしまうよりは、その子がプログラミングがキライであることを尊重した上で、プログラミングと付き合う手段を講じるのが、きっとベストなんだと思います。
余談2:どんな言語を選べばいいのか?
これはとても難しい質問です。
どういうことをやりたいのかによる場合もありますし、理解しやすい・しにくい言語もあるでしょう。
ウェブで調べても、どの言語がメジャーなのかがわかりません。
PyPLのような言語ランキング系のサイトのトップ10の何かを学べばいいという人もいるでしょう。
コンピュータ言語にも歴史があり、その時々に「パラダイム」というものが登場します。
プログラミング言語におけるパラダイムを特に「プログラミングパラダイム」といいますが、プログラミング言語における技術革新といえるものです。
プログラミングパラダイムは、過去のプログラミング言語の失敗や反省に基づいて生まれてきたものが多いので、過去のプログラミング言語よりも多少なりとも理解困難なものがあるのは事実です。つまり、問題解決をするために、より概念化・抽象化させたり、ある場面においてはそれが複雑化の要因になったりすることがあります。
これを回避するためには、「古くからある言語」を選択するという手があるかもしれません。
新しい言語は、どうしても新しいプログラミングパラダイムに基づいた言語設計がなされていることが多いです。
そんなところでつまずいてしまっていては、非常にもったいないです。
その先の技術は、基礎基本を学んだ後で、さらにプラスさせていくことができるので、そこでつまずくような学習方法を選択しないというのは大切な理由の1つであると私は考えています。
BASICという昔からある言語も一つ勉強になるでしょう。といっても今時BASICというのもあまり言語処理系としては流行ってないし…ということであれば、JavaScriptやPerl、Pythonといったものでもいいでしょう。コンパイラ言語であればC/C++も選択肢に入るでしょうが、これはこれで別の壁が聳え立つと思うので、新しくて古い技術のいい部分も持ち合わせているというところでGoやRUstという選択もアリではないでしょうか。