てくのろじーたのしー

Haskellぺろぺろ

自分のプログラミング遍歴

なぜこれを書くか

年末には大掃除しますよね?そういうことです。

プログラミング歴も5年半を超え、色々なことがあったのでまとめておきます。できるだけ時系列順に書いていますが同じ時期に起こったことや長期間に渡る話もあるので正確性には欠けると思います。

自分用PC

「なぜプログラミングを始めたのですか?」

最近、IT企業の方と真面目な話をすることが増えたせいかこう尋ねられることが増えました。

プログラミングを始めた時期は今から5年半ほど前になります。大学に入る前に自分用のノートPCを買ってもらいました。確か「大学に入ればWordとかで課題を提出することもあるだろうから」という名目で与えられたものだったと思います。数年前に妹に譲渡したので詳しい型番やスペックは分からないのですが、Windows7の白いノートPCでした。普通の家電量販店で買ったのでどこかのメーカのものだったはずです。値段も判然としないのですが6, 7万円ほどだったかと。当時、パソコンを使う機会と言えば、ゲームの攻略wikiを見る時ぐらいのものだったため、買う時も特に何も考えずに選んだ気がします。

脱線しますが、twitterは大学に入る1年ほど前からPSPのブラウザ機能を使って、軽量のtwitterクライアントでやっていました。techno_tanoCというアカウントではありませんでしたが。

ともかく、大学に入る1ヶ月ほど前に自分用のノートPCを入手しました。前述したように当初はゲームの攻略wikiを見るためぐらいの認識だったのですが、少し経ってからニコニコ生放送を見るようになりました。竹島さんの放送が大好きで、ずっと見てました。\キャーオーバーレイサーン/

冒頭の質問を投げかけられると基本的に「自分用のPCを手に入れた時になんとなく」と言っているわけですが、実は買ってしばらくはプログラミングを始めるとは夢にも思っていませんでした。

プログラミングを始めた理由なのですが、当初はただの暇潰しでした。あの暇潰しが5年以上続くわけですから人生何があるか分からないものですね。プログラミングをする理由はいくつか思いつくのですが、プログラミングを始めた理由なんて無いに等しいです。強いて言うなら家系かもしれません。これはプログラミングを始めて数年経ってから知ったのですが、父方の叔父は元SEで、父親は昔趣味でBASICやFORTRANを書いていたらしいです。血というのはげに恐ろしきかな、僕も血には抗えなかったのでしょうか?

C++は最強らしい

そんなこんなで大学のために田舎から山口から都会の兵庫県に引っ越しました。

部屋でいつものようにtwitterをしていると、プログラミング言語に関するツイートが流れてきました。曰く、「C++は最強。これがあれば何でもできる。速度も早くてwindowsのアプリケーションも作れる」。特に深く考えることもなくググってみるとC++はどうもすごいものらしい。

最初は「暇だしやってみるか」ぐらいのノリでした。本を買うのも面倒ですし、かわいい猫の写真に釣られて猫でもわかるプログラミングというサイトでC++に入門しました。

C++を始めたと言ったな。あれは嘘だ

1週間で挫折しました。

いや、頑張ったんですよ?何も知らない初心者がwindowsコンパイラ入れて、テキストエディタにぽちぽちソースコードを打ち、コンパイラ様に怒られながらソースコードとにらめっこ。

でもコンストラクタで挫折しました。「コンストラクタってなんだ」。

猫様がおっしゃるには

[作り方手順]
1.コンストラクタは、クラスの名前と同じ名前である。
2.コンストラクタは、引数を取ることができる。
3.コンストラクタは、戻り値がない(注:void型ではない)
4.デストラクタは、クラスの名前の前にチルダを付ける。
5.デストラクタは、引数がない。戻り値もない
6.コンストラクタもデストラクタも省略されると暗黙のうちに
  引数や、中身のない関数が定義されている。
7.コンストラクタもデストラクタもpublicな関数である。

らしいです。完全に「おまえは何を言っているんだ」状態。

f:id:techno_tanoC:20171224181910j:plain

今となってはコンストラクタは常識どころか呼吸レベルですが、当時はオブジェクト指向のオの字も知らないド素人です。

