UCBLOGO

UCBLogo (Berkeley Logo)

Logo は 1960年代後半に MIT の人工知能研究所で Seymour Papert さんを中心に開発されたプログラミング言語です。 Basic と Lisp の良い面を合わせ持つような、教育用にも優れた言語なのですが、 「教育向き=子供用で実用ではない」と思われてしまうのか、 言語としてはあまり普及しませんでした。 特徴であるタートルグラフィックスも却って「オモチャ」と受け取られた感があります。
現在ではマルチメディア対応など視覚面を拡張した製品がいくつかありますが、 UCBLogo は言語としての側面を重視した実装になっています。

(右図をクリックすると大きく表示します。)

作者: Brian Harvey さん 他
ホームページ: http://www.cs.berkeley.edu/~bh/logo.html
バージョン: 5.3 (2003/02/01)
ライセンス: GPL
README を読む
付属ドキュメント User's Manual

使い方

インストールしたら、 適当なターミナル・エミュレータから

$ logo

で起動します。

Welcome to Berkeley Logo version 5.3
?

プロンプト ? はコマンド入力を待っていることを示しています。 終了のコマンドは bye です。

Logo はインタープリタですからコマンドを入力(リターンキーまで)すると ただちに実行されます。

? print "Hello
Hello

Logo プログラムを構成するのは WORD です。WORD は、英語のそれと同じく 空白で区切られる文字列です (他に +-*/ などの演算記号なども区切り文字になります)。 WORD には値を与えたり procedure を割り当てたり出来ます。 上の print はあらかじめ定義された procedure で、 primitive と呼ばれます。 Hello も WORD ですが、ここでは WORD の文字列そのものを使うために 先頭に " を付けます (Lisp だと ' ですね)。

print の help を見るには次のようにします。 " を付けるのを忘れないように。

? help "print
PRINT thing
PR thing
(PRINT thing1 thing2 ...)
(PR thing1 thing2 ...)

        command.  Prints the input or inputs to the current write stream
        (initially the terminal).  All the inputs are printed on a single
        line, separated by spaces, ending with a newline.  If an input is a
        list, square brackets are not printed around it, but brackets are
        printed around sublists.  Braces are always printed around arrays.

print に2つの引数を与えると

? print "Hello "World!
You don't say what to do with World!

とエラーになりますが、カッコで囲むと複数の引数を受け付けます。

? (print "Hello "World!)
Hello World!

Logo ではコマンドは引数も含めて1行内に書く必要がありますが、カッコの中は 行を分けても構いません。そのときはプロンプトとして ~ が出ます。

