変数は「箱」か?(3)

概要

  • 本記事では、「プログラミング入門者に初めて《変数》を教えるとき、どのように説明することが適切か」ということ、そして「その際に《箱》を喩えに用いることで生じる問題を、別のどのような説明を用いることで解消できるか」ということについて考える。
  • この際、まず何よりも重要なことは、「議論の前提を明らかにし、それを一致させてから議論をスタートする」ということである。
  • 他の場面で他の人が似たような話題をとり上げているかもしれないが、本記事と同じ前提や問題意識による議論であるかはわからない。似たような話題だからといって、その目的や前提も安易に同一視してしまうと、関わる皆の時間が無駄になってしまうので、注意が必要である。
  • 箱以外の説明の仕方には、さしあたって良いものが二つある。
    • 変数を「名前を付けたデータ」であると説明する
    • 変数を「あだ名」に喩える
  • ただし、変数の利便性を伝える最も効率的な方法は、それを使った場合と使わなかった場合とのコード例を比べて見せることである。
  • このような問題提起に対しては、「しょせん比喩に過ぎないのだから、その疑問自体がおかしい」という定番の応答がよくあるが、それはメタレベルからの視点にもとづいており、疑問の真意を直視していない。
    • 「比喩」が「現実ではないこと」を理解できない人などいないし、稀にそのような人がいるとしても、このような疑問を呈したからという理由でそう決めつけるのは非論理的である。
  • 本記事は、「箱を使った喩えが悪い」という主張でも、「そのように喩えた人が悪い」という主張でもない。より良い変数の説明の仕方を考えることを目的としている。
  • 論理を丁寧に積み上げていくと、以前に採用していた粗雑な論理には戻れなくなる。そして、箱の喩えに疑問を感じた人に対する「比喩と現実を並べて考えてはいけない」という意見は、その雑な論理から導かれている。
  • そのような粗い論理の段階を早々に抜け出す一助になればと思い、これを書いた。

はじめに

この話については、すでに2度も長文を書いていて、

変数は「箱」か? - the code to rock
変数は「箱」か?(2) - the code to rock

かつ、今それらをざっと見返してみたら、今回書こうと思ったこともほぼ書いてあったので、じゃあそれでいいか、という気もしたのだけど、話題自体はまだ時々見かけるというか、以前にまとめたそれらの考えがあまりちゃんと外に届いていないようなのと、あとは前に書いたものの方は自分でもまどろっこしいというか、その時点でも「あまり上手く書けないなあ」と思いながら書いていて、しかしそれからしばらく時間が経って、もう少しシンプルに「こんな感じかなあ」というふうに思えるようになってきたので、今の視点からあらためて書き直してみたい。

前提を定義する

変数を箱に喩えるのがいいのか悪いのか、あるいは「良くも悪くもないけど何らかの問題がある」のか、それとも「問題なんてない」のか、みたいな議論が起こるとき、どうもありがちなパターンとして、異なる見解をもつ人同士が「同じ前提」を共有していない、ということがあるように思う。

前提や目的が一致していないと、途中で「そもそも何が問題なんだっけ?」みたいになりやすい。

そうなると、時間の無駄とまでは言わないまでも、やはり不毛感や消耗感から逃れがたい。
誰もそんなものは望んでいないのだから、まずは「前提」を一致させ、共有しなければいけない。

では、この記事における「前提」は何かというと、変数を「箱」に喩えることに対する、ぼくが持っている次の意見に集約される。

 プログラミングを学ぶ初心者に対して、「変数」の使い方を初めて教えるとき、変数を箱に喩えて、「値を箱に入れるイメージ」を伝える人がいるけれど、現実の世界で箱に物体を入れてしまったら、その物体を複数の場所から同時に取り出すことはできないのだから、本来そのようなことが可能になる変数の有用さを、箱のイメージでは伝えることができない。
 たしかにその喩えは、値を「格納」するイメージを伝えることには適しているが、「ひとつの値を複数の場所で同時に使える」という変数の性質を一緒に説明できる別のイメージがあった方が良いのではないか。

まあ、これだけと言えばこれだけである。

これに対しては、「いやいや、こういうときはひとまず値を《格納》するイメージだけでも伝えられれば良いのだよ。複数の場所でどうした、なんていうことはまた別に説明すればいいのだ」という意見もあると思うし、そういう意見があるのはまったく構わない。