当時は

  • 「そういえば関数って数学で習ったぞ」
  • 「つまりコンストラクタは二次元座標のx軸とy軸みたいなもんなんだろうな!」
  • 「じゃあデストラクタってなんだ?」
  • 「なんでクラスと同じ名前なんだ?」

とか明後日の方向に思考が飛んで、どうにもならない状態でした。

コンストラクタが分からないならC言語をやればいいじゃない

今思えばC言語もできないのにC++ができるわけないです。当時の僕もそれに気づいたのか、猫様の下でC言語を学び始めました。

C言語の勉強はそこそこ上手くいき、どこかで見つけた素数列挙プログラムを書いてニヤニヤしていました。アルゴリズムは確か、「nを2以上n未満の数字で割ってみて、割り切れなければ素数。それをnをカウントアップしながら繰り返す」だったと思います。ズラズラ出てくる素数、だんだん見つかるのが遅くなる素数素数の列を見ながら奇妙な満足感を得ていました。学校の授業中にノートにそのプログラムを書いてアルゴリズムをトレースしてはちゃんと動くことを確認していた記憶があります。

最終的にはビットマップで画像処理のを参考に、「BMPファイルをアスキーアートもどきに変換するプログラム」を作りました。大層なものではなく、画素ごとに明度をもとに数種類の文字から選択して出力しただけのものです。遠目で見ればちゃんともとの画像が分かる程度のものでしたが、まどマギの画像をAA化して友達に見せたりしていました。意外とBMPフォーマットって簡単なんですよね。

ソースコードこちら

C言語時代に書いたコードを探してみたのですが、これ以外は見つかりませんでした。残念。多分C++, C言語C#Javaソースコードはほぼ全て喪失しています。

C#は楽だった

実際に役に立つプログラムを作るにはGUIの方が楽ということでC#を始めました。VisualStudioはすごいもので、GUIGUIを作れるんですよね。分からない方のために説明すると、以下のようにツールボックスからデザイン画面にD&Dして、プロパティを設定するだけでそこそこいい感じのGUIがデザインできてしまいます。

f:id:techno_tanoC:20171224190631j:plain

あとは各コンポーネントに対応するクラスのイベントハンドラに処理を書けば動くわけです。

最初に作ったちゃんと使えるようなものは確かこれまたどこかのサイトを参考にした電卓だったと思います。四則演算、べき乗、消費税の計算などの機能があったと思います。

C#ではいくつかのソフトを作りました。覚えている範囲では、

  • 1つのウィンドウを分割して同時に2つのサイトを見れるブラウザ
  • RSSを表示するサーバプログラム(当時はHTTPという便利なものを知らなかったのでTCPで無理やり文字列を送っていました)
  • ニコニコ動画APIを叩き、キリ番一歩手前の動画を探し、キリ番を踏むためのコンソールアプリ
  • Vistaで入ったDWM(Desktop Window Manager)を用いたウィンドウのサムネイルを一覧化し、クリックするとそのウィンドウがアクティブになるタスクスイッチャー
  • 好きな画像をもとに15パズルを生成して遊べるゲーム

などを作りました。例によってソースコードはもうありません。

特に後半の3つは思い入れがあります。

ニコニコ動画APIを叩くものは、実装そのものよりも後述する関数型プログラミングの話になります。

 

DWMという言葉を知らない人でも、Vistaでタスクバーにあるアプリの部分にカーソルを乗せた時に表示されるリアルタイムのサムネイルを見たことがある人は多いのではないでしょうか?

f:id:techno_tanoC:20171224193407p:plain

タスクスイッチャーの方はこれを一覧化したものでした。 APIの叩き方はProgramming the Windows Vista DWM in C# - B# .NET Blogを見ながら作りました。

いつ消えるかも分からない古いサイトなのでウェブ魚拓megalodon.jp

同時に全てのウィンドウを見ることができたので、他のウィンドウの状況を見ながら作業する時には便利でした。このサムネイル、ウィンドウと同じ解像度を持っているので、大きく表示すればちゃんと文字まで見えるんですよね。

 

15パズルというのは以下のようなものです。あくまでイメージで、実際に作ったものとは違います。

f:id:techno_tanoC:20171224193645p:plain

jpgなどの画像をD&Dすると画像を16分割して、シャッフルして、プレイヤーはバラバラになった絵をピースをスライドさせて完成させるというものでした。

