みねこあ

mineko. A! ―from mi-neko online.

2010-02-10

[]ひまわり基礎文法最速マスター 14:47 ひまわり基礎文法最速マスターを含むブックマーク

ブームも去りつつある最速マスターシリーズですが、自宅サーバをあさっていたら 2005年くらいに書いた ひまわりの紹介記事を発掘したので、これもご縁とそのままもってきてみました*1

他の言語をある程度知っている人はこれを読めば ひまわり の基礎をマスターして ひまわり を書くことができるようになります。

とはいえ、後継の なでしこ に道を譲って久しい ひまわりですので、「最速マスター」の需要はそんなになさそうですが、枯れ木も山の賑わいということで。


ハローワールド

ハローワールドを実現するソース。

「こんにちは」と、言う。

「ひまわり」は手続き言語です。 しかも「構造化プログラミング」もいまいち馴染みません。

これは「構造化プログラミング」という手法を利用しなくてはいけないほどの 大規模開発をターゲットにしていないという潔い割り切りで、 その結果として「ひまわり」は「普通の人」にとって解りやすいという力を得ます。*2

これは「言」命令、つまりメッセージボックスの表示でしたが、

「こんにちは」と、表示する。

で、ひまわり実行時に開かれるメインウィンドウに表示されます。 (ひまわり ではこのメインウィンドウを「母艦」と呼びます)

ちなみにこれでは起動しっぱなしになるため、

「こんにちは」と、言う。

おわり。

で、実行を終了します。


送り仮名

ひまわりに於いて、送り仮名はコメントのようなものです。

「こんにちは」と、言う。

「さようなら」と、言いいました。

「元気でね」と、言ったりして。

「貴方もね」と、言。

これらは全て同じ命令ですが、 人間から見れば微妙にニュアンスが違います。


「言う」命令の実体

画面にメッセージボックスを表示する「言う」命令ですが、 本質はこうです。

 【引数】と、言

"と" は命令に対して引数を渡します。 メッセージボックスを表示する命令「言う」の 識別子は「言」です。

ちなみに実はひまわりは フツーのプログラム言語風の ファンクションコールも持っていて、

言( 【引数】 )

も可能です。 (プログラマにはこっちの方がなじみやすいかも)


「と、」

「と、」は 関数に引数を渡します。 これは連結可能なシンタックスです。 「を、」も同じ働きをします。

これの働きを理解するため、一つ実験をして見ましょう。

「こんにちは」と、「さようなら」を、言う。

日本語的には崩壊していませんが、これを実行すると、 「さようなら」と表示された後、

[エラー] himapad.bak(1行目): "言"命令の引数に誤りがあります。引数が多いです。"`こんにちは`と"
[エラー] himapad.bak(2行目): "`こんにちは`と"は未定義の命令です。(;o;)<綴りミスか、命令の引数に注意!

というエラーが出ます。*3

要するに、引数が多いという訳でです。


コメント

ひまわりのコメントは以下の形式となります。

// ここは、文末までコメント。

※ ここも、文末までコメント。

' ここも、文末までコメント。

何れも一行コメントです。

また、

 「あ、貴方は・・」と、言う。{ここはこめんとです} 「フフフ・・・」と、言った。

のようなブロックコメントもあります。


文字列

ひまわりの文字列リテラルは 以下の形式になります。

「ここは文字列」

"ここも文字列"

文字列の結合について、ちょっと実験。

//『+』で結合してみる。
それは、「あなた」+「わたし」
それを、言う。

//『&』で結合してみる。
それは、「あなた」&「わたし」
それを、言う。

最初の『+』で結合したものは「0」が表示されます。 一方、次の『&』で結合したものは「あなたわたし」が表示されます。というわけで、文字列の結合は『&』を用います。

というのも、ひまわりでは『+』で結合されたものは 無条件に数値として扱われ、 『&』で結合されたものは 無条件で 文字列 として扱われる シンプルなルールが採用されている為です(たぶん)。

また、もうちょっとエレガントな文字列編集もあって、

「あなたのお名前は?」と、尋ねる。
あなたは、それ。

わたしは、「みねこあ」。

「{あなた}と{わたし}の夢の国」と、言う。

のように {変数名} で、文字列フォーマットが出来る。 ちなみに『{』『}』を表示するには、エスケープすれば良いです。

