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 コンパイラで、
card
、multi
、psort
、tower
はその Pascal のプログラムです。)
UCBLogo の X11 インターフェースは最小限の機能しかなく (usermanual には書かれてませんが、マウス位置を取得する mousepos はあります)、 特に再描画をしないので他のウィンドウに隠れると消えてしまいます。 ソースを見るとイベントドリブンでは処理していないのも気になる。 gnuplot のように描画部分を別プロセスにしてしまうのがいいのかもしれません。 コマンドヒストリーも欲しいですね。どなたか contrib してみませんか。
Web 上の参考になるページを御紹介します。
兼宗さんは現在は新しい教育用言語 ドリトル を開発されています。Java で書かれているようなので Linux でも動作させられるようです。
「 Logoで知る認知科学 ―工学のための教育メモランダム」 (東京電機大学出版局, 1999) という本を書いておられます。 同書の一部を TeX のソースで公開されています。 取り上げられている logo は、ロゴジャパン(株)のロゴライター (Windows 用) です。ロゴライター は現在 (株)ロゴコミュニティ が販売しているようです。
Macintosh/Windows 用の Terrapin Logo (Terrapin Software の製品) による Logoプログラミングのページ
LCSI (Logo Computer Systems Inc.) 社の MicroWorlds (Windows/Macintosh 用) の日本語版を販売しています。
Logo をベースに、様々なモデリングを並列タートルによって可能にした言語。 Java による実装が公開されています。
Logo は一時期 LEGO を制御する言語として使われていたのですが、その発展形の MindStorms では 別のシステムが採用されてしまいました。
「MindStorms」はパパートさんの著書 『Mindstorms : Children, Computers, and Powerful Ideas』(1980) (邦訳は『マインドストーム−子供、コンピューター、そして強力なアイデア』 奥村貴世子訳、未来社) のタイトルでもあります。