重要なのは、どちらの意見が正しいのかということではなく、ましてやどちらか一方の意見に統一することでもなく、「何を目的にこの話を進めるのか」という、前提を一致させておくことである。

前提に関する行き違いを解消する

しかしながら、上記の前提を受け入れられない(同意できない)という人もいると思う。

というより、冒頭に書いたこととも繋がるが、この話で行き違いが生じるとすれば、その大半は、上記の前提を受け入れられるか、受け入れられないか、という違いに起因しているようにも思える。

上の話に対して「なるほど、たしかにそうだよね」と思えない人の中には、おそらく「しょせん比喩じゃないか」と思う人が少なくないだろうと想像する。

「しょせん比喩じゃないか」に続くのは、「比喩に過ぎないものと現実世界の物体とを繋げて考えるなんて、馬鹿げている。考えるだけ時間の無駄だ」といったものだろう。

そして、このズレこそが、もしかすると本件における最大の論点なのではないかと個人的には思っている。

「箱に喩えたら矛盾が生じるじゃないか」というぼくの疑問は、上の「前提」の最初に出てくる、「プログラミングを学ぶ初心者」の視点である。

一方で、「そんな疑問は馬鹿馬鹿しい」という回答は、プログラミングをすでに身につけた、「教える側」の視点によるものである。

この二つの視点は、同じ地平に立っていない。永遠に交わらない二つの線分である。

じつを言えば、最初にぼくが「箱」で説明を受けたとき(そう、「箱」で説明を受けたのだ)には、べつにそれを不思議とは思わなかった。
よく言われるように、その喩えを「わかりやすい」とすら思った。

しかしながら、自分で変数を使ってあれこれやれるようになってから、「あれ……でも、箱じゃ喩えとして変じゃないか?」と思うようになった。
どのような意味で「変」だと思ったのか、何が矛盾すると思ったのかということは、上に書いたとおりである。

これを聞いて、「箱でよい」と思っている人は「そら見たことか」と思うだろう。

「キミは箱の喩えを聞いて変数を理解したのだろう? そして自分で変数を使えるようになって、後から矛盾に気づいたのなら、それはキミが成長したということだよ。キミのその成長こそが、箱の喩えが学習に適している証拠なのだよ」と。

しかし、それは話がズレている。

ここでの議論の目的は、「初学者が最短コースで変数を理解すること」ではない。
「最終的に変数の性質をちゃんと理解できること」でもない。

ここで明らかにしたいのは、「箱に喩えることによって生じる矛盾を、何か別の説明の仕方で解消できないか?」ということだ。
「箱では変じゃないか?」というのはそういう疑問である。

その疑問に対して、「最終的に理解できるんだから問題ない」というのは答えになっていない。
視点が一段、メタレベルに上がってしまっている。

「最終的に理解できることがいいことかどうか」という問題なら、誰だって「理解できるのはいいことだ」と答えるだろう。

また、もしぼくが「箱に代わる説明の仕方さえわかれば、最終的に変数を理解できなくたっていい」と主張しているなら、それに対して「経緯はなんであろうと、最終的に理解できればいいんだよ」という反論も成り立つが、そういう話もしていない。

ここまで書けば、「比喩に過ぎない」とか「わかればいい」といったことはもう言う必要がなくなるのではないだろうか。

というかまあ、そもそも箱の喩えが「比喩に過ぎない」ことがわからない人などいるのだろうか? という疑問もあるのだけれど。

それが比喩に過ぎなくて、現実そのままの話ではないことなど当然わかっている。
それが比喩であるという前提で、「比喩として」もっと良いものがあるのではないか? と言っているのである。

このような質問をした人が、なぜ「比喩と現実の区別がつかない人」として扱われなければならないのか。そこにもまた、じつはこの議論を左右する核心が隠れているような気がしているのだけど、その問題については追々回収していきたい。

参照渡しは関係ない

さて、大前提についてはすでに説明したが、より具体的に話を進めるためには、もう少し細かい前提を補足していく必要がある。

よくこの話をしていると、「変数といっても、値渡しの変数と参照渡しの変数で性質が違うからなあ」みたいな意見を聞くことがある。

しかし、ここでぼくが想定しているのは、値渡しに使う変数でも、参照渡しに使う変数でも、どちらでもよい(というか関係ない)ものだ。

繰り返しになるが、ここで前提としているのは、「プログラミング初学者に初めて変数を教えるとき」のことである。