エスケープは、C言語風で、シーケンス文字「\」を使います。 タブ→「\t」、 改行→「\n」、{ →「\{」といった感じです。

文字列比較は『=&』『!&』演算子を使います。

それは、「三猫」

もし、それ =& 「三猫」ならば、
  「猫でした」と、言う。

違えば、もし、それ !&「名無しさん」 ならば、
  「{それ}さん、初めまして」と、言う。

「==」「!=」では比較できません。


反復命令と複文

まずは、反復命令を。

 【n】回【文】

これでn回 文を実行します。

10回「ワン」と、言う。

この結果「ワン」というメッセージボックスが10回開くことになります。 (ええぃ、うっとおしい!)

ところが

10回( 「ワン」と、言って。「ニャン」と、言う。)

という風に『()』で 一つのブロックに纏めることが出来ます。

ブロックというより複文な印象で、ひまわりは 見た目の独自さに誤魔化されがちですが、セマンティックスは Cライクななものが多いです。


条件分岐

まずはこれを。

「助けを求めていますか?」と、二択。

もし、それが、はいならば、
  「誰か〜っ!」と、言う。
違えば、
  「意地っ張り!」と、言う。

まんま、if-elseです。 これはもちろん複文で書くこともできます。

「助けを求めていますか?」と、二択。

もし、それが、はいならば、
(
  「誰か〜っ!」と、言う。
  「テケスタ〜っ!」と、言う。
)
違えば、
(
  「意地っ張り!」と、言う。
  「もう、知らないから!」と、言う。
)

では、『else if』はできるのかというと、

// あなた を取得。
「貴方は誰?」と、尋ねる。
あなたは、それ。

// 助けを求めるかの確認
「助けを求めていますか?」と、二択。

もし、それが、いいえならば、
  「意地っ張り」と、言う。
違えば、もし、あなたが、「」ならば、
  「誰かが助けを求めてる!」と、言う。
違えば、
  「{あなた}が助けを求めてる!」と、言う。

は、もちろん実行出来ます。 ただし、『違えば、もし、』句があるわけではなくって、 このコードは、

// あなた を取得。
「貴方は誰?」と、尋ねる。
あなたは、それ。

// 助けを求めるかの確認
「助けを求めていますか?」と、二択。

もし、それが、いいえならば、
  「意地っ張り」と、言う。
違えば、
(
  もし、あなた=「」ならば、
    「誰かが助けを求めてる!」と、言う。
  違えば、
    「{あなた}が助けを求めてる!」と、言う。
)

の、カッコを省略したものにすぎません。(ここらへんも Cっぽいですね)


それ

ひまわりの醍醐味は特殊変数『それ』です。 (perl の $_ みたいなもの、で判っちゃう人は、この項は読み飛ばして下さい)

ひまわりの全ての関数(というか式)は、捕縛してない戻り値を『それ』に書き出します。

たとえば

現在時刻 = 今。
"現在時刻は{現在時刻}です。"と、言う。

今。
"現在時刻は{それ}です。"と、言う。

と書けます。(ここまでしたら『"現在時刻は{今}です"と、言う』 と書くべきですけれど、例なので..)


『それ』のもう一つ重要な特徴は、 関数の引数を省略したときに、暗黙のうちに『それ』があてがわれるというものです。

そのため、

今。            // 『それ』に現在時刻をセット
表示。          // 『それ』を表示。

のような、実に日本語チックな省略が可能です。


飛ぶ・呼ぶ

ひまわりの言語設計は手続き型であることを強く意識しているため、 当然無条件ジャンプ文(いわゆるGoTo文)を持っています。

構造化プログラミング以降、GoTo文はプログラマの敵なので 出来れば無かったことにして説明せずにすませたいのですが、 ひまわりの場合、「関数(もどき)」の実現に深く関与しているため 説明しないわけにはいきません。

無条件ジャンプ文には、「飛ぶ」と「呼ぶ」の 二つの構文があります。二つともラベルの所まで 実行行をジャンプさせる命令ですが、 純粋にGoTo文と言えるのは「飛ぶ」文で、 「呼ぶ」文は必ず呼び元に戻ってきます。

    朝の挨拶へ、飛ぶ。
    「ごきげんいかが?」と、言う。

*朝の挨拶
    「おはよう」と、言う。

*昼の挨拶
    「こんにちは」と、言う。

「*」はラベルを指定します。 GoTo文の期待を裏切らず、このソースは実行すると「おはよう」「こんにちは」と 続けてメッセージボックスを連続して表示します。(「ご機嫌いかが?」は表示されない。)

一方「呼ぶ」文はジャンプ先に「戻る」文があった場合、 呼出元へジャンプする機能を持つ 無条件ジャンプ文です。

    朝の挨拶を、呼ぶ。
    「ごきげんいかが」と、言う。
    おわり。

*朝の挨拶
    「おはよう」と、言う。
    戻る。

*昼の挨拶
    「こんにちは」と、言う。
    戻る。

こちらは期待どおり、「おはよう」「ごきげんいかが」と メッセージボックスが表示されます。 (おわり、がミソでこれが無いとそのまま処理が 朝の挨拶 部へフォールスローします。)

なお、ジャンプしてきてもいないのに「戻る」文に 遭遇した場合、そこでスクリプトの実行が停止するようです。(終了はしない) なので、もし3行目の 『おわり。』が無いばあい、 そのまま 朝の挨拶 の部分にフォールスローし、そして「戻る」文に遭遇して処理がストップします。

また「呼ぶ」文にはシンタックスシュガーがあって、

    朝の挨拶。
    「ごきげんいかが」と、言う。
    おわり。

*朝の挨拶
    「おはよう」と、言う。
    戻る。

のように、ラベル名だけで記述することも出来ます。


関数モドキを作る

結論から言えばひまわりは関数を作れません。 ですが、関数モドキを作ることは出来ます。

まず、関数に要求されるものは何かを整理してみましょう。 すると次の様な要求を満たせば、それは関数として扱えそうです。

  1. 任意のコード行へジャンプし、コードを実行後呼び出し部に戻る。
  2. 呼び出し部に値を渡す。(引数)
  3. 呼び出し部に戻ったとき、戻り値を返す。(戻り値)
  4. 関数内部で宣言した変数は、その内部のみのスコープを持つ(自動変数)

ひまわりには、かならず呼出元に戻ってくる特殊なジャンプ命令「呼ぶ」があります。 ([1]をクリア) また、ひまわりの関数コールは戻り値を 特殊変数「それ」を通して受け渡すという 特徴がありますから、関数で「それ」に戻り値をセットすれば、 呼出元に戻り値を渡すことができます。([3]をクリア)

残すは引数の受け渡しとローカル変数の定義です。 まずは引数の受け渡しですが、ひまわりはラベルに引数を定義することができます。

    「祥子」様に、挨拶。
    おわり。

*挨拶(?様に)
    引数取得。      // 「それ」に引数を取得
    「{それ}さま、ごきげんよう。」と、表示。
     戻る。

こうすると、引数とその助詞(にとどまらないのだけれど)を ラベルに指定することが出来ます。 (※himawari 1.83以降の機能です。それ以前のverだとエラーになります。)

『引数取得』で『それ』に格納されるのは配列なので、 複数の引数でも問題ありません。

ローカル変数を使いたいときには、ローカル変数を定義する「を、ローカル変数」という構文がありますのでそれを使います。


と言う風に、かなり関数らしくできるのですが、あくまで「もどき」であることを忘れてはいけません。

特に注意したいのは、全然カプセル化がなされていないと言うこと。 ファンクションコールに見えるのは、 単なる拡張された無条件ジャンプにすぎないので、呼出以外でも関数のコードに実行行が到達すれば そのまま実行されます。



まとめ:ひまわりの神髄

ひまわりの素晴らしいところは、「日本語の語彙」「日本語風の構文」を備えているだけじゃなく、(コーダーの努力によっては)生成されたコードが完全な日本語の文章になってしまうところです。

これはちょうど、漢文にレ点や一二点、送り仮名をつけて日本語として読み下すテクニックに似ています。人間が読めば日本語に、コンピュータが読めばプログラムに。一つのコードを全く文法体系が違う二つの視点から読み下せるように巧みに設計してあるという意味で、ひまわりと漢文読み下しは本当によく似ています。

ひまわりでの美しいコードとは、いかに自然な日本語に見えるように書くかだと思います。そうやってかかれたコードは、読むだけなら日本人なら誰でも意味がわかるようになります。「送り仮名の無視」や特種変数「それ」のように、ひまわりには「自然言語に見間違うコード」を実現するための心配りがたくさんあります。

しかし、いくら日本語のように読めるからと行って、ひまわりプログラムとして有効なコードを書くには、当然プログラミングの知識が必要です。このRead/Writeのユーザスキルの不均衡さを受け入れるかどうかが、ひまわりの評価の分かれ目かな?って思います。「読めるけどかけない」は良くある話ですが、それが「日本人ならほぼ誰でも読める」まで拡大しきっちゃった時の威力には、素晴らしい可能性があると思います。

*1:これをベースに、コンパクトに再編集したエントリを以前書いていますが、3,4年前のエントリなので 気にしないということで(^^;

*2:ひまわりは、なでしこへの移行直前まで 関数のサポートを拒んでいました。まつもとさんのこれに通ずる話ですね

*3:顔文字がかわいいです