2011年3月30日水曜日

NetBeans IDE 7.0 RC 1 リリース

NetBeans IDE 7.0 RC1 がリリースされました
ダウンロードはコチラからできるようになっております

恒例のスプラッシュです


既に3月も終わろうとしていますが、本日(2011年3月30日)時点では4月4日の正式リリース予定に変更はないようです
何かお気づきの点などありましたら、 ML 等へご連絡頂ければと思います

2011年3月21日月曜日

プログラミング言語 efene について

今回はプログラミング言語 efene についてです

efene は2010年1月にバージョン 0.1 をリリースし、開発がスタートした新しい言語で、 Erlang が提供する、 ErlangVM 上で動作し、Erlang とほぼ 100% の互換性を持つことを目標として実装されています

ErlangVM 上で動く言語としては、 Ruby に似た文法を持つ、 reiaElixir、 LISP 文法の LFE(Lisp Flavoured Erlang) などがありますが、これらは直接 ErlangVM 用のバイトコードを出力するのに対して、 efene は一度 Erlang のソースコードに変換し、 Erlang のソースコードとしてコンパイルして、バイトコードを出力しており、そのため Erlang との高い互換性を実現できています

文法は "{...}" でブロックを表す JavaScript 、またはインデントでブロックを表す Python に似た 2種類の構文で記述が可能で、 C / C++ 、 Java や LL 言語の開発者にはちょっとクセのある Erlang の文法よりもなじみやすいと思います
公式のドキュメントでは JavaScript 形式を efene 、 Python 形式を ifene (idented efene) とし、各拡張子を fn、ifnとするようにしていますが、コンパイラレベルでは区別はないようで、1つのファイルに efene 、ifene の文法が混在していても、コンパイル可能なようです(そんな実装をすることはないと思いますが…)

まずは、efene のコンパイル、実行環境をインストールします
インストールには agner を利用します
(もちろん、 agner を使用せず、ソースから直接ビルドして利用することも可能です)
agner については、コチラの記事を参照ください
ターミナル等で下記コマンドを実行します
$ agner install efene
インストールが正常に完了したら、環境変数 FNPATH を設定します
(今回 .bashrc ファイルに環境変数を記述しますが、お使いの環境に合わせて適宜読み替えてください)
$ vi ~/.bashrc
内容は以下の通りとなります
(例では agner を使用してインストールしたものですので、直接ソースコードよりビルド、インストールした場合は読み替えて設定してください)
export FNPATH=/usr/local/agner/packages/efene-\@master
以上で、 efene を実行する準備が完了です

定番の "Hello World!" は efene では以下のように書きます
@public
run = fn () {
    io.format("Hello World!~n")
}
上記の内容を、ファイル名を "hellofn.fn" として保存します

簡単な文法の説明は以下の通りです
(細かい用語の説明は行っていませんが、ご了承ください)
1行目の "@public" は以降に定義される関数へのアクセス権を表すもので、モジュール外からアクセス可能であることを表します
2行目の "run = fn () {" は "run" という引数を持たない関数を定義しています
関数の実態(処理内容)は以降の行("{...}"ブロック内)に定義しています
3行目の " io.format("Hello World!~n")" は "io" モジュールの "format()" 関数に 表示する "Hello World!~n" という文字列を渡しています
文字列内の "~n" は改行を表します
4行目の "}" は関数の処理部分(ブロック)の終端となります
また、4行目の "}" 記述後に必ず、改行を入れてください
(改行がない場合は、コンパイルエラーとなります)

下記 fnc コマンドを実行し、コンパイルします
$ fnc hellofn.fn
コンパイル後、下記のように実行します
$ fnc -r hellofn run
実行後、下記のように表示されます
(以下の表示は実行したコマンドも含めて記述しています)
$ fnc -r hellofn run
Hello World!

ifene では以下のように書きます
(ファイル名は "helloifn.ifn" として保存します)
@public
run = fn ()
    io.format("Hello World!~n")

efene 版と処理内容の違いは全くないのですが、ブロックを "{...}" ではなく、インデントで表すため、 "{" と "}" がなくなっています
コンパイル、実行も efene 版と同様です
(コンパイル、実行、実行結果をまとめて以下に記述します)
$ fnc helloifn.ifn
Compiling helloifn.ifn
$ fnc -r helloifn run
Hello World!
文法に関する詳細は公式ドキュメントを参照頂ければと思います

