カッコの無い世界
何となくLogo を使ってみたくなりました。(C4 の影響かもしれない)
Logo は 乱暴に言ってしまえば Lisp のプリプロセッサのようなもので、
カジュアルなLogo → 正規Logo → Lisp
と順番にほぼ1対1で変換可能になっています。
「カジュアルなLogo」とか「正規Logo」とはは、あまり聞き覚えのない言葉ですが*1、Logo の文法は 2段階変換になっていて、正規Logo は 単純に Lisp から カッコを取っ払ったもの、カジュアルなLogo はそれをもう少しユーザフレンドリにしたものだそうです。
正規Logo
S式からカッコを取っ払う手段として、Logo は
- クォートされていないのは全て 関数だ!(つまり直前でカッコがひらいている)
- その関数が何個引数を取るかあらかじめ解っていれば、閉じ括弧の位置は判断できる
で対応しました。(シンプル!)例えば
(F 'x (G 'y 'z))
という S式は
F "x G "y "z
とそのまま変換されます。(Logo のクォートは 「"」を使う)
じゃあ、クォートされていないシンボルはどうするの、という話は、THING をつけて対応します。(Lisp とは逆で、何もしないとクォート、THING を着けて評価 になります)したがって、
(F x (G y z))
は、
F THING "x G THING "y THING "z
になります。
Logo も Lisp 同様、「リスト」を持っています。Logoのリストは Lisp のモノそのまんまですが、丸括弧「()」の代わりに 角カッコ「[]」を使います。そして Lisp と違い、何も着けないと クォート、評価する場合は RUN を着けます。
(SUM 1 (SUM 2 3))
は、
SUM "1 RUN [SUM "2 "3]
になります。基本的にこれだけです。
カジュアルなLogo
カジュアルなLogo になると、もう少しがんばるようになります。
まず、数値アトムの暗黙のクォート処理が入ります。数値のみの語を見つけたら勝手にクォートを着けてくれます。つまり正規Logo
SUM "1 "250
をカジュアルなLogo では、
SUM 1 250
と、スッキリ書くことができます。
次になまら THING! THING! うるさいプログラムになりがちなので、ドット表現と呼ばれる「:」を使った略記法を導入します。
F THING "x G THING "y THING "z
は、
F :x G :y :z
と簡潔に書くことができるようになります。(Lisp の 「quote」 と 「'」のちょうど逆ですね)
また、カジュアルなLogoは 二項演算子にも対応します ( + とか - とか)。 これは単純にカジュアルなLogo中で
1 + 2 * 3
を見つけたら正規Logoにコンバートするときに
SUM 1 2
に変換するだけです。ただし中記法 を導入すると演算子の優先順位が気になるようになるので、強制的に優先順位に逆らった評価をさせるために 丸括弧(グルーピングかっこ)を導入します。
1 + 2 * 3 (1 + 2) * 3
はそれぞれ、
SUM 1 PRODUCT 2 3 PRODUCT SUM 1 2 3
になります。また、丸括弧のもう一つの使い方として可変長引数の実現もあります。これは Lispまんまの表現で、
(SUM 1 2 3 4)
などと書くことが出来ます。
最後に、カジュアルなLogo では TO 〜 END でユーザ手続きを定義できる、機能が追加されました。実は、正規Logo で手続きを定義するのには DEFINE コマンドを使います。これは、
DEFINE "FuncName [[Arg1 Arg2] [MAKE "Hoge SUM THING "Arg1 "256] [OUTPUT PRODUCT THING "Hoge THING "Arg2]]
のように、DEFINE "関数名 [ [仮引数リスト] 本体] という単なるコマンドなのですが *2、対話式環境ではちと使いにくいというのもあるので、カジュアルなロゴでは TO 〜 END を使います。
TO FuncName :Arg1 :Arg2 MAKE "Hoge :Arg1 + 256 OUTPUT :Hoge * :Arg2 END
となります。*3
以上、LOGO入門 (川野 洋 著、倍風館 1987)から、そのまんままとめてみました。(この時代の「○○言語入門」はどうして 「○○言語の作り方入門」になってるのが多いのだろう・・・)
* * *
さて、今に買った訳じゃないこの本から、何で今頃 Logo文法をまとめているかというと・・・・・・それは次回につづくのです。
*1:どうも 「LOGO入門」 の著者 川野さんの造語のようです
*2:でも手元の処理系で、これ通りにDEFINE 手続きを認識するのは MSWLogo だけ(T△T ..ロゴ坊 は DEFINE 自体はあるのだけれど、 引数が :Arg1 のようなドット表記じゃないと怒られます。ロゴライターに至っては DEFINE なんて知らないと言われる。もう「正規Logo」なんて昔の言語仕様なのかしら....orz
*3:Logo では手続きは 戻り値を持たない「コマンド」と戻り値を持つ「オペレーション」に区別されます。ユーザ定義手続きでは、本体中で OUTPUT で値を返せば「オペレーション」に、返さなければば「コマンド」になります。