まずは単純な文から [wython]
wythonはPythonを日本語で記述するものだから、Pythonの文法を参考に考えることができる。
まず、一番簡単な、複合的でない文のうち、wythonで対応するものを挙げよう。
- 関数のみからなる文
- 代入文
- print文
- return文
- break文
- continue文
- import文
- グローバル文
これらはほとんどのものが特定の動詞に置き換えられる。たとえば、
- 関数keisan()を呼び出す。
- 数値データnとmを足して、整数型変数xに代入する。
- 文字列「これはコンソールに印字されます。」を表示する。
- 結果aを戻す。
- 繰り返しを中断する。
- 次の繰り返し。
- モジュールreを読み込む。
- 変数aとbはグローバル変数である。
といった具合に、特定の動詞で終わる文に対応する。
変数はアルファベットを使用し、関数も英数字の名前にする。一方、これらの文の中心となる動詞はみな日本語である。その日本語を検索ないしは正規表現で取り出すことにする。
また、以前、「変数」や「代入する」という表現は用いないとように設計していたこともあるが、このwithonは教育用であると同時に、変数や代入という簡潔な言葉の方が、回りくどい「名付ける」などの表現よりも、結局のところは、分かりやすいと思う。また、wythonはPythonなどの他の言語に変換するものである。つまり、のちにPythonのコードに直接書き直すので、最初から、その「代入」の構文に近い日本語を使っていた方が、理解が早まるだろう。というのが理由である。
次回は、複合的な文について考えてみることにする。
日本語スクリプト言語再始動 [wython]
「やはり日本語スクリプト言語が必要か」にも書いたが、再び、この話題を追いかけようと思う。
というのも、大谷大学をアピールするために、高校で模擬授業をやることになり、人文情報学科でできるテーマをいくつか出してほしい、という話が来たので、「日本語プログラミング入門」という題を出しておいた。まだ決まったわけではなく、そういう模擬授業の候補を示し、高校の方から要望があった場合、そちらに出向いて模擬授業をすることになる。とはいえ、もしそういう要望があったら、即対応しないといけないので、予め作っておかなければならない。
というわけで、おしりに火がついた、というか、自ら火の中に飛び込んだ、というか、とにかく、少しずつ形のあるものを作っていかなければならない。御託を並べている暇はないのだ。
大体の方針は決まっている。要するに、日本語で書いたスクリプトをPythonプログラムに変換し、Pythonでそれを実行するようにすればよい。だから、基本的には、あるプログラミング言語から別のプログラミング言語へのトランスレータを作ればいいということになる。ということは、正規表現使いまくり、でいいということだ。少し難しとすれば、一つは日本語の正規表現がどの程度Pythonでサポートされているか、ということと、制御構造をどのように日本語で表現するかだ。特に繰り返しの部分。
まず、簡単な「単文」についてのみ、作ってみることにしよう。そもそもプログラミングは、制御構文が出てくるまでに、かなり間がある。最初のうちは、変数だとか、代入だとか、表示だとか、型だとか、計算だとか、といった、一行で完結するような構文の話が続く。とりあえず、その最初の方の部分を処理できるようにしよう。
wythonの肝は、全部を日本語だけで書こうとしていないところである。変数名と関数名はPythonと同じ規則、つまり英数字で付けることにする。高校生も理解できるようなものを考えるとすると、
変数名はアルファベット一文字を多用するのがいいような気がする。文字はa、b、cなど、文字列はs1、s2、s3など、数値はn、m、i、j、p、qなど。
関数名は日本語をローマ字化して名付ける。もちろん、簡単な英語で済むものは英語でつける。
あとは、「文」を構成するために必要な部分は、日本語で記述する。この部分は定型的なので、必要な語彙を決めて、また解析するときには、それらを正規表現でヒットさせればよい。また、変数名や関数名に先立つ部分は、それら変数名や関数名に対して、日本的な説明をつけられるようにする。それらはトランスレータには無視される。
今後は、徐々に具体例と、それを処理するプログラムとを同時に提示していくことにしたい。
やはり日本語スクリプト言語が必要か [wython]
今年の初め、日本語スクリプト言語を設計しようとして、いろいろと書いたが、その後、授業の内容を変更するに及んで、少し停滞してしまった。
しかし、C言語を教えるうちに、やはり日本語でのプログラムの記述は有効ではないかと思うようになった。ごく初歩的なプログラムならば、わざわざ日本語で述べなくても、ある決まり切ったパターンさえ覚えればプログラムを書けるようになると思っていたが、何らかの問題を出して、それについてのプログラムを書かせようとすると、やはり変数の処理、繰り返しや条件判断など制御構造などを、どのように組み合わせるのか、そしてプログラムの中でのデータの流れをどう考えるのか、についての理解、というかイメージが不十分なようなのだ。
たとえば、
int c; while ((c = getchar()) != EOF) if (c == ' ') putchar('¥n'); else putchar(c);
というごく単純なプログラム、これも出来上がってみれば簡単だが、単語一つ一つを一行ごとに書き出す、という問題を聞いて、何もないところからここまでプログラムを書くのは、初心者には難しい。
特にcという変数がこのプログラムの中心を動いていくキーになるが、それをどのように使い回していくのか思いつくまでが大変である。このとき、
整数型のデータcを宣言する。 一文字入力し、それをcに代入する。そのcがEOFになるまで以下を繰り返す。 もしcがスペースならば、 改行文字を表示する。 そうでなければ、 入力された文字cを表示する。
とすると、プログラム全体の流れが理解しやすくなる。なぜcを宣言し、それをプログラムのの個々の部分でどのように使い、何を判断し、どのように処理しているかが分かるようになる。
そもそも日本語スクリプトは、擬似コードであってよく、それでコンパイルなどができなくてもいいのではないかと思う。擬似コードという意味では、フローチャートも、プログラムの流れを示すものだが、このフローチャートとプログラムコードの間のギャップはかなり大きい。それに対して、制御構造も含め、ほぼプログラムコードの流れを再現しながら、その意味を日本語で説明したかのような日本語スクリプト言語による擬似コード記述は、もし、覚えやすく、規則的な文法が設計できれば、プログラミング学習にかなり有効だと思う。
繰り返しの表現 [wython]
久しぶり、日本語スクリプト言語wythonの仕様について、少し追加あるいは修正しておきたい。
Pythonでの繰り返しの構文に基づき、wythonでは、whileとforに変換される繰り返し構文を採用している。これらの表現を
数値0をiと名付ける。 数値iが数値max_countより大きい間、 数値iを表示する。 数値iに1を足す。
および
ファイルfile_nameの各行lineに対して、 文字列lineを表示する。
あるいは
リスト["a", "b", "c"]をalpha_listと名付ける。 リストalpha_listの各項目itemに対して、 項目itemを表示する。
というように書くことにしたい。つまり、繰り返しの条件を述べる文の最後は、文の終止形ではなく、「の間」とか「に対して」という非終止形で、句点で終え、次からのインデントした段落に続けるようにする。細かいことだが、この方が自然な日本語になる。
それと、変数に代入するタイプの文も、上に挙げたように、「名付ける」とすることで、変数と代入の分かりづらさをある程度解消できているのでないかと思う。
日本語スクリプト言語wythonの変換プログラム [wython]
これまで、いくつかwython用の日本語スクリプト例を考えてきた。ここで、少し、wythonを処理するための基本的な考え方をまとめておこう。
前にも言ったように、wythonは言語としては新たに設計はしているが、その実態は、Pythonのスクリプトを日本語でオブラートしたようなものである。ほとんど一文ずつ、Pythonのスクリプトに書き直せるし、そのように一文ずつ変換していくことを前提に考えている。
そのため、wython自体に、意味解析や構文解析などの処理は全く必要なく、文字列の単純な置換(と言っても、正規表現を駆使するが)ですますことができる。つまり、コンパイラではなく、言語処理系でもなく、トランスレータとして機能する。
ここで、日本語のスクリプトでありながら、変換を容易にするために、wythonでは、識別子は通常のPythonと同じ英数字にしている。つまり、変数の名前や関数の名前を英数字にし、そのままPythonのスクリプトに利用している。
そのため、一つの文から、英数字の並びを、変数名ないしは関数名として取り出すことが容易になる。あとは、文法的な構文の部分を日本語にしていることぐらいが、強制的な仕様である。特に、変数は、その直後に「に」とか「を」とか、「と」とかの限られた助詞を使うようにしておけば、一文の中に複数の変数があっても、容易に区別して取り出せる。
また、計算式はかならず変数への代入を伴うようにし、計算式を別の式の中に組み込むようなことはしないようにしている。それをやると、単純な置換では処理ができないことになる、という横着のためでもあるが、また初心者に、変数や代入、データのインプットとアウトプットという概念を繰り返し覚え込ませるための方法でもある。
そのため、若干冗長な表現になるが、簡潔さは、基本を理解してから徐々に導入しても遅くはない、と割り切っている。
以上の最低限のルールを守る限りは、それ以外の日本語にどのような言葉を書こうが、ほとんど無視される。これまてのwythonのコードで、「文字列オブジェクト」とか、「数値オブジェクト」とか、「これこれのことをする関数」などの表現を用いているが、これらは全て変換時には無視される。それらはスクリプトを書く人、読む人が理解しやすくするための、人間のための説明語句にすぎない。分かるようになれば、それらを省略して書くこともできる。
また、たとえ冗長ではあっても、一文ごとにPythonのスクリプトに直せるので、慣れてきたときには、直接Pythonのコードを書いてしまうことさえできる。
ブロックをインデントするのもPython譲りである。
以上のような方針で作るので、割合簡単に、かつかなりの自由度をもって、プログラムすることができるであろう。(まだ、実際には作っていないが。)
日本語スクリプトの例12 [wython]
import sys
i = 0
for arg in sys.argv[1:]:
for line in open(arg, "r"):
if i >= 10:
break
else:
print line,
i += 1
システム・ライブラリーをインポートする。
数値iを0に初期化しておく。
2番目以降のコマンドライン引数を一つずつ文字列argに代入して、以下を繰り返す。
文字列argのファイルをオープンし、一行ずつ文字列lineに代入して、以下を繰り返す。
もし、iが10以上ならば、
繰り返しを中断する。
そうでなければ、
文字列lineを表示する。
iに1を足す。
日本語スクリプトの例11 [wython]
import sys
file_name = sys.argv[1]
for line in open(file_name, "r"):
print line,
システム・ライブラリーをインポートする。
2番目のコマンドライン引数を、文字列オブジェクトfile_nameに保存する。
file_nameを読み込み用に開き、一行ずつ文字列lineに代入しながら、以下を繰り返す。
文字列lineを表示する。
日本語スクリプトの例10 [wython]
enzan = ""
sum = 0
import sys
for arg in sys.argv[1:]:
if arg == "+":
enzan = "+"
elif arg == "-":
enzan = "-"
else:
if enzan == "+":
sum += int(arg)
elif enzan == "-":
sum -= int(arg)
elif enzan == "":
sum = int(arg)
print "答えは", sum, "です。"
システム・ライブラリーをインポートする。
文字列argに、コマンドライン引数リストの項目を一つずつ代入しながら、以下を繰り返す。
もし、argが「+」ならば、
文字列オブジェクトenzanに「+」を入れておく。
あるいはもし、argが「-」ならば、
文字列オブジェクトenzanに「-」を入れておく。
そうでなければ、
もし、enzanが「+」か、あるいは「」ならば、
文字列argを整数にして、数値sumに足す。
あるいはもし、enzanが「-」ならば、
文字列argを整数にして、数値sumから引く。
「答えは」、sum、「です。」を出力する。
「変数」や「代入」という言葉を使わない [wython]
現在、連載している「日本語スクリプトの例」では、普通のプログラミング言語で言及される「変数」とか、「代入」とかいう言葉を使用しないようにしている。
文系の初心者は、「変数」や「代入」という概念が、そもそも理解するのが困難である。もちろん、それが困難な人にプログラムを教える必要はない、という意見もあり得る。しかし、この最初の関門を通過すれば、それなりに簡単な処理をプログラムできるようになるのであるから、決して、この最初の関門がプログラムを学ぶ試金石になるとは言えないのである。
あるいは、高校で情報基礎などの科目が取り入れられ、Perlなどのスクリプトを学ばせる必要が出てくるとするならば、やはり同様に「変数」や「代入」が躓きの石になり得るだろう。
プログラムは変数と関数から成り立っている、というのは正しいだろうか。そうではなく、物と物に対する働きかけから成り立っていると考えた方が自然ではないか。それは現実の世界の有り様にも対応している。現実の世界には変数もなければ代入も存在しないだろう。
物と働きとを、バーチャルなプログラムという世界においてモデル化したら、それはプロクラム世界に存在する様々なオブジェクトと、それに対して働きかける動詞とになるだろう。プロクラム上に存在するオブジェクトには、いくつかの種類がある。最も基本的には、文字列オブジェクトと数値オブジェクトである。
物には名前がある。従って、文字列オブジェクトにも名前が必要であり、いくつもの文字列オブジェクトは名前で区別される。wythonでは、Pythonへの変換を容易にするために、そして、場合によってはPythonスクリプト自体を混在させることもできるように、名前は英数字にしている。よくよく考えてみたら、変数などという、変な日本語(数?)を使わなくてもすむではないか。
よく、変数は箱で、その中に値を格納することを代入する、と言う、という説明がなされる。しかし、これも変な話だ。箱と値を区別する必要があるだろうか。たとえば、
文字列オブジェクトIamを「私は日本人です。」という文字列にする。
という場合、それは「私は日本人です。」という文字列オブジェクトにIamという名前を付けているのである。箱とか値とか代入とか、という話ではない。
問題は、「オブジェクト」や「文字列」や「数値」という表現を使うというところにあるのではない。それは自然なことである。困るのは、それに対応する動詞ないしは述語の方である。「設定する」とか「保存する」とか「初期化する」とか、あるいは単に「する」とかという表現を考えたが、まだ、完全に決定されているわけではない。今でも、これらの動詞部分は揺れている。これはもう少し時間を必要とするようだ。
日本語スクリプトの例9 [wython]
import sys
for arg in sys.argv:
print arg
システム・ライブラリをインポートする。
文字列argに、コマンドライン引数リストの項目を順に代入しつつ、以下を繰り返す。
文字列argを表示する。