前回は、cygwinにGoogleで開発している関数型並行プログラミング言語"Go"をインストールしようとして失敗してしまった話をしました。

今回は、VMware上のUbuntuでインストールに再挑戦してみたいと思います。

ビルドまでの準備


Goにはgccを利用したものとネイティブなものがあるそうですが、今回はネイティブな方インストールします。

まず最初にmercurialというパッケージが必要になるそうで黙ってインストール。その他、環境変数を設定して、ソースをダウンロードします。

% sudo apt-get install mercurial
% mkdir ~/src/go
% export GOROOT=$HOME/src
% export GOOS=linux
% export GOARCH=386
% export GOBIN=$HOME/bin
% hg clone -r release https://go.googlecode.com/hg/ $GOROOT
requesting all changes (ソース取得の所要時間3分程)
:


ソースの取得はサックリ行きました。

Goのビルド



% cd $GOROOT/src
% ./all.bash (ビルトの所要時間10分程)
 :
--- cd ../test
N known bugs; 0 unexpected bugs


とエラーメッセージも出ずビルドも簡単にできました。

Hello Worldでコンパイルと実行を試す



サンプルのコードをviで書きます。

% vi hello.go

package main
import "fmt"
func main() {
fmt.Printf("hello world\n");
}


インポートするパッケージにはダブルクオートがあるのに、なんでパッケージ宣言にはクオートが無いのか意味がわかりません。

で、コンパイルとリンクです。

% 8g hello.go
% 8l -o hello hello.8
% ./hello
hello world


おお、動いた。

パッケージを使った例を書いてみる



パッケージの使い方を知るために、execパッケージのテストコードから"who"のプログラムをフォークして標準出力に出すようなプログラムを書いてみます。

package main
import ("io"; "exec"; "fmt";)

func main() {
 cmd, err1 :=
  exec.Run("/usr/bin/who", []string{},
    nil, exec.DevNull, exec.Pipe, exec.DevNull);
 if err1 != null {
fmt.Printf("err1\n");
}
 buf, err2 := io.ReadAll(cmd.Stdout);
 if err2 != nil {
  fmt.Printf("err1\n");
 }
 fmt.Printf(string(buf));
}


例題その(2)としてencoding/base64の例題で、文字列"aaa"をBase64で円コーディングして表示してみる。

package main
import ("fmt"; "encoding/base64"; "strings";);
func main() {
 s := "aaa";
 buf := make([]byte, base64.StdEncoding.EncodedLen(len(s)));
 base64.StdEncoding.Encode(buf, strings.Bytes(s));
 fmt.Printf(string(buf) + "\n");
}


実行してみると

% 8g t_base64.go
% 8l -o t_base64 t_base64.8
% ./t_base64
YWFh


うん、ちゃんとうまくいってる。

さてと、セキュリティ関係で遊べそうなパッケージは無いか?



Goのパッケージの説明はココにあるんですが、自分が(暗号、PKI、セキュリティ関係で)使いそうなのは

- asn1
- bignum
- crypto/{aes,hmac,md5,rsa,sha1,x509}
- encoding/base64

といったところでしょうか。例えば(crypto/x509はほぼカラッぽなので)encoding/base64の例でも書いてみるかと思い、マニュアルを開いてみるとパッケージのソースコードはココにあります。

で、パッケージのテストコードは一つ上のこちらのURLにあるわけです。

で、使ってみるかと思ったところで、今日はタイムオーバー、、、

プログラミング言語Goの感想をぶっちゃけちゃうに、、、



プログラミング言語Goを昨日よりはまともに見てみたんですが、正直「つかえね〜〜」っていう気がしてきました。

C#, Java, JavaScript、(J)Ruby, (J)Python, Perlなどのモダンなプログラミング言語の必須要素って


  • 組み込み、サードパーティを含めて豊富なクラスライブラリが利用できること

  • 文字列の扱いに優れていること。部分文字列や検索、一致、置換、正規表現などが提供されていること。

  • リストやタプルなどが簡単に表現できやスライス、繰り返し処理がシンプルに書けること。

  • オブジェクト指向、または、オブジェクト指向っぽく書けること

  • 例外処理を記述できること



かなぁと思っています。そう考えると"Go"には、モダンなプログラミング言語として以下は致命的かと思えてくるわけです。(上の2つは言語設計のところなので今後多分良くなりようがありません。)


  • オブジェクト指向っぽくは書けず純粋な関数型言語

  • 例外処理が書けない

  • 文字列を扱う関数が弱く、正規表現が使えない



昔から並行(concurrent)プログラミングには興味があって、Concurrent-C、Concurrent Prolog、GHC(KL/1)など見てきましたが、確かこれらが作られて結局あまり実用にはならなかった後、POSIX ThreadやJavaのThreadが出てきたような気がします。もうそろそろ、Threadをうまく活用しながらThreadを意識せず書けるような並行プログラミング言語が出てきてもいい頃かなぁと思っていました。

"Go"にはそういう意味で、ちょっと期待してしまったんですが、モダンなプログラミング言語の必須要件と思われるような仕様を無くしてまでメモリリークとかが発生しない安全な並行プログラミングが必要かと思うわけです。

今はまだ、仕様もクラスライブラリも小さいので問題になりませんが、システムが膨れてくると破綻して、いずれ消え行く運命なんだろうなぁ、、、と思ってます。

<追記2009.11.16>
コンパイル時間が速いのがメリットと書かれた記事を見たんですが、そもそも大規模システムの開発に向かないので、コンパイル時間の遅さに閉口するようなことは無いのでは?と思いました。