シャッフルは適当なピースをランダムに動かして行うものだったと思います。確か下手に入れ替えると解けないパズルになることがあるので。

このゲームは徹夜をして作った思い出があります。当時は「テスト」なんて便利なものをしらないので、デバッグがなかなか終わらず、ソースをいじっては動かしいじっては動かしを繰り返していました。デバッグの時間の内、けっこうな時間は実際にパズルを解いていたかもしれません(笑)。

Androidアプリが作りたい

C#で色々作ってる間に、並行してAndroidアプリの作り方も学びました。特に始めた理由はないのですが、使っていたのがAndroidだったので作ってみたくなったのだと思います。(ちなみに悪名高きARROWSのISW11Fでした。F士通が嫌いになりました)

Androidアプリでも色々作ろうとしていました。Eclipse上でAndroidアプリのプロジェクトがうまく作れなくて1ヶ月コードを書くところまで辿りつけなかったのは良い思い出(良くない)。

結局実用に至るレベルのものは作れなかったのですが、

  • Dropboxに置いてある音楽ファイルをストリーミングで再生する
  • USB接続したwindows上にある動画ファイルをストリーミングで再生する
  • URLを指定するとファイルをダウンロードするアプリ(未完成)
  • OpenGLで立方体を回すだけ
  • 音楽プレイヤー(未完成)

などを作りました。

最初の2つは実際に再生ができるだけの部分しか作っていません。

確かUSB接続したwindows上にある動画ファイルを再生するアプリは、アプリの裏側でプロキシとなるwebサーバを立てて、そこからのストリーミングで再生するような実装だったと思います。Androidはwebサーバからのデータをストリーミング再生できるので無理やりそういう実装にしました。

多分この辺りまでがプログラミングを始めて1年か1年半ぐらいまでだったと思います。

基本情報技術者応用情報技術者試験

プログラミングを始めて1年ほどで基本情報技術者を取得しました。その半年後には応用情報技術者を取得しました。

僕の家はちょっとスキル主義なところがあって、小学生の頃にはハンダ付けやノコギリ、金槌の使い方からネジの締め方まで、父親から教わっていました。その延長線上に資格取得はあります。

小学6年生の時に第4級アマチュア無線技士、中学2年生の時に丙種危険物取扱者と乙種第4類危険物取扱者、高校2年生の時には二級小型船舶操縦士を取得しました。

上記の資格は特段難しいものではなく、父親曰く「資格取得の体験をさせるのが目的」だったようです。「こういう資格取ってみるか?」と聞かれ、それに乗っかる形で勉強しました。両親とも資格を要求される仕事に就いていたため、僕自身も資格に対する漠然とした憧れは幼少の頃からあり、資格取得には意欲的だったと思います。ただし資格自体が役に立ったことはありません。

さて、上記の資格は「取ると決めてから勉強を始めた」という形なのですが、情報技術者の資格は違います。

大学に入ってからプログラミングを始め、ある時ふと思いました。「一介の薬学生が『プログラミングを勉強しました』と言ってどこまで信用されるのか。そもそもちゃんと勉強したと言えるのか。資格を取って客観的に証明してやろう」。早速ネットで検索してみると基本情報技術者というのがあるようです。その後本屋でその参考書を立ち読みしてみました。感想としては「なんだ意外と知ってることばっかりだ」。C言語アルゴリズムの基本を、C#でネットワークの基本を、AndroidJavaSQLiteを知っていたのが幸いして、あとは暗記すべき点を暗記すれば勉強は終わりました。同様に半年後に応用情報技術者を勉強して合格しました。

ちなみに調子に乗ってその後にデータベーススペシャリストネットワークスペシャリストを受けたのですが不合格でした。その頃から学校の勉強に追われるようになったため、再挑戦は叶わず。いつか再挑戦したいものです。

関数型との出会い

Rubyを始めるのと関数型プログラミングを始めるのは時期的に近いのですが、先に関数型プログラミングについて書きます。