プログラミング初学者に初めて教えるのが「参照渡し」を主とするプログラミング言語でも、「値渡し」を主とする言語でも、その初学者にしてみれば大した違いではない。

それに、これも上に書いたように、ここで言う「箱の矛盾」というのは、「一回代入しただけで複数の場所で同時に使えるようになる」という変数の現象を「箱」では説明できない、ということである。

この点に関しては、値渡しであろうが参照渡しであろうが変わらないはずである。

つまり、これもまた「前提」の問題であって、今回ぼくはそのような前提を持っているが、そのことを知らずに「変数と言っても値渡しと参照渡しがあるから……」と考えはじめてしまったら、それは無用な回り道になる。

配列も関係ない

また同様に、「配列」も関係ない。

たしかに配列を説明するときには、ぼくも「箱」(というか下駄箱など)は有用な喩えとして使えるかもしれないと思う。

しかし、ここでの前提に配列は関係ない。プログラミングの初心者に配列の説明から入るケースはほとんど無いだろうし、そのような教え方があるとしても、ここではそれを前提としていない。

理想的な変数の教え方

ここからさらに、具体的な点を補足する。
ようやく少しだけコードも出てくる。

もしぼくが、初心者に変数の概念を教えるなら、たぶんこういう順番で教える。
見てもらえればわかるが、ここでは喩えを一切使わない。

まず、以下のような式を並べる。
Perlに慣れているのでPerlで)

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';

say 13 + 1;
say 13 - 2;
say 13 * 3;
say 13 / 4;
say 13 % 5;

これを実行すると、こんな。

14
11
39
3.25
3

次に、このプログラム内の「13」をすべて「21」にしましょう、と言う。

Vimなどを使っていると一瞬でできるけど、ポチポチ書き換えているとけっこう面倒くさい。

ましてや、ここでは5行しかないけど、もし業務で100行も200行も同じことをする羽目になったら結構つらい。
ということを軽く言っておく。

ちなみに、「13」を「21」に変えて実行するとこうなる。

22
19
63
5.25
1

さてそして、ここで変数を紹介する。
まずは先ほど「13」から「21」に変えた場所に、今度は変数xを入れてもらう。
こんな感じで。

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';

my $x = 21;

say $x + 1;
say $x - 2;
say $x * 3;
say $x / 4;
say $x % 5;

実行結果は前述のとおり。

そしてさらに、満を持してという感じで、「21」を「13」に戻してもらう。
もちろん、こうなる。

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';

my $x = 13; #<= ここだけ変更

say $x + 1;
say $x - 2;
say $x * 3;
say $x / 4;
say $x % 5;

先ほどは5行分の修正が必要だったが、今度は1箇所変えただけで終わった。

そしてここでまた、「これがもし100行や200行あったらどうなったか」とか言ってみる。

変数というのは基本的に、こうやって「それがなかった場合に比べてどれだけ便利になるのか」を示しながら教えるのがいいと思う。*1

だから、そうではなく「言葉」で説明するとき、つまり箱などの喩えを使うときというのは、あくまでその本題的な説明(実際のコードを示しながらの説明)に入る前のイントロ程度のもの、と考えるのが合理的だと思える。

喩えを使わない説明 〜名前を付けたデータ〜

そこまでを踏まえた上で、ではその「言葉」で説明するときに、箱の喩えを使わずにどう説明したらいいのかといったら、以下の二つのあり方を示したい。

  1. 「名前を付けたデータ」と説明する
  2. 「あだ名」に喩える

まず前者だが、個人的には、ほとんどこれだけで充分という気もしている。

これの元ネタは、ござ先輩こと湯本堅隆さんによる以下の本である。

独習Python入門――1日でプログラミングに強くなる!

独習Python入門――1日でプログラミングに強くなる!

ぼくはいつも、入門書のたぐいを読むときには避けがたく「この本は変数をどう説明してるのかな」と、その本の試金石のようにそれをチェックしてしまうのだけど、この説明にはかなり関心してしまった。*2

非常にシンプルで、まあ身もふたもないとも言えるけど、いずれにせよ著者がちゃんと自分の体験と考えにもとづいて出してきた説明だと感じる。

そしてこの説明を見て、「べつに何かに喩えなくてもいいのでは?」という思いも少し強くなった。

喩えを使う説明 〜あだ名〜

と同時に、「何かもっと適した喩えはないのか」と考えてきた身としては、それはそれでちょっと悔しいというか、何か具体的な物事に喩えたい気持ちも落ち着かない。

