カッコの無い世界

何となくLogo を使ってみたくなりました。(C4 の影響かもしれない)


Logo は 乱暴に言ってしまえば Lispプリプロセッサのようなもので、

カジュアルなLogo → 正規Logo → Lisp 

と順番にほぼ1対1で変換可能になっています。

「カジュアルなLogo」とか「正規Logo」とはは、あまり聞き覚えのない言葉ですが*1、Logo の文法は 2段階変換になっていて、正規Logo は 単純に Lisp から カッコを取っ払ったもの、カジュアルなLogo はそれをもう少しユーザフレンドリにしたものだそうです。

正規Logo

S式からカッコを取っ払う手段として、Logo は

  1. クォートされていないのは全て 関数だ!(つまり直前でカッコがひらいている)
  2. その関数が何個引数を取るかあらかじめ解っていれば、閉じ括弧の位置は判断できる

で対応しました。(シンプル!)例えば

(F 'x (G 'y 'z))

という S式は

とそのまま変換されます。(Logo のクォートは 「"」を使う)

じゃあ、クォートされていないシンボルはどうするの、という話は、THING をつけて対応します。(Lisp とは逆で、何もしないとクォート、THING を着けて評価 になります)したがって、

(F x (G y z))

は、

になります。

Logo も Lisp 同様、「リスト」を持っています。Logoのリストは Lisp のモノそのまんまですが、丸括弧「()」の代わりに 角カッコ「[]」を使います。そして Lisp と違い、何も着けないと クォート、評価する場合は RUN を着けます。

(SUM 1 (SUM 2 3))

は、

になります。基本的にこれだけです。

カジュアルなLogo

カジュアルなLogo になると、もう少しがんばるようになります。

まず、数値アトムの暗黙のクォート処理が入ります。数値のみの語を見つけたら勝手にクォートを着けてくれます。つまり正規Logo

をカジュアルなLogo では、

と、スッキリ書くことができます。


次になまら THING! THING! うるさいプログラムになりがちなので、ドット表現と呼ばれる「:」を使った略記法を導入します。

は、

と簡潔に書くことができるようになります。(Lisp の 「quote」 と 「'」のちょうど逆ですね)

また、カジュアルなLogoは 二項演算子にも対応します ( + とか - とか)。 これは単純にカジュアルなLogo中で

を見つけたら正規Logoにコンバートするときに

に変換するだけです。ただし中記法 を導入すると演算子の優先順位が気になるようになるので、強制的に優先順位に逆らった評価をさせるために 丸括弧(グルーピングかっこ)を導入します。

はそれぞれ、

になります。また、丸括弧のもう一つの使い方として可変長引数の実現もあります。これは Lispまんまの表現で、

などと書くことが出来ます。

最後に、カジュアルなLogo では TO 〜 END でユーザ手続きを定義できる、機能が追加されました。実は、正規Logo で手続きを定義するのには DEFINE コマンドを使います。これは、

のように、DEFINE "関数名 [ [仮引数リスト] 本体] という単なるコマンドなのですが *2、対話式環境ではちと使いにくいというのもあるので、カジュアルなロゴでは TO 〜 END を使います。

となります。*3

以上、LOGO入門 (川野 洋 著、倍風館 1987)から、そのまんままとめてみました。(この時代の「○○言語入門」はどうして 「○○言語の作り方入門」になってるのが多いのだろう・・・)


* * *


さて、今に買った訳じゃないこの本から、何で今頃 Logo文法をまとめているかというと・・・・・・それは次回につづくのです。

*1:どうも 「LOGO入門」 の著者 川野さんの造語のようです

*2:でも手元の処理系で、これ通りにDEFINE 手続きを認識するのは MSWLogo だけ(T△T ..ロゴ坊 は DEFINE 自体はあるのだけれど、 引数が :Arg1 のようなドット表記じゃないと怒られます。ロゴライターに至っては DEFINE なんて知らないと言われる。もう「正規Logo」なんて昔の言語仕様なのかしら....orz

*3:Logo では手続きは 戻り値を持たない「コマンド」と戻り値を持つ「オペレーション」に区別されます。ユーザ定義手続きでは、本体中で OUTPUT で値を返せば「オペレーション」に、返さなければば「コマンド」になります。