見出し画像

非エンジニアのための基礎知識 ②言語の仕組み

こんにちは、のっちです。
前回、非エンジニアの基礎知識ということで、web開発全体の仕組みについてお話しました。詳しくはこちら

前回に引き続き、開発に携わる際に知っておきたかったことを書いていきたいと思います。
今回は、プログラミング言語の仕組みについてです。

書こうと思ったきっかけ

プログラミングを学び始める時にまず考えることのひとつが「どの言語を学ぶか」ですよね。僕も最初に色々調べました。そのうちに
・そもそも何でこんなに言語あるの...?1つで良くない...?(デザインツールなんて2つでもめっちゃ大変ですよ...?)
・そんなに言語使ったらコンピュータ大変なのでは...?
・Railsってフレームワーク?言語のことですか何なんですか...?
のような疑問がむくむくと湧いてきました。

その後学んでいく中で、言語が分かれていく背景やその重要性について知り、上の疑問は解決していきました。
そして、そういった言語の仕組みやライブラリ・フレームワークについて正しく知っておくことで、エンジニアとより建設的な対話ができ、より良いプロダクトが作れるのでは、と感じました。
そこで今回は、言語の仕組みと分けられ方、その中で必要な知識であるライブラリとフレームワークについてまとめていきたいと思います。

どうして言語が必要なのか

そもそも、何故プログラミング言語が必要なのでしょうか。

実は、今でもコンピュータは0と1しか読み取ることができませんすべての処理は0と1だけで行われています
「0」と「1」を「false」「true」と考えて情報処理を行うことを論理演算といいますが、論理演算を用いて足し算や引き算などの算術処理も行うことができるんですね。本旨と逸れるので割愛しますが、仕組みを知りたい方はこちらを見てください。

このコンピュータが扱うことのできる、0と1のみでできた言語を機械語といいます。
機械語は省略形として16進数を扱うこともありますが、いずれにしても数字の羅列はコンピュータのために書かれたものであり、機械語でのプログラムの作成はそのコンピュータの開発者のみが行うことができました。
しかしそれでは他の人が命令を解読することができません。そこで機械語をニックネームでまとめ、それを使って表示する試みが行われました。この言語をアセンブリ言語といいます。
アセンブリ言語は、アセンブラという翻訳機を通すことで、機械語に翻訳され、それをコンピュータが読み取ることで、コンピュータを動かすことができます。

名称未設定 P19

アセンブリ語は、例えばこのように書くと、

pushl %ebp
movl %esp, %ebp

以下のように16進数に変換されます。

B8FF00

これによってある程度理解できるようになりましたが、機械の作業プロセスを言語化しただけであり、人が普段扱うような言語の組み立てではできていません。そのため、依然として機械の作業プロセスを知っている人しか開発できないという問題がありました。
多くのエンジニアが開発に携わるようになると、より労力をかけずに学べることが必要となります。
そこで、機械語にニックネームをつけるのではなく、人が使う言葉から機械語に訳す試みが行われます。これによって、人の思考プロセスでコンピュータに指令をだすことができるようになります。
これがプログラミング言語であり、プログラミング言語を機械語に翻訳する機能をコンパイラといいます。

名称未設定 P20

このように、01のみを読み取るコンピュータを、より多くの人が効率的に動かすため、プログラミング言語が生まれました。

なぜ多くの言語が生まれるのか

このようにして生まれたプログラミング言語ですが、この変遷からは言語の種類の多さを説明できません。
現在、よく使われるものだけでも数十種類の言語が存在しています。

プログラムを書くエンジニアからしても、どんどん増える言語に対応するのは苦労が多いはず。
一体何故、このように多くの言語が使われているのでしょうか。

目的最適化のためにプログラミング言語が生まれる

プログラムには「webアプリケーションの構築」「ゲームの開発」「研究」など、実現したい目的があります。
すべての言語を同じ言語で行うことも可能ですが、目的にあわせて言語を開発することで、言語それ自体に目的に沿った機能を持たせることができます。

例えばwebアプリケーションの構築であれば、よりサーバーの構築や運用・フロントの動的処理が行いやすい機能。そのために、PHP、Ruby、Python、Goなどが生まれました。
モバイルであれば、位置情報やカメラ情報が扱いやすい機能が求められます。その上、各端末に最適化した機能が必要となります。iOSであればSwift、AndroidであればCotlinJavaが使用されます。
ブラウザに表示させるための言語としてはJavaScriptが使用されます。
その他、ゲームの開発ではC#C++、研究目的ではR言語FORTRANHaskellなどがあります。

特化した機能を持つ言語によって、同じ目的を持つ開発者が同じ言語を集中的に使うようになります。
開発者が集まるようになると、よく使われる機能や仕組みをライブラリフレームワークとして開発し、よりその目的を達成するのが簡単になります。そしてさらに開発者が集まり、更に他の言語と差別化されるようになってくる。
このように、目的最適化を図ることで、プログラミング言語は生まれます

すべてを1つの言語で行った時、どうなる?

