Inferno-limbo

Limbo

Links

http://www.vitanuova.com/inferno/papers/limbo.html

http://www.vitanuova.com/inferno/papers/dev.html

http://p9c.cc.titech.ac.jp/inferno/module.html

2003/10/17にamazonで買っちゃいました。届くのが楽しみです。 2003/10/27に届きました。でも、暇がなくてまだ読んでません… 2chでのつっこみによると、この本は4thでは半分ぐらい意味がなくなってい るらしい…が〜ん。

Inferno Programming Book : An Introduction to Programming for the 
Inferno Distributed System 
ISBN:0470849711 (Hard cover book) Atkins,
Martin /Pike, Rob /Trickey, Howard / Publisher:John Wiley & Sons Inc
(Sd) Published 2003/10

こっちが最新らしいが、まだ出ていないらしいです。(2003/10/30現在)

特徴

Over View

sample program

Hello World

    implement Myprog;
    include "sys.m";
            sys: Sys;
    include "draw.m";
    
    Myprog: module {
            init: fn(ctxt: ref Draw->Context, argv: list of string);
    };

    init(ctxt: ref Draw->Context, argv: list of string)
    {
            sys = load Sys Sys->PATH;
            sys->print("Hello, world\n");
            for (; argv!=nil; argv = tl argv)
                    sys->print("%s ", hd argv);
            sys->print("\n");
    }

"Hello, world"のところに日本語を書いても平気。(ただし、フォントがあれば)

compile

上記のソースコードを適当なファイル名(ここではMyprog.b)で保存して、

> limbo Myprog.b

すると、Myprog.disっていうファイルができる。

>./Myprog.dis
とかやると実行される。

sample code 解説

01: implement Myprog; # Myprogというmoduleを実装するぜ、ということを宣言。 02: include "sys.m"; # /moduleにある"sys.m"というファイルをinclude 03: sys: Sys; # sysという変数はSysを表すことを宣言 04: include "draw.m"; # /moduleにある"draw.m"というファイルをinclude

05: Myprog: module { 06: init: fn(nil: ref Draw->Context, argv: list of string); 07: };

08: init(nil: ref Draw->Context, argv: list of string) 09: { 10: sys = load Sys Sys->PATH; 11: sys->print("Hello, world\n"); 12: for (; argv!=nil; argv = tl argv) 13: sys->print("%s ", hd argv); 14: sys->print("\n"); 15: }

3行目の宣言は、Sys moduleのinstanceを利用するときに重要となる。

5-7行目はこのmoduleで実装されるcommandの宣言。このmoduleではinitという 関数がref Draw->Contextとlist of stringsという二つの引数をとって実装さ れるって宣言している。

"nil : "は返り値がないことを示す。 "ref Draw->Context"はdraw.m moduleを呼び出して、グラフィックに 書くときにreferされるっていうことを示す。 このmoduleでは単にprintするだけなので、結局これは使われない。

limboでは、Cのmainみたいに必ずinitで始めなければならない、ということはない。 でも、習慣的にinitを使う。

10行目はSys moduleと接続する。Sysをsysって宣言してるのかな?

11行目で表示。Sysではなくsysで使用している。

12行目と13行目のforは、iterater。hdはHeadをtlはTailをさしている。14行目 は改行を出しているだけ。

Keyword

以下の文字は予約語。

            adt     alt     array   big
            break   byte    case    chan
            con     continue        cyclic  do
            else    exit    fn      for
            hd      if      implement       import
            include int     len     list
            load    module  nil     of
            or      pick    real    ref
            return  self    spawn   string
            tagof   tl      to      type
            while

特殊文字

    \'              single quote
    \"              double quote
    \\              backslash
    \t              tab
    \n              newline
    \r              carriage return
    \b              backspace
    \a              alert character (bell)
    \v              vertical tab
    \udddd  Unicode character named by 4 hexadecimal digits
    \0              NUL

TypeとObject

limboにはObjectは三つある。

type

文法は以下の通り。

    type:
            data-type
            function-type

data-type

以下の種類がdata-typeの中にある。

    data-type:
            byte
            int
            big
            real
            string
            tuple-type
            array of data-type
            list of data-type
            chan of data-type
            adt-type
            ref adt-type
            module-type
            module-qualified-type
            type-name
    
    data-type-list:
            data-type
            data-type-list , data-type

Channel Type

chan of data-type

system中の他のAgentとの通信を確立する。 channelは、ローカル上のプロセス 間通信に使われる。

chan of (int, string)

はintegerとstringのtupleを送信するchannel typeである。

            c <-= (123, "Hello");

は、このようなchannel(ここではC)の宣言と初期化を示している。

Function Types

