頭があれで、説明が下手ですいませんが、
「コンピュータはなぜ動くのか~知っておきたいハードウエア&ソフトウエアの基礎知識~」の書籍のP16の「ソフトウェアは命令とデータの集合体」のところの
プログラミングでは、データに名前を付け、これを「変数」と呼びます。皆さんは「変数」や「関数」という言葉から「数学」を想像するでしょう。まさにその通りで、多くのプログラミング言語では、
y=f(x)
のような構文が使われます。これは、「数学」の「関数」と同じ表現であり、「f」という名前の「関数」に「x」という「変数」を入力すると、「関数」内部で何らかの演算が行われ、その結果が「y」に「代入」(出力)されることを意味します。
と書かれており、さらに
全ての情報を数値で表し、それを演算するのがコンピュータなのですから、プログラミング言語の構文が数学に似たものとなるのは当然です。
と載っておりました。それを読んでふと思ったのですが、
「数学」と「プログラミング言語の構文」はどこの部分が同じで、どこの部分が違うのでしょうか?
例えば「変数」では
・「数学」…1文字のアルファベット
・「プログラム言語の構文」…1文字以上のアルファベット文
と違う部分がありますが、他に「数学」と「プログラミング言語の構文」での違いは何なんでしょうか?
又、「数学」と「プログラミング言語の構文」での同じなところは何なんでしょうか?
Javaをやっているくせに、頭があれなのか、あまり思いつきません。
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
数学とプログラミングの最大の違いは「命題」と「命令」の違いです。
###数式をプログラミングのコードにしてみる。
次のような数式を考えてみましょう。
x = 6 y = x * 9
*
は掛け算を表すとします。y = 9x
やy = x・9
やy = x × 9
やY IS X MULTIPLIED BY NINE
などの表現もありますが、表記だけの問題ですので、気にしないことにします。さて、この数式によって導かれるy
は54
です。究極の疑問の答えは42
なのですが、そこも気にしてはなりません。
この数式をプログラミングで表現し、計算結果を得ることにしましょう。言語はPythonを使用してみます。(Pythonは3を使用します。)
Python
1x = 6 2y = x * 9 3print(y)
54
結果は54
でしたね。究極の疑問の答えである42
とは違いますが、本来はDeep Thoughtでも750万年かかる計算ですので、まずまずと言えます。
さて、数式は次のようにも書けます。
y = x * 9 x = 6
y
は変わらず54
のはずです。では、Pythonではどうでしょう。
Python
1y = x * 9 2x = 6 3print(y)
Traceback (most recent call last): File "auq.py", line 1, in <module> y = x * 9 NameError: name 'x' is not defined
エラーになってしまいました。どうやら、x
は知らないからy
を求める事ができなかったようです。もし、数学とプログラミングが同じ考えだったら、こんなことにはならないはずです。なぜ、うまく行かなかったのでしょうか?
###数学の数式は「命題」だが、プログラミングの文は「命令」である。
数式であるx = 6
やy = x * 9
は命題です。これは、x
と6
は同じである、y
とx * 9
は同じである、という命題を表し、それぞれが成り立つ場合を考えるというものです。そして、それが成り立つのはy
が54
の時しかありません。命題ですから、別に前後しても問題ありません。始めにy
とx
の関係を述べた後に、x
が何であるかを述べても、結果が変わることはありません。
別の見方をすると、常に成立する命題というのは定義と言い換えることができます。x
を6
と定義する、y
をx * 9
と定義する、という感じです。定義ですので、y
が何か定めてから、後からx
を定めても問題ありません。どちらの定義が最初に来ようが、同じく結果が変わることはありません。
しかし、プログラミングのコード、つまり、Pythonのコードにおいては、x = 6
とy = x * 9
は命令です。それぞれ、次のような意味です。
x = 6
:6
をx
に割り当てよ。y = x * 9
:x * 9
を評価し、その結果をy
に割り当てよ。pirnt(y)
:y
を評価し、その結果を印字せよ。
「割り当て」という言葉を使いましたが、これは「代入」と同じく"assignment"の日本語訳としての表現です。これは命令ですので、一つ一つが順番に処理されます。初めの1.でx
に6
が割り当てられました。これは、x
が何か調べる(評価する)と6
が出てくるようになったと言うことです。次の、2.で、まずx * 9
が評価されます。評価とは何か説明するととても長くなるのですが、x * 9
の評価とは「x
を評価して、その結果に9
を掛けること」とだけ説明しておきます。最初の割り当てで、x
は評価すると6
になるようになっていたのでした。ですので、6
に9
を掛けて54
がその結果になり、y
に割り当てることになります。最後の3.は、さきほどy
を評価して、結果の54
を印字するとなります。
さて、この動作ですが、1.と2.が逆であったらどうでしょうか? 2.の命令を実行する時に「x
を評価する」という動作がありました。まだ1.が実行されていない場合、x
には何も割り当てられていません。ましてや、将来何が割り当てられるのかもわかりません。命令は一つ一つこなしていく必要があり、保留にすると言うこともできません。つまり、「x
を評価する」ということが1.が実行される前に行うことはできず、プログラミングの処理ができないため、エラーになってしまったのです。
Pythonはエラーでしたが、他のプログラミング言語も同じとは限りません。暗黙的にデフォルト値が割り当てられる場合もあれば、不確定の値が割り当てられる場合もあります。どちらにしても、1.と2.が逆の場合、未来に行われる命令を予想してx
を正しく評価すると言うことはできません。
###「命令」ではないプログラミング言語もある。
実はここまでの話は全てのプログラミング言語に当て嵌まる訳ではありません。C、C++、Java、C#、VB.NET、Perl、Python、PHP、Ruby、JavaScrit、Lua等の命令型プログラミング言語と言われるものに対してのみ言えることです。それに対して関数型プログラミング言語(Haskell、Erlang、Elixir等)や論理型プログラミング言語(Prolog等)等の宣言型プログラミング言語というものがあります。
Haskellでの例を見てみましょう。
Haskell
1y = x * 9 2x = 6 3main = print y
54
x = 6
の方が後なのに問題なく処理できました。これは、Haskellにとって、x = 6
やy = x * 9
が定義だからです。数学の数式は定義としても考えられると述べましたね。そう、Haskellにおいては数学と同じように考えることができると言えます。ただ、実際の処理を行うCPUは命令としか動くことはできません。どういう処理になるのかは、thunk、遅延評価、必要呼びといった概念を説明しないと難しいので割愛しますが、命令型プログラミングよりも数学に近い考え方でプログラミングできると言えます。
実は、先ほどのPythonも定義として作ることができます。
Python
1y = lambda: x() * 9 2x = lambda: 6 3print(y())
54
x
やy
を何らかの数値の変数として考えるのではなく、何らかの関数として考えるという物です。数式をプログラミングのコードにすると考えた場合、こちらのほうが正しいと言えるのかも知れません。
投稿2017/07/16 13:55
編集2017/11/23 10:27総合スコア21735
0
ベストアンサー
結論から書くと、
「プログラミング言語と数学の共通点は何でしょう?」って質問には、
「そもそも何も共通点なんてねーよ」が正解。
何故共通点が無いはずのプログラミング言語と数学が似てるの?
コンピュータは膨大な計算を任せたい数学者に需要が多くあり早い段階で受け入れられたので、
C言語を始めとする一部のプログラミング言語が数式に寄せて設計されたという話。
ところがC言語の本業は命令を処理することであり、数学を完全再現することじゃない。
そもそも上付き文字や下付き文字や分数がパソコン上で表現出来ない以上、数列や階乗なんて表現するのは絶対無理。
従って、プログラミング言語は数学の式の模倣(エミュレート)でしかない。
階乗の代わりにpow(a, b)
という関数を用意しました、数列は無いけど配列はある、みたいな別の書き方や逃げ方で数学の多くの部分を再現することに成功しているけど、再現率もプログラミング言語によってまちまちってわけ。
数学の式の再現に関しては、他の回答者さんが答えてくれているので割愛。
コンピュータの本来の役割って何?
でもコンピュータに求められる役割はそれだけじゃない。
コンピュータの本業は「仕事の自動化」になるわけだ。
だからプログラミングのもう一つのゴールは「ネイティブな文章の評価」。
もしこれに成功すれば、論理的思考が出来る全ての人間がコンピュータという超有能な秘書を駆使してバリバリ仕事をこなせるようになる。
こっちは50年程経った今もまだまだ試行錯誤中。
プログラミング言語はマイナーな言語も含めると200種類以上に登る。
その中には数学なんて知った事ではない、英文なんて知った事ではないと考えて作られたプログラミング言語も多数存在する。
有名な言語で言うとSQLとかね。
(SQLはプログラミング言語ではないけど、ルールに沿って作られたネイティブの英文をデータベースに送りつけて望むデータを引き出す事ができる)
以下、質問文の引用部分に対するツッコミ
全ての情報を数値で表し、それを演算するのがコンピュータなのですから、プログラミング言語の構文が数学に似たものとなるのは当然です。
因果関係が逆じゃない?
コンピュータってのは元々機械語(0101)しか認識出来ない
→2進数の計算は超得意だけど10進数の計算はできない
→10進数計算できないとか論外!プログラミングを利用して10進数の計算を実現した
→機械語じゃ使いづらい!簡単な英文を受け入れるアセンブラ言語が生まれた
→アセンブラも使いづらい!英文や数式をそのまま命令に認識して欲しい(高級言語の開発が急がれる)
四則演算を表現することはわりと実装が簡単だったし需要もあった。
数式に寄り添うプログラミング言語が次々と生まれ、支持され、開拓されていったという話。
その一つ(C言語)の言語を指して「似たものとなるのは当然」と言われても、
似るように作ったのだから似てるのは当然でしょ。
他にも新しいものを作る時は別の分野の再現や発想を得たりするけど、その時はインスパイア元の名前がそのまま使われる事が多い。
ほら、セーターだってタートルネック(亀の襟)とか名付けたりするじゃん?
あれと同じで、コンピュータに変数や関数を数学の世界から拝借してその機能を作ったって話。
投稿2017/07/17 02:15
編集2017/07/18 02:24総合スコア21158
0
数学の場合、ab
と書くと「変数a
と変数b
の値の積」という意味になるので、変数は1文字が多いですが、それに限定されるわけではありません。
また、数列やベクトルや行列の要素は、変数名の右下の添え字で表すことが多い(上付きの場合もある)ですが、プログラミング言語だとa[i]
かa(i)
で表します。
あと、べき乗は数学だと右上の添え字で表しますが、プログラミング言語だとa^b
かa**b
かpow(a,b)
等ですね。その他の演算子も違ったりします。
プログラミング初心者が躓くかもしれないことの一つがイコールですね。数学だとa=b
は「aの値とbの値が等しい」といういみですが、プログラミング言語の多くでは、a=b
は「変数aへbの値
の代入」という意味になり、「等しい」については別の演算子(==
とか===
とか)が使われることがあります。もちろん数学と同じくイコールは等しいという意味にだけ使う言語もあります。
あと、数学で使う総和Σとか総積Πとか、微分d/dxとか積分∫などは、多くのプログラミング言語ではシンプルには記述出来ません。
ざっと思いつくのはこれくらいですが、もっとあるかと思います。
投稿2017/07/16 10:40
総合スコア84529
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
x = x + 1
こんな式はいろんなプログラミング言語の、それも入門レベルから登場しますが、こんな等式を満足する x はありません。等式のような姿をしているけど、これは代入ですから。
投稿2017/07/20 04:14
総合スコア1380
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/07/16 14:12