それでは、このような目的最適化を無視して、すべてを1つの言語で行っていこうとした場合、どのような事が起こるでしょうか。
すべてを1つの言語で行う場合、1つの言語にバラバラな仕組みが追加されていくことになります。
その結果、1つの機能をどうやって取り出したらいいかわからない百徳ナイフのような状態が出来上がります。

画像1

百徳ナイフとはいろいろなナイフを詰め込もうとした結果逆に使いにくくなるナイフの例ですが、言語に当てはめてみると以下のようなことが言えます。
機能が取り出しにくい:多くの仕組みがあるため、使いたい機能が複雑な手続きを経ないと使えない。
機能が中途半端:1つに特化させることが難しいので目的を最大に満たす機能が生まれない。
メンテナンスしにくい:バージョンアップなどのメンテナンスが煩雑になり、また他の仕組みへの影響を考えながらやらなくてはいけないので時間がかかる。
学習しにくい:初学者が使いこなせるようになるまで時間がかかり職人しか使えなくなる。
重い:使うのは数種類なのに多くの仕組みを携えているのでとにかく動きが重い。

このような言語が本当に使いやすい言語と言えるでしょうか。
いくつかは気合と根性で乗り切れるかもしれませんが、「重い」はユーザーに負担をかけてしまう可能性があるので、どうにも乗り切るのが難しそうです。
さらに、このような言語を使うと開発スピードが落ちるため、結果としてユーザーに価値を届けるまでの時間が長くなり、ユーザーが不利益を被ることとなります。
言語が分けられることによって、開発者も、それを使うユーザーもハッピーになるのです。

ライブラリ・フレームワークについて

さて、言語をより便利にする機能・仕組みとして「ライブラリ」と「フレームワーク」という言葉を使いました。
「jQueryというライブラリ」「Ruby on Railsというフレームワーク」など、時々耳にする言葉だと思いますが、両者を区別が曖昧になることが多々あります。
ここで、2つの違いについてまとめていきたいと思います。

ライブラリとフレームワークの違いを理解するために、部屋を作ることを考えてみましょう。部屋は自分ですべて作るのではなく、購入して家具を揃えていくのが一般的ですね。

ここで、ライブラリはニトリのような家具屋さんです。いろいろな家具から、自分の部屋に合いそうな家具を選びます。部屋の全体設計を決めるのはあなた自身です。気に入らなかったら別の家具を探します。

一方、フレームワークはモデルルームです。すでに家具一式が用意されていて、モデルルームが指定した家具の中でパターンを選ぶことができます。モデルルームの指示に従うだけでいい感じの部屋を作ることができます。部屋の全体設計を決めるのはモデルルームで、あなたはいくつかの部分だけ自分の嗜好を入れることができます。

名称未設定 P21

技術に話を戻して考えます。
例えばjQueryはJavaScriptのライブラリです。
JavaScriptを使っている途中で「ここはjQueryを使いたいな」と思ったところに使うことができます。そしてjQuery以外の部分では他のJavaScriptライブラリを使うことができます。
いろいろなJavaScriptライブラリを組み合わせて、部屋を作っていきます。ベースにあるのはJavaScriptです。
自分で決めるので、頭を使わなければいけませんが、組み合わせ次第でいろいろな創意工夫をすることができます。
でも、JavaScriptを知らないと組み上げることができません。

フレームワークの例では、Ruby on Rails(以下Rails)はRubyのフレームワークです。
Rubyのコードは使いますが、Railsのルールでコードを書き、Railsが用意したオプションを利用してプログラムを組み上げていきます。
Railsが用意した仕組みの中だけなので選択の余地は比較的狭いですが、工数をかけずに高機能なプログラムを構築することができます。

名称未設定 P22

意識しておくべき違いとしては、以下です。
・ライブラリは単品なので、それが最新のコードまでサポートされているかをきちんと見定める必要がある。
・フレームワークはそこから逸脱しようとしたときの実装が大変なので、将来的な機能も含め、事前に必要な機能が実装できるか確認する必要がある。

ライブラリとフレームワークの違い、わかっていただけたでしょうか?
webアプリケーションで使用される言語としてPHP、Ruby、Pythonがありますが、ライブラリやフレームワークに違いがあります。
PHPwebアプリケーションが作りやすいCakePHPLaravelRubyにはRuby on Railsというフレームワークが存在します。これらのフレームワークによって、効率的に高機能なアプリケーションを構築することができます。
また、Pythonでは機械学習系のライブラリが多く存在しており、自分のプログラムにライブラリを導入して機械学習アプリケーションの構築を早めることができます。

いずれにしても言語に優劣があるのではなく、その目的によって言語が選ばれるということを心に留めておく必要があります。

ここまで、言語の目的別に分類し、その目的を増強するライブラリ・フレームワークについて話してきましたが、言語を分ける目的は他にもあります。代表的なものをご紹介します。

目的:開発のスピードを上げる!

別の視点として、同じ機能を作る目的であったとしても、開発時のスピードを重要視したいという考え方があります。
ここで生まれたのがコンパイル言語スクリプト言語です。