前述したように関数型プログラミングとの出会いはニコニコ動画APIを叩くライブラリです。githubニコニコ動画APIを叩くライブラリを見つけてそのソースを読んでいる時でした。C#にはLINQという機能があり、そのメソッド構文ではラムダ式を使ってリスト処理ができます。ラムダ式を始めて見た瞬間に「プログラミングにはこんなに物事を簡潔に書くことができる機能があるのか!!!」と衝撃を受けました。後から思えばこれが関数型プログラミングとの出会いでした。

そういうわけでラムダ式を知り、関数型プログラミングの存在を知り、Haskellを知りました。『すごいH本』を読んでHaskellを勉強しました。

Haskellは素晴らしい言語です。ここでは多くを語ることはしませんが、代数的データ型、パターンマッチ、オフサイドルール、モナドなどなど今までの言語とは全く違う世界が広がっており、その簡潔で安全な性質に魅了され、その後のプログラミング観に大きな影響を与えました。

勉強会初参加 Python?いやRubyだ!

AndroidJavaを触っているうちに、近くでJavaの勉強会が開かれているようだったので参加しました。初勉強会参加です。

そこからいくつかの勉強会に参加するようになりました。

当時は「そろそろスクリプト言語もやりたいなぁ」「とりあえずPythonやるかー」などと下手の横好きなことを考えて、『パーフェクトPython』を買いました。しかし直後にRubyの勉強会に参加し、Rubyをメインに触るようになったのでPythonはこの本を読んだだけで終わってしまいました。そういえばRubyの本は一冊も買っていません。借りた『メタプログラミングRuby』を読んだぐらいでしょうか。

というわけでRubyの勉強会に参加したのですが、それがあの有名な(?)、神戸.rb(当時は東灘.rb)です。

Rubyの言語仕様を知らないどころか、RubyすらインストールされていないノートPCを抱えて参加するという、今思えば大変申し訳ない状態での参加でした。しかもあろうことかペアプロ回に。更に言うとペアのお相手は伊藤淳一さん(@jnchito)でした。

windows + ruby未インストール + rspecも知らない初心者というトリプルコンボです。目も当てられない惨状です。伊藤さん、あの時はすみませんでした。

この辺りまでが大体プログラミングを始めて2年ぐらいだったと思います。

以降、1年ほど神戸.rbに参加したり、LTをしたりしました。

アルバイト

神戸.rbに参加したり、rubyで色々書いているうちに言語仕様や標準ライブラリには詳しくなってきたある日、僕が神戸.rbの飲み会でとある方に「プログラミングのアルバイトをしたい」と言ったところ「じゃあウチで働いてみる?」と声をかけて頂きました。そこはRailsを使ってECサイトを構築し、運営する会社でした。

当時はrubyは書けるけどrailsはサッパリ分からないという状態で、まずはrails tutorialで勉強をしました。rails tutorialは良いものです。gitとrspecも同時に勉強しました。

色々思い出はあるのですが記事がドンドン長くなるので短く箇条書きにします。

  • git pushでエラーが出て、"-f付ければ?"的なメッセージが出ていたのでforce pushして怒られた
  • active_recordのベストプラクティスを知らないせいで変なこと言ってとても優秀な高専エンジニアと衝突する
  • tap + breakのコンボで高専エンジニアのコードをリファクタリング
  • プロダクトオーナーが「テストは無駄、バグを出さなければもっと早く開発が進められる」と発言して戦々恐々
  • 社長にプログラミングの難しさを説く

初めての自作PC

rubyを書くならLinuxの方が良いと思い、とりあえずファイルサーバ兼rubyプログラミング用サーバを組みました。このサーバは今も隣で元気に動いています。この前(2017年12月上旬)、OS用HDDが壊れて大変でしたが。自作PCはパーツの使い回しが効くことや、換装して修理することができるのが良いです。おまけに少しだけハードウェアについて詳しくなれます。

お金が無いのでCPUはCeleron、メモリ2GBの低スペックです。合計3万円いかないぐらいだったと思います。windowsのノートからSSHでログインしてrubyを書いていました。

デスクトップも自作PCを組んでwindows卒業したのがこの半年後ぐらいです。

アルバイトその2

いろいろあって前述のアルバイトを辞めたのですが、すぐに次のアルバイトを始めました。

今度は学習サービスを作っている会社で、僕はそこで勤怠管理用のタイムカードアプリを作りました。

結局学校の勉強が危うくなってきて、このアルバイトは泣く泣く辞めることとなりました。