Function typeは返値を持つ。その文法を下記に示す。

    function-type:
            fn function-arg-ret
    
    function-arg-ret:
            ( formal-arg-listopt )
            ( formal-arg-listopt ) : data-type
    
    formal-arg-list:
            formal-arg
            formal-arg-list , formal-arg
    
    formal-arg:
            nil-or-D-list : type
            nil-or-D : self refopt identifier
            nil-or-D : self identifier
            *
    
    nil-or-D-list:
            nil-or-D
            nil-or-D-list , nil-or-D
    
    nil-or-D:
            identifier
            nil

例を下記に示す。

            fn (nil: int, nil: int): int
            fn (radius: int, angle: int): int
            fn (radius, angle: int): int

宣言

            i, j: int = 1;
            r, s: real = 1.0;

このとき、iとjはintとして宣言され、両方に1が入る。rとsはrealとして宣言さ れ、両方に1.0が入る

            identifier := expression ;
            ( identifier-list ) := expression ;
も同じ意味。

つまり、以下の二つは同じ意味。

下のも可能。

6.2 Constant declarations

            Seven: con 3+4;
Sevenは、constant 7とまったく同じ意味になる。

con typeの宣言中では、iotaという識別子は特別な意味が生じる。

It is equivalent to the integer constant 0 when evaluating the expression for the first (leftmost) identifier declared, 1 for the second, and so on numerically. For example, the declaration

            M0, M1, M2, M3, M4: con (1<<iota);

declares several constants M0 through M4 with the values 1, 2, 4, 8, 16 respectively.

6.3 adt declarations

adtはabstract data typeという意味である。

After an adt-declaration, the identifier becomes the name of the type of that adt. For example, after

    
            Point: adt {
                    x, y: int;
                    add: fn (p: Point, q: Point): Point;
                    eq: fn (p: Point, q: Point): int;
            };

the name Point is a type name for an adt of two integers and two functions; the fragment

            r, s: Point;
            xcoord: int;
            ...
            xcoord = s.x;
            r = r.add(r, s);

makes sense. The first assignment selects one of the data members of s; the second calls one of the function members of r.

9 Statements

9.1 Expression statements

            expression ;

9.3 Blocks

{}で記述を囲むと、scopeがその中だけに制限される。Cと同じ。

9.4 Conditional statements

The conditional statement takes two forms:

            if ( expression ) statement
            if ( expression ) statement else statement

9.5 Simple looping statements

The simple looping statements are

            labelopt  while ( expressionopt ) statement
            labelopt  do statement while ( expressionopt ) ;

9.6 for statement

            labelopt  for ( expression-1opt ; expression-2opt ; expression-3opt ) statement

これは下記と同じ。

    
            expression-1 ;
            while ( expression-2 ) {
                    statement
                    expression-3 ;
            }

9.7 case statement

The case statement transfers control to one of several places depending on the value of an expression:

            labelopt  case expression { qual-statement-sequence }

実際の使用例。

            case i {
            1 or 8 =>
                    sys->print("Begins with a vowel\n)";
            0 or 2 to 7 or 9 =>
                    sys->print("Begins with a consonant\n");
            * =>
                    sys->print("Sorry, didn't understand\n");
            }

9.8 alt statement

The alt statement transfers control to one of several groups of statements depending on the readiness of communication channels. Its syntax resembles that of case:

            labelopt  alt { qual-statement-sequence }

outchan := chan of string; inchan := chan of int; alt { i := <-inchan => sys->print("Received %d\n", i); outchan <- = "message" => sys->print("Sent the message\n"); }

                    i := <-inchan =>
                            sys->print("Received %d\n", i);

9.9 pick statement

The pick statement transfers control to one of several groups of statements depending upon the resulting variant type of a pick adt expression. The syntax resembles that of case:

    
            labelopt  pick identifier := expression { pqual-statement-sequence }

9.10 break statement

The break statement

               break identifieropt ;

9.11 continue statement

The continue statement

    
            continue identifieropt ;

9.12 return statement

return expressionopt ;

f, g: fn(a: int); f(a: int) { . . . return g(a+1); }

これは下記と同じ。

f(a: int) { . . . g(a+1); return; }

9.13 spawn statement

spwanは、新しいthreadを作り出す。

    
            spawn term ( expression-listopt ) ;

9.14 exit statement

              exit ;

10 Referring to modules; import

For example, after the module and variable declarations

            M: module {
                    One: con 1;
                    Thing: adt {
                            t: int;
                            f: fn();
                    };
                    g: fn();
            };
            m: M;

th1: M->Thing; th2: m->Thing;

モジュールを呼び出すには、以下のようにする。

            m->g();
            m->th1.f();