2009-11-20[金] go言語

話題のgoogleのgo言語、おもしろそうですね。
ネイティブコード吐し、 ケン・トンプソンとかロブ・パイクとかの名前で釣られます。
結構、わくわくです。始めてD言語を知ったときと同様に。
でもって、いろいろな失望もD言語と同様:)
まあこれから変わっていくんだろうけど.

とりあえず、確かにC言語系だけれど、perl以上に似ていない。
java,C#等のC系しか使ったことない人だと詐欺に思うかも。

でも、javaやC#が、C/C++ユーザーの習慣に妥協した、 型宣言やビット演算子の順位等の'不味い仕様'の部分にも手をつけていて、 基本的な部分での記述量を減らす工夫が多々あり、

  • 名前 型 順の宣言になってるとか、
  • 型も*intのようにCと逆(英語の語順?)だったりとか、
  • 変数宣言が初期値からの型推論されるのは当然としてさらに :=で簡略表記できるとか、
  • 関数が複数の値を簡単に返せるとか、
  • ビットクリア演算子&^が追加されたりとか、
  • ビット演算子の順位が&,&^,<<,>>が*,/,%と同位、|,^が+,-に同位になってたりとか(<<8+bが合法)、
  • 制御文if 条件式 {文} で{}必須で条件に()不要だとか、
  • while,do while 無しで高機能な for を用意したりとか、
  • packageのアクセス制御指定を名前の先頭が大文字(公開)か小文字(非公開)で設定できたりとか、
  • スレッドを簡単に生成できたりとか

C風というには、あまりに思い切りがいいです。結構好みです.

ビットクリア演算子は、ビット演算が敬遠されるご時勢にいれてくるのは、 執念か何かでしょうかね. 関数の他値返しも今風だけれどタプルなんてクッションも無く... アセンブラからCに移った人のボヤキがよみがえってきたり.


プログラムの分割については、 公開/非公開の制御を classベースでなく package ベースのみ、ってのもばっさり感があり.

指定方法が、名前の先頭文字が、 大文字なら外部(public)公開、小文字なら内部(private)、 というネーミングルール強制というのもそうだし.

構造体メンバー変数についても、構造体固有のアクセス制御ができないだけで、 メンバー変数名の名前の大小文字で、packageレベルでは行われる。 もちろん同一パッケージ内の他の関数からも丸見えですが、 このへんはD言語での同一ファイル内の非メンバー関数をfriend扱いするのと同じ考え方でしょうね.

パッケージの規模を大きくしすぎず設計しろよ、ってことで.


クラス関係は C++やjava等のclassがもつ(継承とかの)強力さをあえて抑えることで、 必要以上に強力な機能を濫用して発生してた複雑さを軽減しようって感じでしょうか.

継承はないけど struct のメンバー関数は、struct宣言と同一package内なら 別ファイルでも宣言できるので、既存のパッケージのstructの拡張がわりと容易のよう.

... と、まあ、見てるとわくわくするのですが、

  • GC必須とか、生ポインタ演算無しとか、
  • ロウレベル・プログラミングを捨ててかかっている. (もちろんそれがメリットでもあるんだけれど)
  • ジェネリック(template)関係がない.
  • 内/外やポイント先に対する読書制御(const,mutable)が無い。
    D言語も最初は無しですまそうとしてたけど
  • 結局D2でconst,immutable指定するようになったし、 スレッドを思うと要求あるような. (で、個人的にはデフォconstでmutable指定のほうが)

なあたりで、様子見な感じになってしまうのでした. (例外が無いのは個人的にはok)


ちょこっと弄ってみましたが、 package のコンパイルは、 同一packageのソースはコンパイラに一度に指定する 必要があるぽい。

6g foo.go foo_sub.go

逆に違うパッケージは一緒に指定しちゃダメ.

生成されるオブジェファイルは .o 等と違い go 固有の情報を含んでるみたいで import "foo" で参照されるファイルはソースじゃなくて .6(.8) のよう.

なんで、依存関係を考慮した順番にコンパイルしないとダメかも... D言語での rebuild や bud 相当のツールがほしいところです.

GCCベースのほうはどうなのかは未見.