? (print "Goodby
~ "World!)
Goodby World!

入力の最後を ~ にすると強制的に次の行に継続できます。

? print "longlong~
~ line
longlongline

1行に複数のコマンドを書くのは構いません。

WORD に値を与えるのは make です。

? make "Hello 123
? print thing "Hello
123
? print :Hello
123

WORD の値を取り出す primitive は thing ですが、 単に WORD の先頭に : を付けるだけで同じ意味になります。 ただし、UCBLogo では、": も付かない WORD が現れた場合は、

例えば World に procedure も値もないとすると

? print World
I don't know how  to World

Logo では文字列と数値の明確な区別はありません。数値として判断できる文字列は それ自身が値と見なされます。

? print 23
23
print 2+3
5

23 も WORD ですから本当に値を与えることもできます。 でもやめましょうね。

? make "23 45
? print 23
23
? print :23
45

WORD の文字列そのものをデータとする場合以外は 英字の大文字小文字は無視されます。 日本語など2バイト文字の使用は考慮されていませんが euc-jp なら特に問題なく使えるようです。

? print "こんにちは
こんにちは
? make "百 100
? print 百
100

WORD の文字列に空白を含めるには \ を空白の前に置きます。 または全体を | で囲みます。

? print "Hello\ World!
Hello World!
? print "|Hello World!|
Hello World!

WORD を並べて [] で囲むと LIST です (やっと Logo らしくなってきました)。 LIST の中では " を付けません。

? print [Hello World!]
Hello World!

LIST の形のままプリントするには show を使います。

? show [Hello World!]
[Hello World!]

LIST の先頭の要素を取り出したり、LIST に要素を付け加えたり、連結したりすることができます。

? show first [Hello World!]
Hello
? show butfirst [Hello World!]
[World!]
? show fput "Goodby [World!]
[Goodby World!]
? show sentence "Hello [World!]
[Hello World!]
? show list "Goodby [World!]
[Goodby [World!]]

これは Lisp に似ています (first は car、butfirst は cdr ですね) が、Logo では first などは WORD に対しても行えます。

? show first "Hello
H
? show butfirst 7*15
05

なお、LIST の中では +-*/ などは WORD の区切りになりません。

? print 1+2
3
? print first [1+2 abc]
1+2

procedure を定義するのは to です。 to は特別な構文を持ち、同じ行に他のコマンドは書けません。

? to fact :n
>   if :n = 0 [output 1]
>   output :n * fact :n-1
> end
fact defined
? print fact 5
120

これは階乗を計算します。 to のあとに procedure名 と引数の並びを入力すると プロンプトとして > が出てきます。 output は procedure の値を返します (output のない procedure は値を返しません)。 end で procedure の定義が終わります。

これは再帰呼び出し (recursion) の例ですが、 上のような、手続きの最後に自身を呼び出す tail recursion は Logo ではスタックを消費しないよう最適化されます。 限界を試そうとして

? to for_ever
>   type "A
>   for_ever
> end
for_ever defined
? for_ever

とすると、本当にいつまでも終わりません。 強制的に終わらせるには Ctrl-C (Ctrl を押しながら C を押す) してください。

procedure の内部では、その procedure を呼び出す直前の環境で定義されていた変数はすべて参照したり再定義したりできます。procedure の内部 (およびそこから呼び出される procedure) だけで参照できる変数は local (または make の代わりに localmake) で定義できます。引数は local になります。

つまり、procedure 内に現れる local でない変数の実体は、それを呼び出した環境で決まります。 このような振る舞いは dynamic scope rule といいます。 例を示します。

to printx
  print :x
end

to a
  local "x
  make "x 2
  printx
end

make "x 1
a
printx

これは 2 と 1 を出力します。

procedure を定義したあとで (いや、前でもいいですが) 編集するには

? edit "fact

のようにします。デフォルトでは vi が起動します (オリジナルでは jove というエディタになっていますが変更しています)が、環境変数 EDITOR が定義されていればそれが起動します。 edall とするとすべての procedure (とトップレベルで定義された 変数) を編集できます。

定義した procedure をファイルに保存するには、

? save "file_name

ファイルから読み込むのは

? load "file_name

Logo では procedure を動的に書き換える (まあ Lisp では当たり前ですが) こともできます。 UCBLogo では template 機能などおもしろい拡張がいろいろあります。

最後にタートルグラフィックスの例です。 有名なヒルベルト曲線を書いてみましょう。プロンプトは省略します。

to hDraw :level :turn
    if :level > 0 [right :turn hDraw :level-1 -:turn left :turn
        forward :s
        hDraw :level-1 :turn right :turn
        forward :s
        left :turn hDraw :level-1 :turn
        back :s
        left :turn hDraw :level-1 -:turn right :turn]
end

to hilbert :n
    make "size 300
    clearscreen
    penup
    setxy -:size/2 -:size/2
    pendown
    hideturtle
    make "s :size/((power 2 n) - 1)
    hDraw :n 90
end

hilbert 5

インストール

LinuxMLD 5,6,7 用の RPM ucblogo-5.3-1_mlb1.i386.rpm (812,544 bytes) をインストールします。
rpm コマンドでインストールするにはスーパーユーザになって

# rpm -i ucblogo-5.3-1_mlb1.i386.rpm

とします。
MLD 5,6 では Gnome の GUI でインストールすることもできます。

その他

html ドキュメントは /usr/share/logo/docs/html/usermanual.html をみてください。PS ファイルは /usr/share/logo/docs/usermanual.ps、 プレーンテキストの usermanual は /usr/share/doc/ucblogo-5.2/usermanual にあります。
usermanual で言及されている「Computer_Science_Logo_Style」からの例題がいくつか /usr/share/logo/csls/ にあります。 (pascal は Logo で書かれた Pascal コンパイラで、 cardmultipsorttower はその Pascal のプログラムです。)

UCBLogo の X11 インターフェースは最小限の機能しかなく (usermanual には書かれてませんが、マウス位置を取得する mousepos はあります)、 特に再描画をしないので他のウィンドウに隠れると消えてしまいます。 ソースを見るとイベントドリブンでは処理していないのも気になる。 gnuplot のように描画部分を別プロセスにしてしまうのがいいのかもしれません。 コマンドヒストリーも欲しいですね。どなたか contrib してみませんか。

参考

Web 上の参考になるページを御紹介します。

Logo は一時期 LEGO を制御する言語として使われていたのですが、その発展形の MindStorms では 別のシステムが採用されてしまいました。

「MindStorms」はパパートさんの著書 『Mindstorms : Children, Computers, and Powerful Ideas』(1980) (邦訳は『マインドストーム−子供、コンピューター、そして強力なアイデア』 奥村貴世子訳、未来社) のタイトルでもあります。

[2002/12/21 作成] [2005/09/06 更新]


このページに関する御意見、御要望を science@mlb.co.jp までお寄せ下さい
Copyright © 2002-2005 Media Lab. All Rights Reserved.