Booがやば過ぎる件

InfoQの以下の記事を読んでBooというCLR上で動作するプログラミング言語に興味を持った。

Boo自体はMonoに付いてくるので名前だけは知っていたけど、実際に触ったことがなかった*1。でもこの記事を読んでPythonベースの言語という点に惹かれてちょっと触ってみることにした。

Booの公式サイトは以下。

Booの特徴は、

らしい。

環境構築

まずは環境構築から。

以下のサイトから最新のバイナリ(boo-x.x.x.xxxx-bin.zip)をダウンロードしてくる。

ダウンロードしたZIPファイルを解凍して、適当なフォルダに配置する(ここでは「D:\Program Files\Boo」にする)。
「bin」フォルダへのパス(ここでは「D:\Program Files\Boo\bin」)を環境変数PATHに追加しておく。

「bin」フォルダに含まれている実行可能ファイルを見てみると、

というのがある。

インタプリタコンパイラがあるということはBooでは、ソースを直接実行するのとexeファイルから実行という二種類の実行形式があるのがわかる。へ〜、これはナウいですね!!

とりあえず開発環境の構築はこれで完了。あとはテキストエディタでしこしこ書いていけばいい。

本格的に使う場合は、Visual Studio 2008用のアドインが開発されているようなので、それを使ったほうがいいかもしれん。

初めてのBoo

じゃあ、とりあえずHelloWorldでもやってみる。

まずは「helloworld.boo」というファイル名でテキストファイルを作る。Booのソースファイルの拡張子は「boo」にする。

こんな感じ。

helloworld.boo
print "hello, world"

これを実行するには、コマンドプロンプトから以下のコマンドを実行する。

PS > booi.exe helloworld.boo
hello, world

うん、特に目新しいことはなし。

実行可能ファイルを作る場合は、コマンドプロンプトから以下のコマンドを実行する。

PS > booc.exe helloworld.boo

コンパイルに成功すると「helloworld.exe」というファイルが作られているはず。これを実行すれば先程と同様の結果が返ってくる。

言語仕様

変数の扱いや制御構文、コメントなどはPythonとほとんど同じなので説明は割愛する。

Booの言語仕様については、以下のURLを参照されたし。

関数の定義

関数の定義はPythonとほとんど同じで「def」で定義する。

# メソッド
def hello(msg):
    print "hello" + msg
hello("world")

おもしろいのがC#のような匿名メソッドを定義できること。もちろんこれはクロージャとしても機能する。

# 匿名メソッド
anonymousHello = def(msg):
    print "hello" + msg
anonymousHello("world")

また、引数の型を指定することもできるので、型安全性を保証することもできる。

def hello(msg as string):
    print "hello" + msg
# エラー
hello(1)

戻り値の型も以下のように指定することができる。

def func() as string:
    return "hoge"

クラスの定義

クラスはPythonと同じく「class」で定義する。

class Hoge:
    pass

o = Hoge()

インスタンス化するにはクラス名の後に「()」を付ければいい。

プロパティ

BooにはC#と同じようにプロパティが用意されていて、以下のように定義することができる。

class Hoge:
    _name as string

    Name:
        get:
            return _name
        set:
            _name = value

o = Hoge(Name: "Hoge")
# Hoge
print o.Name

C#と同じように「get」アクセサ、「set」アクセサを定義する。「get」アクセサだけにして読み取り専用のプロパティを作ったりもできる。

また、プロパティの定義は以下のように書くこともできる。フィールドを定義して、それに「Property」という属性を宣言するだけで自動的にプロパティを作ってくれる。C#3.0の自動プロパティの逆バージョン*2みたいなもの。

class Hoge:
    [Property(Name)]
    _name as string

コンストラクタ & オーバーライド

他にもコンストラクタの定義やメソッドのオーバーライドなんかもできる。

class Person:
   [Property(FirstName)]
   _firstname as string
   [Property(LastName)]
   _lastname as string

   def constructor(firstname as string, lastname as string):
       _firstname = firstname
       _lastname = lastname
        
   override def ToString():
       return "${FirstName} ${LastName}"
        
o = Person("Kouji", "Yamaguchi")
# Kouji Yamaguchi
print o
# Yamaguchi Kouji
print "${o.LastName} ${o.FirstName}"

コンストラクタはPythonでは「__init__」メソッドで定義したが、Booでは「constructor」というメソッドを定義して行う。この辺はわかりやすくていいね。
メソッドのオーバーライドもC#のように明示的に「override」と宣言してやる必要がある。ここではobject型の「ToString」メソッドをオーバーライドしている。

Booにはアクセス修飾子も用意されているので、メソッドやフィールドに対してアクセス制限を設けることもできる。

用意されているアクセス修飾子は、

  • private
  • protected
  • public

とお馴染みのもの。

継承

継承ももちろんできる。

class Person:
    pass
    
class Programmer(Person):
    def hack():
        print "hack"
    
o = Programmer()
o.hack()

多重継承はできないけど、Booにはインターフェースも用意されているので、インターフェースを複数実装することで補える。

メソッドのオーバーロード

BooではPythonと違いメソッドのオーバーロードが許されている。

class Hoge:
    def method():
        print "引数なし"
    def method(arg1):
        print "引数あり"

o = Hoge()
# 引数なし
o.method()
# 引数あり
o.method(1)

これが許されるという事は、Booではメソッドの引数にデフォルト値を設定して、引数を省略するなんて事ができないということになる。これはPython好きには嫌なところかもしれん。

クラスメソッド

クラスメソッドを定義する場合は「static」を頭に付ければいい。

class Hoge:
    static def staticMethod():
        pass

Hoge.staticMethod()

他にも演算子オーバーロードもできるので、C#のクラスでできる事はほとんどBooでもできると考えていい。

他にも色々*3あるけど、面倒になってきたのでまた今度に書く。

言語の印象としては、Pythonからモダンじゃない部分を削って、C#のいい所を持ってきた感じ。PythonC#のハイブリッド言語と言える。

*1:名前がなんかかっこ悪いというのが主な理由

*2:あっちはプロパティを定義したらフィールドが勝手に作られる

*3:インターフェース、構造体、列挙型、マクロ