プログラミング言語について知っておくべきこと
2019 年 2 月 7 日 Emil Hozan 著
この記事では、以前に掲載した記事の内容を少し発展させて、高水準のアプリケーション/プログラミング言語(Python や C)と低水準のプログラミング言語(マシン語やアセンブリ言語)について解説したいと思います。ただし、範囲を広げすぎることなく、ブログのタイトルが示すように、プログラミング言語の仕組みをできるだけわかりやすく説明するよう心掛けるつもりです。プログラミング言語を理解するためには、構文やコードの記述方法だけでなく、プログラミング言語のセマンティクス、すなわち、記述するコードの意味も理解しなければなりません。
プログラミングには、記述にあたって必要になる構文や形式だけではなく、その言語のセマンティクス、つまり、意味やロジックが含まれます。構文エラーがあると、おそらくコードは正しく動作しませんが、セマンティクスに誤りがあると、想定外の結果が生じる可能性があります。ウィキペディアはこれを、
「…言語の構文は、構文的に正しいプログラムを形成する記号の組み合わせである…したがって、記号の組み合わせはセマンティクスによって処理される…」
と説明しています。また、これ以外にも、異なるデータ型、変数の命名オプション、予約語、演算子などといった、知っておくべき重要な情報がいくつもあります。
この記事では、いくつかの異なるプログラミング言語に共通する側面について説明しますが、基本的には Python を前提に解説を進めます。また、私にとって馴染みのある言語を例として使用しますが、プログラミングとは何かを理解していただくことが、この記事の主旨です。
基礎知識 – 変数、配列
プログラムを作成する目的は、問題の解決、あるいは、ゲームであればエンターテイメントを提供する手助けをすることです。記述したコードをメモリ内に保存し、プログラムのどこからでも保存されたデータを参照できるようにする必要があります。わかりやすく言えば、プログラムのメモリ内での動作やメモリセルを使った参照については、技術的に細かく定義されていますが、保存されているデータを表す変数を使用すれば、データをずっと簡単に参照することができるのです。たとえば、「cu_first_name」、「cu_last_name」、「cu_age」といった変数の名前の作成は、そのための1つの方法であり、変数とは、覚えやすいメモリアドレスの場所と考えるとよいでしょう。
上記の変数名はいずれも推測しやすいものですが、それぞれ、顧客の名前、顧客の姓、顧客の年齢を保存するための変数です。これらの変数の名前を使ってデータを保存すれば、メモリセルの管理でセル番号を覚えておく必要はありません(メモリセルの管理は複雑であり、独立した記事が書けるほど長い説明が必要です)。
変数名にはさまざまなの種類のデータ(データ型)を保存でき、データ型によって、表現するデータが異なります。たとえば、氏名の場合は、おそらくは(氏名が数字である人でなければ)文字列と呼ばれる一連の英字あるいは文字で構成され、年齢の場合は、数字または整数で表現されます。この 2 つが最もよく使われるデータ型ですが、実際には、浮動小数点数や 10 進数などの多くのデータ型があります。どのデータ型であっても、変数にわかりやすい名前を付けることで、自分がかなり前に記述したコードを見直す場合も、プログラムを理解しやすくなります。また、他のプログラマがソースコードをチェックすることになったとしても、変数にわかりやすい名前が付いていれば、プログラムを簡単に理解でき、コードや関連文書にコメントが入っていれば、大いに役立つはずです。
次に、関連するデータをまとめて保存する、変数名以外の方法について説明します。具体的な状況として、たとえば、複数の変数を作成するのは簡単ですが、すべてをまとめて記憶するにはどうすれば良いのでしょうか。どうすれば、特性が似ているすべての変数をまとめて簡単に参照できるのでしょうか。特定の個人や物に関する名前やその他の情報をどのように関連付ければよいのでしょうか。データの編成方法を記述するために使用する、データ構造と呼ばれる用語があります。
コードを読み取り、値が保存されている複数の変数を参照したり、顧客のフルネームと関連データが保存されているリストを作成したりする場合を考えてみましょう。先ず初めに、「cu_first_name」(顧客の名前)と「cu_last_name」(顧客の姓)を連結して、「cu_full_name」(顧客のフルネーム)に入れ、次に、Customer1 = [cu_full_name, cu_age](顧客のフルネーム, 顧客の年齢)などのリストを作成します。ユーザが 10 人いる場合は、ユーザごとに姓と名を質問し、その 2 つを連結して「cu_full_name」というフルネームにし、さらにそれを「customer_names_list」という名前のリストに保存します。
この例のようなリストは配列と呼ばれることもこともあり、プログラミング言語によって呼び方は異なります。一般的には、関連性のある情報が 1 つのリストに保存されますが、必ずしもそうである必要はありません。また、さまざまなデータ型(文字列や整数)をこれらのリストに保存することができます。
関連する一連のデータを表現する効率的な方法として、辞書(Python のデータ構造)あるいはキー/値ペアと呼ばれる方法もあります。たとえば、ユーザのファーストネームまたはフルネームがキーで、ユーザの年齢、電話番号、住所などの値が含まれる辞書を使えば、特定のオブジェクト(この場合は人)に関する関連情報を簡単にまとめることができます。
繰り返しになりますが、どのプログラミング言語を学ぶ場合であっても、変数をどのように作成し、それらの変数をどのようにデータ型(整数または文字列)に割り当て、収集したデータをデータ構造の形でどのように整理するかを、基本的な知識として知っておく必要があります。
予約語
プログラミング言語には、特別な目的に使用する、予約語と呼ばれるキーワードが組み込まれています。学ぼうとするプログラミング言語にはどのような予約語があり、どのような目的で使用するのかを理解することが重要です。
多くの場合、予約語には、目的を推測できるような名前が付けられており、プログラミング言語で定義されたそれらのキーワードが出現すると、そのキーワードに対応する何らかのアクションを実行するものと判断されます。そのため、予約語であるキーワードを変数名として使用することはできません。キーワードがあれば、その言語で定義されている処理が実行されるため、コードのいずれかの場所でエラーが発生することになるでしょう。一般的な例として、「for」は、特定のリストまたはその他の「反復可能な」データ構造を反復処理し、「if」は、特定の条件と照合して、その条件に従って処理を実行し、「break」は、プログラムの現在のループを抜けたり、プログラムを終了したりするために使用されます。
演算子の動作、すなわち、算術演算(計算)の実行方法、関係演算子/比較(2 つの値が等しい、より大きい、より小さい)、論理演算子(複数の条件付きステートメントの組み合わせ:AND、OR、および NOT)についても知っておく必要があります。
関数、データの保存
ここまでのセクションを理解できたら、今度は、関数を定義してデータを永続的に保存する方法を学びます。
コーディングの大きなメリットの 1 つとして、1 度記述してしまえば、必要に応じてコードを再利用したり変更したりできる点が挙げられます。特定のタスクを実行する関数を定義しておくと、複数のプログラムからその関数を呼び出すことができます。たとえば、データ構造を反復処理して、そのデータセットの各要素に対して何らかの処理を実行する、独自の関数を定義できます。セミナーの参加者リストがあって、参加者ごとに歓迎メッセージを印刷する場合などには、このような関数を利用すると便利です。
これまでに説明したデータ構造はいずれも、プログラムの実行時にのみ存在する、RAM(ランダムアクセスメモリ)に保存されるものであり、RAM が揮発性メモリであること、すなわち、データがそこには永続的に保存されないことを覚えておくことが重要です。ハードディスクは長期的な保存の用途に使用され、ファイル、アプリケーション、そしておそらくは、将来的にアクセスする写真や動画も、ここに保存されます。プログラムが終了または完了すると、作成した変数やデータ構造は削除されます。このガベージコレクションと呼ばれる処理によって、プログラムが使用した RAM が元の状態になり、他のプログラムがアクセスして利用できるようになります。
永続的なストレージと言うと、ファイルやアプリケーションなどをすぐに思い付きますが、データベースもこれに分類されます。たとえば、データを取得して、必要に応じてそれを処理し、永続的なストレージソリューションに書き込むスクリプトを作成できます。あるいは、収集したデータの結果を人間が読み取り可能なテキストファイルに書き込み、レポートの作成に利用できるようにしたり、データベースに保存して列名や特定の値を使ってデータを参照できるようにしたりすることもできます。どのようなアプローチであっても、必要なデータを取得するためのいくつかのオプションがあります。
個人的には、スクリプトをセクションに分割することと、結果をテキストファイルに書き込む方法をお勧めします。プログラムの実行時間は一定ではありませんが、終了すると、データを自由に見直すことができ、RAM の使用について心配する必要はありません。ハードディスクの記憶域は一般的に RAM より大きく、ここからファイルを読み取り、そのファイルから収集したデータに基づいて、スクリプトが実行する処理を決定することができます。
高水準言語と低水準言語
ここまでの説明は、すべてのプログラミング言語の学習に共通する内容でしたが、低水準言語についても説明しておく必要があるでしょう。高水準言語と低水準言語では、ユーザにとっての理解しやすさのレベルとコードが動作するシステムとの距離が異なります。
高水準言語は、人間にとって理解しやすく、キーワードや変数がプログラムのさまざまな場所で使われますが、簡単に見つけられます。コーディング方法を知らないと複雑そうに思えるかもしれませんが、低水準言語と比べると難易度は低く、プログラムを開いて読んだり書いたりするのはそれほど難しくありません。予約語であるキーワードは、高水準言語の使いやすさを示す良い例です。
低水準言語に分類されるものとしては、システムが理解できる言語があります。コンピュータは 0 と 1 だけを理解するため、高水準言語の場合は、コンパイラまたはインタープリタによってアセンブリ(アセンブリ言語)に変換されて、さらにそのコードがマシン語(マシンコード)、すなわち 1 と 0 に変換されます。これらの言語でコーディングされているプログラムはあまりに複雑で、プログラミングを学ぼうという意欲をなくしてしまうように思えるかもしれません。
実際に見たことがない方には、アセンブリコードあるいはマシンコードを少なくとも 1 度は目を通して、高水準言語と低水準言語では使いやすさにどの程度の違いがあるのかを理解することをお勧めします。低水準言語を学ぶのはとても良いことであり、それは、プログラムの実行が高水準言語より高速であるためです。高水準言語でコンパイラあるいはインタープリタを使ってコードを実行する場合は、コードをマシン語に変換する必要がありますが、アセンブリですでに記述された、0 と 1 だけで構成されるプログラムの場合は、その変換が必要ありません。
個人にお奨めする学習の進め方
先ず初めに、この記事を参考にして、学習するプログラミング言語の候補を調査することをお奨めします。時間をかけて経験しない限り、プログラミング言語を理解できるようにはなりません。ある程度の時間をかけて、この記事の各セクションをお読みいただきながら、さまざまなデータ型の変数を作成する練習をし、データ構造形式をいくつか選んで、データを整理して使いやすくする方法を学びます。そして、データを永続的に保存する方法を理解するために、ファイルに書き出すコーディングをしてみます。そうすることで、プログラミング言語とデータベース構造とのインタフェースなどの方法を理解できるようになるはずです。
一般的なプログラミング言語であれば、その言語の公式文書だけでなくStackOverflow、GitHub などに優れたリソースが提供されています。もちろん、”<プログラミング言語> <やりたいこと>” (<> の部分を実際の値に置き換えます)で検索するだけで、参考になるリソースがたくさん見つかります。たとえば、この記事の執筆にあたって、「プログラミング言語について知っておくべきこと」が説明されているページを探してみたところ、この Web ページが見つかり、関連するいくつかのコンテンツや言語ごとの具体的な例が紹介されていました。
コンピュータテクノロジを極めたいのであれば、人気のある高水準言語だけでなく、低水準言語についても学ぶことをお奨めします。場合によっては、低水準と高水準の両方の言語を学ぶことに楽しみを見出だせるようになるかもしれません。
まとめ
学習を始めるのに最適な言語は 1 つではありませんが、どの言語から始めるにしても、何も始めないよりはるかに有益です。プログラミングを学ぶ最良の方法は、自分の最終目標を設定し、その目標に従って、この記事でご紹介しているお奨めの方法を参考にしながら、特定の言語での具体的な方法を習得することです。Web 開発を学ぶ場合であれば、本ガイドとリンクでご紹介する Web ページを参考にして、Web に特化した言語の概要を理解し、変数を保存し、ユーザ入力を受け付け、その内容をユーザに表示するといった、具体的な方法を学習します。システム言語やアプリケーション言語についても同様です。
練習こそがここでの鍵となります。何回も本や資料を読み返す学習方法もありますが、練習なしに実践的な知識を習得することはできません。コンピュータがまだ新しい概念であった頃とは異なり、プログラミングを学ぶためのリソースをオンラインで簡単に手に入れられるようになりました。
最後に、プログラミング言語を学ぶ際に役立つ参考資料を以下にご紹介します。役に立つものから順番に並べようと考えましたが、判断が難し過ぎたため、断念しました。いずれも、プログラミング言語を詳しく理解するための全体的スキームにおいて、優れた情報と付加価値を提供してくれるものです。
参考資料
プログラミング言語の作成に何が必要か:
https://www.quora.com/How-does-one-create-a-programming-language
コードのおおまかな仕組み:
https://www.codeconquest.com/what-is-coding/how-does-coding-work/
ウィキペディアのプログラミング言語の説明:
https://en.wikipedia.org/wiki/Programming_language
低水準言語の仕組みの解説:
https://www.codeproject.com/Articles/315505/How-processor-assembler-and-programming-languages
プログラミング言語の仕組みの別の観点からの解説:
https://code.likeagirl.io/how-do-programming-languages-work-9f3d83fa629e