次に、 Erlang の関数型言語としての面を紹介する際によく出てくる、 クイックソートというアルゴリズムの実装を紹介します
Erlang 版のクイックソートは以下のように書かれます
(Wikipedia の "Erlang" の項目より引用しています)
%% quicksort:qsort(List)
%% Sort a list of items
 -module(quicksort).
 -export([qsort/1]).
 
 qsort([]) -> [];
 qsort([Pivot|Rest]) ->
     qsort([ X || X <- Rest, X < Pivot]) ++ [Pivot] ++ qsort([ Y || Y <- Rest, Y >= Pivot]).
efene では以下のように記述することができます
@public
qsort = fn([]) {
  []
}

fn([Pivot : Rest]) {
  qsort([X for X in Rest if X < Pivot]) ++ [Pivot] ++ qsort([Y for Y in Rest if Y >= Pivot])
}
ブロックを明示的に記述している分、若干コードの量は増えていますが、ほぼ同様に書くことができます
また、 efene コマンドの機能として、"-t erl" オプションを指定すると Erlang 形式にて出力することが可能です
上記クイックソートのコードを Erlang 形式に出力した場合は以下のようになります
$ fnc -t erl quicksort.fn
-module(quicksort).

-export([qsort/1]).

qsort([]) -> [];
qsort([Pivot | Rest]) ->
qsort([X || X <- Rest, X < Pivot]) ++ [Pivot] ++ qsort([Y || Y <- Rest, Y >= Pivot]).

Erlang のプロセス間通信(非同期メッセージ転送)も使用することができます
@public
ping = fn(0, Pong_PID) {
  Pong_PID ! finished
  io.format("Ping finished~n")
}

fn(N, Pong_PID) {
  Pong_PID ! (ping, self())
  
  receive (pong) {
    io.format("Ping received pong~n")
  }
  
  ping(N - 1, Pong_PID)
}

@public
pong = fn() {
  receive (finished) {
    io.format("Pong finished~n")
  } else receive (ping, Ping_PID) {
    io.format("Pong received ping~n")
    Ping_PID ! pong
    pong()
  } 
}

@public
run = fn() {
  Pong_PID = spawn(pingpong, pong, [])
  spawn(pingpong, ping, [3, Pong_PID])
}
コンパイルし、実行すると、下記のように表示されます
$ fnc -r pingpong run
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Ping finished
Pong finished
Erlang で書かれたライブラリをそのまま利用することも可能です
下記例では Riak という NoSQL データベースの Erlang 用クライアントライブラリ riak-erlang-client を使用する例です
(なお、Riak 、riak-erlang-client に関する詳細やインストール、利用方法などの説明は省略しています)
@public
run = fn () {
  (ok, Pid) = riakc_pb_socket.start_link("127.0.0.1", 8087)
  riakc_pb_socket.ping(Pid)
  Object = riakc_obj.new(<["groceries"]>, <["mine"]>, <["eggs & bacon"]>)
  riakc_pb_socket.put(Pid, Object)
  (ok, O) = riakc_pb_socket.get(Pid, <["groceries"]>, <["mine"]>)
   io.format("~p~n", [O])
}
コンパイルし、実行すると、下記のように表示されます
$ fnc -a ./riakc/ebin -a ./riakc/deps/protobuffs/ebin -r riakc run
{riakc_obj,<<"groceries">>,<<"mine">>,
<<107,206,97,96,96,224,202,96,202,5,82,108,205,73,140,156,46,143,50, 152,18,25,243,88,25,30,73,188,61,198,7,145,96,97,10,11,92,135,41, 12,84,207,254,242,132,56,84,34,58,227,61,92,61,219,145,174,61,152, 194,64,245,108,246,60,90,80,137,110,100,245,58,114,2,152,194,64, 245,172,12,115,68,161,18,223,196,127,195,213,179,79,121,84,140,77, 216,38,175,19,42,204,32,241,27,201,24,134,199,6,26,200,18,89,0>>,
[{{dict,2,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
{{[],[],[],[],[],[],[],[],[],[],
[[<<"X-Riak-VTag">>,87,51,74,53,119,109,67,70,90,50,86,
70,53,115,51,75,82,102,85,106,76]],
[],[],
[[<<"X-Riak-Last-Modified">>|{1300,667392,457396}]],
[],[]}}},
<<"eggs & bacon">>}],
undefined,undefined}
fnc コマンドにて "-s" オプションを付加することでシェルを起動することができます
このシェルでは計算や簡単な入出力が行えます
$ fnc -s
>>> 1+1
2
>>> A = "efene"
[101, 102, 101, 110, 101]
>>> io.format("Hello, ~s.~n", [A])
Hello, efene.
ok
シェルは "Ctrl+C" を押し、さらに "a" を押すことで停止することができます
なお、 Erlang のシェルと比較して、履歴機能がない、束縛した変数の表示や解放などの機能が実装されていなかったりとやや貧弱な面があります
(履歴に関しては、 rlwrap コマンドと一緒に使うことで擬似的に実現することは可能です)
また、簡単な使用には支障はないかと思いますが、表示部分にバグがあるようです
(上記 Riak クライアント利用もシェルにて実行可能なのですが、最後のデータ取得後の表示にてエラーが発生します)

