初投稿です。テストを兼ねたQiitaからの移植記事になります
大学・高専の教員や学生に向けてGoを紹介します。
いち学生として研究でプログラム書くうえで感じた問題点を交えながら紹介するよう心がけました。
この記事をきっかけに研究でGoを使うことに興味を持っていただけたら幸いです。
対象読者は学生や教員を想定していますが、非エンジニアの方などもでも通じるところはあるのでは無いかと思います。
Docker/docker-compose で.env を使っていると本番環境のシークレットの管理がめんどうですよね。 シークレットは AWS のパラメータストアに登録して、ECS など環境変数として利用するのが一般的のようですが、一つ一つコンソールに打ち込むのは骨が折れます。 なので.env ファイルからパラメータストアの Terraform ファイルを生成するツールを作りました。
私はある高専の非情報系の学科の学生です。
普段は音響工学に関する研究をしているのですが、研究をする上でプログラムを書くことが多々あります。
私は研究用のプログラムで大事なのは再利用性であると考えています。研究でプログラムを使うときは、教員や先輩の残したコードを改良したり参照したりすることがあるのですが、エラーメッセージが適当であったり、スコープが分かりづらかったりと、読むだけで時間がかかります。これらは結果的に本質的でないところに時間をかけることになり、研究者にとっては致命的なロスに繋がります。
特に、高専はその特性上、1年ほどで研究室のメンバーがガラリと入れ替わるので、プログラムを再利用できることは死活問題になります。
毎年、新たに研究室に加入する学生は、授業でCやPythonを習っていますが、実務に応用できるほどのことは習っていない学生がほとんどという印象があります(主観)。
そのため、新人の研究室員は実質的に1からプログラムを覚えることになります。しかし、研究に使える時間は限られているので、必然的に基礎がわかっているCもしくはPythonを勉強することになります。
したがって、先代たちが作成したプログラムはCやPythonで書かれているものがほとんどになります。
しかし、経験上CやPythonで書かれたプログラムは再利用し辛いものが多いです。
ドキュメントやコメントをしっかり書くように教えればいいのかもしれませんが、これはどの言語を使うにしても必要なことですし、全ての学生に教え込むのは無理があると思います。
したがって、CやPythonで研究用のコードを書くのが問題なのではないかと考えました。
教員達は世代的に(?) Cを書ける方が多く、学生は教員のサポートを受けやすくなります。また、型が明示的であることや変数宣言がある点は読みやすいプログラムを書くうえでメリットとなります。
一方で、Cを使うと以下の問題が多く起きます。
- コンパイラのエラーメッセージが分かりづらい
- メモリ管理が必要 - 安全なコードを書くことは経験の少ない学生とって難しい
- ライブラリやリンクの概念の学習コストが高い
- リンク?どういうこと?
- Makefile? なにそれ
- 巨大なプログラム
- 繰り返されるコピペ
- コピペしたものを改良するため、一見同じでも動かない紛らわしいやつ
- OSのバージョンが変わると動かなくなる実行ファイル
などなど、勉強する学生にとっても、教える教員にとっても地獄です。
もちろんCにも良い点はありますが、初心者からすると使いづらいと言わざるを得ないと思います。
最近はこのような流れからPythonを使う研究室も増えてきています。
PythonはCに比べて入門しやすく、ライブラリも豊富です。 特にnumpyやscipyなどは研究をする上で非常に便利なツールとなります。
しかしながらPythonを使うとまた別の問題が発生します。
- Pythonは簡単に動くコードをかけるが、言語仕様が柔軟すぎるため本人しかわからないコードができてしまう
- 値渡しなのか参照渡しなのか (正確にはミュータブルかイミュータブルか) 分かりにくいため副作用が見つけづらい
- 型がコードに書かれない(数値演算を行うときに)
- ライブラリが多機能ものが多く、学習コストがかかる
- ソースコードがpipで隠蔽されており簡単に見ることができない (Goにくらべて)
- 高度な言語仕様を使用して作られている場合が多く、初心者にはコードが読みづらい
- ライブラリがCで書かれていることもある
- 研究に使用する以上ライブラリの中身を説明できないのは問題となり得る
- 個人的にnumpyは便利だが曖昧でも動いてしまう点が気に食わないです(転置せずとも行列演算ができてしまうなど)
Pythonはささっと書いて動かすプログラムを作るには非常に便利ですが、後に継承されていくような?比較的大きめのプログラムを作るには不向きという印象があります。
ここまでで出てきたプログラムとして想定しているのは
- 一連の実験の実行
- 軽い数値演算
- バッチ処理
- ファイル整理
などです。
全てにおいてGoが最高というわけではなく、ゴリゴリの数値演算やリアルタイム性が必要なものはCやC++、データ処理やグラフ化ならPythonなど、はっきりとした目的があるならば用途に合った言語が最適だと思います。
私は、CやPythonの問題を解決するにはGoを使うのが手っ取り早いと考えています。
Goは
- シンプルなので学習コストが低い
- Cが分かればGoもだいたい分かるので教員も馴染みやすい
- 動かないものはコンパイルされない
- 誰が書いても同じコードになりやすい
- Cのように強い型付けがある
- Pythonのようにシンプルな記法
- コンパイラのエラーメッセージが親切
- ガーベッジコレクションがあるため、メモリ管理を基本的に考えなくて良い
といった特徴の言語です。
このような特徴から、学生にとっても教員にとっても学習しやすく、バランスの取れた言語であると思います。
また、特筆するべき点は誰が書いても同じコードになりやすいという点です。研究に使う上ではこれは非常に大きなメリットになります。
詳しくはGoについて非常によくまとめられたmattnさんのスライド(プログラミング言語 Goのススメ)が参考になります。
また、ライブラリに関しても
- Goでシンプルに書かれている事が多く、中身を参照しやすい
- ライブラリと自作のソースコードが同じように管理される
- 基本的にgithubからダウンロードして使うことになる
といった特徴があるので、ソースコードを参照するハードルが低く、プログラムの透明度が高くなります。
さらにGoの特徴の1つとしてクロスコンパイルが容易にできるというものがあります。
私は研究テーマの都合上Raspberry Piなどを使うことが多いのですが、プログラムをデスクトップで開発し、コンパイルしたものRaspberry Piに送って動かすということを良く行います。
Goにはcgoという機能があり、?Goのソースの中にCを埋め込むことが可能です。また、Cのライブラリを読み込むことができます。したがって、Cで書かれた資産を書き換える必要も(ほぼ)ありません。
パフォーマンスは落ちてしまいますが、速度が必要でなければ使用する価値は十分にあります。
作ったライブラリはgithubで簡単に公開・利用できるので、他の研究者とノウハウの共有も簡単に行えるようになると思います。
また、Goのライブラリはまだまだ少ない状況です。これはOSSのコミッターになれるチャンスです。
是非、専門知識をコードにして貢献しましょう。
蛇足ですが、私は適応アルゴリズムを利用した研究をGoを使用して行っています。
適応アルゴリズムとは簡単にいうと、過去の入力信号から次の信号を予測するアルゴリズムです。
稚拙なプログラムですが、Githubでライブラリを公開しています。
今は基本のアルゴリズムしかありませんが、順次発展的なアルゴリズムを増やす予定です。また、Goの並行処理を活かしたプログラムも書きたいと考えています。興味のある方は見て頂けると幸いです。
Goのコードが全く無く恐縮ですが、ここまで読んでいただきありがとうございました。
間違い・意見等あれば指摘していただけると幸いです。
教員・学生のみなさん、Goを書きましょう。