この辺りでプログラミングを始めて3年半ぐらいでしょうか。

Shinosaka.rb

この時期頃からshinosaka.rbという大阪のrubyのコミュニティに参加し始めました。

rubyに限らずフロントエンドに関係する勉強会もあり、最新のWeb業界の技術に触れ、学ぶことができました。大学5年生の間は実家の山口県で薬局・病院実習をしていたため、あまり参加できていなかったのですが、これからはドシドシ参加していきたいです。

ないなら作れば良いじゃん Shinosaka.hs(Shinosaka.fp)

shinosaka.rbで「関数型の勉強会って大阪じゃあんまりないんですよね〜」と愚痴ったところ、「じゃあ自分でやれば良いじゃん」と言われ発足したコミュニティ、それがshinosaka.hsです。コミュニティの目的は「関数型言語を盛り上げること」です。

過去の発表のスライドと勉強会の反省ブログは以下です。

スライド 反省ブログ
What's Haskell? Haskell勉強会をしたことに関する反省会
Elixir入門 shinosaka.hs #2 Elixir入門を開催した
マクロ + phoenixハンズオン Shinosaka.hs #3 Elixir入門をした
ブログなし 関数型プログラミング基礎論

elixirの勉強会もしているので、shinosaka.hs(hsはhaskellの意)ではなく、shinosaka.fp(fpはfunctional programming: 関数型プログラミング)への変更を検討しています。

Elixirって良いよね

2016年の春~夏ごろに始めた言語です。「rubyと似たシンタックス関数型言語」という評判を聞きつけて始めました。shinosaka.hsでも2回、elixir関係の勉強会を開きました。

2017年にはElixir Conf Japan 2017に参加し、Elixirを現場で使っているエンジニアの方々のお話を聞き、Elixirを使っている企業への関心が高まったように思います。

Elixirに対するイメージは別のエントリで書いているため、気になる方はそちらをどうぞ。

AWSインターンシップ

インターンシップの内容を公開しても問題ない旨を担当の方が仰っていたので書きます。

当初、インターンシップに参加するつもりはあまりありませんでした。正確にはインターンシップに参加するための選考に合格できるとは思っていませんでした。

AWSクラウドサポートエンジニアのインターンシップに参加するためには技術試験と技術面接に合格する必要があります。僕はこの技術試験に興味を持ちました。「AWSの課す試験とはどういうものだろう」、そんな興味に抗えず選考を受けました。技術試験内容に言及することは避けますが、実践的なものだったとだけ述べておきます。

技術試験の結果は合格で、技術面接に進めることになりました。技術面接も実践的で、事前に提示されたテーマについて必死に情報を集めなんとか形にし、面接に挑みました。面接時点で山口で薬局実習を行っていたため、ビデオ面接という形でした。柔軟な対応がいかにも今時のIT企業という感じです。

技術面接も通過し、晴れてインターンシップに参加が決まりました。

僕が参加したのは大阪での1週間のインターンシップです。参加者は僕を含めて7人でした。皆さん、情報学部か工学部で僕だけ薬学部という非常に浮いた存在でしたが、その壁を感じることはなく、楽しくインターンシップを行えました。

初日は実践形式のトラブルシュート大会が行われました。予め問題を発生させておいたEC2サーバが用意され、問題を解決することによって点数を競うというものでした。結果は僕は4位だったと思います。AWSのEC2の設定・権限周りはもちろん、ネットワークからHTTPサーバ、果てはDBの知識まで要求される非常にレベルの高い大会でした。1位の人も全ての問題は解決できなかったようでした(しかしかなりゴールに近いところまで行っていたようでした)。

2日目以降は2, 3人のチームを組まれ、ハッカソンのようなことを行いました。僕は3人チームでした。テーマは「AWSサービスをできるだけ使い、Amazon Our Leadership Principlesを体現せよ」。僕達のチームは「議論を活性化する」ためのプロダクトを作りました。

機能としては

  • 写真から顔認識で寝ている人を発見、カウント
  • 議論の感想についての投票機能及び、円グラフによるそのビジュアライズ
  • 議論が活発かどうかの評価機能

です。

バックエンドでAWSのS3、Lambda, API Gateway, DynamoDB, Rekognitionを用いており、AWSの機能を多く使うことができたと思います。