そんな中で、そういう「喩え系」として現状一番いいかなと思うのが、上記後者の「あだ名」である。

まあニックネーム、あるいはTwitterなどのWebサービスのアカウント名も近い感じだろうか。

一瞬話がズレるが(と言っても変数の話だが)、以前に基本情報技術者試験の勉強をしていたら、本の中で「変数というのは中身の値がコロコロ変わっていくから《変数》と言うのだ」と説明していて、それもけっこう目からウロコだった。

だったら「変数」ではなく「変値」とかにしてくれたらもう少し直感的だったのに、とも思ったが、それはそれとして、「中身がコロコロ変わる」という性質は変数を語る上でたしかに重要である。

上に示したコード例でも、「13」が「21」に変わり、それがまた「13」に戻っていく。

そのまま話を戻すと、人のあだ名というのも、中身は交換可能である。

まあ「永ちゃん」と言えば矢沢永吉だし、「ミスター」と言えば長嶋茂雄だが(たぶん)、それは定数みたいなものだとして、たとえば「健ちゃん」とか「よっしー」とか「ジョニー」とかは、地域や時代によって、対象となる実在の人物がバラバラのはずである。

ここでまた一瞬離れてしまうが、ぼくがプログラミングに入門して、エンジニア界に近づいていろいろ受けたカルチャーショックの中でも、とくに印象的だったのは「みんなハンドルネームで呼びあってる」ということだった。
「本名は知らないけど、Twitterのアカウント名は知ってる」みたいなケースがけっこう多い。

これって何かに似ているなあ、とその時に思ったのが、昔はデイヴ平尾とかジョニー大倉みたいに外国人の名前をニックネームにして、「よう、ジョニー」とか言い合ってたんだよなあ、見たことないけど。なんかそれに似ているなあ、ということだった。

あらためて話を戻すと、その「あだ名」とか、あるいは「肩書き」、またあるいはその上位概念である「名前」などはじつに「変数的」である。

たとえば居酒屋で、そこに同席していない部長や社長についていろいろ話題にするとき、その場に部長や社長本人がいなくても、「このまえ部長がどうしたこうした」と言えば、皆の頭の中にその人の姿が思い浮かぶ。

これは変数が同時に複数の場所で呼び出され、それぞれが同じ値を取り出していることによく似ている。

そして「部長」や「社長」の中身が交換可能であったり、あるいは「よっしー」の中身が高校時代の友達である吉沢くんと会社の同僚である吉田さんとで交換可能であったりすることも、また変数的である。

ここでは、箱に見られた矛盾(破綻)が解消されている。

逆に、もし同じ状況を箱で再現しようとしたら、たとえば「部長」と書かれた箱の中に実在の部長が入らなくてはいけなくなる。
そしてそうなれば、複数の異なる場所で同時に部長の話をすることもできなくなる。

そう考えると、そもそも物体に喩えることに問題があるように思えてくるが、ある現象を何か他の事象に喩えるメリットというのは、複数の異なる人間が「ありありとした実感」を共有することにあるので、必ずしも物体に喩える必要はないし、物体以外のもの(つまりあだ名や肩書き)に喩えることでそれを実現できるならそれでいい。

「わかりやすさ」とは何か

ということで、ひとまず結論的なことも書いたので話は終わりに向かうが、まだこの文章で触れていなかったことについていくつか触れておきたい。

まず、これは少し前にTwitterにも書いたのだけど、「箱に喩えればわかりやすい」などと言うときの「わかりやすさ」とは、「その情景をイメージしやすい」という意味でのわかりやすさであって、「変数の性質を理解しやすい」ということとイコールではない。

思うに、「箱ならわかりやすい」と言う人はそこをごっちゃにしている。

「箱にモノを入れる様子」がイメージしやすいことについては、ぼくも同意できる。

しかし、それは「言葉から映像を想像しやすい」ということであって、「変数の性質を理解しやすい」ということとは別である。
まずはそこを分けて考えるべきである。

プログラマーは本当に箱を想像しているのかもしれない

と同時に、ぼくは最近、プログラマーは変数に値を代入しているとき、実際にモノを箱に格納しているかのようなイメージを頭の中に思い浮かべているのかもしれない、とも思っている。

というか、むしろプログラマーが普段からそういう状況を頭に思い浮かべているからこそ、変数を「箱」に喩える説明が生まれたのではないかと思っている。