言語の成り立ちについて説明をした部分で、プログラミング言語は一度コンパイル(機械語に翻訳)してからコンピュータに読み込んでもらうという話をしました。
そのような言語をコンパイル言語というのですが、コンパイル言語はコードの挙動を確認する際に毎回コンパイルするため、実装をチェックするのに時間がかかり、手早く実装を確認することができません

一方、スクリプト言語は別の手法を取ります。
これはコンピュータとの間に、プログラミング言語が読めてコンピュータと会話できるプログラムを置くことで、言語が指示を出すと逐次コンピュータに指令を出してコンピュータを作動させることができます。
これによってコンパイルの実装をする必要がなく、また実行時に毎回指示を出すため、実装チェック時に時間をとる必要がありません。

スクリプト言語は開発をスピード感を持って進められるので多くの言語のベースとなっています。Python、PHP、Ruby、JavaScriptなどがスクリプト言語です。

一方、コンパイル言語は最初に機械語に全て翻訳するので、コンピュータがそのまま指示を読むことができ、スクリプト言語と比べて高速に動きます。そのため大規模なプログラムを動かす際に使われることが多く、Java、C、C++、COBOL、FORTRANなどがコンパイル言語です。(Javaは両者の中間に位置するが今回は簡単のため)

目的:保守性を高める!

別の視点で言語をみてみます。
プログラムの開発は初期の実装も大切ですが、大部分はリリース後の運用や改善であると言えます。
その際に大切なのは、コードが誰にとっても読みやすく、バグが起こったときに把握しやすいことです。
そのために生まれた概念が、動的型付け言語静的型付け言語です。
まず、型について簡単に紹介します。
プログラムは複数の処理を行って最終的な値を出しますが、その際、ユーザーが入力した値やデータを変数という箱に入れ、その箱の情報に基づいて処理を行います。

名称未設定 P23

その変数を入れる時、変数には「型」が決められます。
型はその名の通り、変数という箱に入る値のタイプのことを指します。
例えば「数字」「テキスト」「画像」など、決められたタイプの変数だけが入ることになります。

名称未設定 P24

動的型付け言語と静的型付け言語の2つを分けるのは、その型の付け方です。

動的型付け言語は、変数の箱を作るときにどんな型にするか決めず、実際に箱に値を入れるタイミングで(動的に)型が決定します。
一方、静的型付け言語は、変数の箱を作るときに、どんな型にするのかを決めます。

動的型付け言語は後から自動的に型が決まってくれるので、「この変数にどんな値が入ってくるのか」を厳密に考えずに開発をすすめることができます。開発においてデータの設計はとても時間のかかる部分なので、その工数削減は開発の工数短縮に大いに貢献します。

しかし短所も存在します。
例えば、リリース後に新しい機能を加えようとした時を考えてみます。新しいエンジニアは1つの変数を見て、この変数にどんな型が入るのか、書いてないので把握することができません。そのため、誤った使い方をしてしまう可能性があります。
しかも、コードにとってはエラーではないので、最終的に意図しない結果が出たときに初めて、誤った使い方をしたことがわかってしまいます。

名称未設定 P25

一方、静的型付け言語は、最初に型を決めるので、どの処理を見ても、その箱にどんな値が入ってくるのか理解できます。また、変数の型が決まっているので、間違った型を入れようとすると、その場でエラーをだしてくれます
最初の設計時はしっかりと意識しないと書くことはできませんが、その後の保守のタイミングや新しい機能の追加のときに大いに役に立ちます。

名称未設定 P26

動的型付け言語は開発工数を削減できるので、最近使われるweb言語で多く取り入れられています。Python、Ruby、JavaScript、PHPが動的型付け言語の例です。

静的型付け言語は保守性が高く、型がわかっているので実行速度が早いというメリットもあるため、大規模開発やシステム開発に利用されます。C言語、Java、Swift、Cotlinなどが静的型付け言語の例です。

ただ、web開発が大規模になるにつれて、JavaScriptなどの動的型付け言語の中でも、静的型付け処理を行いたいという動きが多くあります。
例としてマイクロソフトが開発したTypeScriptはJavaScriptを静的型付け処理に変えた言語であり、多くの企業で導入されています。

このように、新しい技術の導入やデバイスの普及だけでなく、開発において何を大切にしたいのかという視点で、新しい言語が生まれることもあります。
しかしここでも言語は一長一短であり、優劣はないことを心に留めておく必要があります。

まとめ

今回は、プログラミング言語について、言語の成り立ちと主な目的の違いを書きました。
エンジニアでなければ言語の選択などどうでもいいことかもしれません。
しかしここまで見てきたように、言語の選択はプロダクトの成長する方向を決めます
すべてを知る必要はありませんが、今回の知識をベースに、プロダクトが目指す方向性大切にしたいことをエンジニアと対話すれば、建設的な議論をすることができ、適切な言語選択をサポートできるのではないでしょうか。

これからも様々な言語が生まれてくると思いますが、その言語がほかと何が違うのか、何がより良くなるのかを知っておくことで、より技術に対して親和性を持つことができるのではないでしょうか。

最後に、今回参考にしたリンクをご紹介します。
今回書いたことについて更に知りたい方は読んでいただければと思います。

それでは、またよろしくお願いします。

この記事が気に入ったらサポートをしてみませんか?