以上のように、 efene は JavaScript / Python ライクな文法で Erlang の強力な機能を使用できる環境を提供してくれます
Erlang の文法に抵抗を感じていた人でも入りやすいと思います
しかし、やはり障害が発生した場合には最終的に Erlang のコードを読むことも多く、 efene を使えば、 Erlang に関しての知識が不要というわけではないので、ご注意ください

Erlang については Voluntas さんのブログ"Erlang に興味を持った人へ" がお勧めです
(Erlang での開発に関する貴重な最新情報が記載されています)

時間があるときに、(今更ですが)基礎文法最速マスターも書いてみたいなと思います

2011年3月10日木曜日

Erlang パッケージ管理ツール Agner を試す

Erlang には様々なライブラリが存在しますが、依存関係やバージョン管理を個別に管理するのは大変です
このような問題に対して、 Perl には CPAN 、 Ruby には RubyGems といったパッケージリポジトリや管理ツールがあります
Erlang では CEANFaxien などが有名ですが、今回は Agner という新しいツールを紹介します

Agner は ClojarsHomebrew の影響を受けたパッケージ管理ツールです
そのため、これらのツールを利用するユーザには使いやすいと思われます
(ちなみにツール名の Agner は "A Giant Nebula of Erlang Repositories" の頭文字を取った略称であり、Erlang の名前の起源となった数学者 Agner Krarup Erlang への敬意を表したものでもあるとしていますが、そのため erlang という単語と組み合わせたときに検索しづらくなってもいます)
なお、管理しているパッケージ数は上記のような有名なツールには劣りますが、主要なライブラリは登録されているように思います

インストールは下記コマンドを実行して行います
$ curl https://github.com/agner/agner/raw/master/scripts/oneliner | sh

下記コマンドを実行して、バージョン情報が表示されれば、インストールは完了です
$ agner version
0.4.12

現在管理しているパッケージ情報の一覧は下記コマンドにて確認できます
$ agner list

パッケージのビルドには下記コマンドを使います
$ agner build [パッケージ名]

パッケージのインストールには下記コマンドを使います(インストールスクリプトが書かれていないパッケージはインストールできません)
$ agner install [パッケージ名]

パッケージのアンインストールには下記コマンドを使います
$ agner uninstall [パッケージ名]

上記以外にも複数のコマンドやオプション指定できますので、詳しくは公式 Wiki を確認頂ければと思います

2011年3月9日水曜日

Mac OS X に Erlang をインストールする

Mac OS X に Erlang をインストールする方法の紹介です

Windows 環境の場合では、公式ページにてバイナリが配布されていますが、Mac用はありません
そのため、ソースからビルドする必要がありますが、 Homebrew などのパッケージ管理ツールを入れていると簡単に導入することができます
Homebrew を使用した Erlang のインストール方法は以下の通りです
(インストール前にパッケージリストを最新にすることをおすすめします)

$ brew install erlang

上記コマンド実行後、github から最新のソースコードを取得し、ビルドします
(2011年03月09日時点での最新バージョンは R14B01 です)
ビルド完了後、下記コマンドを実行して、バージョン情報が表示されれば、インストールは完了です

$ erl -version
Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 5.8.2