チームの中でweb開発をしたことがあるのは僕だけで、僕はAWSについては詳しくなかったため、僕はフロントエンドをメインで担当しました。と言ってもjQueryを使ってバックエンドからデータを持ってきてChart.jsやCSSで良い感じに表示しただけなのですが。4日しかないとreactやreduxを使って作り込むのは難しいため、jQueryで妥協しました。

そういうわけでフロントエンドを作るのに大して問題はありませんでした。むしろAWSを使い慣れているメンバーがいない分、バックエンド側が大変でした。僕はバックエンドではRekognitionを用いた顔認識の処理を実装しました。Lambdaの中でrekognitionのAPIを叩くだけで様々な顔認識の結果が吐き出されて面白かったです。寝ているかどうかは顔認識の中に目を閉じているかどうかのデータを見て判断しました。目が閉じている人数を数えるだけの簡単な実装でした。APIがすごいと、物事を簡単に実現できて素晴らしいですね。

それ以外の機能もフロントエンド側からLambdaで作ったAPIを叩いてDynamoDBに保存しておき、別途フロントエンドからその情報を取得して実現しています。

チームで一緒に企画・開発するというのは楽しいですね。アルバイトはアルバイトで楽しかったのですが、企画の方には全く関わっていなかったので仕様通りに実装したり、バグを直したり、リファクタリングをするのがメインだったのでした。インターンシップではどんなものを作るのか考えながらものを作ることの楽しさを感じることができました。

最終日には各チームのプロダクトについての発表とAWSエンジニアからの評価・フィードバックと最優秀賞の発表が行われました。

ありがたいことに僕達のチームが最優秀賞を受賞しました。フィードバックには

  • UIが綺麗だった。使いやすそう
  • 技術的にもアイデア的にも素晴らしかった。可能性を感じた
  • 実装アイデアをもっとプレゼンして欲しかった
  • アプリの可能性にもう一歩踏み込んで欲しい
  • 技術的に面白かったところ
    • dynamo streamに気づいていた
    • 3チームの中で一番AWSサービスを使っていた

がありました。賞品としてfire7を戴きました。

インターンシップ中にはトラブルシュート大会とハッカソンの他にも多くのプレゼンテーションやスライド発表があり、AWSの概要や社内の雰囲気について知ることができ、貴重な体験ができたと思います。

今後

やはりITエンジニアになりたいです。特段、関数型プログラミング言語を使って仕事がしたいとは思ってはいません。もちろん使えるのであれば使いたいですが、僕が関数型プログラミングが好きな理由はむしろ「快適に綺麗なコードを書きたい」であるため、解決したい問題がオブジェクト指向や論理型プログラミング言語が適しているのであればそちらを使うべきだと思います。

「快適に綺麗なコードを書きたい」という思いがあるため、新しい技術に挑戦できることや開発環境が恵まれている、あるいは綺麗なコードが評価される文化のあるところで働きたいです。例えば関数型プログラミングであれば簡潔に書くことができる問題でも、オブジェクト指向で書くことを強制されるような社風のところでは働きたくないと感じます。より適した方法があるのであれば、それを使って問題を解決することに挑戦できるような、そんなところで働きたいです。

また、僕はプログラミングをする際に周りに人がいなかったため、OS、DBなどのミドルウェア、ネットワーク、Webバックエンド、Webフロントエンドについては独学で学んできました。それゆえ知識も浅いと思います。今後はこれらの知識も伸ばしていきたいと思うため、様々な業務をしていきたいです。

最後に

C, C++, C#, Ruby, Elixir, Haskellは文章中に登場しましたが、実はscalaも触っていたりLinuxを普段使いしていたりと全てについては書ききれていません。あと今は大学の研究室にファイルサーバを置くことになり、耐久性全振りのために生協にパーツを型番指定で注文していたりと忙しくITをエンジョイしています。

とても長いエントリになりましたが(12,000文字オーバー!)、今までのプログラミング遍歴を思い出して、「こんなこともあったなぁ」と思い出に浸ることができました。とても長い期間のことだったように感じていたのですが、書いてみると意外と短い期間で、不思議な感覚です。

今後もITに携わっていければ幸いです。