ぼくが「箱に入れてしまったら、複数の場所から同時に取り出せないではないか」と言ったとき、「それとこれとは別の問題だ」という反応があるのは、現実空間にある箱と、プログラマーの頭の中にある箱とが、異なる性質を持っているからではないだろうか。

もしそうであるなら、教える側(プログラミングをすでに身につけた人)が、教わる側に「箱」と言ったとき、それは初めから「現実には存在しない不思議な箱」を意味している。

またそうであるなら、「現実世界に存在する箱と性質が違うよ!」なんて言ったところで、「何を自明なことを……」と思われてしまうのも理解はできる。

しかし一方で、このように「変数と箱」の問題がくすぶり続けるということは、その教える側の「自明さ」が、必ずしも教わる側にきちんと伝わっていない、ということなのではないだろうか。

そしてこの点を解消できないかぎりは、同様のコンフリクトがもうしばらく続いてしまいそうな気がしている。

それでも大切にすべきこと

さてその上で、もしそのように、認識のズレにある程度避けがたい経緯があるとしても、より優先すべきことは、「箱に喩えるのは変じゃないか?」といった疑問が挙がったときに、上に書いたような「メタレベル」の回答をしたり、相手の真剣な疑問を踏みつぶしたりしてしまわないことである。

よくTwitterでは、大人の矛盾した説明に対して素朴な疑問を提示した小学生が、教師から理不尽に叱責されるエピソードなどがRTで回ってきて、「こんな教師は嫌だ」みたいな話が盛り上がるけれど、そのわりにこういう疑問に対しては冷淡というか、情の薄い反応が少なくないのは不思議というか、むしろ人間の本性がそのようなものだから、そういう小学生のエピソードもなくならないということかな、という気もしてくる。

「人」を否定しているわけではない

その話とも繋がるが、この変数と箱の話題に対しては「なぜそんなことを言うのかわからない。まったく無意味である」という、攻撃のようにも受け取れる感情的な反応が少なくないと感じるのだけど、それはもしかすると、「箱」を例に使って教えたり、教わったりしてきた自分を否定されたように感じさせてしまうからかな、と思うこともある。

だから明記しておくのだけど、これはそういう例を使っている「人」を否定する話ではない。

結果的に、この話題によって自分を否定されたような気持ちになる人はいるかもしれないし、それを100%避けることもできないのだけど、目的はそこにはない。

目的は、「もっと良い説明はないだろうか? それを考えてみたい」ということである。

極められた思考がもたらす不可逆な論理

ここまで長く書いてきたのは、「ある種の思考の道筋は、一度通ったら戻れなくなる不可逆性を持っている」と考えているからだ。

どれだけ意見の異なる人同士でも、「それでも一致する共通見解」というものはあるはずで、それが見つかってしまうと、もうそれより前には戻れない。

少し前に、天動説と地動説の盛衰について語った面白い記事があったけど、

gendai.ismedia.jp

どれだけ多様な観点から考えたとしても、現代において天動説を本気で(地動説より)支持する人は出てきえない。

深い思考を丹念に積み重ねれば、「たしかにそこまでは言えるよね、そこまでは同意できるよ」という共通見解を作っていくことができる。

それは、「もう今から天動説には戻れないよね」というのと同じで、「ここより前には戻らない」という不可逆な地点の発見でもある。

「箱」で説明を受けた人が、「それだと矛盾しますよね?」と言ったときに、「ただの喩えだよ」と答えるのではあまりに雑すぎる。
というより、それはまともに答えられないことを誤魔化しているだけである。

「箱」で説明するのが悪いわけではない。上にも書いたが、説明する人の頭の中では実際に「値を箱に格納するイメージ」が動いているのかもしれないし、もしそうなら、それはもはや「喩え」ではなく「事実の伝達」である。

でも、その説明で納得できないという人がいるなら、「ただの喩え」などと回答するのではなく、一体どこに疑問を持っているのか、それを解消するにはどんな説明が必要なのか、一緒に考えてみてほしい。

そんな暇がないのであれば、非情な言葉を投げつけるのではなく、静かに離れてあげてほしい。

すでにここまでは考えた。ここより前の段階には、もう戻らないでほしいなあと思っている。

*1:変数に限らず、新しいことを教える際には多くの場面で有効な方法だと思う。

*2:厳密には「名前を付けられたデータ」と説明されているが、こちらでそのように書くと少し冗長になるので、「られ」は端折らせてもらった。