Part2プログラミングについて、どのように学習していくか。LispのS式、リスト、アトム、シンボルについての入門。27Lispをはじめる前に小さなコードをきちんと理解する利用できるものは利用するもう少し具体的にプログラミングのことをLispをはじめようオペレーターと引数リストLispをはじめる前にLispをはじめる前に、プログラミングについて改めて説明する。プログラミング言語をひとつ以上習得しているのであれば、このページはうんざりするものになるかもしれないので注意。小さなコードをきちんと理解するプログラミングは、コンピューターに計算させる行為だ。テキストで行いたい処理を記述し、それをコンピューターが解釈して実行する。エディタの支援などもあるが、一文字ずつ入力し、多大な時間をかけてソフトウェアを作る。問題や壁にぶち当たり、前に進めなくなることもある。困難を乗り越えても、新しい困難が立ちはだかることも多い。計算処理によってゲームや普段使用するアプリケーションが出来上がるのかと最初は疑問に思うかもしれない。world”という文字が出力されます、というような初学者向けのプログラムコードからはじまる入門書の類を読む限り、とても何かが作れるような気はしない。自分が初めて学んだC言語では、最初に文字を出力するプログラムを書いた。以下のようなコードだ。0;}このようなことを続けて、何か素晴らしいものが作れるとは到底思えない。物事は積み重ねが大事で、プログラムもまた、小さな小さな計算の欠片を積み重ね、組み合わせて作られていく。単純な計算も組み合わされば、複雑な計算になる。複雑な計算は、複雑な処理、複雑な機能を実現する。小さなコードを退屈に思うことはない。小さなコードが理解できれば、それが積み重なっている巨大なコードも理解できるようになるし、それを自分で書けるようにもなる。利用できるものは利用する膨大なコードを書かなければ、作りたいものを実現できないのではないかと怖がる必要もない。ゼロから全てを自分で作る必要はないのだ。あなたがもしゲームを作りたいと考えたとき、まずは画像を表示することを考えるだろうか。画像を表示するための計算、音を鳴らすための計算、ネットワーク通信を行うための計算、様々な計算≒様々な処理を簡単にしてくれるためのプログラムの資産(ライブラリと呼ばれる)は既に世の中に存在していることが多い。自分が実現したい事柄を実現しやすくしてくれるライブラリを探して利用することで、より少ない労力でソフトウェアを作ることができる。具体的にプログラミングのことをPart1では開発環境構築の流れで、REPL上でいくつかのテキストを入力した。CL-USER>に続けてテキストを入力したわけだが、ここに入力して結果を表示させることがプログラミングだ。ひとつの方法として、ファイルにテキストを入力して、それを保存した後に読み込ませて実行し、結果を表示させることもできる。どちらの方法にしろ、Lispが理解できるテキストを与えて、それを処理させて、結果を得るという部分に変わりはない。Lispが理解できるテキストとは、プログラムコードのことだ。どのような処理を行うかをひとつひとつ記述していく。その書き方はプログラミング言語によって異なるため、言語が異なれば違う書き方になる。Lispのルールに則ってプログラムコードを記述する必要がある。CLは1対1の関係ではないことに注意する。CLというものが存在するという関係になる。Lispには様々な実体≒実装(処理系とも呼ぶ)が存在する。CL以外にも以下のような処理系が存在している(もっと他にもある)。Lispという規格によって実装されている一方、処理系毎に独自の特徴を持ち、また拡張を施しているものが多い。そのため、一方の処理系で動作していたプログラムが、別の処理系では動作しないという問題を引き起こすこともある。Lisp特有のものではない。Rubyと言ったプログラミング言語では、派生があるものの実際には単一の処理系しか存在しないと言っても差し支えない状態のため、このような問題は引き起こさない。JavaScriptでは、ブラウザに備わる実行環境、Node.js、GTMと言った環境の違いによって使用できる構文、機能が異なってくる。その良し悪しをここで説くことはしない。CLという処理系におけるプログラミングの方法であるため、他の処理系では問題が起きる可能性があることを覚えておいてほしい。Lispには多数の処理系が存在し、そして世の中にあるプログラミング言語の数はより多く、多様性を持っている。これらに共通するのは、以下のプロセスだ。プログラムコードを用意する処理系がプログラムコードを解釈する処理を実行し、結果を得るこれらのプロセスのうち、プログラムを書くときに着目する点はおおざっぱに言ってしまうと2箇所だけだ。いうコードを書くのかどういう結果を得たいのかしかしこの順番は少しおかしい。いうコードを書くのかは、どういう結果を得たいのかがわかっていなければ導き出せない。考える順番としては、以下の順序が正しい。いう結果を得たいのかどういうコードを書くのか中年の配管工をジャンプさせたい。なければ世界が滅んでしまう。中年の配管工をジャンプさせるという結果を得るためには、どういうコードを書く必要があるのか。コードは小さな計算の積み重ねであり、そのひとつひとつを書いていくためには、実現したいことを細かく紐解いていく必要がある。具体的には、以下のように考えていく。中年の配管工が表示されている必要があるスクリーンに表示させる必要がるジャンプさせるには地面が必要だ地面があるなら空も必要だボタンをおしたときにジャンプさせたいボタンをおしていないときには何もさせたくない中年の配管工は画像を作って表示させる中年の配管工の画像サイズは....キリがないように思えるかもしれないが、これは必要なことだ。細かく物事を分解していけば、それは最終的に数値で表現され、計算可能なものになる。画像データでさえ、ただの数値の並びに過ぎない。言い換えると、数値として取り扱えるものは計算することができ、コンピューター上で表現可能だ。最初から複雑で巨大なものを作り上げることはできない。開発手法や効率化の面では議論の余地もあるだろうが、熟練のプログラマーであっても、小さな部品を作り、積み重ねて大きなものにしていくことに変わりはない。「昔はこうやってテキストをひとつひとつ入力しながらソフトウェアを作っていたんだよ」と言ったように、プログラミングという行為が伝統工芸になる日が来るかもしれない。実際、コードを記述しない実験的なソフトウェア開発手法は今日までいくつも提案されてきており、将来的にはより効率的なソフトウェア開発の手法が生み出されるだろう。実用的な分野に限っていえば、幸いなことにテキストを入力していくという面倒なやり方しかまだ存在しない。プログラミングについてまとめよう。いったことをソフトウェアで実現したいのかを明確にする実現したいことを細分化する。計算可能な状態にまで分割する細分化し、分割した実現したいことをプログラムコードとして記述する実現したいことの明確化は、あやふやな、頭の中に浮かんでいる作りたいものをきちんと言葉にしていくことだ。細分化、分割は、設計方法論として様々なものがあり、議論される部分も多い。ここでは、作るものに従ってサンプルコードを示していくが、書いてあるものがベストだとは限らない。分割しておいたほうが良い、こう設計したほうが良いと思えば、個人個人がそれを実際に試し、結果を自分の目で確認していこう。最後に、プログラムコードとして記述する部分だが、これは単純な学習によって習熟できるもっとも簡単な部分だ。いう処理を行うべきかが完全に頭の中にあり、コードを記述するための少ないルールを覚えていれさえすれば、それをコードとして表現することは容易い。取り掛かりやすいプログラムコードの記述方法の説明から始める。Lispをはじめようオペレーターと引数Lispは、括弧の中に色々と書いていく。以下のように、開き括弧と綴じ括弧を書いて、その中に処理を書く。2)3上記のコードは足し算で、1と2を足す処理だ。そのため、入力してENTERキーを押すと3という数字が出力される。足し算の記号が一番前にあり、その後ろに数字が並ぶ。引き算にはマイナス記号を使う。3はどう書くと良いだろうか。答えは以下のようになる。3)6括弧の先頭にある要素が、後ろに続く数字の計算方法を決めていることに気付くだろうか。先頭の要素はオペレーター(operator)と呼び、その後ろに続く要素を引数(argument)と呼ぶ。重要なことは、+だからオペレーターなのではなく、先頭にあるからオペレーターだと言うことだ。Lispは、問答無用で先頭にある要素をオペレーターとして解釈する。+は加算のオペレーターとしてLispが理解しているため、足し算になる。-は減算のオペレーターとしてLispが理解しているため、引き算になる。1を先頭に持ってきたらどうだろう。3)このコードは、Lisp側で処理できずエラーになる。Lispは1をオペレーターとして解釈しようと試みるものの、残念ながら1というオペレーターはLispに備わっていない。備わっていないということは、2番目以降に続く要素をどのようにオペレーション(操作)して良いかが、Lispにはわからないということだ。その結果として、エラーになる。Lispに備わっている四則演算用オペレーターのうち、掛け算と割り算を見ていこう。掛け算は*を使い、割り算は/を使う。2)3Lispが知っているオペレーターを使う限り、問題なく計算されることが確認できる。オペレーターには四則演算以外にも様々なものが用意されており、Lispが予め備えているものに加えて、プログラマーが自分で作ることもできる。+や-などの記号だけではなく、アルファベットを使いわかりやすい名前で作ることができる。Lispに備わっているアルファベットのオペレーターとして、文字を出力するformatというオペレーターを使ってみる。world"括弧の先頭はオペレーター、2番目以降に続く要素は引数ということをまずは覚えよう。このようなLispで解釈する式を、S式と呼ぶ。プログラミングは小さなコードの欠片を組み合わせて、複雑なものを作り上げていく。単一の括弧の組の中に、オペレーターと引数を指定して計算や文字の出力を行ったが、括弧の中に括弧を入れるといった形で、より複雑な処理を行うことができる。3)と書いたが、これは1と2を足した後、その結果を3と足すという言葉に置き換えることができる。これをREPLでそのまま書くと2回の入力に分けることができる。3)6この2つの括弧を、1つの式にするためには、括弧の中に括弧を入れる形で表現する。具体的には、以下のように記述する。3)6はじめて見ると混乱するかもしれない。このように括弧が二重以上になっている場合の処理は、必ず一番内側の括弧内から見ていく。2)は3そのものだと言える。2)、3番目の要素は3が与えられている。2)が計算されて3という数字になると、2番目の要素は3、3番目の要素は3という状態になる。Lispがどのようにコードを解釈しているか、という点から考えたほうがわかりやすいかもしれない。先頭からひとつひとつ見ていく。3)を1文字ずつ切り出したものだ。それぞれの段階で、Lispがどのように解釈して計算を行うかを説明する。開き括弧があるので、LispのS式がはじまる。次にある要素をオペレーターとして取り扱おう。これは加算のオペレーターだ。以降に続く要素は加算していくぞ。加算だからきっと数値の要素が来るはずだ。これは入れ子のS式なんだな。この内側の括弧内を優先して計算しよう。次にある要素をオペレーターとして取り扱おう。加算のオペレーターを発見。続く要素は全部足すぞ。