JavaFX
2009年11月30日
1週間前の話になるが、札幌Java第17回勉強会に参加した。
Maraigue風。:JavaFXが可愛い(言語的な意味で)
以前第13回勉強会において、JavaFXに対して言語としての面白さを感じてきたが、今回扱われた言語「Scala」からも、それに近い面白さを感じられた。
ScalaはJavaFXと同様、Javaバイトコードにコンパイルされて動くコンパイル型言語である。Javaのライブラリを利用できるのもJavaFXと同様である。Scalaは、言語の基本構造は手続き的言語に属するものの、関数型言語としての性質も兼ね備えている。
私がこの勉強会で知ったのはScalaのごく一部であるものの、それでもScalaには「プログラムを書きやすくする仕掛けが多数ある」という点で面白さを感じた。この点はJavaFXも同じである。
ScalaとJavaFXを比べたとき、JavaFXもプログラムの書きやすさを考慮した記法が多数導入されているものの、JavaFXの「書きやすさ」は(JavaFXのそもそもの目的である)GUIアプリケーションの開発で強く現れるのに対し、Scalaのそれはより汎用的だと感じられた。
私がScalaの面白さを強く感じられたのは、私がRubyに慣れていた、すなわちRubyと同様に「手続き型言語ながら、関数型言語の便利な点を多数取り込んでいる」言語であることに起因しているのかもしれない。
今回の勉強会で現れた内容のうち、いくつか(Javaから見て)Scalaに特徴的なコードの例を挙げる。(資料はファイル - java-sapporo | Google グループの「JavaプログラマーのためのScala入門.pdf」にあります)
型推論
scala> var a = 5 // 型を明示した宣言 "var a:Int = 5" をしなくても…
a: Int = 5 // 自動的にIntが指定される
scala> a = 42
a: Int = 42
scala> a = "Maraigue" // 指定した型に反する代入は出来ない
<console>:5: error: type mismatch;
found : java.lang.String("Maraigue")
required: Int
a = "Maraigue"
^
メソッド定義 / クロージャ
// クロージャをリテラルの形で書く(関数リテラル)際は
// "{引数 => 内容}" という形になる
scala> var hoge = {x:Int => x * 3}
hoge: (Int) => Int = <function>
scala> hoge(42) // 変数に代入されたクロージャの呼び出し
res1: Int = 126
// メソッド定義
scala> def test(i:Int, j:Int) = i*j
test: (Int,Int)Int
// 定義されたメソッドは、「_」を付与するとクロージャとして扱える
scala> var func = test _
func: (Int, Int) =< Int = <function>
scala> func(9, 8)
res2: Int = 72
リストリテラル
scala> var int_list = List(5, 7, 8)
int_list: List[Int] = List(5, 7, 8)
// IntのListであると自動的に判断される
scala> var str_list = List("5", "7", "8")
str_list: List[java.lang.String] = List(5, 7, 8)
// java.lang.StringのListであると自動的に判断される
// mapは、リストの各要素に対して、引数として与えられた
// 関数の処理を施すメソッド。
// この場合、"i:Int => i * 3" のように "Int" を
// 付けなくても、メソッドの呼び出し元が List[Int] だと
// 分かっているので、自動的にiはIntと扱われる。
scala> int_list.map(i => i * 3)
res1: List[Int] = List(15, 21, 24)
// 同様に以下の例では、自動的にiはjava.lang.Stringと
// 扱われる。
scala> str_list.map(i => i * 3)
res2: List[String] = List(555, 777, 888)
ループ
scala> var int_list = List(5, 7, 8)
int_list: List[Int] = List(5, 7, 8)
scala> for(i <- int_list) println(i * 3)
15
21
24
// 特定の範囲の整数でループさせる方法
scala> for(i <- 1 to 3) println(i * 3)
3
6
9
// 二重ループも簡単に書ける
scala> for(i <- int_list; j <- 1 to 3){
| println("(" + i + "," + j + ")") }
(5,1)
(5,2)
(5,3)
(7,1)
(7,2)
(7,3)
(8,1)
(8,2)
(8,3)2009年08月23日
JavaFXが可愛い。プログラム言語として。 正直そう思った。
今日の札幌Javaの勉強会の午前の部は、JavaFXの紹介であった。
JavaFXとは、GUIアプリケーション、とりわけRIA(Rich Internet Application)の構築を想定した、プログラム言語(JavaFX Script)および必要なライブラリ等を含んだ環境である。
JavaFXは、コンパイルしてJava VM上で利用するという点はJavaと同じであるが、プログラム言語としてはJavaとは別物である。その文法には、多分にJavaScriptなどの要素が含まれている。
次のコードは、文字列を表示したウィンドウを出すだけのJavaFXプログラムである(「javafxtest」パッケージの中に定義した場合)。なおほとんど、NetBeansで新規にJavaFXのプロジェクトを作ったときに、初期状態で書かれているコードそのものである。
package javafxtest;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
Stage {
title: "何かのウィンドウ"
width: 250
height: 80
scene: Scene {
content: [
Text {
font : Font {
size : 16
}
x: 10
y: 30
content: "JavaFXのテスト"
}
]
}
}
このコードを実行すると、次のようなウィンドウが表示される。
コードを見ると、packageとかimportとかはJavaそのものだが、ウィンドウを定義する部分(「Stage」以下)は、コードが全くもってJavaっぽくない。これはむしろJavaScript(JSON)に近い。
Javaは、こういった配列や構造体のリテラル記述は得意でないという印象が私にはある。しかしJavaFXはそんなことは一切なく、むしろ書きやすいと感じた。
他にも以下のようなコードが通る。すなわち、RubyのEnumerable#mapやPythonのリスト内包記法みたいなことが出来る。
// 結果として、[1, 4, 9, 16, ... ] というシーケンス(配列)が返る var squares = for (i in [1..10]) i*i;
最近私は、Rubyの書きやすさに慣れすぎてしまって、他の言語(*1)を使っていると、「もっと楽な記法がないのかなあ」と感じることがよくある。特に上の例に挙げたように、配列や連想配列のような基本的なデータ構造とか、データの一括処理といったものにおいて強くそういうことを感じる。
またRubyは書きやすいものの、実行速度等においてはスクリプト言語ゆえの限界があり、「Rubyの書きやすさはそのままに、コンパイルして利用出来る言語が出ないかな」と考えたりもしていた。
そのような中でJavaFXと出会ったことはかなりの衝撃だった。Javaの「コンパイルしてVM上で動かす」という利点を生かしつつ、面倒な表記を簡略化している(*2)。これは、Rubyに慣れた自分も「進んで使いたい」と感じられた。
ということで、JavaFXでたまに遊んでいきたいと思います。
(*1) 具体的にはC++とかJavaとかVB.NETとか
(*2) 今回の講師のid:shuji_w6e氏によると、GUIアプリ作成を便利にするという意図でこれらのような記法が導入されているとのことであった。しかし、そうでない場合でも非常に便利だと感じた。
2009.8.28 若干修正
